@kadoui/react 1.0.0 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (179) hide show
  1. package/README.md +1 -0
  2. package/dist/components/AccessNavigation/AccessNavigation.d.ts.map +1 -1
  3. package/dist/components/AccessNavigation/AccessNavigation.jsx +1 -1
  4. package/dist/components/Accordion/AccordionBody.jsx +1 -1
  5. package/dist/components/Affix/Affix.jsx +1 -1
  6. package/dist/components/Breadcrumbs/BreadcrumbsItem.jsx +1 -1
  7. package/dist/components/Breadcrumbs/BreadcrumbsRoot.jsx +1 -1
  8. package/dist/components/Carousel/CarouselContainer.jsx +1 -1
  9. package/dist/components/Carousel/CarouselRoot.jsx +1 -1
  10. package/dist/components/ContextMenu/ContextMenuContent.d.ts.map +1 -1
  11. package/dist/components/ContextMenu/ContextMenuContent.jsx +2 -1
  12. package/dist/components/ContextMenu/ContextMenuRoot.d.ts.map +1 -1
  13. package/dist/components/ContextMenu/ContextMenuRoot.jsx +1 -1
  14. package/dist/components/Drawer/DrawerBody.jsx +1 -1
  15. package/dist/components/Drawer/DrawerPortal.jsx +1 -1
  16. package/dist/components/Drawer/DrawerRoot.jsx +1 -1
  17. package/dist/components/Dropdown/DropdownMenu.d.ts.map +1 -1
  18. package/dist/components/Dropdown/DropdownMenu.jsx +1 -1
  19. package/dist/components/Dropdown/DropdownRoot.d.ts.map +1 -1
  20. package/dist/components/Dropdown/DropdownRoot.jsx +2 -1
  21. package/dist/components/LinkLoader/LinkLoader.jsx +1 -1
  22. package/dist/components/Modal/ModalBody.jsx +1 -1
  23. package/dist/components/Modal/ModalContent.jsx +1 -1
  24. package/dist/components/Modal/ModalHeader.jsx +1 -1
  25. package/dist/components/Modal/ModalPortal.jsx +1 -1
  26. package/dist/components/Modal/ModalRoot.d.ts.map +1 -1
  27. package/dist/components/Modal/ModalRoot.jsx +1 -1
  28. package/dist/components/Otp/OtpInputs.jsx +1 -1
  29. package/dist/components/Otp/OtpRoot.jsx +1 -1
  30. package/dist/components/Progress/ProgressBar.jsx +1 -1
  31. package/dist/components/Progress/ProgressRoot.jsx +1 -1
  32. package/dist/components/Rating/RatingItems.jsx +1 -1
  33. package/dist/components/Rating/RatingRoot.jsx +1 -1
  34. package/dist/components/Sheet/SheetBody.jsx +1 -1
  35. package/dist/components/Sheet/SheetContent.jsx +1 -1
  36. package/dist/components/Sheet/SheetHeader.jsx +1 -1
  37. package/dist/components/Sheet/SheetPortal.jsx +1 -1
  38. package/dist/components/ShowMore/ShowMoreContent.jsx +1 -1
  39. package/dist/components/ShowMore/ShowMoreFade.jsx +1 -1
  40. package/dist/components/ShowMore/ShowMoreRoot.jsx +1 -1
  41. package/dist/components/ShowMore/ShowMoreTrigger.jsx +1 -1
  42. package/dist/components/Slide/SlideContent.jsx +1 -1
  43. package/dist/components/Slide/SlideHeader.jsx +1 -1
  44. package/dist/components/Slide/SlidePortal.jsx +1 -1
  45. package/dist/components/Spoiler/Spoiler.jsx +1 -1
  46. package/dist/components/Steps/StepsControls.jsx +1 -1
  47. package/dist/components/Tabs/TabsList.jsx +1 -1
  48. package/dist/components/Tabs/TabsPanel.jsx +1 -1
  49. package/dist/components/Toast/ToastBox.jsx +1 -1
  50. package/dist/index.d.ts +3 -0
  51. package/dist/index.d.ts.map +1 -1
  52. package/dist/index.js +5 -0
  53. package/dist/utils/browser.d.ts +3 -0
  54. package/dist/utils/browser.d.ts.map +1 -0
  55. package/dist/utils/browser.js +21 -0
  56. package/dist/utils/cn.d.ts +3 -0
  57. package/dist/utils/cn.d.ts.map +1 -0
  58. package/dist/utils/cn.js +3 -0
  59. package/dist/utils/form.d.ts +2 -0
  60. package/dist/utils/form.d.ts.map +1 -0
  61. package/dist/utils/form.js +8 -0
  62. package/package.json +4 -3
  63. package/src/components/AccessNavigation/AccessNavigation.tsx +0 -46
  64. package/src/components/Accordion/Accordion.ts +0 -8
  65. package/src/components/Accordion/AccordionBody.tsx +0 -31
  66. package/src/components/Accordion/AccordionContext.ts +0 -8
  67. package/src/components/Accordion/AccordionRoot.tsx +0 -17
  68. package/src/components/Accordion/AccordionToggle.tsx +0 -29
  69. package/src/components/Affix/Affix.tsx +0 -59
  70. package/src/components/Breadcrumbs/Breadcrumbs.ts +0 -6
  71. package/src/components/Breadcrumbs/BreadcrumbsContext.ts +0 -7
  72. package/src/components/Breadcrumbs/BreadcrumbsItem.tsx +0 -24
  73. package/src/components/Breadcrumbs/BreadcrumbsRoot.tsx +0 -21
  74. package/src/components/Carousel/Carousel.ts +0 -6
  75. package/src/components/Carousel/CarouselContainer.tsx +0 -18
  76. package/src/components/Carousel/CarouselContext.ts +0 -7
  77. package/src/components/Carousel/CarouselRoot.tsx +0 -75
  78. package/src/components/ClientOnly/ClientOnly.tsx +0 -12
  79. package/src/components/Clipboard/Clipboard.tsx +0 -36
  80. package/src/components/ContextMenu/ContextMenu.ts +0 -6
  81. package/src/components/ContextMenu/ContextMenuContent.tsx +0 -51
  82. package/src/components/ContextMenu/ContextMenuContext.ts +0 -9
  83. package/src/components/ContextMenu/ContextMenuRoot.tsx +0 -79
  84. package/src/components/Drawer/Drawer.ts +0 -10
  85. package/src/components/Drawer/DrawerBody.tsx +0 -67
  86. package/src/components/Drawer/DrawerContext.ts +0 -8
  87. package/src/components/Drawer/DrawerPortal.tsx +0 -40
  88. package/src/components/Drawer/DrawerRoot.tsx +0 -45
  89. package/src/components/Drawer/DrawerToggle.tsx +0 -21
  90. package/src/components/Dropdown/Dropdown.ts +0 -8
  91. package/src/components/Dropdown/DropdownContext.ts +0 -10
  92. package/src/components/Dropdown/DropdownMenu.tsx +0 -34
  93. package/src/components/Dropdown/DropdownRoot.tsx +0 -90
  94. package/src/components/Dropdown/DropdownToggle.tsx +0 -23
  95. package/src/components/LinkLoader/LinkLoader.tsx +0 -16
  96. package/src/components/Modal/Modal.ts +0 -14
  97. package/src/components/Modal/ModalBody.tsx +0 -12
  98. package/src/components/Modal/ModalContent.tsx +0 -44
  99. package/src/components/Modal/ModalContext.ts +0 -8
  100. package/src/components/Modal/ModalHeader.tsx +0 -10
  101. package/src/components/Modal/ModalPortal.tsx +0 -40
  102. package/src/components/Modal/ModalRoot.tsx +0 -47
  103. package/src/components/Modal/ModalTrigger.tsx +0 -21
  104. package/src/components/Otp/Otp.ts +0 -8
  105. package/src/components/Otp/OtpContext.ts +0 -10
  106. package/src/components/Otp/OtpHiddenInput.tsx +0 -15
  107. package/src/components/Otp/OtpInputs.tsx +0 -86
  108. package/src/components/Otp/OtpRoot.tsx +0 -26
  109. package/src/components/Pagination/Pagination.ts +0 -15
  110. package/src/components/Pagination/PaginationContext.tsx +0 -10
  111. package/src/components/Pagination/PaginationCounts.tsx +0 -17
  112. package/src/components/Pagination/PaginationNextBtn.tsx +0 -27
  113. package/src/components/Pagination/PaginationPrevBtn.tsx +0 -27
  114. package/src/components/Pagination/PaginationSearchParamsRoot.tsx +0 -45
  115. package/src/components/Pagination/PaginationStateRoot.tsx +0 -23
  116. package/src/components/PasswordInput/PasswordInput.ts +0 -8
  117. package/src/components/PasswordInput/PasswordInputContext.tsx +0 -8
  118. package/src/components/PasswordInput/PasswordInputField.tsx +0 -15
  119. package/src/components/PasswordInput/PasswordInputRoot.tsx +0 -17
  120. package/src/components/PasswordInput/PasswordInputToggle.tsx +0 -52
  121. package/src/components/Portal/Portal.tsx +0 -17
  122. package/src/components/Progress/Progress.ts +0 -6
  123. package/src/components/Progress/ProgressBar.tsx +0 -29
  124. package/src/components/Progress/ProgressContext.ts +0 -8
  125. package/src/components/Progress/ProgressRoot.tsx +0 -22
  126. package/src/components/QrCode/QrCode.tsx +0 -22
  127. package/src/components/Rating/Rating.ts +0 -6
  128. package/src/components/Rating/RatingContext.ts +0 -8
  129. package/src/components/Rating/RatingItems.tsx +0 -50
  130. package/src/components/Rating/RatingRoot.tsx +0 -22
  131. package/src/components/Sheet/Sheet.tsx +0 -14
  132. package/src/components/Sheet/SheetBody.tsx +0 -49
  133. package/src/components/Sheet/SheetContent.tsx +0 -8
  134. package/src/components/Sheet/SheetContext.ts +0 -14
  135. package/src/components/Sheet/SheetHeader.tsx +0 -24
  136. package/src/components/Sheet/SheetPortal.tsx +0 -35
  137. package/src/components/Sheet/SheetRoot.tsx +0 -56
  138. package/src/components/Sheet/SheetToggle.tsx +0 -21
  139. package/src/components/ShowMore/ShowMore.ts +0 -10
  140. package/src/components/ShowMore/ShowMoreContent.tsx +0 -31
  141. package/src/components/ShowMore/ShowMoreContext.ts +0 -11
  142. package/src/components/ShowMore/ShowMoreFade.tsx +0 -18
  143. package/src/components/ShowMore/ShowMoreRoot.tsx +0 -37
  144. package/src/components/ShowMore/ShowMoreTrigger.tsx +0 -23
  145. package/src/components/Slide/Slide.ts +0 -12
  146. package/src/components/Slide/SlideContent.tsx +0 -8
  147. package/src/components/Slide/SlideContext.ts +0 -11
  148. package/src/components/Slide/SlideHeader.tsx +0 -10
  149. package/src/components/Slide/SlidePortal.tsx +0 -26
  150. package/src/components/Slide/SlideRoot.tsx +0 -39
  151. package/src/components/Slide/SlideToggle.tsx +0 -21
  152. package/src/components/Spoiler/Spoiler.tsx +0 -28
  153. package/src/components/Steps/Steps.ts +0 -15
  154. package/src/components/Steps/StepsContext.tsx +0 -16
  155. package/src/components/Steps/StepsControls.tsx +0 -56
  156. package/src/components/Steps/StepsNextBtn.tsx +0 -27
  157. package/src/components/Steps/StepsPrevBtn.tsx +0 -27
  158. package/src/components/Steps/StepsSearchParamsRoot.tsx +0 -45
  159. package/src/components/Steps/StepsStateRoot.tsx +0 -23
  160. package/src/components/Swap/Swap.ts +0 -8
  161. package/src/components/Swap/SwapContext.ts +0 -9
  162. package/src/components/Swap/SwapItem.tsx +0 -16
  163. package/src/components/Swap/SwapRoot.tsx +0 -29
  164. package/src/components/Swap/SwapTrigger.tsx +0 -31
  165. package/src/components/Tabs/Tabs.ts +0 -10
  166. package/src/components/Tabs/TabsContext.ts +0 -11
  167. package/src/components/Tabs/TabsList.tsx +0 -12
  168. package/src/components/Tabs/TabsPanel.tsx +0 -23
  169. package/src/components/Tabs/TabsRoot.tsx +0 -18
  170. package/src/components/Tabs/TabsTab.tsx +0 -23
  171. package/src/components/Toast/Toast.ts +0 -3
  172. package/src/components/Toast/ToastBox.tsx +0 -50
  173. package/src/components/Toast/ToastRoot.tsx +0 -71
  174. package/src/components/Toast/toastStore.ts +0 -22
  175. package/src/components/Toggle/Toggle.ts +0 -6
  176. package/src/components/Toggle/ToggleContext.ts +0 -9
  177. package/src/components/Toggle/ToggleRoot.tsx +0 -26
  178. package/src/components/Toggle/ToggleSwitch.tsx +0 -41
  179. package/src/index.ts +0 -28
@@ -1,8 +0,0 @@
1
- import { DropdownMenu } from "./DropdownMenu";
2
- import { DropdownRoot } from "./DropdownRoot";
3
- import { DropdownToggle } from "./DropdownToggle";
4
-
5
- export const Dropdown = Object.assign(DropdownRoot, {
6
- Toggle: DropdownToggle,
7
- Menu: DropdownMenu
8
- });
@@ -1,10 +0,0 @@
1
- import { createContext, Dispatch, RefObject, SetStateAction } from "react";
2
-
3
- export type DropdownContextT = {
4
- isOpen: boolean;
5
- setOpen: Dispatch<SetStateAction<boolean>>;
6
- toggleRef: RefObject<HTMLButtonElement | null>;
7
- menuRef: RefObject<HTMLDivElement | null>;
8
- }
9
-
10
- export const DropdownContext = createContext<DropdownContextT>({} as DropdownContextT);
@@ -1,34 +0,0 @@
1
- "use client";
2
-
3
- import { cn } from "@kadoui/utils";
4
- import { HTMLAttributes, use } from "react";
5
-
6
- import { DropdownContext } from "./DropdownContext";
7
-
8
- export type DropdownMenuPropsT = HTMLAttributes<HTMLDivElement> & {
9
- preventClose?: boolean;
10
- }
11
-
12
- export function DropdownMenu({ preventClose, onClick, className, ...p }: DropdownMenuPropsT) {
13
- const { menuRef, isOpen } = use(DropdownContext);
14
-
15
- return (
16
- isOpen ? (
17
- <div
18
- ref={menuRef}
19
- onClick={ev => {
20
- if (preventClose) {
21
- ev.stopPropagation();
22
- }
23
-
24
- onClick?.(ev);
25
- }}
26
- className={cn(
27
- "absolute w-max z-10",
28
- className
29
- )}
30
- {...p}
31
- />
32
- ) : null
33
- )
34
- }
@@ -1,90 +0,0 @@
1
- "use client";
2
-
3
- import { cn, selectAccessibleChildren } from "@kadoui/utils";
4
- import { HTMLAttributes, KeyboardEvent, useEffect, useRef, useState } from "react";
5
-
6
- import { DropdownContext } from "./DropdownContext";
7
-
8
-
9
- export type DropdownRootPropsT = HTMLAttributes<HTMLDivElement> & {
10
- accessHorizontalArrows?: "ArrowRight" | "ArrowLeft";
11
- }
12
-
13
- export function DropdownRoot({ accessHorizontalArrows, onKeyDown, className, ...p }: DropdownRootPropsT) {
14
- const [isOpen, setOpen] = useState(false);
15
-
16
- const toggleRef = useRef<HTMLButtonElement>(null);
17
- const menuRef = useRef<HTMLDivElement>(null);
18
-
19
- useEffect(() => {
20
- const closeHandler = () => {
21
- setOpen(false);
22
- }
23
-
24
- window.addEventListener("click", closeHandler);
25
-
26
- return () => window.removeEventListener("click", closeHandler);
27
- }, []);
28
-
29
- useEffect(() => {
30
- if (isOpen) {
31
- selectFirstMenuChild();
32
- }
33
- }, [isOpen]);
34
-
35
- const selectFirstMenuChild = () => {
36
- if (!menuRef.current) {
37
- return;
38
- }
39
-
40
- const children = selectAccessibleChildren(menuRef.current);
41
- const firstChild = children[0];
42
-
43
- if (!firstChild) {
44
- return;
45
- }
46
-
47
- firstChild.focus();
48
- }
49
-
50
- const handleKeyDown = (ev: KeyboardEvent<HTMLDivElement>) => {
51
- if (!accessHorizontalArrows) {
52
- return null;
53
- }
54
-
55
- if (ev.key === "ArrowRight") {
56
- if (accessHorizontalArrows === "ArrowRight") {
57
- setOpen(true);
58
- selectFirstMenuChild();
59
- } else {
60
- setOpen(false);
61
- toggleRef.current?.focus();
62
- }
63
- }
64
-
65
- if (ev.key === "ArrowLeft") {
66
- if (accessHorizontalArrows === "ArrowLeft") {
67
- setOpen(true);
68
- selectFirstMenuChild();
69
- } else {
70
- setOpen(false);
71
- toggleRef.current?.focus();
72
- }
73
- }
74
- }
75
-
76
- return (
77
- <DropdownContext value={{
78
- isOpen, setOpen, toggleRef, menuRef
79
- }}>
80
- <div
81
- className={cn("relative w-fit max-w-full", className)}
82
- onKeyDown={ev => {
83
- onKeyDown?.(ev);
84
- handleKeyDown(ev);
85
- }}
86
- {...p}
87
- />
88
- </DropdownContext>
89
- )
90
- }
@@ -1,23 +0,0 @@
1
- "use client";
2
-
3
- import { HTMLAttributes, use } from "react";
4
-
5
- import { DropdownContext } from "./DropdownContext";
6
-
7
- export type DropdownTogglePropsT = HTMLAttributes<HTMLButtonElement>;
8
-
9
- export function DropdownToggle({ onClick, ...props }: DropdownTogglePropsT) {
10
- const { toggleRef, setOpen } = use(DropdownContext);
11
-
12
- return (
13
- <button
14
- ref={toggleRef}
15
- onClick={ev => {
16
- ev.stopPropagation();
17
- onClick?.(ev);
18
- setOpen(prev => !prev);
19
- }}
20
- {...props}
21
- />
22
- )
23
- }
@@ -1,16 +0,0 @@
1
- "use client"
2
-
3
- import { cn } from "@kadoui/utils";
4
- import { LoaderIcon } from "lucide-react";
5
- import { useLinkStatus } from "next/link";
6
- import { PropsWithChildren } from "react";
7
-
8
- export type LinkLoaderPropsT = PropsWithChildren & {
9
- className?: string;
10
- }
11
-
12
- export function LinkLoader({ children, className }: LinkLoaderPropsT) {
13
- const { pending } = useLinkStatus()
14
-
15
- return pending ? <LoaderIcon className={cn("compatible-icon animate-spin", className)} /> : children
16
- }
@@ -1,14 +0,0 @@
1
- import { ModalBody } from "./ModalBody";
2
- import { ModalRoot } from "./ModalRoot";
3
- import { ModalHeader } from "./ModalHeader";
4
- import { ModalPortal } from "./ModalPortal";
5
- import { ModalToggle } from "./ModalTrigger";
6
- import { ModalContent } from "./ModalContent";
7
-
8
- export const Modal = Object.assign(ModalRoot, {
9
- Toggle: ModalToggle,
10
- Portal: ModalPortal,
11
- Content: ModalContent,
12
- Header: ModalHeader,
13
- Body: ModalBody
14
- });
@@ -1,12 +0,0 @@
1
- import { cn } from "@kadoui/utils";
2
- import type { HTMLAttributes } from "react";
3
-
4
- export type ModalBodyPropsT = HTMLAttributes<HTMLDivElement>;
5
-
6
- export function ModalBody({ children, className, ...props }: ModalBodyPropsT) {
7
- return (
8
- <div className={cn("py-3 px-1.5 mx-1.5 max-h-[calc(100%-4rem)] overflow-y-auto", className)} {...props}>
9
- {children}
10
- </div>
11
- );
12
- }
@@ -1,44 +0,0 @@
1
- "use client"
2
-
3
- import { cn } from "@kadoui/utils";
4
- import { use, useEffect, useRef } from "react";
5
- import { AnimatePresence, HTMLMotionProps, motion } from "framer-motion";
6
-
7
- import { ModalContext } from "./ModalContext";
8
-
9
- export type ModalContentPropsT = HTMLMotionProps<"div">;
10
-
11
- export function ModalContent({ onClick, className, ...props }: ModalContentPropsT) {
12
- const { isOpen } = use(ModalContext);
13
- const contentRef = useRef<HTMLDivElement>(null);
14
-
15
- useEffect(() => {
16
- if (isOpen) {
17
- const indexElement = contentRef.current?.querySelector("[data-modal='index']") as HTMLElement | null | undefined;
18
- indexElement?.focus();
19
- };
20
- }, [isOpen]);
21
-
22
- return (
23
- <AnimatePresence>
24
- {isOpen ? (
25
- <motion.div
26
- ref={contentRef}
27
- initial={{ opacity: 0, scale: 0.9 }}
28
- animate={{ opacity: 1, scale: 1 }}
29
- exit={{ opacity: 0, scale: 0.9 }}
30
- transition={{ ease: "easeInOut" }}
31
- onClick={ev => {
32
- onClick?.(ev);
33
- ev.stopPropagation();
34
- }}
35
- className={cn(
36
- "bg-background rounded-2xl w-max max-w-[90%] h-full max-h-[90%]",
37
- className,
38
- )}
39
- {...props}
40
- />
41
- ) : null}
42
- </AnimatePresence>
43
- );
44
- }
@@ -1,8 +0,0 @@
1
- import { createContext, Dispatch, SetStateAction } from "react";
2
-
3
- export type ModalContextT = {
4
- isOpen: boolean;
5
- setOpen: Dispatch<SetStateAction<boolean>>;
6
- }
7
-
8
- export const ModalContext = createContext<ModalContextT>({} as ModalContextT);
@@ -1,10 +0,0 @@
1
- import { cn } from "@kadoui/utils";
2
- import type { HTMLAttributes } from "react";
3
-
4
- export type ModalHeaderPropsT = HTMLAttributes<HTMLDivElement>;
5
-
6
- export function ModalHeader({ className, ...props }: ModalHeaderPropsT) {
7
- return (
8
- <div className={cn("h-16 f-align px-3 bg-background rounded-t-2xl border-b border-separator sticky top-0", className)} {...props} />
9
- );
10
- }
@@ -1,40 +0,0 @@
1
- "use client";
2
-
3
- import { use } from "react";
4
- import { cn } from "@kadoui/utils";
5
- import { motion, AnimatePresence, HTMLMotionProps } from "framer-motion";
6
-
7
- import { Portal } from "../Portal/Portal";
8
- import { ModalContext } from "./ModalContext";
9
- import { ClientOnly } from "../ClientOnly/ClientOnly";
10
-
11
- export type ModalPortalPropsT = HTMLMotionProps<"div">;
12
-
13
- export function ModalPortal({ onClick, className, ...props }: ModalPortalPropsT) {
14
- const { isOpen, setOpen } = use(ModalContext);
15
-
16
- return (
17
- <ClientOnly>
18
- <Portal>
19
- <AnimatePresence>
20
- {isOpen ? (
21
- <motion.div
22
- initial={{ opacity: 0 }}
23
- animate={{ opacity: 1 }}
24
- exit={{ opacity: 0 }}
25
- onClick={ev => {
26
- onClick?.(ev);
27
- setOpen(false);
28
- }}
29
- className={cn(
30
- "fixed inset-0 z-50 f-center bg-foreground/10",
31
- className
32
- )}
33
- {...props}
34
- />
35
- ) : null}
36
- </AnimatePresence>
37
- </Portal>
38
- </ClientOnly>
39
- );
40
- }
@@ -1,47 +0,0 @@
1
- "use client"
2
-
3
- import { getBrowserScrollbarWith } from "@kadoui/utils";
4
- import { useState, useEffect, PropsWithChildren } from "react";
5
-
6
- import { ModalContext } from "./ModalContext";
7
-
8
- export type ModalRootPropsT = PropsWithChildren & {
9
- defaultOpen?: boolean;
10
- }
11
-
12
- export function ModalRoot({ children, defaultOpen = false }: ModalRootPropsT) {
13
- const [isOpen, setOpen] = useState(defaultOpen);
14
-
15
- useEffect(() => {
16
- const handleEscape = (e: KeyboardEvent) => {
17
- if (e.key === "Escape") {
18
- setOpen(false);
19
- };
20
- };
21
-
22
- document.addEventListener("keydown", handleEscape);
23
-
24
- return () => {
25
- document.removeEventListener("keydown", handleEscape);
26
- document.body.style.overflow = "unset";
27
- };
28
- }, [])
29
-
30
- useEffect(() => {
31
- const scrollbarWidth = getBrowserScrollbarWith();
32
-
33
- if (isOpen) {
34
- document.body.style.overflow = "hidden";
35
- document.body.style.paddingRight = `${scrollbarWidth}px`;
36
- } else {
37
- document.body.style.overflow = "unset";
38
- document.body.style.paddingRight = "0px";
39
- };
40
- }, [isOpen]);
41
-
42
- return (
43
- <ModalContext value={{ isOpen, setOpen }}>
44
- {children}
45
- </ModalContext>
46
- );
47
- }
@@ -1,21 +0,0 @@
1
- "use client"
2
-
3
- import { ButtonHTMLAttributes, use } from "react";
4
-
5
- import { ModalContext } from "./ModalContext";
6
-
7
- export type ModalTogglePropsT = ButtonHTMLAttributes<HTMLButtonElement>;
8
-
9
- export function ModalToggle({ onClick, ...props }: ModalTogglePropsT) {
10
- const { setOpen } = use(ModalContext);
11
-
12
- return (
13
- <button
14
- onClick={(ev) => {
15
- onClick?.(ev);
16
- setOpen(prev => !prev);
17
- }}
18
- {...props}
19
- />
20
- );
21
- }
@@ -1,8 +0,0 @@
1
- import { OtpRoot } from "./OtpRoot";
2
- import { OtpInputs } from "./OtpInputs";
3
- import { OtpHiddenInput } from "./OtpHiddenInput";
4
-
5
- export const Otp = Object.assign(OtpRoot, {
6
- Inputs: OtpInputs,
7
- HiddenInput: OtpHiddenInput
8
- });
@@ -1,10 +0,0 @@
1
- import { createContext, RefObject } from "react";
2
-
3
- export type createContextT = {
4
- inputs?: RefObject<(HTMLInputElement | null)[]>;
5
- getInputsValue: () => string
6
- }
7
-
8
- export const OtpContext = createContext<createContextT>({
9
- getInputsValue: () => ""
10
- });
@@ -1,15 +0,0 @@
1
- "use client";
2
-
3
- import { InputHTMLAttributes, use } from "react";
4
-
5
- import { OtpContext } from "./OtpContext";
6
-
7
- export type OtpHiddenInputPropsT = InputHTMLAttributes<HTMLInputElement>;
8
-
9
- export function OtpHiddenInput({ name, ...p }: OtpHiddenInputPropsT) {
10
- const { getInputsValue } = use(OtpContext);
11
-
12
- return (
13
- <input type="hidden" tabIndex={-1} name={name || "otp"} value={getInputsValue()} {...p} />
14
- )
15
- }
@@ -1,86 +0,0 @@
1
- "use client";
2
-
3
- import { cn } from "@kadoui/utils";
4
- import { ClipboardEvent, InputHTMLAttributes, KeyboardEvent, use } from "react";
5
-
6
- import { OtpContext } from "./OtpContext";
7
-
8
- export type OtpInputsPropsT = InputHTMLAttributes<HTMLInputElement> & {
9
- length: number;
10
- onLastChange?: (otp: string) => void;
11
- }
12
-
13
- export function OtpInputs({ className, name, length, onLastChange, ...props }: OtpInputsPropsT) {
14
- const { inputs, getInputsValue } = use(OtpContext);
15
-
16
- const handlePaste = (ev: ClipboardEvent<HTMLInputElement>, startIndex: number) => {
17
- ev.preventDefault();
18
-
19
- const pastedData = ev.clipboardData.getData("text").replace(/\s/g, ""); // Remove whitespace
20
- if (!pastedData) return;
21
-
22
- for (let i = 0; i < pastedData.length; i++) {
23
- const inputIndex = startIndex + i;
24
- if (inputIndex >= length) break; // Don't exceed OTP length
25
-
26
- const input = inputs?.current[inputIndex];
27
- const indexedPastedData = pastedData[i];
28
- if (input && indexedPastedData) {
29
- input.value = indexedPastedData;
30
- }
31
- }
32
-
33
- const nextIndex = Math.min(startIndex + pastedData.length, length - 1);
34
- inputs?.current[nextIndex]?.focus();
35
-
36
- const otpValue = getInputsValue();
37
- if (otpValue.length === length) {
38
- onLastChange?.(otpValue);
39
- }
40
- };
41
-
42
- const handleInputChange = (value: string, index: number) => {
43
- if (value) {
44
- const currentInput = inputs?.current[index];
45
- const currentValue = currentInput?.value[currentInput.value.length - 1];
46
- if (currentValue) {
47
- currentInput.value = currentValue;
48
- }
49
-
50
- const nextInput = inputs?.current[index + 1]
51
- if (nextInput) {
52
- nextInput.value = "";
53
- nextInput.focus();
54
-
55
- return
56
- }
57
-
58
- onLastChange?.(getInputsValue());
59
- }
60
- };
61
-
62
- const handleBackspace = (e: KeyboardEvent<HTMLInputElement>, index: number) => {
63
- if (e.key === "Backspace" && !e.currentTarget.value && index > 0) {
64
- inputs?.current[index - 1]?.focus();
65
- }
66
- };
67
-
68
- return Array.from({ length }).map((_, index) => (
69
- <input
70
- key={index}
71
- autoComplete="off"
72
- name={`${name || "otp"}-${index}`}
73
- onPaste={ev => handlePaste(ev, index)}
74
- onKeyDown={ev => handleBackspace(ev, index)}
75
- onChange={ev => handleInputChange(ev.target.value, index)}
76
- className={cn("input-outline input-square text-center", className)}
77
- ref={el => {
78
- if (inputs) {
79
- inputs.current[index] = el;
80
- }
81
- }}
82
- {...props}
83
- />
84
- )
85
- );
86
- }
@@ -1,26 +0,0 @@
1
- "use client";
2
-
3
- import { cn } from "@kadoui/utils";
4
- import { HTMLAttributes, useEffect, useRef } from "react";
5
-
6
- import { OtpContext } from "./OtpContext";
7
-
8
- export type OtpRootPropsT = HTMLAttributes<HTMLDivElement>;
9
-
10
- export function OtpRoot({ className, ...props }: OtpRootPropsT) {
11
- const inputs = useRef<(HTMLInputElement | null)[]>([]);
12
-
13
- useEffect(() => {
14
- inputs.current[0]?.focus();
15
- }, []);
16
-
17
- const getInputsValue = () => {
18
- return inputs?.current.map(input => input?.value || "").join("") || "";
19
- };
20
-
21
- return (
22
- <OtpContext value={{ inputs, getInputsValue }}>
23
- <div className={cn("f-align gap-1.5", className)} {...props} />
24
- </OtpContext>
25
- );
26
- }
@@ -1,15 +0,0 @@
1
- import { PaginationCounts } from "./PaginationCounts";
2
- import { PaginationNextBtn } from "./PaginationNextBtn";
3
- import { PaginationPrevBtn } from "./PaginationPrevBtn";
4
- import { PaginationStateRoot } from "./PaginationStateRoot";
5
- import { PaginationSearchParamsRoot } from "./PaginationSearchParamsRoot";
6
-
7
- const baseComponents = {
8
- Counts: PaginationCounts,
9
- NextBtn: PaginationNextBtn,
10
- PrevBtn: PaginationPrevBtn
11
- }
12
-
13
- export const PaginationWithState = Object.assign(PaginationStateRoot, baseComponents);
14
-
15
- export const PaginationWithSearchParams = Object.assign(PaginationSearchParamsRoot, baseComponents);
@@ -1,10 +0,0 @@
1
- import { createContext } from 'react';
2
-
3
- export type PaginationContextT = {
4
- page: number;
5
- pageLength: number;
6
- nextPage: () => void;
7
- prevPage: () => void;
8
- }
9
-
10
- export const PaginationContext = createContext<PaginationContextT>({} as PaginationContextT);
@@ -1,17 +0,0 @@
1
- "use client";
2
-
3
- import { HTMLAttributes, use } from "react";
4
-
5
- import { PaginationContext } from "./PaginationContext";
6
-
7
- export type PaginationCountsPropsT = HTMLAttributes<HTMLParagraphElement>;
8
-
9
- export function PaginationCounts(props: PaginationCountsPropsT) {
10
- const { page, pageLength } = use(PaginationContext);
11
-
12
- return (
13
- <p {...props}>
14
- Page {page} / {pageLength}
15
- </p>
16
- );
17
- }
@@ -1,27 +0,0 @@
1
- "use client";
2
-
3
- import { HTMLAttributes, use } from "react";
4
- import { ChevronRightIcon } from "lucide-react";
5
-
6
- import { PaginationContext } from "./PaginationContext";
7
-
8
- export type PaginationNextBtnPropsT = HTMLAttributes<HTMLButtonElement> & {
9
- disabled?: boolean;
10
- };
11
-
12
- export function PaginationNextBtn({ onClick, disabled, children, ...props }: PaginationNextBtnPropsT) {
13
- const { page, pageLength, nextPage } = use(PaginationContext);
14
-
15
- return (
16
- <button
17
- disabled={disabled || page === pageLength}
18
- onClick={ev => {
19
- onClick?.(ev);
20
- nextPage();
21
- }}
22
- {...props}
23
- >
24
- {children || <ChevronRightIcon className="compatible-icon" />}
25
- </button>
26
- )
27
- }
@@ -1,27 +0,0 @@
1
- "use client";
2
-
3
- import { HTMLAttributes, use } from "react";
4
- import { ChevronLeftIcon } from "lucide-react";
5
-
6
- import { PaginationContext } from "./PaginationContext";
7
-
8
- export type PaginationPrevBtnPropsT = HTMLAttributes<HTMLButtonElement> & {
9
- disabled?: boolean;
10
- }
11
-
12
- export function PaginationPrevBtn({ onClick, disabled, children, ...props }: PaginationPrevBtnPropsT) {
13
- const { page, prevPage } = use(PaginationContext);
14
-
15
- return (
16
- <button
17
- disabled={disabled || page === 1}
18
- onClick={ev => {
19
- onClick?.(ev);
20
- prevPage();
21
- }}
22
- {...props}
23
- >
24
- {children || <ChevronLeftIcon className="compatible-icon" />}
25
- </button>
26
- )
27
- }