sea-react-components 1.3.20 → 1.3.22
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/comments-container/comment-form/index.d.ts +20 -1
- package/dist/components/comments-container/comment-form/index.d.ts.map +1 -1
- package/dist/components/comments-container/comment-form/index.js +30 -4
- package/dist/components/comments-container/index.d.ts +3 -1
- package/dist/components/comments-container/index.d.ts.map +1 -1
- package/dist/components/comments-container/index.js +2 -2
- package/dist/components/jwt-checker/index.d.ts +5 -0
- package/dist/components/jwt-checker/index.d.ts.map +1 -0
- package/dist/components/jwt-checker/index.js +14 -0
- package/dist/components/jwt-token-checker/index.d.ts +1 -0
- package/dist/components/jwt-token-checker/index.d.ts.map +1 -0
- package/dist/components/jwt-token-checker/index.js +0 -0
- package/dist/components/searchable-select/index.js +1 -1
- package/dist/components/select/SelectChips.d.ts +9 -0
- package/dist/components/select/SelectChips.d.ts.map +1 -0
- package/dist/components/select/SelectChips.js +8 -0
- package/dist/components/select/SelectControl.d.ts +13 -0
- package/dist/components/select/SelectControl.d.ts.map +1 -0
- package/dist/components/select/SelectControl.js +12 -0
- package/dist/components/select/SelectDropdownContent.d.ts +23 -0
- package/dist/components/select/SelectDropdownContent.d.ts.map +1 -0
- package/dist/components/select/SelectDropdownContent.js +25 -0
- package/dist/components/select/SelectPlaceholder.d.ts +7 -0
- package/dist/components/select/SelectPlaceholder.d.ts.map +1 -0
- package/dist/components/select/SelectPlaceholder.js +4 -0
- package/dist/components/select/SelectTypes.d.ts +5 -0
- package/dist/components/select/SelectTypes.d.ts.map +1 -0
- package/dist/components/select/SelectTypes.js +1 -0
- package/dist/components/select/SelectView.d.ts +33 -0
- package/dist/components/select/SelectView.d.ts.map +1 -0
- package/dist/components/select/SelectView.js +16 -0
- package/dist/components/select/index.d.ts +5 -5
- package/dist/components/select/index.d.ts.map +1 -1
- package/dist/components/select/index.js +28 -64
- package/dist/components/select/useSelectPortal.d.ts +27 -0
- package/dist/components/select/useSelectPortal.d.ts.map +1 -0
- package/dist/components/select/useSelectPortal.js +110 -0
- package/dist/hooks/use-/index.d.ts +1 -0
- package/dist/hooks/use-/index.d.ts.map +1 -0
- package/dist/hooks/use-/index.js +0 -0
- package/dist/hooks/use-has-permission-access/index.d.ts.map +1 -1
- package/dist/hooks/use-has-permission-access/index.js +4 -0
- package/dist/hooks/use-interval/index.d.ts +2 -0
- package/dist/hooks/use-interval/index.d.ts.map +1 -0
- package/dist/hooks/use-interval/index.js +16 -0
- package/dist/hooks/use-token-watcher/index.d.ts +7 -0
- package/dist/hooks/use-token-watcher/index.d.ts.map +1 -0
- package/dist/hooks/use-token-watcher/index.js +23 -0
- package/dist/hooks/user-has-application-access/index.d.ts.map +1 -1
- package/dist/hooks/user-has-application-access/index.js +2 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/utils/axios/index.d.ts.map +1 -1
- package/dist/utils/axios/index.js +3 -0
- package/dist/utils/cookie/index.d.ts.map +1 -1
- package/dist/utils/cookie/index.js +2 -0
- package/package.json +2 -2
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { useFormik } from "formik";
|
|
1
3
|
import { DTO } from "sea-platform-helpers";
|
|
2
4
|
import * as Yup from "yup";
|
|
3
5
|
export declare const createNewCommentValidation: () => Yup.ObjectSchema<{
|
|
@@ -5,6 +7,21 @@ export declare const createNewCommentValidation: () => Yup.ObjectSchema<{
|
|
|
5
7
|
}, Yup.AnyObject, {
|
|
6
8
|
description: undefined;
|
|
7
9
|
}, "">;
|
|
10
|
+
type Values = {
|
|
11
|
+
objectId: string;
|
|
12
|
+
model: DTO.Comment.CommentSupportedModels;
|
|
13
|
+
description: string;
|
|
14
|
+
parentCommentId?: string;
|
|
15
|
+
};
|
|
16
|
+
export type CommentFormRenderProps = {
|
|
17
|
+
formik: ReturnType<typeof useFormik<Values>>;
|
|
18
|
+
isReplying: boolean;
|
|
19
|
+
isEditing: boolean;
|
|
20
|
+
replyOnComment?: DTO.Comment.IComment;
|
|
21
|
+
cancelReply: () => void;
|
|
22
|
+
cancelEdit: () => void;
|
|
23
|
+
handleKeyDown?: (e: React.KeyboardEvent<HTMLTextAreaElement>) => void;
|
|
24
|
+
};
|
|
8
25
|
export type Props = {
|
|
9
26
|
objectId: string;
|
|
10
27
|
model: DTO.Comment.CommentSupportedModels;
|
|
@@ -15,6 +32,8 @@ export type Props = {
|
|
|
15
32
|
setReplyOnComment: (comment: DTO.Comment.IComment | undefined) => void;
|
|
16
33
|
onCreateCommentSuccess?: (comment: DTO.Comment.IComment) => void;
|
|
17
34
|
onEditCommentSuccess?: (comment: DTO.Comment.IComment) => void;
|
|
35
|
+
renderForm?: (props: CommentFormRenderProps) => React.ReactNode;
|
|
18
36
|
};
|
|
19
|
-
export default function CommentForm({ objectId, model, commentsBaseUrl, commentToEdit, setCommentToEdit, replyOnComment, setReplyOnComment, onCreateCommentSuccess, onEditCommentSuccess, }: Props): import("react/jsx-runtime").JSX.Element;
|
|
37
|
+
export default function CommentForm({ objectId, model, commentsBaseUrl, commentToEdit, setCommentToEdit, replyOnComment, setReplyOnComment, onCreateCommentSuccess, onEditCommentSuccess, renderForm, }: Props): import("react/jsx-runtime").JSX.Element;
|
|
38
|
+
export {};
|
|
20
39
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/comments-container/comment-form/index.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/comments-container/comment-form/index.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,OAAO,EAAiB,SAAS,EAAE,MAAM,QAAQ,CAAC;AAClD,OAAO,EAAE,GAAG,EAAE,MAAM,sBAAsB,CAAC;AAC3C,OAAO,KAAK,GAAG,MAAM,KAAK,CAAC;AAK3B,eAAO,MAAM,0BAA0B;;;;MAQtC,CAAC;AAEF,KAAK,MAAM,GAAG;IACZ,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,GAAG,CAAC,OAAO,CAAC,sBAAsB,CAAC;IAC1C,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B,CAAC;AAEF,MAAM,MAAM,sBAAsB,GAAG;IACnC,MAAM,EAAE,UAAU,CAAC,OAAO,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC;IAC7C,UAAU,EAAE,OAAO,CAAC;IACpB,SAAS,EAAE,OAAO,CAAC;IACnB,cAAc,CAAC,EAAE,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC;IACtC,WAAW,EAAE,MAAM,IAAI,CAAC;IACxB,UAAU,EAAE,MAAM,IAAI,CAAC;IACvB,aAAa,CAAC,EAAE,CAAC,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC,mBAAmB,CAAC,KAAK,IAAI,CAAC;CACvE,CAAC;AAEF,MAAM,MAAM,KAAK,GAAG;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,GAAG,CAAC,OAAO,CAAC,sBAAsB,CAAC;IAC1C,eAAe,EAAE,MAAM,CAAC;IAExB,aAAa,CAAC,EAAE,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC;IACrC,gBAAgB,EAAE,CAAC,OAAO,EAAE,GAAG,CAAC,OAAO,CAAC,QAAQ,GAAG,SAAS,KAAK,IAAI,CAAC;IAEtE,cAAc,CAAC,EAAE,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC;IACtC,iBAAiB,EAAE,CAAC,OAAO,EAAE,GAAG,CAAC,OAAO,CAAC,QAAQ,GAAG,SAAS,KAAK,IAAI,CAAC;IAEvE,sBAAsB,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,CAAC,OAAO,CAAC,QAAQ,KAAK,IAAI,CAAC;IACjE,oBAAoB,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,CAAC,OAAO,CAAC,QAAQ,KAAK,IAAI,CAAC;IAE/D,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,sBAAsB,KAAK,KAAK,CAAC,SAAS,CAAC;CACjE,CAAC;AAEF,MAAM,CAAC,OAAO,UAAU,WAAW,CAAC,EAClC,QAAQ,EACR,KAAK,EACL,eAAe,EACf,aAAa,EACb,gBAAgB,EAChB,cAAc,EACd,iBAAiB,EACjB,sBAAsB,EACtB,oBAAoB,EACpB,UAAU,GACX,EAAE,KAAK,2CAsIP"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import Textarea from "../../textarea";
|
|
4
4
|
import Button from "../../button";
|
|
5
5
|
import { useFormik } from "formik";
|
|
@@ -9,10 +9,14 @@ import eventBus from "../comment-event-bus";
|
|
|
9
9
|
import { COMMENT_EVENTS } from "../constants";
|
|
10
10
|
export const createNewCommentValidation = () => {
|
|
11
11
|
return Yup.object({
|
|
12
|
-
description: Yup.string()
|
|
12
|
+
description: Yup.string()
|
|
13
|
+
.trim()
|
|
14
|
+
.min(1, "Required")
|
|
15
|
+
.max(1000, "Must be at most 1000 characters")
|
|
16
|
+
.required("Required"),
|
|
13
17
|
});
|
|
14
18
|
};
|
|
15
|
-
export default function CommentForm({ objectId, model, commentsBaseUrl, commentToEdit, setCommentToEdit, replyOnComment, setReplyOnComment, onCreateCommentSuccess, onEditCommentSuccess, }) {
|
|
19
|
+
export default function CommentForm({ objectId, model, commentsBaseUrl, commentToEdit, setCommentToEdit, replyOnComment, setReplyOnComment, onCreateCommentSuccess, onEditCommentSuccess, renderForm, }) {
|
|
16
20
|
var _a;
|
|
17
21
|
const initialValues = {
|
|
18
22
|
model,
|
|
@@ -49,9 +53,31 @@ export default function CommentForm({ objectId, model, commentsBaseUrl, commentT
|
|
|
49
53
|
onSubmit,
|
|
50
54
|
enableReinitialize: true,
|
|
51
55
|
});
|
|
56
|
+
const handleKeyDown = (e) => {
|
|
57
|
+
// If user pressed Ctrl+Enter (Windows/Linux) or Cmd+Enter (Mac)
|
|
58
|
+
if ((e.ctrlKey || e.metaKey) && e.key === "Enter") {
|
|
59
|
+
e.preventDefault(); // prevent new line
|
|
60
|
+
if (!formik.isSubmitting && formik.isValid) {
|
|
61
|
+
formik.submitForm();
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
const cancelReply = () => setReplyOnComment(undefined);
|
|
66
|
+
const cancelEdit = () => setCommentToEdit(undefined);
|
|
67
|
+
const renderProps = {
|
|
68
|
+
formik,
|
|
69
|
+
isReplying: Boolean(replyOnComment),
|
|
70
|
+
isEditing: Boolean(commentToEdit),
|
|
71
|
+
replyOnComment,
|
|
72
|
+
cancelReply,
|
|
73
|
+
cancelEdit,
|
|
74
|
+
handleKeyDown,
|
|
75
|
+
};
|
|
76
|
+
if (renderForm)
|
|
77
|
+
return _jsx(_Fragment, { children: renderForm(renderProps) });
|
|
52
78
|
return (_jsxs("form", { onSubmit: formik.handleSubmit, className: "flex flex-col gap-3", children: [replyOnComment && (_jsxs("div", { className: "flex items-center justify-between bg-primary/5 px-3 py-2 rounded-lg border border-primary/10", children: [_jsxs("p", { className: "text-sm text-gray-700", children: ["Replying to", " ", _jsx("span", { className: "font-semibold text-primary", children: (_a = replyOnComment.account) === null || _a === void 0 ? void 0 : _a.name })] }), _jsx(Button, { type: "button", onClick: () => setReplyOnComment(undefined), className: "bg-transparent", children: _jsx("p", { className: "text-error hover:text-opacity-75 custom-animation", children: "Cancel" }) })] })), _jsx(Textarea, { name: "description", placeholder: commentToEdit
|
|
53
79
|
? "Edit your comment..."
|
|
54
80
|
: replyOnComment
|
|
55
81
|
? "Write a reply..."
|
|
56
|
-
: "Add a comment...", onChange: formik.handleChange, onBlur: formik.handleBlur, value: formik.values.description, errorMessage: formik.touched.description ? formik.errors.description : "", className: "min-h-[80px]" }), _jsxs("div", { className: "flex justify-end gap-2 pt-1", children: [commentToEdit && (_jsx(Button, { type: "button", onClick: () => setCommentToEdit(undefined), className: "bg-transparent", children: _jsx("p", { className: "text-error hover:text-opacity-75 custom-animation", children: "Cancel" }) })), _jsx(Button, { type: "submit", loading: formik.isSubmitting, disabled: formik.isSubmitting || !formik.isValid, children: commentToEdit ? "Update Comment" : "Add Comment" })] })] }));
|
|
82
|
+
: "Add a comment...", onChange: formik.handleChange, onBlur: formik.handleBlur, value: formik.values.description, errorMessage: formik.touched.description ? formik.errors.description : "", className: "min-h-[80px]", onKeyDown: handleKeyDown }), _jsxs("div", { className: "flex justify-end gap-2 pt-1", children: [commentToEdit && (_jsx(Button, { type: "button", onClick: () => setCommentToEdit(undefined), className: "bg-transparent", children: _jsx("p", { className: "text-error hover:text-opacity-75 custom-animation", children: "Cancel" }) })), _jsx(Button, { type: "submit", loading: formik.isSubmitting, disabled: formik.isSubmitting || !formik.isValid, children: commentToEdit ? "Update Comment" : "Add Comment" })] })] }));
|
|
57
83
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { DTO } from "sea-platform-helpers";
|
|
2
|
+
import { CommentFormRenderProps } from "./comment-form";
|
|
2
3
|
export type Props = {
|
|
3
4
|
commentsBaseUrl: string;
|
|
4
5
|
objectId: string;
|
|
@@ -14,6 +15,7 @@ export type Props = {
|
|
|
14
15
|
limit?: number;
|
|
15
16
|
highlightCommentId?: string;
|
|
16
17
|
}) => React.ReactNode;
|
|
18
|
+
renderForm?: (props: CommentFormRenderProps) => React.ReactNode;
|
|
17
19
|
};
|
|
18
|
-
export default function CommentsContainer({ commentsBaseUrl, objectId, model, limit, highlightCommentId, renderCommentItem, }: Props): import("react/jsx-runtime").JSX.Element;
|
|
20
|
+
export default function CommentsContainer({ commentsBaseUrl, objectId, model, limit, highlightCommentId, renderCommentItem, renderForm, }: Props): import("react/jsx-runtime").JSX.Element;
|
|
19
21
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/comments-container/index.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAE,GAAG,EAAa,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/comments-container/index.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAE,GAAG,EAAa,MAAM,sBAAsB,CAAC;AAItD,OAAoB,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AAIrE,MAAM,MAAM,KAAK,GAAG;IAClB,eAAe,EAAE,MAAM,CAAC;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,GAAG,CAAC,OAAO,CAAC,sBAAsB,CAAC;IAC1C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAE5B,iBAAiB,CAAC,EAAE,CAClB,OAAO,EAAE,GAAG,CAAC,OAAO,CAAC,QAAQ,EAC7B,WAAW,EAAE;QACX,gBAAgB,CAAC,EAAE,MAAM,CAAC;QAC1B,WAAW,EAAE,CAAC,OAAO,EAAE,GAAG,CAAC,OAAO,CAAC,QAAQ,GAAG,SAAS,KAAK,IAAI,CAAC;QACjE,cAAc,EAAE,CAAC,OAAO,EAAE,GAAG,CAAC,OAAO,CAAC,QAAQ,GAAG,SAAS,KAAK,IAAI,CAAC;QACpE,eAAe,EAAE,MAAM,CAAC;QACxB,QAAQ,EAAE,MAAM,CAAC;QACjB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,kBAAkB,CAAC,EAAE,MAAM,CAAC;KAC7B,KACE,KAAK,CAAC,SAAS,CAAC;IAErB,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,sBAAsB,KAAK,KAAK,CAAC,SAAS,CAAC;CACjE,CAAC;AAEF,MAAM,CAAC,OAAO,UAAU,iBAAiB,CAAC,EACxC,eAAe,EACf,QAAQ,EACR,KAAK,EACL,KAAU,EACV,kBAAkB,EAClB,iBAAiB,EACjB,UAAU,GACX,EAAE,KAAK,2CAmDP"}
|
|
@@ -7,7 +7,7 @@ import { jwtDecode } from "../../utils/jwt";
|
|
|
7
7
|
import CommentForm from "./comment-form";
|
|
8
8
|
import CommentsList from "./comments-list";
|
|
9
9
|
import CommentItem from "./comment-item";
|
|
10
|
-
export default function CommentsContainer({ commentsBaseUrl, objectId, model, limit = 10, highlightCommentId, renderCommentItem, }) {
|
|
10
|
+
export default function CommentsContainer({ commentsBaseUrl, objectId, model, limit = 10, highlightCommentId, renderCommentItem, renderForm, }) {
|
|
11
11
|
const [accountId, setAccountId] = useState("");
|
|
12
12
|
const [commentToEdit, setCommentToEdit] = useState();
|
|
13
13
|
const [replyOnComment, setReplyOnComment] = useState();
|
|
@@ -23,5 +23,5 @@ export default function CommentsContainer({ commentsBaseUrl, objectId, model, li
|
|
|
23
23
|
}, onEditCommentSuccess: () => {
|
|
24
24
|
setCommentToEdit(undefined);
|
|
25
25
|
setReplyOnComment(undefined);
|
|
26
|
-
} }), _jsx(CommentsList, { editComment: setCommentToEdit, replyOnComment: setReplyOnComment, highlightCommentId: highlightCommentId, currentAccountId: accountId, commentsBaseUrl: commentsBaseUrl, objectId: objectId, limit: limit, renderCommentItem: renderCommentItem !== null && renderCommentItem !== void 0 ? renderCommentItem : ((comment, props) => (_jsx(CommentItem, { comment: comment, ...props }, comment.id))) })] }));
|
|
26
|
+
}, renderForm: renderForm }), _jsx(CommentsList, { editComment: setCommentToEdit, replyOnComment: setReplyOnComment, highlightCommentId: highlightCommentId, currentAccountId: accountId, commentsBaseUrl: commentsBaseUrl, objectId: objectId, limit: limit, renderCommentItem: renderCommentItem !== null && renderCommentItem !== void 0 ? renderCommentItem : ((comment, props) => (_jsx(CommentItem, { comment: comment, ...props }, comment.id))) })] }));
|
|
27
27
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/jwt-checker/index.tsx"],"names":[],"mappings":"AAKA,MAAM,MAAM,KAAK,GAAG;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AACF,MAAM,CAAC,OAAO,UAAU,UAAU,CAAC,EAAE,KAAY,EAAE,EAAE,KAAK,2CAOzD"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { Fragment as _Fragment, jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
import { CONSTANTS } from "sea-platform-helpers";
|
|
4
|
+
import { useInterval } from "../../hooks/use-interval";
|
|
5
|
+
import { getCookie } from "../../utils/cookie";
|
|
6
|
+
export default function JWTChecker({ delay = 2000 }) {
|
|
7
|
+
useInterval(() => {
|
|
8
|
+
const jwt = getCookie(CONSTANTS.JWT.JWTCookieKey);
|
|
9
|
+
console.log("JWTChecker - current JWT:", jwt);
|
|
10
|
+
if (!jwt)
|
|
11
|
+
window.location.reload();
|
|
12
|
+
}, delay);
|
|
13
|
+
return _jsx(_Fragment, {});
|
|
14
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/jwt-token-checker/index.tsx"],"names":[],"mappings":""}
|
|
File without changes
|
|
@@ -18,7 +18,7 @@ export default function SearchableSelect({ getItems, getLabel, getValue, ...prop
|
|
|
18
18
|
return () => {
|
|
19
19
|
active = false; // cancel stale promises
|
|
20
20
|
};
|
|
21
|
-
}, [query
|
|
21
|
+
}, [query]);
|
|
22
22
|
// --- Memoize mapped options ---
|
|
23
23
|
const mappedOptions = useMemo(() => options.map((item) => ({
|
|
24
24
|
label: memoGetLabel(item),
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { SelectOption } from "./SelectTypes";
|
|
2
|
+
export type SelectChipsProps<T> = {
|
|
3
|
+
name: string;
|
|
4
|
+
selectedOptions: SelectOption<T>[];
|
|
5
|
+
disabled: boolean;
|
|
6
|
+
onRemove: (option: SelectOption<T>) => void;
|
|
7
|
+
};
|
|
8
|
+
export default function SelectChips<T>({ name, selectedOptions, disabled, onRemove, }: SelectChipsProps<T>): import("react/jsx-runtime").JSX.Element;
|
|
9
|
+
//# sourceMappingURL=SelectChips.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SelectChips.d.ts","sourceRoot":"","sources":["../../../src/components/select/SelectChips.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAElD,MAAM,MAAM,gBAAgB,CAAC,CAAC,IAAI;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,eAAe,EAAE,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC;IACnC,QAAQ,EAAE,OAAO,CAAC;IAClB,QAAQ,EAAE,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC;CAC7C,CAAC;AAEF,MAAM,CAAC,OAAO,UAAU,WAAW,CAAC,CAAC,EAAE,EACrC,IAAI,EACJ,eAAe,EACf,QAAQ,EACR,QAAQ,GACT,EAAE,gBAAgB,CAAC,CAAC,CAAC,2CAwBrB"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Icon } from "@iconify/react";
|
|
3
|
+
export default function SelectChips({ name, selectedOptions, disabled, onRemove, }) {
|
|
4
|
+
return (_jsx("div", { className: "flex flex-wrap gap-2", id: name, children: selectedOptions.map((o, i) => (_jsxs("div", { className: "bg-primary bg-opacity-50 px-2 py-1 rounded-2xl flex items-center gap-1", children: [_jsx("span", { className: "text-black text-sm", children: o.label }), !disabled && (_jsx("button", { type: "button", onClick: (e) => {
|
|
5
|
+
e.stopPropagation();
|
|
6
|
+
onRemove(o);
|
|
7
|
+
}, children: _jsx(Icon, { icon: "line-md:close-small", className: "w-4 h-4" }) }))] }, `${name}-${i}`))) }));
|
|
8
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
export type SelectControlProps = {
|
|
3
|
+
disabled: boolean;
|
|
4
|
+
errorMessage?: string | boolean;
|
|
5
|
+
isOpen: boolean;
|
|
6
|
+
buttonClassName?: string;
|
|
7
|
+
onToggle: () => void;
|
|
8
|
+
leftContent: React.ReactNode;
|
|
9
|
+
showClear: boolean;
|
|
10
|
+
onClear: (e: React.MouseEvent) => void;
|
|
11
|
+
};
|
|
12
|
+
export default function SelectControl({ disabled, errorMessage, isOpen, buttonClassName, onToggle, leftContent, showClear, onClear, }: SelectControlProps): import("react/jsx-runtime").JSX.Element;
|
|
13
|
+
//# sourceMappingURL=SelectControl.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SelectControl.d.ts","sourceRoot":"","sources":["../../../src/components/select/SelectControl.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAI1B,MAAM,MAAM,kBAAkB,GAAG;IAC/B,QAAQ,EAAE,OAAO,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAChC,MAAM,EAAE,OAAO,CAAC;IAChB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,WAAW,EAAE,KAAK,CAAC,SAAS,CAAC;IAC7B,SAAS,EAAE,OAAO,CAAC;IACnB,OAAO,EAAE,CAAC,CAAC,EAAE,KAAK,CAAC,UAAU,KAAK,IAAI,CAAC;CACxC,CAAC;AAEF,MAAM,CAAC,OAAO,UAAU,aAAa,CAAC,EACpC,QAAQ,EACR,YAAY,EACZ,MAAM,EACN,eAAe,EACf,QAAQ,EACR,WAAW,EACX,SAAS,EACT,OAAO,GACR,EAAE,kBAAkB,2CAuCpB"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import clsx from "clsx";
|
|
3
|
+
import { Icon } from "@iconify/react";
|
|
4
|
+
export default function SelectControl({ disabled, errorMessage, isOpen, buttonClassName, onToggle, leftContent, showClear, onClear, }) {
|
|
5
|
+
return (_jsxs("div", { onClick: () => !disabled && onToggle(), className: clsx("text-text flex items-center justify-between gap-2 px-3 py-2 rounded-md border-0.5 hover:border-primary transition-all", disabled
|
|
6
|
+
? "bg-gray-100 text-gray-400 cursor-not-allowed"
|
|
7
|
+
: "bg-white cursor-pointer", errorMessage
|
|
8
|
+
? "border-error"
|
|
9
|
+
: isOpen
|
|
10
|
+
? "border-primary"
|
|
11
|
+
: "border-gray-200", buttonClassName), children: [leftContent, _jsxs("div", { className: "flex items-center gap-1", children: [!disabled && showClear && (_jsx("button", { type: "button", onClick: onClear, title: "Clear selection", className: "text-gray-500 hover:text-primary", children: _jsx(Icon, { icon: "line-md:close-small", className: "w-5 h-5" }) })), _jsx(Icon, { icon: "iconamoon:arrow-down-2", className: clsx("transition-transform duration-200", isOpen && "rotate-180") })] })] }));
|
|
12
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import React, { ChangeEvent } from "react";
|
|
2
|
+
import { MenuPosition } from "./useSelectPortal";
|
|
3
|
+
import type { SelectOption } from "./SelectTypes";
|
|
4
|
+
export type SelectDropdownContentProps<T> = {
|
|
5
|
+
usePortal: boolean;
|
|
6
|
+
dropdownClassName?: string;
|
|
7
|
+
animate: boolean;
|
|
8
|
+
menuPos: MenuPosition;
|
|
9
|
+
isSearchable: boolean;
|
|
10
|
+
search: string;
|
|
11
|
+
onChangeSearchInput: (e: ChangeEvent<HTMLInputElement>) => void;
|
|
12
|
+
filteredOptions: SelectOption<T>[];
|
|
13
|
+
selectedOptions: SelectOption<T>[];
|
|
14
|
+
name: string;
|
|
15
|
+
onOptionClick: (option: SelectOption<T>) => void;
|
|
16
|
+
onStopClick?: (e: React.MouseEvent) => void;
|
|
17
|
+
};
|
|
18
|
+
declare function BaseSelectDropdownContent<T>({ usePortal, dropdownClassName, animate, menuPos, isSearchable, search, onChangeSearchInput, filteredOptions, selectedOptions, name, onOptionClick, onStopClick, }: SelectDropdownContentProps<T>, ref: React.ForwardedRef<HTMLDivElement>): import("react/jsx-runtime").JSX.Element;
|
|
19
|
+
declare const SelectDropdownContent: <T>(p: SelectDropdownContentProps<T> & {
|
|
20
|
+
ref?: React.ForwardedRef<HTMLDivElement>;
|
|
21
|
+
}) => ReturnType<typeof BaseSelectDropdownContent>;
|
|
22
|
+
export default SelectDropdownContent;
|
|
23
|
+
//# sourceMappingURL=SelectDropdownContent.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SelectDropdownContent.d.ts","sourceRoot":"","sources":["../../../src/components/select/SelectDropdownContent.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,WAAW,EAAc,MAAM,OAAO,CAAC;AAGvD,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAElD,MAAM,MAAM,0BAA0B,CAAC,CAAC,IAAI;IAC1C,SAAS,EAAE,OAAO,CAAC;IACnB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,YAAY,CAAC;IACtB,YAAY,EAAE,OAAO,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,mBAAmB,EAAE,CAAC,CAAC,EAAE,WAAW,CAAC,gBAAgB,CAAC,KAAK,IAAI,CAAC;IAChE,eAAe,EAAE,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC;IACnC,eAAe,EAAE,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,EAAE,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC;IACjD,WAAW,CAAC,EAAE,CAAC,CAAC,EAAE,KAAK,CAAC,UAAU,KAAK,IAAI,CAAC;CAC7C,CAAC;AAEF,iBAAS,yBAAyB,CAAC,CAAC,EAClC,EACE,SAAS,EACT,iBAAiB,EACjB,OAAO,EACP,OAAO,EACP,YAAY,EACZ,MAAM,EACN,mBAAmB,EACnB,eAAe,EACf,eAAe,EACf,IAAI,EACJ,aAAa,EACb,WAAW,GACZ,EAAE,0BAA0B,CAAC,CAAC,CAAC,EAChC,GAAG,EAAE,KAAK,CAAC,YAAY,CAAC,cAAc,CAAC,2CAsExC;AAED,QAAA,MAAM,qBAAqB,EAA4C,CAAC,CAAC,EACvE,CAAC,EAAE,0BAA0B,CAAC,CAAC,CAAC,GAAG;IACjC,GAAG,CAAC,EAAE,KAAK,CAAC,YAAY,CAAC,cAAc,CAAC,CAAC;CAC1C,KACE,UAAU,CAAC,OAAO,yBAAyB,CAAC,CAAC;AAElD,eAAe,qBAAqB,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { forwardRef } from "react";
|
|
3
|
+
import clsx from "clsx";
|
|
4
|
+
import { Icon } from "@iconify/react";
|
|
5
|
+
function BaseSelectDropdownContent({ usePortal, dropdownClassName, animate, menuPos, isSearchable, search, onChangeSearchInput, filteredOptions, selectedOptions, name, onOptionClick, onStopClick, }, ref) {
|
|
6
|
+
return (_jsxs("div", { className: clsx("bg-white border border-gray-200 rounded-md shadow-lg overflow-auto transition-all duration-200 ease-out", animate
|
|
7
|
+
? "opacity-100 translate-y-0 scale-100"
|
|
8
|
+
: menuPos.placement === "bottom"
|
|
9
|
+
? "opacity-0 -translate-y-1 scale-95"
|
|
10
|
+
: "opacity-0 translate-y-1 scale-95", menuPos.placement === "bottom" ? "origin-top" : "origin-bottom", dropdownClassName), onClick: onStopClick, style: usePortal
|
|
11
|
+
? {
|
|
12
|
+
position: "fixed",
|
|
13
|
+
zIndex: 60,
|
|
14
|
+
left: menuPos.left,
|
|
15
|
+
top: menuPos.top,
|
|
16
|
+
width: menuPos.width,
|
|
17
|
+
maxHeight: menuPos.maxHeight,
|
|
18
|
+
}
|
|
19
|
+
: undefined, ref: ref, children: [isSearchable && (_jsxs("div", { className: "sticky top-0 bg-white border-b border-gray-100 px-2 py-1 flex items-center gap-2", children: [_jsx(Icon, { icon: "mdi:magnify", className: "text-gray-500 w-5 h-5" }), _jsx("input", { type: "text", placeholder: "Search...", value: search, onChange: onChangeSearchInput, className: "w-full outline-none text-sm bg-transparent py-1" })] })), filteredOptions.length > 0 ? (filteredOptions.map((o, i) => {
|
|
20
|
+
const isSelected = selectedOptions.some((s) => Object.is(s.value, o.value));
|
|
21
|
+
return (_jsxs("div", { onClick: () => onOptionClick(o), className: clsx("mx-1 px-3 py-2 cursor-pointer flex items-center gap-2 rounded text-sm hover:text-primary hover:bg-primary/20", isSelected && "bg-primary/10 text-primary"), children: [isSelected ? (_jsx(Icon, { icon: "mdi:check", className: "w-4 h-4 text-primary" })) : (_jsx("div", { className: "w-4 h-4" })), o.label] }, `${name}-option-${i}`));
|
|
22
|
+
})) : (_jsx("div", { className: "px-3 py-2 text-gray-400 text-sm", children: "No results" }))] }));
|
|
23
|
+
}
|
|
24
|
+
const SelectDropdownContent = forwardRef(BaseSelectDropdownContent);
|
|
25
|
+
export default SelectDropdownContent;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
export type SelectPlaceHolderProps = {
|
|
3
|
+
placeholder: string;
|
|
4
|
+
IconPlaceholderLeft?: React.ReactNode;
|
|
5
|
+
};
|
|
6
|
+
export default function SelectPlaceHolder({ placeholder, IconPlaceholderLeft, }: SelectPlaceHolderProps): import("react/jsx-runtime").JSX.Element;
|
|
7
|
+
//# sourceMappingURL=SelectPlaceholder.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SelectPlaceholder.d.ts","sourceRoot":"","sources":["../../../src/components/select/SelectPlaceholder.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,MAAM,MAAM,sBAAsB,GAAG;IACnC,WAAW,EAAE,MAAM,CAAC;IACpB,mBAAmB,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CACvC,CAAC;AAEF,MAAM,CAAC,OAAO,UAAU,iBAAiB,CAAC,EACxC,WAAW,EACX,mBAAmB,GACpB,EAAE,sBAAsB,2CAOxB"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
export default function SelectPlaceHolder({ placeholder, IconPlaceholderLeft, }) {
|
|
3
|
+
return (_jsxs("div", { className: "flex gap-2 items-center overflow-hidden", children: [IconPlaceholderLeft, _jsx("p", { className: "text-gray-500 truncate line-clamp-1", children: placeholder })] }));
|
|
4
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SelectTypes.d.ts","sourceRoot":"","sources":["../../../src/components/select/SelectTypes.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,YAAY,CAAC,CAAC,IAAI;IAC5B,KAAK,EAAE,CAAC,CAAC;IACT,KAAK,EAAE,KAAK,CAAC,SAAS,CAAC;CACxB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import React, { ChangeEvent } from "react";
|
|
2
|
+
import type { SelectOption } from "./SelectTypes";
|
|
3
|
+
import type { MenuPosition } from "./useSelectPortal";
|
|
4
|
+
export type SelectViewProps<T> = {
|
|
5
|
+
label?: string;
|
|
6
|
+
required?: boolean;
|
|
7
|
+
errorMessage?: string | boolean;
|
|
8
|
+
containerRef: React.RefObject<HTMLDivElement>;
|
|
9
|
+
menuRef: React.RefObject<HTMLDivElement>;
|
|
10
|
+
disabled: boolean;
|
|
11
|
+
isOpen: boolean;
|
|
12
|
+
buttonClassName?: string;
|
|
13
|
+
onToggle: () => void;
|
|
14
|
+
multiselect: boolean;
|
|
15
|
+
selectedOptions: SelectOption<T>[];
|
|
16
|
+
placeholder: string;
|
|
17
|
+
IconPlaceholderLeft?: React.ReactNode;
|
|
18
|
+
onClear: (e: React.MouseEvent) => void;
|
|
19
|
+
name: string;
|
|
20
|
+
show: boolean;
|
|
21
|
+
usePortal: boolean;
|
|
22
|
+
dropdownClassName?: string;
|
|
23
|
+
animate: boolean;
|
|
24
|
+
menuPos: MenuPosition;
|
|
25
|
+
isSearchable: boolean;
|
|
26
|
+
search: string;
|
|
27
|
+
onChangeSearchInput: (e: ChangeEvent<HTMLInputElement>) => void;
|
|
28
|
+
filteredOptions: SelectOption<T>[];
|
|
29
|
+
onOptionClick: (o: SelectOption<T>) => void;
|
|
30
|
+
desiredMax: number;
|
|
31
|
+
};
|
|
32
|
+
export default function SelectView<T>({ label, required, errorMessage, containerRef, menuRef, disabled, isOpen, buttonClassName, onToggle, multiselect, selectedOptions, placeholder, IconPlaceholderLeft, onClear, name, show, usePortal, dropdownClassName, animate, menuPos, isSearchable, search, onChangeSearchInput, filteredOptions, onOptionClick, desiredMax, }: SelectViewProps<T>): import("react/jsx-runtime").JSX.Element;
|
|
33
|
+
//# sourceMappingURL=SelectView.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SelectView.d.ts","sourceRoot":"","sources":["../../../src/components/select/SelectView.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,EAAE,WAAW,EAAE,MAAM,OAAO,CAAC;AAO3C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEtD,MAAM,MAAM,eAAe,CAAC,CAAC,IAAI;IAE/B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAGhC,YAAY,EAAE,KAAK,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC;IAC9C,OAAO,EAAE,KAAK,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC;IAGzC,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,EAAE,OAAO,CAAC;IAChB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,WAAW,EAAE,OAAO,CAAC;IACrB,eAAe,EAAE,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC;IACnC,WAAW,EAAE,MAAM,CAAC;IACpB,mBAAmB,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACtC,OAAO,EAAE,CAAC,CAAC,EAAE,KAAK,CAAC,UAAU,KAAK,IAAI,CAAC;IAGvC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,OAAO,CAAC;IACd,SAAS,EAAE,OAAO,CAAC;IACnB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,YAAY,CAAC;IACtB,YAAY,EAAE,OAAO,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,mBAAmB,EAAE,CAAC,CAAC,EAAE,WAAW,CAAC,gBAAgB,CAAC,KAAK,IAAI,CAAC;IAChE,eAAe,EAAE,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC;IACnC,aAAa,EAAE,CAAC,CAAC,EAAE,YAAY,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC;IAC5C,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,MAAM,CAAC,OAAO,UAAU,UAAU,CAAC,CAAC,EAAE,EACpC,KAAK,EACL,QAAQ,EACR,YAAY,EACZ,YAAY,EACZ,OAAO,EACP,QAAQ,EACR,MAAM,EACN,eAAe,EACf,QAAQ,EACR,WAAW,EACX,eAAe,EACf,WAAW,EACX,mBAAmB,EACnB,OAAO,EACP,IAAI,EACJ,IAAI,EACJ,SAAS,EACT,iBAAiB,EACjB,OAAO,EACP,OAAO,EACP,YAAY,EACZ,MAAM,EACN,mBAAmB,EACnB,eAAe,EACf,aAAa,EACb,UAAU,GACX,EAAE,eAAe,CAAC,CAAC,CAAC,2CA2FpB"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { createPortal } from "react-dom";
|
|
4
|
+
import clsx from "clsx";
|
|
5
|
+
import SelectControl from "./SelectControl";
|
|
6
|
+
import SelectPlaceHolder from "./SelectPlaceholder";
|
|
7
|
+
import SelectChips from "./SelectChips";
|
|
8
|
+
import SelectDropdownContent from "./SelectDropdownContent";
|
|
9
|
+
export default function SelectView({ label, required, errorMessage, containerRef, menuRef, disabled, isOpen, buttonClassName, onToggle, multiselect, selectedOptions, placeholder, IconPlaceholderLeft, onClear, name, show, usePortal, dropdownClassName, animate, menuPos, isSearchable, search, onChangeSearchInput, filteredOptions, onOptionClick, desiredMax, }) {
|
|
10
|
+
const leftContent = multiselect ? (selectedOptions.length ? (_jsx(SelectChips, { name: name, selectedOptions: selectedOptions, disabled: disabled, onRemove: (o) => onOptionClick(o) })) : (_jsx(SelectPlaceHolder, { placeholder: placeholder, IconPlaceholderLeft: IconPlaceholderLeft }))) : selectedOptions[0] ? (_jsx("div", { className: "text-text truncate line-clamp-1", children: selectedOptions[0].label })) : (_jsx(SelectPlaceHolder, { placeholder: placeholder, IconPlaceholderLeft: IconPlaceholderLeft }));
|
|
11
|
+
const dropdownEl = (_jsx(SelectDropdownContent, { ref: menuRef, usePortal: usePortal, dropdownClassName: dropdownClassName, animate: animate, menuPos: menuPos, isSearchable: isSearchable, search: search, onChangeSearchInput: onChangeSearchInput, filteredOptions: filteredOptions, selectedOptions: selectedOptions, name: name, onOptionClick: onOptionClick, onStopClick: (e) => e.stopPropagation() }));
|
|
12
|
+
return (_jsxs("div", { className: "flex flex-col gap-1", children: [label && (_jsxs("label", { htmlFor: name, className: "pl-1 text-sm text-foreground font-medium mb-2", children: [label, " ", required && _jsx("span", { className: "font-bold", children: "*" })] })), _jsxs("div", { ref: containerRef, className: "relative w-full", children: [_jsx(SelectControl, { disabled: disabled, errorMessage: errorMessage, isOpen: isOpen, buttonClassName: buttonClassName, onToggle: onToggle, leftContent: leftContent, showClear: !disabled &&
|
|
13
|
+
(multiselect ? selectedOptions.length > 0 : !!selectedOptions[0]), onClear: onClear }), show &&
|
|
14
|
+
!disabled &&
|
|
15
|
+
(usePortal ? (createPortal(dropdownEl, document.body)) : (_jsx("div", { className: clsx("absolute left-0 mt-1 z-50 max-w-[360px] min-w-[260px] w-full"), style: { maxHeight: desiredMax }, children: dropdownEl })))] }), errorMessage && (_jsx("p", { className: "pl-1 text-sm text-error", children: errorMessage }))] }));
|
|
16
|
+
}
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
label: React.ReactNode;
|
|
5
|
-
};
|
|
2
|
+
import type { SelectOption } from "./SelectTypes";
|
|
3
|
+
export type { SelectOption } from "./SelectTypes";
|
|
6
4
|
export type Props<T> = {
|
|
7
5
|
name: string;
|
|
8
6
|
options: SelectOption<T>[];
|
|
@@ -21,6 +19,8 @@ export type Props<T> = {
|
|
|
21
19
|
onRemove?: () => void;
|
|
22
20
|
searchDebounceTimeout?: number;
|
|
23
21
|
isRemote?: boolean;
|
|
22
|
+
usePortal?: boolean;
|
|
23
|
+
dropdownClassName?: string;
|
|
24
24
|
};
|
|
25
|
-
export default function Select<T>({ name, options, values, setValues, errorMessage, buttonClassName, placeholder, multiselect, disabled, label, isSearchable, required, IconPlaceholderLeft, onChangeSearchInput, onRemove, searchDebounceTimeout, isRemote, }: Props<T>): import("react/jsx-runtime").JSX.Element;
|
|
25
|
+
export default function Select<T>({ name, options, values, setValues, errorMessage, buttonClassName, placeholder, multiselect, disabled, label, isSearchable, required, IconPlaceholderLeft, onChangeSearchInput, onRemove, searchDebounceTimeout, isRemote, usePortal, dropdownClassName, }: Props<T>): import("react/jsx-runtime").JSX.Element;
|
|
26
26
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/select/index.tsx"],"names":[],"mappings":"AACA,OAAO,KAON,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/select/index.tsx"],"names":[],"mappings":"AACA,OAAO,KAON,MAAM,OAAO,CAAC;AAGf,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAGlD,YAAY,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAElD,MAAM,MAAM,KAAK,CAAC,CAAC,IAAI;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC;IAE3B,MAAM,EAAE,CAAC,EAAE,CAAC;IACZ,SAAS,EAAE,CAAC,SAAS,EAAE,CAAC,EAAE,KAAK,IAAI,CAAC;IAEpC,YAAY,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAChC,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,mBAAmB,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACtC,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,mBAAmB,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAC9C,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IACtB,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,EAAE,OAAO,CAAC;IAGnB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B,CAAC;AAEF,MAAM,CAAC,OAAO,UAAU,MAAM,CAAC,CAAC,EAAE,EAChC,IAAI,EACJ,OAAO,EACP,MAAM,EACN,SAAS,EACT,YAAY,EACZ,eAAe,EACf,WAAyB,EACzB,WAAmB,EACnB,QAAgB,EAChB,KAAK,EACL,YAAoB,EACpB,QAAgB,EAChB,mBAAmB,EACnB,mBAAmB,EACnB,QAAQ,EACR,qBAA2B,EAC3B,QAAgB,EAChB,SAAgB,EAChB,iBAAiB,GAClB,EAAE,KAAK,CAAC,CAAC,CAAC,2CAqIV"}
|
|
@@ -1,46 +1,46 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { jsx as _jsx
|
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
3
|
import { useState, useRef, useEffect, useMemo, } from "react";
|
|
4
|
-
import {
|
|
5
|
-
import
|
|
6
|
-
|
|
7
|
-
export default function Select({ name, options, values, setValues, errorMessage, buttonClassName, placeholder = "Select...", multiselect = false, disabled = false, label, isSearchable = false, required = false, IconPlaceholderLeft, onChangeSearchInput, onRemove, searchDebounceTimeout = 500, isRemote = false, }) {
|
|
4
|
+
import { useSelectPortal } from "./useSelectPortal";
|
|
5
|
+
import SelectView from "./SelectView";
|
|
6
|
+
export default function Select({ name, options, values, setValues, errorMessage, buttonClassName, placeholder = "Select...", multiselect = false, disabled = false, label, isSearchable = false, required = false, IconPlaceholderLeft, onChangeSearchInput, onRemove, searchDebounceTimeout = 500, isRemote = false, usePortal = true, dropdownClassName, }) {
|
|
8
7
|
const [isOpen, setIsOpen] = useState(false);
|
|
9
|
-
const [show, setShow] = useState(false);
|
|
10
|
-
const [animate, setAnimate] = useState(false);
|
|
11
8
|
const [search, setSearch] = useState("");
|
|
12
9
|
const [selectedCache, setSelectedCache] = useState([]);
|
|
13
10
|
const containerRef = useRef(null);
|
|
14
|
-
|
|
11
|
+
const menuRef = useRef(null);
|
|
12
|
+
const { show, animate, menuPos, desiredMax } = useSelectPortal({
|
|
13
|
+
isOpen,
|
|
14
|
+
usePortal,
|
|
15
|
+
containerRef,
|
|
16
|
+
menuRef,
|
|
17
|
+
heightDeps: [search, options.length, selectedCache.length],
|
|
18
|
+
});
|
|
19
|
+
// Debounced remote search trigger
|
|
15
20
|
useEffect(() => {
|
|
16
21
|
if (!onChangeSearchInput)
|
|
17
22
|
return;
|
|
18
23
|
const timeout = setTimeout(() => onChangeSearchInput(search), searchDebounceTimeout);
|
|
19
24
|
return () => clearTimeout(timeout);
|
|
20
25
|
}, [search, onChangeSearchInput, searchDebounceTimeout]);
|
|
21
|
-
const handleSearchInputChange = (e) =>
|
|
22
|
-
|
|
23
|
-
};
|
|
24
|
-
// ---------- Derived Values ----------
|
|
26
|
+
const handleSearchInputChange = (e) => setSearch(e.target.value);
|
|
27
|
+
// Derived values
|
|
25
28
|
const mergedOptions = useMemo(() => [
|
|
26
29
|
...options,
|
|
27
30
|
...selectedCache.filter((cached) => !options.some((o) => Object.is(o.value, cached.value))),
|
|
28
31
|
], [options, selectedCache]);
|
|
29
32
|
const selectedOptions = useMemo(() => mergedOptions.filter((o) => values.some((v) => Object.is(v, o.value))), [mergedOptions, values]);
|
|
30
33
|
const filteredOptions = useMemo(() => {
|
|
31
|
-
// Case 1: Not searchable => just return options
|
|
32
34
|
if (!isSearchable)
|
|
33
35
|
return mergedOptions;
|
|
34
|
-
// Case 2: Remote mode => skip local filtering (server handles it)
|
|
35
36
|
if (isRemote)
|
|
36
37
|
return mergedOptions;
|
|
37
|
-
// Case 3: Local filtering
|
|
38
38
|
if (!search.trim())
|
|
39
39
|
return mergedOptions;
|
|
40
40
|
const lower = search.toLowerCase();
|
|
41
41
|
return mergedOptions.filter((o) => String(o.label).toLowerCase().includes(lower));
|
|
42
42
|
}, [isSearchable, mergedOptions, search, isRemote]);
|
|
43
|
-
//
|
|
43
|
+
// Selection logic
|
|
44
44
|
const toggleOption = (option) => {
|
|
45
45
|
if (disabled)
|
|
46
46
|
return;
|
|
@@ -61,12 +61,6 @@ export default function Select({ name, options, values, setValues, errorMessage,
|
|
|
61
61
|
}
|
|
62
62
|
setValues(updatedValues);
|
|
63
63
|
};
|
|
64
|
-
const removeSelected = (option) => {
|
|
65
|
-
if (disabled)
|
|
66
|
-
return;
|
|
67
|
-
setValues(values.filter((v) => !Object.is(v, option.value)));
|
|
68
|
-
setSelectedCache((prev) => prev.filter((s) => !Object.is(s.value, option.value)));
|
|
69
|
-
};
|
|
70
64
|
const handleClear = (e) => {
|
|
71
65
|
e.stopPropagation();
|
|
72
66
|
if (disabled)
|
|
@@ -75,50 +69,20 @@ export default function Select({ name, options, values, setValues, errorMessage,
|
|
|
75
69
|
setSelectedCache([]);
|
|
76
70
|
onRemove === null || onRemove === void 0 ? void 0 : onRemove();
|
|
77
71
|
};
|
|
78
|
-
//
|
|
72
|
+
// Click outside
|
|
79
73
|
useEffect(() => {
|
|
80
|
-
const
|
|
81
|
-
|
|
82
|
-
|
|
74
|
+
const onDocMouseDown = (e) => {
|
|
75
|
+
const target = e.target;
|
|
76
|
+
const inTrigger = containerRef.current && containerRef.current.contains(target);
|
|
77
|
+
const inMenu = menuRef.current && menuRef.current.contains(target);
|
|
78
|
+
if (!inTrigger && !inMenu)
|
|
83
79
|
setIsOpen(false);
|
|
84
|
-
}
|
|
85
80
|
};
|
|
86
|
-
document.addEventListener("mousedown",
|
|
87
|
-
return () => document.removeEventListener("mousedown",
|
|
81
|
+
document.addEventListener("mousedown", onDocMouseDown);
|
|
82
|
+
return () => document.removeEventListener("mousedown", onDocMouseDown);
|
|
88
83
|
}, []);
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
}
|
|
94
|
-
else {
|
|
95
|
-
setAnimate(false);
|
|
96
|
-
const timeout = setTimeout(() => setShow(false), 200);
|
|
97
|
-
return () => clearTimeout(timeout);
|
|
98
|
-
}
|
|
99
|
-
}, [isOpen]);
|
|
100
|
-
// ---------- Render ----------
|
|
101
|
-
const renderSelectedChips = () => selectedOptions.map((o, i) => (_jsxs("div", { className: "bg-primary bg-opacity-50 px-2 py-1 rounded-2xl flex items-center gap-1", children: [_jsx("span", { className: "text-black text-sm", children: o.label }), !disabled && (_jsx("button", { type: "button", onClick: (e) => {
|
|
102
|
-
e.stopPropagation();
|
|
103
|
-
removeSelected(o);
|
|
104
|
-
}, children: _jsx(Icon, { icon: "line-md:close-small", className: "w-4 h-4" }) }))] }, `${name}-${i}`)));
|
|
105
|
-
const renderPlaceholder = () => (_jsxs("div", { className: "flex gap-2 items-center overflow-hidden", children: [IconPlaceholderLeft, _jsx("p", { className: "text-gray-500 truncate line-clamp-1", children: placeholder })] }));
|
|
106
|
-
return (_jsxs("div", { className: "flex flex-col gap-1", children: [label && (_jsxs("label", { htmlFor: name, className: "pl-1 text-sm text-foreground font-medium mb-2", children: [label, " ", required && _jsx("span", { className: "font-bold", children: "*" })] })), _jsxs("div", { ref: containerRef, className: "relative w-full", children: [_jsxs("div", { onClick: () => !disabled && setIsOpen((o) => !o), className: clsx("text-text flex items-center justify-between gap-2 px-3 py-2 rounded-md border-0.5 hover:border-primary transition-all", disabled
|
|
107
|
-
? "bg-gray-100 text-gray-400 cursor-not-allowed"
|
|
108
|
-
: "bg-white cursor-pointer", errorMessage
|
|
109
|
-
? "border-error"
|
|
110
|
-
: isOpen
|
|
111
|
-
? "border-primary"
|
|
112
|
-
: "border-gray-200", buttonClassName), children: [multiselect ? (selectedOptions.length ? (_jsx("div", { className: "flex flex-wrap gap-2", id: name, children: renderSelectedChips() })) : (renderPlaceholder())) : selectedOptions[0] ? (_jsx("div", { className: "text-text truncate line-clamp-1", children: selectedOptions[0].label })) : (renderPlaceholder()), _jsxs("div", { className: "flex items-center gap-1", children: [!disabled &&
|
|
113
|
-
(multiselect
|
|
114
|
-
? selectedOptions.length > 0
|
|
115
|
-
: !!selectedOptions[0]) && (_jsx("button", { type: "button", onClick: handleClear, title: "Clear selection", className: "text-gray-500 hover:text-primary", children: _jsx(Icon, { icon: "line-md:close-small", className: "w-5 h-5" }) })), _jsx(Icon, { icon: "iconamoon:arrow-down-2", className: clsx("transition-transform duration-200", isOpen && "rotate-180") })] })] }), show && !disabled && (_jsxs("div", { className: clsx("absolute left-0 mt-1 z-50 bg-white border border-gray-200 rounded-md shadow-lg max-h-64 overflow-auto max-w-[360px] min-w-[260px] w-full transition-all duration-200 ease-out", animate
|
|
116
|
-
? "opacity-100 translate-y-0 scale-100"
|
|
117
|
-
: "opacity-0 -translate-y-1 scale-95"), children: [isSearchable && (_jsxs("div", { className: "sticky top-0 bg-white border-b border-gray-100 px-2 py-1 flex items-center gap-2", onClick: (e) => e.stopPropagation(), children: [_jsx(Icon, { icon: "mdi:magnify", className: "text-gray-500 w-5 h-5" }), _jsx("input", { type: "text", placeholder: "Search...", value: search, onChange: handleSearchInputChange, className: "w-full outline-none text-sm bg-transparent py-1" })] })), filteredOptions.length > 0 ? (filteredOptions.map((o, i) => {
|
|
118
|
-
const isSelected = selectedOptions.some((s) => Object.is(s.value, o.value));
|
|
119
|
-
return (_jsxs("div", { onClick: () => {
|
|
120
|
-
setSearch("");
|
|
121
|
-
toggleOption(o);
|
|
122
|
-
}, className: clsx("mx-1 px-3 py-2 cursor-pointer flex items-center gap-2 rounded text-sm hover:text-primary hover:bg-primary/20", isSelected && "bg-primary/10 text-primary"), children: [isSelected ? (_jsx(Icon, { icon: "mdi:check", className: "w-4 h-4 text-primary" })) : (_jsx("div", { className: "w-4 h-4" })), o.label] }, `${name}-option-${i}`));
|
|
123
|
-
})) : (_jsx("div", { className: "px-3 py-2 text-gray-400 text-sm", children: "No results" }))] }))] }), errorMessage && (_jsx("p", { className: "pl-1 text-sm text-error", children: errorMessage }))] }));
|
|
84
|
+
return (_jsx(SelectView, { label: label, required: required, errorMessage: errorMessage, containerRef: containerRef, menuRef: menuRef, disabled: disabled, isOpen: isOpen, buttonClassName: buttonClassName, onToggle: () => setIsOpen((o) => !o), multiselect: multiselect, selectedOptions: selectedOptions, placeholder: placeholder, IconPlaceholderLeft: IconPlaceholderLeft, onClear: handleClear, name: name, show: show, usePortal: usePortal, dropdownClassName: dropdownClassName, animate: animate, menuPos: menuPos, isSearchable: isSearchable, search: search, onChangeSearchInput: handleSearchInputChange, filteredOptions: filteredOptions, onOptionClick: (o) => {
|
|
85
|
+
setSearch("");
|
|
86
|
+
toggleOption(o);
|
|
87
|
+
}, desiredMax: desiredMax }));
|
|
124
88
|
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export type MenuPosition = {
|
|
2
|
+
left: number;
|
|
3
|
+
top: number;
|
|
4
|
+
width: number;
|
|
5
|
+
maxHeight: number;
|
|
6
|
+
placement: "top" | "bottom";
|
|
7
|
+
};
|
|
8
|
+
export declare const DEFAULT_GAP = 4;
|
|
9
|
+
export declare const DEFAULT_DESIRED_MAX = 256;
|
|
10
|
+
export declare function useSelectPortal(params: {
|
|
11
|
+
isOpen: boolean;
|
|
12
|
+
usePortal: boolean;
|
|
13
|
+
containerRef: React.RefObject<HTMLDivElement>;
|
|
14
|
+
menuRef: React.RefObject<HTMLDivElement>;
|
|
15
|
+
heightDeps?: unknown[];
|
|
16
|
+
gap?: number;
|
|
17
|
+
desiredMax?: number;
|
|
18
|
+
scrollDebounceMs?: number;
|
|
19
|
+
}): {
|
|
20
|
+
readonly show: boolean;
|
|
21
|
+
readonly animate: boolean;
|
|
22
|
+
readonly menuPos: MenuPosition;
|
|
23
|
+
readonly updateMenuPosition: () => void;
|
|
24
|
+
readonly gap: number;
|
|
25
|
+
readonly desiredMax: number;
|
|
26
|
+
};
|
|
27
|
+
//# sourceMappingURL=useSelectPortal.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useSelectPortal.d.ts","sourceRoot":"","sources":["../../../src/components/select/useSelectPortal.ts"],"names":[],"mappings":"AAQA,MAAM,MAAM,YAAY,GAAG;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,KAAK,GAAG,QAAQ,CAAC;CAC7B,CAAC;AAEF,eAAO,MAAM,WAAW,IAAI,CAAC;AAC7B,eAAO,MAAM,mBAAmB,MAAM,CAAC;AAKvC,wBAAgB,eAAe,CAAC,MAAM,EAAE;IACtC,MAAM,EAAE,OAAO,CAAC;IAChB,SAAS,EAAE,OAAO,CAAC;IACnB,YAAY,EAAE,KAAK,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC;IAC9C,OAAO,EAAE,KAAK,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC;IACzC,UAAU,CAAC,EAAE,OAAO,EAAE,CAAC;IACvB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;;;;;;;EAiIA"}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { useCallback, useEffect, useLayoutEffect, useRef, useState, } from "react";
|
|
2
|
+
export const DEFAULT_GAP = 4;
|
|
3
|
+
export const DEFAULT_DESIRED_MAX = 256; // px
|
|
4
|
+
const clamp = (val, min, max) => Math.max(min, Math.min(val, max));
|
|
5
|
+
export function useSelectPortal(params) {
|
|
6
|
+
const { isOpen, usePortal, containerRef, menuRef, heightDeps = [], gap = DEFAULT_GAP, desiredMax = DEFAULT_DESIRED_MAX, scrollDebounceMs = 120, } = params;
|
|
7
|
+
const [show, setShow] = useState(false);
|
|
8
|
+
const [animate, setAnimate] = useState(false);
|
|
9
|
+
const [menuPos, setMenuPos] = useState({
|
|
10
|
+
left: 0,
|
|
11
|
+
top: 0,
|
|
12
|
+
width: 0,
|
|
13
|
+
maxHeight: desiredMax,
|
|
14
|
+
placement: "bottom",
|
|
15
|
+
});
|
|
16
|
+
const scrollEndTimerRef = useRef(null);
|
|
17
|
+
const updateMenuPosition = useCallback(() => {
|
|
18
|
+
const trigger = containerRef.current;
|
|
19
|
+
if (!trigger)
|
|
20
|
+
return;
|
|
21
|
+
const rect = trigger.getBoundingClientRect();
|
|
22
|
+
const vw = window.innerWidth;
|
|
23
|
+
const vh = window.innerHeight;
|
|
24
|
+
const spaceBelow = vh - rect.bottom;
|
|
25
|
+
const spaceAbove = rect.top;
|
|
26
|
+
const shouldFlip = spaceBelow < 160 && spaceAbove > spaceBelow;
|
|
27
|
+
const placement = shouldFlip ? "top" : "bottom";
|
|
28
|
+
const maxHeight = Math.min(desiredMax, Math.max((shouldFlip ? spaceAbove : spaceBelow) - gap, 120));
|
|
29
|
+
const width = rect.width;
|
|
30
|
+
const rawLeft = usePortal ? rect.left : rect.left + window.scrollX;
|
|
31
|
+
const left = clamp(rawLeft, 8, vw - width - 8);
|
|
32
|
+
const top = shouldFlip
|
|
33
|
+
? usePortal
|
|
34
|
+
? rect.top - gap - maxHeight
|
|
35
|
+
: rect.top + window.scrollY - gap - maxHeight
|
|
36
|
+
: usePortal
|
|
37
|
+
? rect.bottom + gap
|
|
38
|
+
: rect.bottom + window.scrollY + gap;
|
|
39
|
+
setMenuPos({ left, top, width, maxHeight, placement });
|
|
40
|
+
}, [containerRef, usePortal, gap, desiredMax]);
|
|
41
|
+
// Refine top when placement is top (after actual height known)
|
|
42
|
+
useLayoutEffect(() => {
|
|
43
|
+
if (!isOpen)
|
|
44
|
+
return;
|
|
45
|
+
if (!menuRef.current || menuPos.placement !== "top")
|
|
46
|
+
return;
|
|
47
|
+
const trigger = containerRef.current;
|
|
48
|
+
if (!trigger)
|
|
49
|
+
return;
|
|
50
|
+
const rect = trigger.getBoundingClientRect();
|
|
51
|
+
const actualHeight = menuRef.current.offsetHeight || menuPos.maxHeight;
|
|
52
|
+
const correctedTop = usePortal
|
|
53
|
+
? rect.top - gap - actualHeight
|
|
54
|
+
: rect.top + window.scrollY - gap - actualHeight;
|
|
55
|
+
if (Math.abs(correctedTop - menuPos.top) > 1) {
|
|
56
|
+
setMenuPos((prev) => ({ ...prev, top: correctedTop }));
|
|
57
|
+
}
|
|
58
|
+
// include values that change height so we re-evaluate when content changes
|
|
59
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
60
|
+
}, [
|
|
61
|
+
isOpen,
|
|
62
|
+
usePortal,
|
|
63
|
+
menuPos.placement,
|
|
64
|
+
menuPos.top,
|
|
65
|
+
menuPos.maxHeight,
|
|
66
|
+
containerRef,
|
|
67
|
+
menuRef,
|
|
68
|
+
gap,
|
|
69
|
+
...heightDeps,
|
|
70
|
+
]);
|
|
71
|
+
// Open/close lifecycle + resize/scroll handling
|
|
72
|
+
useEffect(() => {
|
|
73
|
+
if (isOpen) {
|
|
74
|
+
setShow(true);
|
|
75
|
+
updateMenuPosition();
|
|
76
|
+
const onResize = () => updateMenuPosition();
|
|
77
|
+
const onAnyScroll = () => {
|
|
78
|
+
if (scrollEndTimerRef.current)
|
|
79
|
+
window.clearTimeout(scrollEndTimerRef.current);
|
|
80
|
+
scrollEndTimerRef.current = window.setTimeout(() => {
|
|
81
|
+
updateMenuPosition();
|
|
82
|
+
}, scrollDebounceMs);
|
|
83
|
+
};
|
|
84
|
+
window.addEventListener("resize", onResize);
|
|
85
|
+
document.addEventListener("scroll", onAnyScroll, true);
|
|
86
|
+
requestAnimationFrame(() => setAnimate(true));
|
|
87
|
+
return () => {
|
|
88
|
+
window.removeEventListener("resize", onResize);
|
|
89
|
+
document.removeEventListener("scroll", onAnyScroll, true);
|
|
90
|
+
if (scrollEndTimerRef.current) {
|
|
91
|
+
window.clearTimeout(scrollEndTimerRef.current);
|
|
92
|
+
scrollEndTimerRef.current = null;
|
|
93
|
+
}
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
else {
|
|
97
|
+
setAnimate(false);
|
|
98
|
+
const t = setTimeout(() => setShow(false), 200);
|
|
99
|
+
return () => clearTimeout(t);
|
|
100
|
+
}
|
|
101
|
+
}, [isOpen, updateMenuPosition, scrollDebounceMs]);
|
|
102
|
+
return {
|
|
103
|
+
show,
|
|
104
|
+
animate,
|
|
105
|
+
menuPos,
|
|
106
|
+
updateMenuPosition,
|
|
107
|
+
gap,
|
|
108
|
+
desiredMax,
|
|
109
|
+
};
|
|
110
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/hooks/use-/index.tsx"],"names":[],"mappings":""}
|
|
File without changes
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/hooks/use-has-permission-access/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAIjD,wBAAgB,gBAAgB,CAC9B,UAAU,EAAE,SAAS,CAAC,UAAU,CAAC,cAAc,GAC9C,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/hooks/use-has-permission-access/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAIjD,wBAAgB,gBAAgB,CAC9B,UAAU,EAAE,SAAS,CAAC,UAAU,CAAC,cAAc,GAC9C,OAAO,CAQT;AAED,wBAAgB,sBAAsB,CACpC,WAAW,EAAE,SAAS,CAAC,UAAU,CAAC,cAAc,EAAE,GACjD,OAAO,CAUT"}
|
|
@@ -5,12 +5,16 @@ import { jwtDecode } from "../../utils/jwt";
|
|
|
5
5
|
export function useHasPermission(permission) {
|
|
6
6
|
var _a, _b;
|
|
7
7
|
const accessToken = getCookie(CONSTANTS.JWT.JWTCookieKey);
|
|
8
|
+
if (!accessToken || accessToken === undefined)
|
|
9
|
+
return false;
|
|
8
10
|
const payload = jwtDecode(accessToken);
|
|
9
11
|
return (_b = (_a = payload === null || payload === void 0 ? void 0 : payload.permissionKeys) === null || _a === void 0 ? void 0 : _a.includes(permission)) !== null && _b !== void 0 ? _b : false;
|
|
10
12
|
}
|
|
11
13
|
export function useHasOneOfPermissions(permissions) {
|
|
12
14
|
var _a, _b;
|
|
13
15
|
const accessToken = getCookie(CONSTANTS.JWT.JWTCookieKey);
|
|
16
|
+
if (!accessToken || accessToken === undefined)
|
|
17
|
+
return false;
|
|
14
18
|
const payload = jwtDecode(accessToken);
|
|
15
19
|
return ((_b = (_a = payload === null || payload === void 0 ? void 0 : payload.permissionKeys) === null || _a === void 0 ? void 0 : _a.some((item) => permissions.includes(item))) !== null && _b !== void 0 ? _b : false);
|
|
16
20
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/hooks/use-interval/index.tsx"],"names":[],"mappings":"AAGA,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,IAAI,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,QAcrE"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useEffect, useRef } from "react";
|
|
3
|
+
export function useInterval(callback, delay) {
|
|
4
|
+
const savedCallback = useRef(callback);
|
|
5
|
+
// Remember the latest callback
|
|
6
|
+
useEffect(() => {
|
|
7
|
+
savedCallback.current = callback;
|
|
8
|
+
}, [callback]);
|
|
9
|
+
// Set up the interval
|
|
10
|
+
useEffect(() => {
|
|
11
|
+
if (delay === null)
|
|
12
|
+
return; // allow pausing
|
|
13
|
+
const id = setInterval(() => savedCallback.current(), delay);
|
|
14
|
+
return () => clearInterval(id);
|
|
15
|
+
}, [delay]);
|
|
16
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/hooks/use-token-watcher/index.tsx"],"names":[],"mappings":"AAKA,KAAK,OAAO,GAAG;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,IAAI,CAAC;CAC5B,CAAC;AAEF,wBAAgB,eAAe,CAAC,EAAE,QAAe,EAAE,cAAc,EAAE,EAAE,OAAO,QAoB3E"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useEffect } from "react";
|
|
3
|
+
import { CONSTANTS } from "sea-platform-helpers";
|
|
4
|
+
import { getCookie } from "../../utils/cookie";
|
|
5
|
+
export function useTokenWatcher({ interval = 3000, onTokenMissing }) {
|
|
6
|
+
useEffect(() => {
|
|
7
|
+
let lastToken = getCookie(CONSTANTS.JWT.JWTCookieKey);
|
|
8
|
+
const id = setInterval(() => {
|
|
9
|
+
console.log("Watching the token");
|
|
10
|
+
const currentToken = getCookie(CONSTANTS.JWT.JWTCookieKey);
|
|
11
|
+
console.log({
|
|
12
|
+
lastToken,
|
|
13
|
+
currentToken,
|
|
14
|
+
});
|
|
15
|
+
if (!currentToken && lastToken) {
|
|
16
|
+
console.log("[MustAuth] Token disappeared — triggering noTokenHandler");
|
|
17
|
+
onTokenMissing();
|
|
18
|
+
}
|
|
19
|
+
lastToken = currentToken;
|
|
20
|
+
}, interval);
|
|
21
|
+
return () => clearInterval(id);
|
|
22
|
+
}, [onTokenMissing, interval]);
|
|
23
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/hooks/user-has-application-access/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAIjD,wBAAgB,uBAAuB,CACrC,cAAc,EAAE,SAAS,CAAC,WAAW,CAAC,eAAe,GACpD,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/hooks/user-has-application-access/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAIjD,wBAAgB,uBAAuB,CACrC,cAAc,EAAE,SAAS,CAAC,WAAW,CAAC,eAAe,GACpD,OAAO,CAST"}
|
|
@@ -5,6 +5,8 @@ import { jwtDecode } from "../../utils/jwt";
|
|
|
5
5
|
export function useHasApplicationAccess(applicationKey) {
|
|
6
6
|
var _a, _b;
|
|
7
7
|
const accessToken = getCookie(CONSTANTS.JWT.JWTCookieKey);
|
|
8
|
+
if (!accessToken || accessToken === undefined)
|
|
9
|
+
return false;
|
|
8
10
|
const payload = jwtDecode(accessToken);
|
|
9
11
|
return (_b = (_a = payload.applicationKeys) === null || _a === void 0 ? void 0 : _a.includes(applicationKey)) !== null && _b !== void 0 ? _b : false;
|
|
10
12
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"root":["../src/index.ts","../src/hoc/can-access-application/index.tsx","../src/hoc/with-authorization/index.tsx","../src/components/accordion/index.tsx","../src/components/activity-message/index.tsx","../src/components/alert/index.tsx","../src/components/auto-complete/auto-complete-context.tsx","../src/components/auto-complete/auto-complete-dropdown.tsx","../src/components/auto-complete/auto-complete-input.tsx","../src/components/auto-complete/auto-complete-selected.tsx","../src/components/auto-complete/auto-complete.tsx","../src/components/auto-complete/index.tsx","../src/components/auto-complete/use-autocomplete.ts","../src/components/auto-complete-input/index.tsx","../src/components/avatar/index.tsx","../src/components/badge/index.tsx","../src/components/breadcrumb/index.tsx","../src/components/break-line/index.tsx","../src/components/button/index.tsx","../src/components/calendar/index.tsx","../src/components/cards-list/index.tsx","../src/components/carousel/index.tsx","../src/components/checkbox/index.tsx","../src/components/color-picker/index.tsx","../src/components/comments-container/index.tsx","../src/components/comments-container/comment-event-bus/index.ts","../src/components/comments-container/comment-form/index.tsx","../src/components/comments-container/comment-item/index.tsx","../src/components/comments-container/comments-list/index.tsx","../src/components/comments-container/constants/index.ts","../src/components/comments-container/use-comments/index.tsx","../src/components/confirm/index.tsx","../src/components/count-down/index.tsx","../src/components/day-calendar/index.tsx","../src/components/drawer/index.tsx","../src/components/editable-text/index.tsx","../src/components/expandable-text/index.tsx","../src/components/file-input/index.tsx","../src/components/file-input/components/file-item/index.tsx","../src/components/firebase-token-handler/index.tsx","../src/components/icon/index.tsx","../src/components/input/index.tsx","../src/components/item-not-found/index.tsx","../src/components/list-item/index.tsx","../src/components/list-item/components/page-button/index.tsx","../src/components/list-item/components/pagination/index.tsx","../src/components/loader/index.tsx","../src/components/menu/index.tsx","../src/components/menu/menu-item/index.tsx","../src/components/modal/index.tsx","../src/components/month-calendar/index.tsx","../src/components/native-menu/index.tsx","../src/components/native-menu/native-menu-item/index.tsx","../src/components/not-authorized/index.tsx","../src/components/notifications-menu/index.tsx","../src/components/otp-input/index.tsx","../src/components/paper/index.tsx","../src/components/progress-bar/index.tsx","../src/components/radio-button/index.tsx","../src/components/search-input/index.tsx","../src/components/searchable-select/index.tsx","../src/components/select/index.tsx","../src/components/skeleton/index.tsx","../src/components/stacked-avatars/index.tsx","../src/components/tab/index.tsx","../src/components/table/index.tsx","../src/components/text-editor/index.tsx","../src/components/text-editor/components/toolbar/index.tsx","../src/components/text-editor/utils/index.ts","../src/components/textarea/index.tsx","../src/components/toggle/index.tsx","../src/components/tooltip/index.tsx","../src/components/tree-checkbox/index.tsx","../src/components/tree-checkbox/components/tree-checkbox-item/index.tsx","../src/components/tree-checkbox/utils/index.ts","../src/components/week-calendar/index.tsx","../src/constants/index.ts","../src/hooks/list-items-hook/types.ts","../src/hooks/list-items-hook/usebulkactions.ts","../src/hooks/list-items-hook/usefilters.ts","../src/hooks/list-items-hook/usepagination.ts","../src/hooks/use-has-permission-access/index.ts","../src/hooks/user-has-application-access/index.ts","../src/middleware/must-auth/index.tsx","../src/utils/auth-axios/index.ts","../src/utils/axios/index.ts","../src/utils/color/index.ts","../src/utils/cookie/index.ts","../src/utils/device/index.ts","../src/utils/file/index.ts","../src/utils/firebase-client/firebase.ts","../src/utils/firebase-client/index.ts","../src/utils/firebase-client/types.ts","../src/utils/jwt/index.ts","../src/utils/notification-localstorage/index.ts","../src/utils/validation/index.ts"],"version":"5.6.3"}
|
|
1
|
+
{"root":["../src/index.ts","../src/hoc/can-access-application/index.tsx","../src/hoc/with-authorization/index.tsx","../src/components/accordion/index.tsx","../src/components/activity-message/index.tsx","../src/components/alert/index.tsx","../src/components/auto-complete/auto-complete-context.tsx","../src/components/auto-complete/auto-complete-dropdown.tsx","../src/components/auto-complete/auto-complete-input.tsx","../src/components/auto-complete/auto-complete-selected.tsx","../src/components/auto-complete/auto-complete.tsx","../src/components/auto-complete/index.tsx","../src/components/auto-complete/use-autocomplete.ts","../src/components/auto-complete-input/index.tsx","../src/components/avatar/index.tsx","../src/components/badge/index.tsx","../src/components/breadcrumb/index.tsx","../src/components/break-line/index.tsx","../src/components/button/index.tsx","../src/components/calendar/index.tsx","../src/components/cards-list/index.tsx","../src/components/carousel/index.tsx","../src/components/checkbox/index.tsx","../src/components/color-picker/index.tsx","../src/components/comments-container/index.tsx","../src/components/comments-container/comment-event-bus/index.ts","../src/components/comments-container/comment-form/index.tsx","../src/components/comments-container/comment-item/index.tsx","../src/components/comments-container/comments-list/index.tsx","../src/components/comments-container/constants/index.ts","../src/components/comments-container/use-comments/index.tsx","../src/components/confirm/index.tsx","../src/components/count-down/index.tsx","../src/components/day-calendar/index.tsx","../src/components/drawer/index.tsx","../src/components/editable-text/index.tsx","../src/components/expandable-text/index.tsx","../src/components/file-input/index.tsx","../src/components/file-input/components/file-item/index.tsx","../src/components/firebase-token-handler/index.tsx","../src/components/icon/index.tsx","../src/components/input/index.tsx","../src/components/item-not-found/index.tsx","../src/components/list-item/index.tsx","../src/components/list-item/components/page-button/index.tsx","../src/components/list-item/components/pagination/index.tsx","../src/components/loader/index.tsx","../src/components/menu/index.tsx","../src/components/menu/menu-item/index.tsx","../src/components/modal/index.tsx","../src/components/month-calendar/index.tsx","../src/components/native-menu/index.tsx","../src/components/native-menu/native-menu-item/index.tsx","../src/components/not-authorized/index.tsx","../src/components/notifications-menu/index.tsx","../src/components/otp-input/index.tsx","../src/components/paper/index.tsx","../src/components/progress-bar/index.tsx","../src/components/radio-button/index.tsx","../src/components/search-input/index.tsx","../src/components/searchable-select/index.tsx","../src/components/select/selectchips.tsx","../src/components/select/selectcontrol.tsx","../src/components/select/selectdropdowncontent.tsx","../src/components/select/selectplaceholder.tsx","../src/components/select/selecttypes.ts","../src/components/select/selectview.tsx","../src/components/select/index.tsx","../src/components/select/useselectportal.ts","../src/components/skeleton/index.tsx","../src/components/stacked-avatars/index.tsx","../src/components/tab/index.tsx","../src/components/table/index.tsx","../src/components/text-editor/index.tsx","../src/components/text-editor/components/toolbar/index.tsx","../src/components/text-editor/utils/index.ts","../src/components/textarea/index.tsx","../src/components/toggle/index.tsx","../src/components/tooltip/index.tsx","../src/components/tree-checkbox/index.tsx","../src/components/tree-checkbox/components/tree-checkbox-item/index.tsx","../src/components/tree-checkbox/utils/index.ts","../src/components/week-calendar/index.tsx","../src/constants/index.ts","../src/hooks/list-items-hook/types.ts","../src/hooks/list-items-hook/usebulkactions.ts","../src/hooks/list-items-hook/usefilters.ts","../src/hooks/list-items-hook/usepagination.ts","../src/hooks/use-has-permission-access/index.ts","../src/hooks/user-has-application-access/index.ts","../src/middleware/must-auth/index.tsx","../src/utils/auth-axios/index.ts","../src/utils/axios/index.ts","../src/utils/color/index.ts","../src/utils/cookie/index.ts","../src/utils/device/index.ts","../src/utils/file/index.ts","../src/utils/firebase-client/firebase.ts","../src/utils/firebase-client/index.ts","../src/utils/firebase-client/types.ts","../src/utils/jwt/index.ts","../src/utils/notification-localstorage/index.ts","../src/utils/validation/index.ts"],"version":"5.6.3"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/utils/axios/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAoC,MAAM,OAAO,CAAC;AAKzD,KAAK,YAAY,GAAG;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,OAAO,CAAC,EAAE,cAAc,GAAG,QAAQ,CAAC;IACpC,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF,eAAO,MAAM,cAAc,YAChB,MAAM,YACN,YAAY,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/utils/axios/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAoC,MAAM,OAAO,CAAC;AAKzD,KAAK,YAAY,GAAG;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,OAAO,CAAC,EAAE,cAAc,GAAG,QAAQ,CAAC;IACpC,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF,eAAO,MAAM,cAAc,YAChB,MAAM,YACN,YAAY,kCAiEtB,CAAC;AAEF,eAAe,KAAK,CAAC"}
|
|
@@ -43,6 +43,9 @@ export const createInstance = (baseURL, options = {
|
|
|
43
43
|
].includes(message)) {
|
|
44
44
|
console.log("Unauthenticated or invalid input - logging out");
|
|
45
45
|
removeCookie(options.JWTTokenKey);
|
|
46
|
+
setTimeout(() => {
|
|
47
|
+
window.location.reload();
|
|
48
|
+
}, 2000);
|
|
46
49
|
}
|
|
47
50
|
return Promise.reject((_d = error.response) === null || _d === void 0 ? void 0 : _d.data);
|
|
48
51
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/utils/cookie/index.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,SAAS,SAAU,MAAM,KAAG,MAAM,GAAG,SAMjD,CAAC;AAEF,eAAO,MAAM,SAAS,SACd,MAAM,SACL,MAAM,YACH;IACR,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,QAAQ,GAAG,KAAK,GAAG,MAAM,CAAC;CACtC,KACA,IAiBF,CAAC;AAEF,eAAO,MAAM,YAAY,SAAU,MAAM,KAAG,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/utils/cookie/index.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,SAAS,SAAU,MAAM,KAAG,MAAM,GAAG,SAMjD,CAAC;AAEF,eAAO,MAAM,SAAS,SACd,MAAM,SACL,MAAM,YACH;IACR,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,QAAQ,GAAG,KAAK,GAAG,MAAM,CAAC;CACtC,KACA,IAiBF,CAAC;AAEF,eAAO,MAAM,YAAY,SAAU,MAAM,KAAG,IAiB3C,CAAC"}
|
|
@@ -26,9 +26,11 @@ export const setCookie = (name, value, options) => {
|
|
|
26
26
|
document.cookie = cookie;
|
|
27
27
|
};
|
|
28
28
|
export const removeCookie = (name) => {
|
|
29
|
+
console.log("removeCookie: ", name);
|
|
29
30
|
// Try removing it for all common scopes
|
|
30
31
|
const domains = [window.location.hostname, `.${window.location.hostname}`];
|
|
31
32
|
const paths = ["/", ""];
|
|
33
|
+
console.log({ domains, paths });
|
|
32
34
|
domains.forEach((domain) => {
|
|
33
35
|
paths.forEach((path) => {
|
|
34
36
|
document.cookie = `${name}=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=${path}; domain=${domain};`;
|
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.22",
|
|
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.19",
|
|
52
52
|
"sea-react-components": "file:",
|
|
53
53
|
"uuid": "^13.0.0",
|
|
54
54
|
"yup": "^1.5.0"
|