From a1612f527a5af9b3934be89eddbb78e28f3aa09a Mon Sep 17 00:00:00 2001 From: faisolavolut Date: Thu, 2 Jan 2025 10:16:29 +0700 Subject: [PATCH] first commit --- components/Popover/Popover.css | 4 + components/Popover/Popover.tsx | 376 ++++ components/card.tsx | 16 + components/comp/500.tsx | 28 + components/comp/AlertBatch.tsx | 168 ++ components/comp/AlertCeoApprove.tsx | 133 ++ components/comp/AlertCeoApproveMPR.tsx | 139 ++ components/comp/AlertCeoReject.tsx | 317 +++ components/comp/AlertCeoRejectMPR.tsx | 203 ++ components/form/Field.tsx | 164 ++ components/form/Form.tsx | 254 +++ components/form/FormBetter.tsx | 70 + components/form/field/FilePreview.tsx | 325 +++ components/form/field/Type.tsx | 14 + components/form/field/TypeCheckbox.tsx | 147 ++ components/form/field/TypeDropdown.tsx | 57 + components/form/field/TypeInput.tsx | 277 +++ components/form/field/TypeUpload.tsx | 32 + components/form/field/TypeUploadMulti.tsx | 177 ++ components/form/field/TypeUploadSingle.tsx | 237 +++ components/form/field/Typeahead.tsx | 631 ++++++ components/form/field/typeahead-opt.tsx | 130 ++ components/partials/Footer.tsx | 141 ++ components/partials/Header.tsx | 45 + components/partials/NavbarFlow.tsx | 445 +++++ components/partials/Script.tsx | 9 + components/partials/Sidebar.tsx | 488 +++++ components/tablelist/TableList.tsx | 702 +++++++ components/tablelist/lib/column.ts | 10 + components/tablist/Tablist copy.tsx | 282 +++ components/tablist/Tablist.tsx | 129 ++ .../Datepicker/components/Calendar/Days.tsx | 467 +++++ .../Datepicker/components/Calendar/Months.tsx | 35 + .../Datepicker/components/Calendar/Week.tsx | 55 + .../Datepicker/components/Calendar/Years.tsx | 66 + .../Datepicker/components/Calendar/index.tsx | 394 ++++ .../ui/Datepicker/components/Datepicker.tsx | 397 ++++ .../ui/Datepicker/components/Footer.tsx | 55 + components/ui/Datepicker/components/Input.tsx | 327 +++ .../ui/Datepicker/components/Shortcuts.tsx | 179 ++ .../ui/Datepicker/components/ToggleButton.tsx | 19 + components/ui/Datepicker/components/utils.tsx | 254 +++ components/ui/Datepicker/constants/index.ts | 285 +++ .../ui/Datepicker/constants/shortcuts.ts | 57 + .../Datepicker/contexts/DatepickerContext.ts | 104 + components/ui/Datepicker/helpers/index.ts | 632 ++++++ components/ui/Datepicker/hooks/index.ts | 24 + components/ui/Datepicker/index.tsx | 4 + components/ui/Datepicker/types/index.ts | 97 + components/ui/Document.tsx | 622 ++++++ components/ui/DocumentMPR.tsx | 1777 +++++++++++++++++ components/ui/Skeleton.tsx | 15 + components/ui/alert-dialog.tsx | 141 ++ components/ui/alert.tsx | 59 + components/ui/badge.tsx | 36 + components/ui/breadcrumb-link.tsx | 61 + components/ui/breadcrumb.tsx | 115 ++ components/ui/button-link.tsx | 69 + components/ui/button.tsx | 71 + components/ui/card.tsx | 76 + components/ui/carousel.tsx | 251 +++ components/ui/checkbox.tsx | 30 + components/ui/dialog.tsx | 122 ++ components/ui/input-search.tsx | 38 + components/ui/input.tsx | 22 + components/ui/link-better.tsx | 38 + components/ui/previewImage.tsx | 36 + components/ui/resize.tsx | 45 + components/ui/spinner.tsx | 9 + components/ui/tabs.tsx | 55 + components/ui/tabslider.tsx | 102 + components/ui/text-area.tsx | 22 + context/SidebarContext.tsx | 76 + helpers/is-browser.ts | 5 + helpers/is-small-screen.ts | 7 + utils/action.tsx | 79 + utils/axios.ts | 30 + utils/cloneFm.ts | 7 + utils/conditionalMPR.ts | 99 + utils/cx.ts | 3 + utils/date.ts | 48 + utils/debounceHandler.ts | 17 + utils/detectCase.ts | 5 + utils/event.ts | 25 + utils/filterMenuByPermission.ts | 47 + utils/generateQueryString.ts | 25 + utils/get-params.ts | 6 + utils/getAccess.ts | 50 + utils/getNumber.ts | 3 + utils/getParamsUrl.ts | 5 + utils/getStatusDate.ts | 54 + utils/getValue.ts | 5 + utils/get_user.ts | 9 + utils/isStringEmpty.ts | 6 + utils/joinString.ts | 9 + utils/makeData.ts | 48 + utils/navigate.ts | 21 + utils/siteurl.ts | 5 + utils/toast.ts | 0 utils/use-local.ts | 104 + utils/utils.ts | 6 + 101 files changed, 14217 insertions(+) create mode 100644 components/Popover/Popover.css create mode 100644 components/Popover/Popover.tsx create mode 100644 components/card.tsx create mode 100644 components/comp/500.tsx create mode 100644 components/comp/AlertBatch.tsx create mode 100644 components/comp/AlertCeoApprove.tsx create mode 100644 components/comp/AlertCeoApproveMPR.tsx create mode 100644 components/comp/AlertCeoReject.tsx create mode 100644 components/comp/AlertCeoRejectMPR.tsx create mode 100644 components/form/Field.tsx create mode 100644 components/form/Form.tsx create mode 100644 components/form/FormBetter.tsx create mode 100644 components/form/field/FilePreview.tsx create mode 100644 components/form/field/Type.tsx create mode 100644 components/form/field/TypeCheckbox.tsx create mode 100644 components/form/field/TypeDropdown.tsx create mode 100644 components/form/field/TypeInput.tsx create mode 100644 components/form/field/TypeUpload.tsx create mode 100644 components/form/field/TypeUploadMulti.tsx create mode 100644 components/form/field/TypeUploadSingle.tsx create mode 100644 components/form/field/Typeahead.tsx create mode 100644 components/form/field/typeahead-opt.tsx create mode 100644 components/partials/Footer.tsx create mode 100644 components/partials/Header.tsx create mode 100644 components/partials/NavbarFlow.tsx create mode 100644 components/partials/Script.tsx create mode 100644 components/partials/Sidebar.tsx create mode 100644 components/tablelist/TableList.tsx create mode 100644 components/tablelist/lib/column.ts create mode 100644 components/tablist/Tablist copy.tsx create mode 100644 components/tablist/Tablist.tsx create mode 100644 components/ui/Datepicker/components/Calendar/Days.tsx create mode 100644 components/ui/Datepicker/components/Calendar/Months.tsx create mode 100644 components/ui/Datepicker/components/Calendar/Week.tsx create mode 100644 components/ui/Datepicker/components/Calendar/Years.tsx create mode 100644 components/ui/Datepicker/components/Calendar/index.tsx create mode 100644 components/ui/Datepicker/components/Datepicker.tsx create mode 100644 components/ui/Datepicker/components/Footer.tsx create mode 100644 components/ui/Datepicker/components/Input.tsx create mode 100644 components/ui/Datepicker/components/Shortcuts.tsx create mode 100644 components/ui/Datepicker/components/ToggleButton.tsx create mode 100644 components/ui/Datepicker/components/utils.tsx create mode 100644 components/ui/Datepicker/constants/index.ts create mode 100644 components/ui/Datepicker/constants/shortcuts.ts create mode 100644 components/ui/Datepicker/contexts/DatepickerContext.ts create mode 100644 components/ui/Datepicker/helpers/index.ts create mode 100644 components/ui/Datepicker/hooks/index.ts create mode 100644 components/ui/Datepicker/index.tsx create mode 100644 components/ui/Datepicker/types/index.ts create mode 100644 components/ui/Document.tsx create mode 100644 components/ui/DocumentMPR.tsx create mode 100644 components/ui/Skeleton.tsx create mode 100644 components/ui/alert-dialog.tsx create mode 100644 components/ui/alert.tsx create mode 100644 components/ui/badge.tsx create mode 100644 components/ui/breadcrumb-link.tsx create mode 100644 components/ui/breadcrumb.tsx create mode 100644 components/ui/button-link.tsx create mode 100644 components/ui/button.tsx create mode 100644 components/ui/card.tsx create mode 100644 components/ui/carousel.tsx create mode 100644 components/ui/checkbox.tsx create mode 100644 components/ui/dialog.tsx create mode 100644 components/ui/input-search.tsx create mode 100644 components/ui/input.tsx create mode 100644 components/ui/link-better.tsx create mode 100644 components/ui/previewImage.tsx create mode 100644 components/ui/resize.tsx create mode 100644 components/ui/spinner.tsx create mode 100644 components/ui/tabs.tsx create mode 100644 components/ui/tabslider.tsx create mode 100644 components/ui/text-area.tsx create mode 100644 context/SidebarContext.tsx create mode 100644 helpers/is-browser.ts create mode 100644 helpers/is-small-screen.ts create mode 100644 utils/action.tsx create mode 100644 utils/axios.ts create mode 100644 utils/cloneFm.ts create mode 100644 utils/conditionalMPR.ts create mode 100644 utils/cx.ts create mode 100644 utils/date.ts create mode 100644 utils/debounceHandler.ts create mode 100644 utils/detectCase.ts create mode 100644 utils/event.ts create mode 100644 utils/filterMenuByPermission.ts create mode 100644 utils/generateQueryString.ts create mode 100644 utils/get-params.ts create mode 100644 utils/getAccess.ts create mode 100644 utils/getNumber.ts create mode 100644 utils/getParamsUrl.ts create mode 100644 utils/getStatusDate.ts create mode 100644 utils/getValue.ts create mode 100644 utils/get_user.ts create mode 100644 utils/isStringEmpty.ts create mode 100644 utils/joinString.ts create mode 100644 utils/makeData.ts create mode 100644 utils/navigate.ts create mode 100644 utils/siteurl.ts create mode 100644 utils/toast.ts create mode 100644 utils/use-local.ts create mode 100644 utils/utils.ts diff --git a/components/Popover/Popover.css b/components/Popover/Popover.css new file mode 100644 index 0000000..36ac889 --- /dev/null +++ b/components/Popover/Popover.css @@ -0,0 +1,4 @@ +[data-floating-ui-portal] > div { + z-index: 100; + } + \ No newline at end of file diff --git a/components/Popover/Popover.tsx b/components/Popover/Popover.tsx new file mode 100644 index 0000000..f90a991 --- /dev/null +++ b/components/Popover/Popover.tsx @@ -0,0 +1,376 @@ +import { + FloatingFocusManager, + FloatingOverlay, + FloatingPortal, + Placement, + arrow, + autoUpdate, + flip, + offset, + shift, + useClick, + useDismiss, + useFloating, + useId, + useInteractions, + useMergeRefs, + useRole, +} from "@floating-ui/react"; +import * as React from "react"; +import "./Popover.css"; +import { css } from "@emotion/css"; + +interface PopoverOptions { + initialOpen?: boolean; + placement?: Placement; + modal?: boolean; + open?: boolean; + offset?: number; + onOpenChange?: (open: boolean) => void; + autoFocus?: boolean; + backdrop?: boolean | "self"; + root?: HTMLElement; +} + +export function usePopover({ + initialOpen = false, + placement = "bottom", + modal = false, + open: controlledOpen, + offset: popoverOffset = 5, + onOpenChange: setControlledOpen, + autoFocus = false, + backdrop = true, + root, +}: PopoverOptions = {}) { + const arrowRef = React.useRef(null); + const [uncontrolledOpen, setUncontrolledOpen] = React.useState(initialOpen); + const [labelId, setLabelId] = React.useState(); + const [descriptionId, setDescriptionId] = React.useState(); + + // Determine whether the popover is open + const open = controlledOpen ?? uncontrolledOpen; + const setOpen = setControlledOpen ?? setUncontrolledOpen; + + // Floating UI setup + const data = useFloating({ + placement, + open, + onOpenChange: setOpen, + whileElementsMounted: autoUpdate, + middleware: [ + offset(popoverOffset), + flip({ + fallbackAxisSideDirection: "end", + padding: 8, + }), + shift({ padding: 5 }), + arrow({ element: arrowRef }), + ], + }); + + const context = data.context; + + // Add interactions (click, dismiss, role) + const click = useClick(context, { + enabled: controlledOpen == null, // Only enable if not controlled + }); + const dismiss = useDismiss(context); + const role = useRole(context); + + // Combine all interactions + const interactions = useInteractions([click, dismiss, role]); + + // Return memoized popover properties + return React.useMemo( + () => ({ + open, + setOpen, + ...interactions, + ...data, + arrowRef, + modal, + labelId, + descriptionId, + setLabelId, + setDescriptionId, + backdrop, + autoFocus, + root, + }), + [ + open, + setOpen, + interactions, + data, + modal, + labelId, + descriptionId, + backdrop, + autoFocus, + root, + ] + ); +} + + +function mapPlacementSideToCSSProperty(placement: Placement) { + const staticPosition = placement.split("-")[0]; + + const staticSide = { + top: "bottom", + right: "left", + bottom: "top", + left: "right", + }[staticPosition]; + + return staticSide; +} +function PopoverArrow() { + const context = usePopoverContext(); + const { x: arrowX, y: arrowY } = context.middlewareData.arrow || { + x: 0, + y: 0, + }; + const staticSide = mapPlacementSideToCSSProperty(context.placement) as string; + + return ( +
+ ); +} + +type ContextType = + | (ReturnType & { + setLabelId: React.Dispatch>; + setDescriptionId: React.Dispatch< + React.SetStateAction + >; + }) + | null; + +const PopoverContext = React.createContext(null); + +export const usePopoverContext = () => { + const context = React.useContext(PopoverContext); + + if (context == null) { + throw new Error("Popover components must be wrapped in "); + } + + return context; +}; + +export function Popover({ + children, + content, + modal = false, + className, + classNameTrigger, + arrow, + ...restOptions +}: { + root?: HTMLElement; + className?: string; + classNameTrigger?: string; + children: React.ReactNode; + content?: React.ReactNode; + arrow?: boolean; +} & PopoverOptions) { + const popover = usePopover({ modal, ...restOptions }); + + let _content = content; + if (!content) _content =
; + return ( + + { + popover.setOpen(!popover.open); + } + : undefined + } + > + {[children]} + + + {_content} + {(typeof arrow === "undefined" || arrow) && } + + + ); +} + +interface PopoverTriggerProps { + children: React.ReactNode; + asChild?: boolean; +} + +export const PopoverTrigger = React.forwardRef< + HTMLElement, + React.HTMLProps & PopoverTriggerProps +>(function PopoverTrigger({ children, asChild = false, ...props }, propRef) { + const context = usePopoverContext(); + + // Gabungkan refs dari popover context dan ref prop + const ref = useMergeRefs([context.refs.setReference, propRef]); + + // `asChild` memungkinkan elemen anak digunakan sebagai anchor + if (asChild && React.isValidElement(children)) { + return React.cloneElement(children, { + ref, + ...context.getReferenceProps({ + ...props, + ...children.props, + "data-state": context.open ? "open" : "closed", + }), + } as any); + } + + return ( +
+ {children} +
+ ); +}); + + +export const PopoverContent = React.forwardRef< + HTMLDivElement, + React.HTMLProps +>(function PopoverContent(props, propRef) { + const { context: floatingContext, ...context } = usePopoverContext(); + const ref = useMergeRefs([context.refs.setFloating, propRef]); + + if (!floatingContext.open) return null; + + const _content = ( +
+ {props.children} +
+ ); + + const content = context.autoFocus ? ( + + {_content} + + ) : ( + _content + ); + + return ( + + {context.backdrop ? ( + + {content} + + ) : ( + content + )} + + ); +}); + +export const PopoverHeading = React.forwardRef< + HTMLHeadingElement, + React.HTMLProps +>(function PopoverHeading({ children, ...props }, ref) { + const { setLabelId } = usePopoverContext(); + const id = useId(); + + // Only sets `aria-labelledby` on the Popover root element + // if this component is mounted inside it. + React.useLayoutEffect(() => { + setLabelId(id); + return () => setLabelId(undefined); + }, [id, setLabelId]); + + return ( +

+ {children} +

+ ); +}); + +export const PopoverDescription = React.forwardRef< + HTMLParagraphElement, + React.HTMLProps +>(function PopoverDescription({ children, ...props }, ref) { + const { setDescriptionId } = usePopoverContext(); + const id = useId(); + + // Only sets `aria-describedby` on the Popover root element + // if this component is mounted inside it. + React.useLayoutEffect(() => { + setDescriptionId(id); + return () => setDescriptionId(undefined); + }, [id, setDescriptionId]); + + return ( +

+ {children} +

+ ); +}); + +export const PopoverClose = React.forwardRef< + HTMLButtonElement, + React.ButtonHTMLAttributes +>(function PopoverClose(props, ref) { + const { setOpen } = usePopoverContext(); + return ( +