@kkcompany/app-ui 0.1.30 → 0.1.32
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/index.cjs +406 -4
- package/dist/index.d.cts +55 -7
- package/dist/index.d.mts +55 -7
- package/dist/index.mjs +406 -6
- package/package.json +7 -3
package/dist/index.cjs
CHANGED
|
@@ -342,6 +342,8 @@ var Banner_default = Banner;
|
|
|
342
342
|
//#endregion
|
|
343
343
|
//#region src/Dropdown.tsx
|
|
344
344
|
/** @jsxImportSource @emotion/react */
|
|
345
|
+
const dropdownBorderRadius = "4px";
|
|
346
|
+
const itemRowElemMarginXSm = "16px";
|
|
345
347
|
const dropdownStyle = __emotion_react.css`
|
|
346
348
|
.text-truncate {
|
|
347
349
|
display: block;
|
|
@@ -411,7 +413,7 @@ const dropdownStyle = __emotion_react.css`
|
|
|
411
413
|
|
|
412
414
|
.kks-dropdown__menu {
|
|
413
415
|
width: 92%;
|
|
414
|
-
border-radius: $
|
|
416
|
+
border-radius: ${dropdownBorderRadius};
|
|
415
417
|
background: #fff;
|
|
416
418
|
overflow: hidden;
|
|
417
419
|
}
|
|
@@ -421,7 +423,7 @@ const dropdownStyle = __emotion_react.css`
|
|
|
421
423
|
border-bottom: 1px solid #e9ecef;
|
|
422
424
|
|
|
423
425
|
.kks-dropdown__menu-title {
|
|
424
|
-
margin-left: $
|
|
426
|
+
margin-left: ${itemRowElemMarginXSm};
|
|
425
427
|
font-size: 1.25rem;
|
|
426
428
|
}
|
|
427
429
|
|
|
@@ -429,7 +431,7 @@ const dropdownStyle = __emotion_react.css`
|
|
|
429
431
|
display: flex;
|
|
430
432
|
align-items: center;
|
|
431
433
|
margin-left: auto;
|
|
432
|
-
padding: 0 $
|
|
434
|
+
padding: 0 ${itemRowElemMarginXSm};
|
|
433
435
|
height: 100%;
|
|
434
436
|
outline: none;
|
|
435
437
|
}
|
|
@@ -449,7 +451,7 @@ const dropdownStyle = __emotion_react.css`
|
|
|
449
451
|
overflow-y: auto;
|
|
450
452
|
|
|
451
453
|
.kks-dropdown__menu-link {
|
|
452
|
-
padding: 10px $
|
|
454
|
+
padding: 10px ${itemRowElemMarginXSm};
|
|
453
455
|
text-decoration: none;
|
|
454
456
|
color: #000;
|
|
455
457
|
outline: none;
|
|
@@ -712,6 +714,404 @@ const Icon = ({ style = {}, src }) => /* @__PURE__ */ (0, __emotion_react_jsx_ru
|
|
|
712
714
|
] });
|
|
713
715
|
var Icon_default = Icon;
|
|
714
716
|
|
|
717
|
+
//#endregion
|
|
718
|
+
//#region src/Modal/styles.ts
|
|
719
|
+
const modalStyle = __emotion_react.css`
|
|
720
|
+
:where(&) {
|
|
721
|
+
position: fixed;
|
|
722
|
+
top: 0;
|
|
723
|
+
right: 0;
|
|
724
|
+
bottom: 0;
|
|
725
|
+
left: 0;
|
|
726
|
+
z-index: 1000;
|
|
727
|
+
padding: 1rem;
|
|
728
|
+
overflow-x: hidden;
|
|
729
|
+
overflow-y: auto;
|
|
730
|
+
visibility: hidden;
|
|
731
|
+
opacity: 0;
|
|
732
|
+
background-color: rgba(0, 0, 0, 0.7);
|
|
733
|
+
transition: opacity 0.3s;
|
|
734
|
+
}
|
|
735
|
+
|
|
736
|
+
:where(&.modal--show),
|
|
737
|
+
:where(&.modal--shown) {
|
|
738
|
+
display: flex;
|
|
739
|
+
justify-content: center;
|
|
740
|
+
visibility: visible;
|
|
741
|
+
opacity: 1;
|
|
742
|
+
}
|
|
743
|
+
|
|
744
|
+
& :where(.modal__content) {
|
|
745
|
+
width: 100%;
|
|
746
|
+
max-width: 700px;
|
|
747
|
+
margin: auto 0;
|
|
748
|
+
}
|
|
749
|
+
`;
|
|
750
|
+
|
|
751
|
+
//#endregion
|
|
752
|
+
//#region src/Modal/index.tsx
|
|
753
|
+
const MODAL_STATE = {
|
|
754
|
+
SHOW: "show",
|
|
755
|
+
SHOWN: "shown",
|
|
756
|
+
HIDE: "hide",
|
|
757
|
+
HIDDEN: "hidden"
|
|
758
|
+
};
|
|
759
|
+
const isShowing = (state) => state === MODAL_STATE.SHOW || state === MODAL_STATE.SHOWN;
|
|
760
|
+
const Modal = (0, react.memo)((0, react.forwardRef)(function Modal$1({ children, className = "", isHideModalOnClickOverlay = true, isShow, onHidden = () => {}, onShown = () => {}, onTriggerHiding = () => {} }, ref) {
|
|
761
|
+
const [visualState, setVisualState] = (0, react.useState)(MODAL_STATE.HIDDEN);
|
|
762
|
+
const shouldLockBody = isShowing(visualState);
|
|
763
|
+
if (isShow && !isShowing(visualState)) setVisualState(MODAL_STATE.SHOW);
|
|
764
|
+
else if (!isShow && isShowing(visualState)) setVisualState(MODAL_STATE.HIDE);
|
|
765
|
+
(0, react.useLayoutEffect)(() => {
|
|
766
|
+
if (!shouldLockBody) return;
|
|
767
|
+
const previousOverflow = document.body.style.overflow;
|
|
768
|
+
document.body.style.overflow = "hidden";
|
|
769
|
+
return () => {
|
|
770
|
+
document.body.style.overflow = previousOverflow;
|
|
771
|
+
};
|
|
772
|
+
}, [shouldLockBody]);
|
|
773
|
+
const previousVisualState = (0, react.useRef)(visualState);
|
|
774
|
+
(0, react.useLayoutEffect)(() => {
|
|
775
|
+
if (previousVisualState.current === visualState) return;
|
|
776
|
+
previousVisualState.current = visualState;
|
|
777
|
+
if (visualState === MODAL_STATE.SHOWN) onShown();
|
|
778
|
+
else if (visualState === MODAL_STATE.HIDDEN) onHidden();
|
|
779
|
+
}, [
|
|
780
|
+
visualState,
|
|
781
|
+
onShown,
|
|
782
|
+
onHidden
|
|
783
|
+
]);
|
|
784
|
+
const handleAnimationEnd = (0, react.useCallback)(() => {
|
|
785
|
+
setVisualState((previousState) => {
|
|
786
|
+
if (previousState === MODAL_STATE.SHOW) return MODAL_STATE.SHOWN;
|
|
787
|
+
if (previousState === MODAL_STATE.HIDE) return MODAL_STATE.HIDDEN;
|
|
788
|
+
return previousState;
|
|
789
|
+
});
|
|
790
|
+
}, []);
|
|
791
|
+
const handleClick = (0, react.useCallback)((event) => {
|
|
792
|
+
if (event.target.getAttribute("data-dismiss") === "modal") onTriggerHiding();
|
|
793
|
+
}, [onTriggerHiding]);
|
|
794
|
+
const handleKeyDown = (0, react.useCallback)((event) => {
|
|
795
|
+
if (event.key !== "Enter" && event.key !== " ") return;
|
|
796
|
+
if (event.target.getAttribute("data-dismiss") !== "modal") return;
|
|
797
|
+
event.preventDefault();
|
|
798
|
+
onTriggerHiding();
|
|
799
|
+
}, [onTriggerHiding]);
|
|
800
|
+
return /* @__PURE__ */ (0, __emotion_react_jsx_runtime.jsx)("div", {
|
|
801
|
+
css: modalStyle,
|
|
802
|
+
ref,
|
|
803
|
+
role: "presentation",
|
|
804
|
+
className: `modal modal--${visualState} ${className}`,
|
|
805
|
+
onClick: handleClick,
|
|
806
|
+
onKeyDown: handleKeyDown,
|
|
807
|
+
onAnimationEnd: handleAnimationEnd,
|
|
808
|
+
onTransitionEnd: handleAnimationEnd,
|
|
809
|
+
"data-dismiss": isHideModalOnClickOverlay ? "modal" : void 0,
|
|
810
|
+
children: /* @__PURE__ */ (0, __emotion_react_jsx_runtime.jsx)("div", {
|
|
811
|
+
className: "modal__content",
|
|
812
|
+
children
|
|
813
|
+
})
|
|
814
|
+
});
|
|
815
|
+
}));
|
|
816
|
+
var Modal_default = Modal;
|
|
817
|
+
|
|
818
|
+
//#endregion
|
|
819
|
+
//#region src/Pagination/PaginationLink.tsx
|
|
820
|
+
const PaginationLink = ({ routeData, nextLink: NextLinkComponent, children, ...anchorProps }) => {
|
|
821
|
+
const anchor = /* @__PURE__ */ (0, react_jsx_runtime.jsx)("a", {
|
|
822
|
+
...anchorProps,
|
|
823
|
+
href: NextLinkComponent ? void 0 : routeData.route,
|
|
824
|
+
children
|
|
825
|
+
});
|
|
826
|
+
if (!NextLinkComponent) return anchor;
|
|
827
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(NextLinkComponent, {
|
|
828
|
+
route: routeData.route,
|
|
829
|
+
params: routeData.routeParams,
|
|
830
|
+
...routeData.routeOptions || {},
|
|
831
|
+
children: anchor
|
|
832
|
+
});
|
|
833
|
+
};
|
|
834
|
+
var PaginationLink_default = PaginationLink;
|
|
835
|
+
|
|
836
|
+
//#endregion
|
|
837
|
+
//#region src/Pagination/ArrowButton.tsx
|
|
838
|
+
const ArrowButton = ({ type, routeData, nextLink, disabled = false, onClick }) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(PaginationLink_default, {
|
|
839
|
+
className: `kks-pagination__btn kks-pagination__arrow-btn kks-pagination__arrow-btn--${type}${disabled ? " kks-pagination__arrow-btn--hidden" : ""}`,
|
|
840
|
+
routeData,
|
|
841
|
+
nextLink,
|
|
842
|
+
rel: type,
|
|
843
|
+
"aria-label": type === "prev" ? "Previous page" : "Next page",
|
|
844
|
+
onClick,
|
|
845
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { className: `kks-pagination__icon kks-pagination__icon-${type}` })
|
|
846
|
+
});
|
|
847
|
+
var ArrowButton_default = ArrowButton;
|
|
848
|
+
|
|
849
|
+
//#endregion
|
|
850
|
+
//#region src/Pagination/DotsButton.tsx
|
|
851
|
+
const DotsButton = ({ dots }) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
852
|
+
className: "kks-pagination__dots",
|
|
853
|
+
children: dots
|
|
854
|
+
});
|
|
855
|
+
var DotsButton_default = DotsButton;
|
|
856
|
+
|
|
857
|
+
//#endregion
|
|
858
|
+
//#region src/Pagination/NumberButton.tsx
|
|
859
|
+
const NumberButton = ({ totalPages, pageNumber, routeData, nextLink, active = false, onClick }) => {
|
|
860
|
+
if (active) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
861
|
+
className: "kks-pagination__btn kks-pagination__num-btn kks-pagination__num-btn--active",
|
|
862
|
+
"data-total-pages": ` / ${totalPages}`,
|
|
863
|
+
"aria-current": "page",
|
|
864
|
+
children: pageNumber
|
|
865
|
+
});
|
|
866
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(PaginationLink_default, {
|
|
867
|
+
className: "kks-pagination__btn kks-pagination__num-btn",
|
|
868
|
+
routeData,
|
|
869
|
+
nextLink,
|
|
870
|
+
onClick,
|
|
871
|
+
children: pageNumber
|
|
872
|
+
});
|
|
873
|
+
};
|
|
874
|
+
var NumberButton_default = NumberButton;
|
|
875
|
+
|
|
876
|
+
//#endregion
|
|
877
|
+
//#region src/Pagination/styles.ts
|
|
878
|
+
const paginationStyle = __emotion_react.css`
|
|
879
|
+
:where(&) {
|
|
880
|
+
display: inline-block;
|
|
881
|
+
}
|
|
882
|
+
|
|
883
|
+
& :where(.kks-pagination__content) {
|
|
884
|
+
display: flex;
|
|
885
|
+
margin: 0;
|
|
886
|
+
padding-left: 0;
|
|
887
|
+
list-style: none;
|
|
888
|
+
}
|
|
889
|
+
|
|
890
|
+
& :where(.kks-pagination__num-item:not(.kks-pagination__num-item--current)) {
|
|
891
|
+
display: none;
|
|
892
|
+
}
|
|
893
|
+
|
|
894
|
+
& :where(.kks-pagination__btn) {
|
|
895
|
+
display: block;
|
|
896
|
+
margin: 0 12px;
|
|
897
|
+
padding: 0.64rem 0.8rem;
|
|
898
|
+
border-radius: 3px;
|
|
899
|
+
font-size: 1rem;
|
|
900
|
+
line-height: 1;
|
|
901
|
+
user-select: none;
|
|
902
|
+
}
|
|
903
|
+
|
|
904
|
+
& :where(.kks-pagination__num-btn) {
|
|
905
|
+
text-decoration: none;
|
|
906
|
+
color: #666;
|
|
907
|
+
}
|
|
908
|
+
|
|
909
|
+
& :where(.kks-pagination__num-btn)::after {
|
|
910
|
+
content: attr(data-total-pages);
|
|
911
|
+
}
|
|
912
|
+
|
|
913
|
+
& :where(.kks-pagination__arrow-btn--prev) {
|
|
914
|
+
margin-left: 0;
|
|
915
|
+
}
|
|
916
|
+
|
|
917
|
+
& :where(.kks-pagination__arrow-btn--next) {
|
|
918
|
+
margin-right: 0;
|
|
919
|
+
}
|
|
920
|
+
|
|
921
|
+
& :where(.kks-pagination__arrow-btn--hidden) {
|
|
922
|
+
display: none;
|
|
923
|
+
}
|
|
924
|
+
|
|
925
|
+
& :where(.kks-pagination__icon) {
|
|
926
|
+
display: block;
|
|
927
|
+
width: 1rem;
|
|
928
|
+
height: 1rem;
|
|
929
|
+
background-size: contain;
|
|
930
|
+
}
|
|
931
|
+
|
|
932
|
+
& :where(.kks-pagination__icon-prev) {
|
|
933
|
+
background-image: url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIj8+PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB2ZXJzaW9uPSIxLjEiIHZpZXdCb3g9IjAgMCAxMjkgMTI5IiBlbmFibGUtYmFja2dyb3VuZD0ibmV3IDAgMCAxMjkgMTI5IiB3aWR0aD0iNTEycHgiIGhlaWdodD0iNTEycHgiPjxnIHRyYW5zZm9ybT0ibWF0cml4KC0xIDAgMCAxIDEyOSAwKSI+PGc+ICAgIDxwYXRoIGQ9Im00MC40LDEyMS4zYy0wLjgsMC44LTEuOCwxLjItMi45LDEuMnMtMi4xLTAuNC0yLjktMS4yYy0xLjYtMS42LTEuNi00LjIgMC01LjhsNTEtNTEtNTEtNTFjLTEuNi0xLjYtMS42LTQuMiAwLTUuOCAxLjYtMS42IDQuMi0xLjYgNS44LDBsNTMuOSw1My45YzEuNiwxLjYgMS42LDQuMiAwLDUuOGwtNTMuOSw1My45eiIgZGF0YS1vcmlnaW5hbD0iIzAwMDAwMCIgY2xhc3M9ImFjdGl2ZS1wYXRoIiBkYXRhLW9sZF9jb2xvcj0iIzAwMDAwMCIgZmlsbD0iIzY2NjY2NiIvPiAgPC9nPjwvZz4gPC9zdmc+");
|
|
934
|
+
}
|
|
935
|
+
|
|
936
|
+
& :where(.kks-pagination__icon-next) {
|
|
937
|
+
background-image: url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIj8+PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB2ZXJzaW9uPSIxLjEiIHZpZXdCb3g9IjAgMCAxMjkgMTI5IiBlbmFibGUtYmFja2dyb3VuZD0ibmV3IDAgMCAxMjkgMTI5IiB3aWR0aD0iNTEycHgiIGhlaWdodD0iNTEycHgiPjxnPjxnPiAgICA8cGF0aCBkPSJtNDAuNCwxMjEuM2MtMC44LDAuOC0xLjgsMS4yLTIuOSwxLjJzLTIuMS0wLjQtMi45LTEuMmMtMS42LTEuNi0xLjYtNC4yIDAtNS44bDUxLTUxLTUxLTUxYy0xLjYtMS42LTEuNi00LjIgMC01LjggMS42LTEuNiA0LjItMS42IDUuOCwwbDUzLjksNTMuOWMxLjYsMS42IDEuNiw0LjIgMCw1LjhsLTUzLjksNTMuOXoiIGRhdGEtb3JpZ2luYWw9IiMwMDAwMDAiIGNsYXNzPSJhY3RpdmUtcGF0aCIgZGF0YS1vbGRfY29sb3I9IiMwMDAwMDAiIGZpbGw9IiM2NjY2NjYiLz4gIDwvZz48L2c+IDwvc3ZnPg==");
|
|
938
|
+
}
|
|
939
|
+
|
|
940
|
+
& :where(.kks-pagination__dots) {
|
|
941
|
+
display: block;
|
|
942
|
+
margin: 0 12px;
|
|
943
|
+
padding: 0.64rem 0;
|
|
944
|
+
font-size: 1rem;
|
|
945
|
+
line-height: 50%;
|
|
946
|
+
color: #aaa;
|
|
947
|
+
user-select: none;
|
|
948
|
+
}
|
|
949
|
+
|
|
950
|
+
@media (min-width: 768px) {
|
|
951
|
+
& :where(.kks-pagination__num-item:not(.kks-pagination__num-item--current)) {
|
|
952
|
+
display: block;
|
|
953
|
+
}
|
|
954
|
+
|
|
955
|
+
& :where(.kks-pagination__btn),
|
|
956
|
+
& :where(.kks-pagination__dots) {
|
|
957
|
+
margin: 0 6px;
|
|
958
|
+
}
|
|
959
|
+
|
|
960
|
+
& :where(.kks-pagination__num-btn)::after {
|
|
961
|
+
content: "";
|
|
962
|
+
}
|
|
963
|
+
|
|
964
|
+
& :where(.kks-pagination__num-btn:hover:not(.kks-pagination__num-btn--active)),
|
|
965
|
+
& :where(.kks-pagination__arrow-btn:hover) {
|
|
966
|
+
background: rgba(0, 161, 179, 0.1);
|
|
967
|
+
}
|
|
968
|
+
|
|
969
|
+
& :where(.kks-pagination__num-btn--active) {
|
|
970
|
+
font-weight: 500;
|
|
971
|
+
color: #fff;
|
|
972
|
+
background: #00a1b3;
|
|
973
|
+
}
|
|
974
|
+
|
|
975
|
+
& :where(.kks-pagination__arrow-btn--prev) {
|
|
976
|
+
margin-left: 0;
|
|
977
|
+
}
|
|
978
|
+
|
|
979
|
+
& :where(.kks-pagination__arrow-btn--next) {
|
|
980
|
+
margin-right: 0;
|
|
981
|
+
}
|
|
982
|
+
}
|
|
983
|
+
`;
|
|
984
|
+
|
|
985
|
+
//#endregion
|
|
986
|
+
//#region src/Pagination/index.tsx
|
|
987
|
+
const DEFAULT_CURRENT_PAGE = 1;
|
|
988
|
+
const DEFAULT_PAGE_NEIGHBOURS = 2;
|
|
989
|
+
const ROUTE_URL_REPLACE_STRING = "$(pageNumber)";
|
|
990
|
+
const range = (start, end) => Array.from({ length: end - start + 1 }, (_, index) => start + index);
|
|
991
|
+
const getPageNumbers = (currentPage, pageNeighbours, totalPages) => {
|
|
992
|
+
const numberBlocks = pageNeighbours * 2 + 3;
|
|
993
|
+
if (totalPages <= numberBlocks + 2) return range(1, totalPages);
|
|
994
|
+
const startPage = Math.max(2, currentPage - pageNeighbours);
|
|
995
|
+
const endPage = Math.min(totalPages - 1, currentPage + pageNeighbours);
|
|
996
|
+
let pages = range(startPage, endPage);
|
|
997
|
+
const hasLeftDots = startPage > 2;
|
|
998
|
+
const hasRightDots = totalPages - endPage > 1;
|
|
999
|
+
const offset = numberBlocks - (pages.length + 2);
|
|
1000
|
+
if (hasLeftDots && !hasRightDots) pages = [
|
|
1001
|
+
"...",
|
|
1002
|
+
...range(startPage - offset, startPage - 1),
|
|
1003
|
+
...pages
|
|
1004
|
+
];
|
|
1005
|
+
else if (!hasLeftDots && hasRightDots) pages = [
|
|
1006
|
+
...pages,
|
|
1007
|
+
...range(endPage + 1, endPage + offset),
|
|
1008
|
+
"..."
|
|
1009
|
+
];
|
|
1010
|
+
else pages = [
|
|
1011
|
+
"...",
|
|
1012
|
+
...pages,
|
|
1013
|
+
"..."
|
|
1014
|
+
];
|
|
1015
|
+
return [
|
|
1016
|
+
1,
|
|
1017
|
+
...pages,
|
|
1018
|
+
totalPages
|
|
1019
|
+
];
|
|
1020
|
+
};
|
|
1021
|
+
const toPositiveInt = (value, fallback) => {
|
|
1022
|
+
const parsed = Number(value);
|
|
1023
|
+
return parsed > 0 ? parsed : fallback;
|
|
1024
|
+
};
|
|
1025
|
+
const toValidPage = (value, totalPages) => {
|
|
1026
|
+
const page = Number(value);
|
|
1027
|
+
return Number.isNaN(page) || page < 1 || page > totalPages ? DEFAULT_CURRENT_PAGE : page;
|
|
1028
|
+
};
|
|
1029
|
+
const normalizePaginationParams = ({ totalCount: rawTotalCount, perPageCount: rawPerPageCount, currentPage: rawCurrentPage = DEFAULT_CURRENT_PAGE, pageNeighbours: rawPageNeighbours = DEFAULT_PAGE_NEIGHBOURS }) => {
|
|
1030
|
+
const totalCount = Number(rawTotalCount);
|
|
1031
|
+
const perPageCount = Number(rawPerPageCount);
|
|
1032
|
+
const totalPages = totalCount && perPageCount ? Math.ceil(totalCount / perPageCount) : 1;
|
|
1033
|
+
return {
|
|
1034
|
+
totalCount,
|
|
1035
|
+
perPageCount,
|
|
1036
|
+
totalPages,
|
|
1037
|
+
currentPage: toValidPage(rawCurrentPage, totalPages),
|
|
1038
|
+
pageNeighbours: toPositiveInt(rawPageNeighbours, DEFAULT_PAGE_NEIGHBOURS)
|
|
1039
|
+
};
|
|
1040
|
+
};
|
|
1041
|
+
const renderEllipsis = (ellipsis, index) => /* @__PURE__ */ (0, __emotion_react_jsx_runtime.jsx)("li", {
|
|
1042
|
+
className: "kks-pagination__num-item",
|
|
1043
|
+
children: /* @__PURE__ */ (0, __emotion_react_jsx_runtime.jsx)(DotsButton_default, { dots: ellipsis })
|
|
1044
|
+
}, `dots-${index}`);
|
|
1045
|
+
const Pagination = (props) => {
|
|
1046
|
+
const { totalCount, perPageCount, totalPages, currentPage, pageNeighbours } = normalizePaginationParams(props);
|
|
1047
|
+
const { route = null, routeParams = null, routeOptions = null, nextRouter = null, nextLink = null, className = "", onPageChange = () => {} } = props;
|
|
1048
|
+
if (totalPages === 1) return null;
|
|
1049
|
+
const getRouteData = (page) => {
|
|
1050
|
+
if (!route) return { route: "#" };
|
|
1051
|
+
const nextRouteParams = routeParams ? Object.fromEntries(Object.entries(routeParams).map(([key, value]) => [key, value === ROUTE_URL_REPLACE_STRING ? page : value])) : null;
|
|
1052
|
+
if (nextRouteParams && !Object.values(routeParams).includes(ROUTE_URL_REPLACE_STRING)) nextRouteParams.page = page;
|
|
1053
|
+
return {
|
|
1054
|
+
route: route.replace(ROUTE_URL_REPLACE_STRING, String(page)),
|
|
1055
|
+
routeParams: nextRouteParams,
|
|
1056
|
+
routeOptions
|
|
1057
|
+
};
|
|
1058
|
+
};
|
|
1059
|
+
const handleClick = (page, routeData) => (event) => {
|
|
1060
|
+
event.preventDefault();
|
|
1061
|
+
const isNavigable = routeData.route !== "#";
|
|
1062
|
+
onPageChange({
|
|
1063
|
+
currentPage: page,
|
|
1064
|
+
totalPages,
|
|
1065
|
+
totalCount,
|
|
1066
|
+
perPageCount,
|
|
1067
|
+
route: isNavigable ? routeData.route : null,
|
|
1068
|
+
...isNavigable ? routeData : {}
|
|
1069
|
+
});
|
|
1070
|
+
if (nextRouter && isNavigable) nextRouter.pushRoute(routeData.route, routeData.routeParams || {}, routeData.routeOptions || {});
|
|
1071
|
+
};
|
|
1072
|
+
const previousPage = currentPage === 1 ? 1 : currentPage - 1;
|
|
1073
|
+
const nextPage = currentPage === totalPages ? totalPages : currentPage + 1;
|
|
1074
|
+
const renderArrow = (type, page, disabled) => {
|
|
1075
|
+
const routeData = getRouteData(page);
|
|
1076
|
+
return /* @__PURE__ */ (0, __emotion_react_jsx_runtime.jsx)(ArrowButton_default, {
|
|
1077
|
+
type,
|
|
1078
|
+
routeData,
|
|
1079
|
+
nextLink,
|
|
1080
|
+
disabled,
|
|
1081
|
+
onClick: handleClick(page, routeData)
|
|
1082
|
+
});
|
|
1083
|
+
};
|
|
1084
|
+
const renderPageNumber = (page) => {
|
|
1085
|
+
const routeData = getRouteData(page);
|
|
1086
|
+
const isCurrentPage = page === currentPage;
|
|
1087
|
+
return /* @__PURE__ */ (0, __emotion_react_jsx_runtime.jsx)("li", {
|
|
1088
|
+
className: `kks-pagination__num-item${isCurrentPage ? " kks-pagination__num-item--current" : ""}`,
|
|
1089
|
+
children: /* @__PURE__ */ (0, __emotion_react_jsx_runtime.jsx)(NumberButton_default, {
|
|
1090
|
+
totalPages,
|
|
1091
|
+
pageNumber: page,
|
|
1092
|
+
routeData,
|
|
1093
|
+
nextLink,
|
|
1094
|
+
active: isCurrentPage,
|
|
1095
|
+
onClick: handleClick(page, routeData)
|
|
1096
|
+
})
|
|
1097
|
+
}, `page-${page}`);
|
|
1098
|
+
};
|
|
1099
|
+
return /* @__PURE__ */ (0, __emotion_react_jsx_runtime.jsx)("nav", {
|
|
1100
|
+
css: paginationStyle,
|
|
1101
|
+
className: `kks-pagination ${className}`,
|
|
1102
|
+
"aria-label": "Page navigation",
|
|
1103
|
+
children: /* @__PURE__ */ (0, __emotion_react_jsx_runtime.jsxs)("ul", {
|
|
1104
|
+
className: "kks-pagination__content",
|
|
1105
|
+
children: [
|
|
1106
|
+
/* @__PURE__ */ (0, __emotion_react_jsx_runtime.jsx)("li", { children: renderArrow("prev", previousPage, currentPage === 1) }),
|
|
1107
|
+
getPageNumbers(currentPage, pageNeighbours, totalPages).map((page, index) => typeof page === "number" ? renderPageNumber(page) : renderEllipsis(page, index)),
|
|
1108
|
+
/* @__PURE__ */ (0, __emotion_react_jsx_runtime.jsx)("li", { children: renderArrow("next", nextPage, currentPage === totalPages) })
|
|
1109
|
+
]
|
|
1110
|
+
})
|
|
1111
|
+
});
|
|
1112
|
+
};
|
|
1113
|
+
var Pagination_default = Pagination;
|
|
1114
|
+
|
|
715
1115
|
//#endregion
|
|
716
1116
|
//#region src/icons/see-more.svg
|
|
717
1117
|
var see_more_default = "PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNCIgaGVpZ2h0PSI4IiBmaWxsPSJub25lIiB2aWV3Qm94PSIwIDAgMTQgOCI+CiAgPHBhdGggc3Ryb2tlPSIjY2NjIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS13aWR0aD0iMS41IiBkPSJNLjc1Ljc1IDYuNyA2LjY4cS4wNy4wNi4xNCAwbTAgMHEwIDAgMCAwWm0wIDBMMTIuNzUuNzUiLz4KPC9zdmc+";
|
|
@@ -1083,6 +1483,8 @@ exports.Banner = Banner_default;
|
|
|
1083
1483
|
exports.Dropdown = Dropdown_default;
|
|
1084
1484
|
exports.HiddenToggle = HiddenToggle_default;
|
|
1085
1485
|
exports.Icon = Icon_default;
|
|
1486
|
+
exports.Modal = Modal_default;
|
|
1487
|
+
exports.Pagination = Pagination_default;
|
|
1086
1488
|
exports.SeeMore = SeeMore_default;
|
|
1087
1489
|
exports.VideoItem = VideoItem_default;
|
|
1088
1490
|
exports.VideoThumbnail = VideoThumbnail_default;
|
package/dist/index.d.cts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as react0 from "react";
|
|
2
|
-
import { ElementType, MouseEventHandler, ReactElement, ReactNode } from "react";
|
|
3
|
-
import * as
|
|
2
|
+
import { ComponentType, ElementType, MouseEventHandler, ReactElement, ReactNode } from "react";
|
|
3
|
+
import * as _emotion_react_jsx_runtime2 from "@emotion/react/jsx-runtime";
|
|
4
4
|
import { CSSObject } from "@emotion/react";
|
|
5
5
|
import Link from "next/link";
|
|
6
6
|
|
|
@@ -65,7 +65,7 @@ declare const HiddenToggle: ({
|
|
|
65
65
|
defaultEnabled?: boolean;
|
|
66
66
|
children: any;
|
|
67
67
|
onChange: any;
|
|
68
|
-
}) =>
|
|
68
|
+
}) => _emotion_react_jsx_runtime2.JSX.Element;
|
|
69
69
|
//#endregion
|
|
70
70
|
//#region src/Icon.d.ts
|
|
71
71
|
declare const Icon: ({
|
|
@@ -74,7 +74,55 @@ declare const Icon: ({
|
|
|
74
74
|
}: {
|
|
75
75
|
style?: {};
|
|
76
76
|
src: any;
|
|
77
|
-
}) =>
|
|
77
|
+
}) => _emotion_react_jsx_runtime2.JSX.Element;
|
|
78
|
+
//#endregion
|
|
79
|
+
//#region src/Modal/index.d.ts
|
|
80
|
+
type ModalProps = {
|
|
81
|
+
children: ReactNode;
|
|
82
|
+
className?: string;
|
|
83
|
+
isHideModalOnClickOverlay?: boolean;
|
|
84
|
+
isShow: boolean;
|
|
85
|
+
onHidden?: () => void;
|
|
86
|
+
onShown?: () => void;
|
|
87
|
+
onTriggerHiding?: () => void;
|
|
88
|
+
};
|
|
89
|
+
declare const Modal: react0.MemoExoticComponent<react0.ForwardRefExoticComponent<ModalProps & react0.RefAttributes<HTMLDivElement>>>;
|
|
90
|
+
//#endregion
|
|
91
|
+
//#region src/Pagination/types.d.ts
|
|
92
|
+
type RouteParams = Record<string, unknown>;
|
|
93
|
+
type RouteOptions = Record<string, unknown>;
|
|
94
|
+
type NextLinkProps = {
|
|
95
|
+
route: string;
|
|
96
|
+
params?: RouteParams | null;
|
|
97
|
+
children: ReactNode;
|
|
98
|
+
} & RouteOptions;
|
|
99
|
+
type NextLink = ComponentType<NextLinkProps>;
|
|
100
|
+
//#endregion
|
|
101
|
+
//#region src/Pagination/index.d.ts
|
|
102
|
+
type PaginationProps = {
|
|
103
|
+
totalCount: number | string;
|
|
104
|
+
perPageCount: number | string;
|
|
105
|
+
currentPage?: number | string;
|
|
106
|
+
pageNeighbours?: number | string;
|
|
107
|
+
route?: string | null;
|
|
108
|
+
routeParams?: RouteParams | null;
|
|
109
|
+
routeOptions?: RouteOptions | null;
|
|
110
|
+
nextRouter?: {
|
|
111
|
+
pushRoute: (route: string, routeParams?: RouteParams, routeOptions?: RouteOptions) => void;
|
|
112
|
+
} | null;
|
|
113
|
+
nextLink?: NextLink | null;
|
|
114
|
+
className?: string;
|
|
115
|
+
onPageChange?: (page: {
|
|
116
|
+
currentPage: number;
|
|
117
|
+
totalPages: number;
|
|
118
|
+
totalCount: number;
|
|
119
|
+
perPageCount: number;
|
|
120
|
+
route: string | null;
|
|
121
|
+
routeParams?: RouteParams | null;
|
|
122
|
+
routeOptions?: RouteOptions | null;
|
|
123
|
+
}) => void;
|
|
124
|
+
};
|
|
125
|
+
declare const Pagination: (props: PaginationProps) => ReactElement | null;
|
|
78
126
|
//#endregion
|
|
79
127
|
//#region src/SeeMore.d.ts
|
|
80
128
|
declare const defaultMessages: {
|
|
@@ -90,7 +138,7 @@ declare const SeeMore: ({
|
|
|
90
138
|
style?: CSSObject;
|
|
91
139
|
messages?: typeof defaultMessages;
|
|
92
140
|
children?: ReactNode;
|
|
93
|
-
}) =>
|
|
141
|
+
}) => _emotion_react_jsx_runtime2.JSX.Element;
|
|
94
142
|
//#endregion
|
|
95
143
|
//#region src/VideoItem.d.ts
|
|
96
144
|
type VideoDetail = {
|
|
@@ -154,6 +202,6 @@ declare const VideoThumbnail: ({
|
|
|
154
202
|
Image?: ElementType;
|
|
155
203
|
};
|
|
156
204
|
onClick?: MouseEventHandler<HTMLAnchorElement>;
|
|
157
|
-
}) =>
|
|
205
|
+
}) => _emotion_react_jsx_runtime2.JSX.Element;
|
|
158
206
|
//#endregion
|
|
159
|
-
export { Banner, Dropdown, HiddenToggle, Icon, SeeMore, VideoItem, VideoThumbnail };
|
|
207
|
+
export { Banner, Dropdown, HiddenToggle, Icon, Modal, Pagination, SeeMore, VideoItem, VideoThumbnail };
|
package/dist/index.d.mts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as react0 from "react";
|
|
2
|
-
import { ElementType, MouseEventHandler, ReactElement, ReactNode } from "react";
|
|
3
|
-
import * as
|
|
2
|
+
import { ComponentType, ElementType, MouseEventHandler, ReactElement, ReactNode } from "react";
|
|
3
|
+
import * as _emotion_react_jsx_runtime0 from "@emotion/react/jsx-runtime";
|
|
4
4
|
import { CSSObject } from "@emotion/react";
|
|
5
5
|
import Link from "next/link";
|
|
6
6
|
|
|
@@ -65,7 +65,7 @@ declare const HiddenToggle: ({
|
|
|
65
65
|
defaultEnabled?: boolean;
|
|
66
66
|
children: any;
|
|
67
67
|
onChange: any;
|
|
68
|
-
}) =>
|
|
68
|
+
}) => _emotion_react_jsx_runtime0.JSX.Element;
|
|
69
69
|
//#endregion
|
|
70
70
|
//#region src/Icon.d.ts
|
|
71
71
|
declare const Icon: ({
|
|
@@ -74,7 +74,55 @@ declare const Icon: ({
|
|
|
74
74
|
}: {
|
|
75
75
|
style?: {};
|
|
76
76
|
src: any;
|
|
77
|
-
}) =>
|
|
77
|
+
}) => _emotion_react_jsx_runtime0.JSX.Element;
|
|
78
|
+
//#endregion
|
|
79
|
+
//#region src/Modal/index.d.ts
|
|
80
|
+
type ModalProps = {
|
|
81
|
+
children: ReactNode;
|
|
82
|
+
className?: string;
|
|
83
|
+
isHideModalOnClickOverlay?: boolean;
|
|
84
|
+
isShow: boolean;
|
|
85
|
+
onHidden?: () => void;
|
|
86
|
+
onShown?: () => void;
|
|
87
|
+
onTriggerHiding?: () => void;
|
|
88
|
+
};
|
|
89
|
+
declare const Modal: react0.MemoExoticComponent<react0.ForwardRefExoticComponent<ModalProps & react0.RefAttributes<HTMLDivElement>>>;
|
|
90
|
+
//#endregion
|
|
91
|
+
//#region src/Pagination/types.d.ts
|
|
92
|
+
type RouteParams = Record<string, unknown>;
|
|
93
|
+
type RouteOptions = Record<string, unknown>;
|
|
94
|
+
type NextLinkProps = {
|
|
95
|
+
route: string;
|
|
96
|
+
params?: RouteParams | null;
|
|
97
|
+
children: ReactNode;
|
|
98
|
+
} & RouteOptions;
|
|
99
|
+
type NextLink = ComponentType<NextLinkProps>;
|
|
100
|
+
//#endregion
|
|
101
|
+
//#region src/Pagination/index.d.ts
|
|
102
|
+
type PaginationProps = {
|
|
103
|
+
totalCount: number | string;
|
|
104
|
+
perPageCount: number | string;
|
|
105
|
+
currentPage?: number | string;
|
|
106
|
+
pageNeighbours?: number | string;
|
|
107
|
+
route?: string | null;
|
|
108
|
+
routeParams?: RouteParams | null;
|
|
109
|
+
routeOptions?: RouteOptions | null;
|
|
110
|
+
nextRouter?: {
|
|
111
|
+
pushRoute: (route: string, routeParams?: RouteParams, routeOptions?: RouteOptions) => void;
|
|
112
|
+
} | null;
|
|
113
|
+
nextLink?: NextLink | null;
|
|
114
|
+
className?: string;
|
|
115
|
+
onPageChange?: (page: {
|
|
116
|
+
currentPage: number;
|
|
117
|
+
totalPages: number;
|
|
118
|
+
totalCount: number;
|
|
119
|
+
perPageCount: number;
|
|
120
|
+
route: string | null;
|
|
121
|
+
routeParams?: RouteParams | null;
|
|
122
|
+
routeOptions?: RouteOptions | null;
|
|
123
|
+
}) => void;
|
|
124
|
+
};
|
|
125
|
+
declare const Pagination: (props: PaginationProps) => ReactElement | null;
|
|
78
126
|
//#endregion
|
|
79
127
|
//#region src/SeeMore.d.ts
|
|
80
128
|
declare const defaultMessages: {
|
|
@@ -90,7 +138,7 @@ declare const SeeMore: ({
|
|
|
90
138
|
style?: CSSObject;
|
|
91
139
|
messages?: typeof defaultMessages;
|
|
92
140
|
children?: ReactNode;
|
|
93
|
-
}) =>
|
|
141
|
+
}) => _emotion_react_jsx_runtime0.JSX.Element;
|
|
94
142
|
//#endregion
|
|
95
143
|
//#region src/VideoItem.d.ts
|
|
96
144
|
type VideoDetail = {
|
|
@@ -154,6 +202,6 @@ declare const VideoThumbnail: ({
|
|
|
154
202
|
Image?: ElementType;
|
|
155
203
|
};
|
|
156
204
|
onClick?: MouseEventHandler<HTMLAnchorElement>;
|
|
157
|
-
}) =>
|
|
205
|
+
}) => _emotion_react_jsx_runtime0.JSX.Element;
|
|
158
206
|
//#endregion
|
|
159
|
-
export { Banner, Dropdown, HiddenToggle, Icon, SeeMore, VideoItem, VideoThumbnail };
|
|
207
|
+
export { Banner, Dropdown, HiddenToggle, Icon, Modal, Pagination, SeeMore, VideoItem, VideoThumbnail };
|
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Children, forwardRef, useCallback, useEffect, useImperativeHandle, useLayoutEffect, useMemo, useReducer, useRef, useState } from "react";
|
|
1
|
+
import { Children, forwardRef, memo, useCallback, useEffect, useImperativeHandle, useLayoutEffect, useMemo, useReducer, useRef, useState } from "react";
|
|
2
2
|
import { jsx } from "react/jsx-runtime";
|
|
3
3
|
import { jsx as jsx$1, jsxs } from "@emotion/react/jsx-runtime";
|
|
4
4
|
import { css } from "@emotion/react";
|
|
@@ -342,6 +342,8 @@ var Banner_default = Banner;
|
|
|
342
342
|
//#endregion
|
|
343
343
|
//#region src/Dropdown.tsx
|
|
344
344
|
/** @jsxImportSource @emotion/react */
|
|
345
|
+
const dropdownBorderRadius = "4px";
|
|
346
|
+
const itemRowElemMarginXSm = "16px";
|
|
345
347
|
const dropdownStyle = css`
|
|
346
348
|
.text-truncate {
|
|
347
349
|
display: block;
|
|
@@ -411,7 +413,7 @@ const dropdownStyle = css`
|
|
|
411
413
|
|
|
412
414
|
.kks-dropdown__menu {
|
|
413
415
|
width: 92%;
|
|
414
|
-
border-radius: $
|
|
416
|
+
border-radius: ${dropdownBorderRadius};
|
|
415
417
|
background: #fff;
|
|
416
418
|
overflow: hidden;
|
|
417
419
|
}
|
|
@@ -421,7 +423,7 @@ const dropdownStyle = css`
|
|
|
421
423
|
border-bottom: 1px solid #e9ecef;
|
|
422
424
|
|
|
423
425
|
.kks-dropdown__menu-title {
|
|
424
|
-
margin-left: $
|
|
426
|
+
margin-left: ${itemRowElemMarginXSm};
|
|
425
427
|
font-size: 1.25rem;
|
|
426
428
|
}
|
|
427
429
|
|
|
@@ -429,7 +431,7 @@ const dropdownStyle = css`
|
|
|
429
431
|
display: flex;
|
|
430
432
|
align-items: center;
|
|
431
433
|
margin-left: auto;
|
|
432
|
-
padding: 0 $
|
|
434
|
+
padding: 0 ${itemRowElemMarginXSm};
|
|
433
435
|
height: 100%;
|
|
434
436
|
outline: none;
|
|
435
437
|
}
|
|
@@ -449,7 +451,7 @@ const dropdownStyle = css`
|
|
|
449
451
|
overflow-y: auto;
|
|
450
452
|
|
|
451
453
|
.kks-dropdown__menu-link {
|
|
452
|
-
padding: 10px $
|
|
454
|
+
padding: 10px ${itemRowElemMarginXSm};
|
|
453
455
|
text-decoration: none;
|
|
454
456
|
color: #000;
|
|
455
457
|
outline: none;
|
|
@@ -712,6 +714,404 @@ const Icon = ({ style = {}, src }) => /* @__PURE__ */ jsx$1("span", { css: [
|
|
|
712
714
|
] });
|
|
713
715
|
var Icon_default = Icon;
|
|
714
716
|
|
|
717
|
+
//#endregion
|
|
718
|
+
//#region src/Modal/styles.ts
|
|
719
|
+
const modalStyle = css`
|
|
720
|
+
:where(&) {
|
|
721
|
+
position: fixed;
|
|
722
|
+
top: 0;
|
|
723
|
+
right: 0;
|
|
724
|
+
bottom: 0;
|
|
725
|
+
left: 0;
|
|
726
|
+
z-index: 1000;
|
|
727
|
+
padding: 1rem;
|
|
728
|
+
overflow-x: hidden;
|
|
729
|
+
overflow-y: auto;
|
|
730
|
+
visibility: hidden;
|
|
731
|
+
opacity: 0;
|
|
732
|
+
background-color: rgba(0, 0, 0, 0.7);
|
|
733
|
+
transition: opacity 0.3s;
|
|
734
|
+
}
|
|
735
|
+
|
|
736
|
+
:where(&.modal--show),
|
|
737
|
+
:where(&.modal--shown) {
|
|
738
|
+
display: flex;
|
|
739
|
+
justify-content: center;
|
|
740
|
+
visibility: visible;
|
|
741
|
+
opacity: 1;
|
|
742
|
+
}
|
|
743
|
+
|
|
744
|
+
& :where(.modal__content) {
|
|
745
|
+
width: 100%;
|
|
746
|
+
max-width: 700px;
|
|
747
|
+
margin: auto 0;
|
|
748
|
+
}
|
|
749
|
+
`;
|
|
750
|
+
|
|
751
|
+
//#endregion
|
|
752
|
+
//#region src/Modal/index.tsx
|
|
753
|
+
const MODAL_STATE = {
|
|
754
|
+
SHOW: "show",
|
|
755
|
+
SHOWN: "shown",
|
|
756
|
+
HIDE: "hide",
|
|
757
|
+
HIDDEN: "hidden"
|
|
758
|
+
};
|
|
759
|
+
const isShowing = (state) => state === MODAL_STATE.SHOW || state === MODAL_STATE.SHOWN;
|
|
760
|
+
const Modal = memo(forwardRef(function Modal$1({ children, className = "", isHideModalOnClickOverlay = true, isShow, onHidden = () => {}, onShown = () => {}, onTriggerHiding = () => {} }, ref) {
|
|
761
|
+
const [visualState, setVisualState] = useState(MODAL_STATE.HIDDEN);
|
|
762
|
+
const shouldLockBody = isShowing(visualState);
|
|
763
|
+
if (isShow && !isShowing(visualState)) setVisualState(MODAL_STATE.SHOW);
|
|
764
|
+
else if (!isShow && isShowing(visualState)) setVisualState(MODAL_STATE.HIDE);
|
|
765
|
+
useLayoutEffect(() => {
|
|
766
|
+
if (!shouldLockBody) return;
|
|
767
|
+
const previousOverflow = document.body.style.overflow;
|
|
768
|
+
document.body.style.overflow = "hidden";
|
|
769
|
+
return () => {
|
|
770
|
+
document.body.style.overflow = previousOverflow;
|
|
771
|
+
};
|
|
772
|
+
}, [shouldLockBody]);
|
|
773
|
+
const previousVisualState = useRef(visualState);
|
|
774
|
+
useLayoutEffect(() => {
|
|
775
|
+
if (previousVisualState.current === visualState) return;
|
|
776
|
+
previousVisualState.current = visualState;
|
|
777
|
+
if (visualState === MODAL_STATE.SHOWN) onShown();
|
|
778
|
+
else if (visualState === MODAL_STATE.HIDDEN) onHidden();
|
|
779
|
+
}, [
|
|
780
|
+
visualState,
|
|
781
|
+
onShown,
|
|
782
|
+
onHidden
|
|
783
|
+
]);
|
|
784
|
+
const handleAnimationEnd = useCallback(() => {
|
|
785
|
+
setVisualState((previousState) => {
|
|
786
|
+
if (previousState === MODAL_STATE.SHOW) return MODAL_STATE.SHOWN;
|
|
787
|
+
if (previousState === MODAL_STATE.HIDE) return MODAL_STATE.HIDDEN;
|
|
788
|
+
return previousState;
|
|
789
|
+
});
|
|
790
|
+
}, []);
|
|
791
|
+
const handleClick = useCallback((event) => {
|
|
792
|
+
if (event.target.getAttribute("data-dismiss") === "modal") onTriggerHiding();
|
|
793
|
+
}, [onTriggerHiding]);
|
|
794
|
+
const handleKeyDown = useCallback((event) => {
|
|
795
|
+
if (event.key !== "Enter" && event.key !== " ") return;
|
|
796
|
+
if (event.target.getAttribute("data-dismiss") !== "modal") return;
|
|
797
|
+
event.preventDefault();
|
|
798
|
+
onTriggerHiding();
|
|
799
|
+
}, [onTriggerHiding]);
|
|
800
|
+
return /* @__PURE__ */ jsx$1("div", {
|
|
801
|
+
css: modalStyle,
|
|
802
|
+
ref,
|
|
803
|
+
role: "presentation",
|
|
804
|
+
className: `modal modal--${visualState} ${className}`,
|
|
805
|
+
onClick: handleClick,
|
|
806
|
+
onKeyDown: handleKeyDown,
|
|
807
|
+
onAnimationEnd: handleAnimationEnd,
|
|
808
|
+
onTransitionEnd: handleAnimationEnd,
|
|
809
|
+
"data-dismiss": isHideModalOnClickOverlay ? "modal" : void 0,
|
|
810
|
+
children: /* @__PURE__ */ jsx$1("div", {
|
|
811
|
+
className: "modal__content",
|
|
812
|
+
children
|
|
813
|
+
})
|
|
814
|
+
});
|
|
815
|
+
}));
|
|
816
|
+
var Modal_default = Modal;
|
|
817
|
+
|
|
818
|
+
//#endregion
|
|
819
|
+
//#region src/Pagination/PaginationLink.tsx
|
|
820
|
+
const PaginationLink = ({ routeData, nextLink: NextLinkComponent, children, ...anchorProps }) => {
|
|
821
|
+
const anchor = /* @__PURE__ */ jsx("a", {
|
|
822
|
+
...anchorProps,
|
|
823
|
+
href: NextLinkComponent ? void 0 : routeData.route,
|
|
824
|
+
children
|
|
825
|
+
});
|
|
826
|
+
if (!NextLinkComponent) return anchor;
|
|
827
|
+
return /* @__PURE__ */ jsx(NextLinkComponent, {
|
|
828
|
+
route: routeData.route,
|
|
829
|
+
params: routeData.routeParams,
|
|
830
|
+
...routeData.routeOptions || {},
|
|
831
|
+
children: anchor
|
|
832
|
+
});
|
|
833
|
+
};
|
|
834
|
+
var PaginationLink_default = PaginationLink;
|
|
835
|
+
|
|
836
|
+
//#endregion
|
|
837
|
+
//#region src/Pagination/ArrowButton.tsx
|
|
838
|
+
const ArrowButton = ({ type, routeData, nextLink, disabled = false, onClick }) => /* @__PURE__ */ jsx(PaginationLink_default, {
|
|
839
|
+
className: `kks-pagination__btn kks-pagination__arrow-btn kks-pagination__arrow-btn--${type}${disabled ? " kks-pagination__arrow-btn--hidden" : ""}`,
|
|
840
|
+
routeData,
|
|
841
|
+
nextLink,
|
|
842
|
+
rel: type,
|
|
843
|
+
"aria-label": type === "prev" ? "Previous page" : "Next page",
|
|
844
|
+
onClick,
|
|
845
|
+
children: /* @__PURE__ */ jsx("span", { className: `kks-pagination__icon kks-pagination__icon-${type}` })
|
|
846
|
+
});
|
|
847
|
+
var ArrowButton_default = ArrowButton;
|
|
848
|
+
|
|
849
|
+
//#endregion
|
|
850
|
+
//#region src/Pagination/DotsButton.tsx
|
|
851
|
+
const DotsButton = ({ dots }) => /* @__PURE__ */ jsx("span", {
|
|
852
|
+
className: "kks-pagination__dots",
|
|
853
|
+
children: dots
|
|
854
|
+
});
|
|
855
|
+
var DotsButton_default = DotsButton;
|
|
856
|
+
|
|
857
|
+
//#endregion
|
|
858
|
+
//#region src/Pagination/NumberButton.tsx
|
|
859
|
+
const NumberButton = ({ totalPages, pageNumber, routeData, nextLink, active = false, onClick }) => {
|
|
860
|
+
if (active) return /* @__PURE__ */ jsx("span", {
|
|
861
|
+
className: "kks-pagination__btn kks-pagination__num-btn kks-pagination__num-btn--active",
|
|
862
|
+
"data-total-pages": ` / ${totalPages}`,
|
|
863
|
+
"aria-current": "page",
|
|
864
|
+
children: pageNumber
|
|
865
|
+
});
|
|
866
|
+
return /* @__PURE__ */ jsx(PaginationLink_default, {
|
|
867
|
+
className: "kks-pagination__btn kks-pagination__num-btn",
|
|
868
|
+
routeData,
|
|
869
|
+
nextLink,
|
|
870
|
+
onClick,
|
|
871
|
+
children: pageNumber
|
|
872
|
+
});
|
|
873
|
+
};
|
|
874
|
+
var NumberButton_default = NumberButton;
|
|
875
|
+
|
|
876
|
+
//#endregion
|
|
877
|
+
//#region src/Pagination/styles.ts
|
|
878
|
+
const paginationStyle = css`
|
|
879
|
+
:where(&) {
|
|
880
|
+
display: inline-block;
|
|
881
|
+
}
|
|
882
|
+
|
|
883
|
+
& :where(.kks-pagination__content) {
|
|
884
|
+
display: flex;
|
|
885
|
+
margin: 0;
|
|
886
|
+
padding-left: 0;
|
|
887
|
+
list-style: none;
|
|
888
|
+
}
|
|
889
|
+
|
|
890
|
+
& :where(.kks-pagination__num-item:not(.kks-pagination__num-item--current)) {
|
|
891
|
+
display: none;
|
|
892
|
+
}
|
|
893
|
+
|
|
894
|
+
& :where(.kks-pagination__btn) {
|
|
895
|
+
display: block;
|
|
896
|
+
margin: 0 12px;
|
|
897
|
+
padding: 0.64rem 0.8rem;
|
|
898
|
+
border-radius: 3px;
|
|
899
|
+
font-size: 1rem;
|
|
900
|
+
line-height: 1;
|
|
901
|
+
user-select: none;
|
|
902
|
+
}
|
|
903
|
+
|
|
904
|
+
& :where(.kks-pagination__num-btn) {
|
|
905
|
+
text-decoration: none;
|
|
906
|
+
color: #666;
|
|
907
|
+
}
|
|
908
|
+
|
|
909
|
+
& :where(.kks-pagination__num-btn)::after {
|
|
910
|
+
content: attr(data-total-pages);
|
|
911
|
+
}
|
|
912
|
+
|
|
913
|
+
& :where(.kks-pagination__arrow-btn--prev) {
|
|
914
|
+
margin-left: 0;
|
|
915
|
+
}
|
|
916
|
+
|
|
917
|
+
& :where(.kks-pagination__arrow-btn--next) {
|
|
918
|
+
margin-right: 0;
|
|
919
|
+
}
|
|
920
|
+
|
|
921
|
+
& :where(.kks-pagination__arrow-btn--hidden) {
|
|
922
|
+
display: none;
|
|
923
|
+
}
|
|
924
|
+
|
|
925
|
+
& :where(.kks-pagination__icon) {
|
|
926
|
+
display: block;
|
|
927
|
+
width: 1rem;
|
|
928
|
+
height: 1rem;
|
|
929
|
+
background-size: contain;
|
|
930
|
+
}
|
|
931
|
+
|
|
932
|
+
& :where(.kks-pagination__icon-prev) {
|
|
933
|
+
background-image: url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIj8+PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB2ZXJzaW9uPSIxLjEiIHZpZXdCb3g9IjAgMCAxMjkgMTI5IiBlbmFibGUtYmFja2dyb3VuZD0ibmV3IDAgMCAxMjkgMTI5IiB3aWR0aD0iNTEycHgiIGhlaWdodD0iNTEycHgiPjxnIHRyYW5zZm9ybT0ibWF0cml4KC0xIDAgMCAxIDEyOSAwKSI+PGc+ICAgIDxwYXRoIGQ9Im00MC40LDEyMS4zYy0wLjgsMC44LTEuOCwxLjItMi45LDEuMnMtMi4xLTAuNC0yLjktMS4yYy0xLjYtMS42LTEuNi00LjIgMC01LjhsNTEtNTEtNTEtNTFjLTEuNi0xLjYtMS42LTQuMiAwLTUuOCAxLjYtMS42IDQuMi0xLjYgNS44LDBsNTMuOSw1My45YzEuNiwxLjYgMS42LDQuMiAwLDUuOGwtNTMuOSw1My45eiIgZGF0YS1vcmlnaW5hbD0iIzAwMDAwMCIgY2xhc3M9ImFjdGl2ZS1wYXRoIiBkYXRhLW9sZF9jb2xvcj0iIzAwMDAwMCIgZmlsbD0iIzY2NjY2NiIvPiAgPC9nPjwvZz4gPC9zdmc+");
|
|
934
|
+
}
|
|
935
|
+
|
|
936
|
+
& :where(.kks-pagination__icon-next) {
|
|
937
|
+
background-image: url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIj8+PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB2ZXJzaW9uPSIxLjEiIHZpZXdCb3g9IjAgMCAxMjkgMTI5IiBlbmFibGUtYmFja2dyb3VuZD0ibmV3IDAgMCAxMjkgMTI5IiB3aWR0aD0iNTEycHgiIGhlaWdodD0iNTEycHgiPjxnPjxnPiAgICA8cGF0aCBkPSJtNDAuNCwxMjEuM2MtMC44LDAuOC0xLjgsMS4yLTIuOSwxLjJzLTIuMS0wLjQtMi45LTEuMmMtMS42LTEuNi0xLjYtNC4yIDAtNS44bDUxLTUxLTUxLTUxYy0xLjYtMS42LTEuNi00LjIgMC01LjggMS42LTEuNiA0LjItMS42IDUuOCwwbDUzLjksNTMuOWMxLjYsMS42IDEuNiw0LjIgMCw1LjhsLTUzLjksNTMuOXoiIGRhdGEtb3JpZ2luYWw9IiMwMDAwMDAiIGNsYXNzPSJhY3RpdmUtcGF0aCIgZGF0YS1vbGRfY29sb3I9IiMwMDAwMDAiIGZpbGw9IiM2NjY2NjYiLz4gIDwvZz48L2c+IDwvc3ZnPg==");
|
|
938
|
+
}
|
|
939
|
+
|
|
940
|
+
& :where(.kks-pagination__dots) {
|
|
941
|
+
display: block;
|
|
942
|
+
margin: 0 12px;
|
|
943
|
+
padding: 0.64rem 0;
|
|
944
|
+
font-size: 1rem;
|
|
945
|
+
line-height: 50%;
|
|
946
|
+
color: #aaa;
|
|
947
|
+
user-select: none;
|
|
948
|
+
}
|
|
949
|
+
|
|
950
|
+
@media (min-width: 768px) {
|
|
951
|
+
& :where(.kks-pagination__num-item:not(.kks-pagination__num-item--current)) {
|
|
952
|
+
display: block;
|
|
953
|
+
}
|
|
954
|
+
|
|
955
|
+
& :where(.kks-pagination__btn),
|
|
956
|
+
& :where(.kks-pagination__dots) {
|
|
957
|
+
margin: 0 6px;
|
|
958
|
+
}
|
|
959
|
+
|
|
960
|
+
& :where(.kks-pagination__num-btn)::after {
|
|
961
|
+
content: "";
|
|
962
|
+
}
|
|
963
|
+
|
|
964
|
+
& :where(.kks-pagination__num-btn:hover:not(.kks-pagination__num-btn--active)),
|
|
965
|
+
& :where(.kks-pagination__arrow-btn:hover) {
|
|
966
|
+
background: rgba(0, 161, 179, 0.1);
|
|
967
|
+
}
|
|
968
|
+
|
|
969
|
+
& :where(.kks-pagination__num-btn--active) {
|
|
970
|
+
font-weight: 500;
|
|
971
|
+
color: #fff;
|
|
972
|
+
background: #00a1b3;
|
|
973
|
+
}
|
|
974
|
+
|
|
975
|
+
& :where(.kks-pagination__arrow-btn--prev) {
|
|
976
|
+
margin-left: 0;
|
|
977
|
+
}
|
|
978
|
+
|
|
979
|
+
& :where(.kks-pagination__arrow-btn--next) {
|
|
980
|
+
margin-right: 0;
|
|
981
|
+
}
|
|
982
|
+
}
|
|
983
|
+
`;
|
|
984
|
+
|
|
985
|
+
//#endregion
|
|
986
|
+
//#region src/Pagination/index.tsx
|
|
987
|
+
const DEFAULT_CURRENT_PAGE = 1;
|
|
988
|
+
const DEFAULT_PAGE_NEIGHBOURS = 2;
|
|
989
|
+
const ROUTE_URL_REPLACE_STRING = "$(pageNumber)";
|
|
990
|
+
const range = (start, end) => Array.from({ length: end - start + 1 }, (_, index) => start + index);
|
|
991
|
+
const getPageNumbers = (currentPage, pageNeighbours, totalPages) => {
|
|
992
|
+
const numberBlocks = pageNeighbours * 2 + 3;
|
|
993
|
+
if (totalPages <= numberBlocks + 2) return range(1, totalPages);
|
|
994
|
+
const startPage = Math.max(2, currentPage - pageNeighbours);
|
|
995
|
+
const endPage = Math.min(totalPages - 1, currentPage + pageNeighbours);
|
|
996
|
+
let pages = range(startPage, endPage);
|
|
997
|
+
const hasLeftDots = startPage > 2;
|
|
998
|
+
const hasRightDots = totalPages - endPage > 1;
|
|
999
|
+
const offset = numberBlocks - (pages.length + 2);
|
|
1000
|
+
if (hasLeftDots && !hasRightDots) pages = [
|
|
1001
|
+
"...",
|
|
1002
|
+
...range(startPage - offset, startPage - 1),
|
|
1003
|
+
...pages
|
|
1004
|
+
];
|
|
1005
|
+
else if (!hasLeftDots && hasRightDots) pages = [
|
|
1006
|
+
...pages,
|
|
1007
|
+
...range(endPage + 1, endPage + offset),
|
|
1008
|
+
"..."
|
|
1009
|
+
];
|
|
1010
|
+
else pages = [
|
|
1011
|
+
"...",
|
|
1012
|
+
...pages,
|
|
1013
|
+
"..."
|
|
1014
|
+
];
|
|
1015
|
+
return [
|
|
1016
|
+
1,
|
|
1017
|
+
...pages,
|
|
1018
|
+
totalPages
|
|
1019
|
+
];
|
|
1020
|
+
};
|
|
1021
|
+
const toPositiveInt = (value, fallback) => {
|
|
1022
|
+
const parsed = Number(value);
|
|
1023
|
+
return parsed > 0 ? parsed : fallback;
|
|
1024
|
+
};
|
|
1025
|
+
const toValidPage = (value, totalPages) => {
|
|
1026
|
+
const page = Number(value);
|
|
1027
|
+
return Number.isNaN(page) || page < 1 || page > totalPages ? DEFAULT_CURRENT_PAGE : page;
|
|
1028
|
+
};
|
|
1029
|
+
const normalizePaginationParams = ({ totalCount: rawTotalCount, perPageCount: rawPerPageCount, currentPage: rawCurrentPage = DEFAULT_CURRENT_PAGE, pageNeighbours: rawPageNeighbours = DEFAULT_PAGE_NEIGHBOURS }) => {
|
|
1030
|
+
const totalCount = Number(rawTotalCount);
|
|
1031
|
+
const perPageCount = Number(rawPerPageCount);
|
|
1032
|
+
const totalPages = totalCount && perPageCount ? Math.ceil(totalCount / perPageCount) : 1;
|
|
1033
|
+
return {
|
|
1034
|
+
totalCount,
|
|
1035
|
+
perPageCount,
|
|
1036
|
+
totalPages,
|
|
1037
|
+
currentPage: toValidPage(rawCurrentPage, totalPages),
|
|
1038
|
+
pageNeighbours: toPositiveInt(rawPageNeighbours, DEFAULT_PAGE_NEIGHBOURS)
|
|
1039
|
+
};
|
|
1040
|
+
};
|
|
1041
|
+
const renderEllipsis = (ellipsis, index) => /* @__PURE__ */ jsx$1("li", {
|
|
1042
|
+
className: "kks-pagination__num-item",
|
|
1043
|
+
children: /* @__PURE__ */ jsx$1(DotsButton_default, { dots: ellipsis })
|
|
1044
|
+
}, `dots-${index}`);
|
|
1045
|
+
const Pagination = (props) => {
|
|
1046
|
+
const { totalCount, perPageCount, totalPages, currentPage, pageNeighbours } = normalizePaginationParams(props);
|
|
1047
|
+
const { route = null, routeParams = null, routeOptions = null, nextRouter = null, nextLink = null, className = "", onPageChange = () => {} } = props;
|
|
1048
|
+
if (totalPages === 1) return null;
|
|
1049
|
+
const getRouteData = (page) => {
|
|
1050
|
+
if (!route) return { route: "#" };
|
|
1051
|
+
const nextRouteParams = routeParams ? Object.fromEntries(Object.entries(routeParams).map(([key, value]) => [key, value === ROUTE_URL_REPLACE_STRING ? page : value])) : null;
|
|
1052
|
+
if (nextRouteParams && !Object.values(routeParams).includes(ROUTE_URL_REPLACE_STRING)) nextRouteParams.page = page;
|
|
1053
|
+
return {
|
|
1054
|
+
route: route.replace(ROUTE_URL_REPLACE_STRING, String(page)),
|
|
1055
|
+
routeParams: nextRouteParams,
|
|
1056
|
+
routeOptions
|
|
1057
|
+
};
|
|
1058
|
+
};
|
|
1059
|
+
const handleClick = (page, routeData) => (event) => {
|
|
1060
|
+
event.preventDefault();
|
|
1061
|
+
const isNavigable = routeData.route !== "#";
|
|
1062
|
+
onPageChange({
|
|
1063
|
+
currentPage: page,
|
|
1064
|
+
totalPages,
|
|
1065
|
+
totalCount,
|
|
1066
|
+
perPageCount,
|
|
1067
|
+
route: isNavigable ? routeData.route : null,
|
|
1068
|
+
...isNavigable ? routeData : {}
|
|
1069
|
+
});
|
|
1070
|
+
if (nextRouter && isNavigable) nextRouter.pushRoute(routeData.route, routeData.routeParams || {}, routeData.routeOptions || {});
|
|
1071
|
+
};
|
|
1072
|
+
const previousPage = currentPage === 1 ? 1 : currentPage - 1;
|
|
1073
|
+
const nextPage = currentPage === totalPages ? totalPages : currentPage + 1;
|
|
1074
|
+
const renderArrow = (type, page, disabled) => {
|
|
1075
|
+
const routeData = getRouteData(page);
|
|
1076
|
+
return /* @__PURE__ */ jsx$1(ArrowButton_default, {
|
|
1077
|
+
type,
|
|
1078
|
+
routeData,
|
|
1079
|
+
nextLink,
|
|
1080
|
+
disabled,
|
|
1081
|
+
onClick: handleClick(page, routeData)
|
|
1082
|
+
});
|
|
1083
|
+
};
|
|
1084
|
+
const renderPageNumber = (page) => {
|
|
1085
|
+
const routeData = getRouteData(page);
|
|
1086
|
+
const isCurrentPage = page === currentPage;
|
|
1087
|
+
return /* @__PURE__ */ jsx$1("li", {
|
|
1088
|
+
className: `kks-pagination__num-item${isCurrentPage ? " kks-pagination__num-item--current" : ""}`,
|
|
1089
|
+
children: /* @__PURE__ */ jsx$1(NumberButton_default, {
|
|
1090
|
+
totalPages,
|
|
1091
|
+
pageNumber: page,
|
|
1092
|
+
routeData,
|
|
1093
|
+
nextLink,
|
|
1094
|
+
active: isCurrentPage,
|
|
1095
|
+
onClick: handleClick(page, routeData)
|
|
1096
|
+
})
|
|
1097
|
+
}, `page-${page}`);
|
|
1098
|
+
};
|
|
1099
|
+
return /* @__PURE__ */ jsx$1("nav", {
|
|
1100
|
+
css: paginationStyle,
|
|
1101
|
+
className: `kks-pagination ${className}`,
|
|
1102
|
+
"aria-label": "Page navigation",
|
|
1103
|
+
children: /* @__PURE__ */ jsxs("ul", {
|
|
1104
|
+
className: "kks-pagination__content",
|
|
1105
|
+
children: [
|
|
1106
|
+
/* @__PURE__ */ jsx$1("li", { children: renderArrow("prev", previousPage, currentPage === 1) }),
|
|
1107
|
+
getPageNumbers(currentPage, pageNeighbours, totalPages).map((page, index) => typeof page === "number" ? renderPageNumber(page) : renderEllipsis(page, index)),
|
|
1108
|
+
/* @__PURE__ */ jsx$1("li", { children: renderArrow("next", nextPage, currentPage === totalPages) })
|
|
1109
|
+
]
|
|
1110
|
+
})
|
|
1111
|
+
});
|
|
1112
|
+
};
|
|
1113
|
+
var Pagination_default = Pagination;
|
|
1114
|
+
|
|
715
1115
|
//#endregion
|
|
716
1116
|
//#region src/icons/see-more.svg
|
|
717
1117
|
var see_more_default = "PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNCIgaGVpZ2h0PSI4IiBmaWxsPSJub25lIiB2aWV3Qm94PSIwIDAgMTQgOCI+CiAgPHBhdGggc3Ryb2tlPSIjY2NjIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS13aWR0aD0iMS41IiBkPSJNLjc1Ljc1IDYuNyA2LjY4cS4wNy4wNi4xNCAwbTAgMHEwIDAgMCAwWm0wIDBMMTIuNzUuNzUiLz4KPC9zdmc+";
|
|
@@ -1079,4 +1479,4 @@ const VideoItem = ({ style, href = "", thumbnailHref = href, imageUrl = "", data
|
|
|
1079
1479
|
var VideoItem_default = VideoItem;
|
|
1080
1480
|
|
|
1081
1481
|
//#endregion
|
|
1082
|
-
export { Banner_default as Banner, Dropdown_default as Dropdown, HiddenToggle_default as HiddenToggle, Icon_default as Icon, SeeMore_default as SeeMore, VideoItem_default as VideoItem, VideoThumbnail_default as VideoThumbnail };
|
|
1482
|
+
export { Banner_default as Banner, Dropdown_default as Dropdown, HiddenToggle_default as HiddenToggle, Icon_default as Icon, Modal_default as Modal, Pagination_default as Pagination, SeeMore_default as SeeMore, VideoItem_default as VideoItem, VideoThumbnail_default as VideoThumbnail };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kkcompany/app-ui",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.32",
|
|
4
4
|
"module": "dist/index.mjs",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.mts",
|
|
@@ -19,7 +19,8 @@
|
|
|
19
19
|
"license": "MIT",
|
|
20
20
|
"scripts": {
|
|
21
21
|
"dev": "next",
|
|
22
|
-
"build": "tsdown --format esm --format cjs"
|
|
22
|
+
"build": "tsdown --format esm --format cjs",
|
|
23
|
+
"test": "vitest run"
|
|
23
24
|
},
|
|
24
25
|
"dependencies": {
|
|
25
26
|
"@emotion/react": "^11.14.0"
|
|
@@ -30,10 +31,13 @@
|
|
|
30
31
|
},
|
|
31
32
|
"devDependencies": {
|
|
32
33
|
"@biomejs/biome": "^2.3.5",
|
|
34
|
+
"@testing-library/react": "^13.4.0",
|
|
33
35
|
"binary-base64-loader": "^1.0.0",
|
|
36
|
+
"jsdom": "^26.1.0",
|
|
34
37
|
"next": "^16.0.2",
|
|
35
38
|
"rollup-plugin-base64": "^1.0.1",
|
|
36
39
|
"tsdown": "^0.16.4",
|
|
37
|
-
"typescript": "^5.9.3"
|
|
40
|
+
"typescript": "^5.9.3",
|
|
41
|
+
"vitest": "^4.1.0"
|
|
38
42
|
}
|
|
39
43
|
}
|