import { useEffect, useId, useState } from "react"; import { BiCheck, BiHide, BiLeftArrowAlt, BiRightArrowAlt, BiShow, BiX, } from "react-icons/bi"; import { apiFormatDate, formatDate, getDateTags } from "./dengi.js"; import { AnimatePresence, motion, LayoutGroup } from "motion/react"; import trashcss from "./trash.module.css"; import { useWebHaptics } from "web-haptics/react"; export function Switch({ checked, defaultChecked = false, onChange, disabled = false, ariaLabel, className = "", size = "md", // "sm" | "md" | "lg" }) { const isControlled = checked !== undefined; const [internalChecked, setInternalChecked] = useState(defaultChecked); const current = isControlled ? checked : internalChecked; useEffect(() => { if (!isControlled) return; setInternalChecked(checked); }, [checked, isControlled]); const sizes = { sm: { track: "w-9 h-5", thumb: "w-3 h-3", translate: "translate-x-4" }, md: { track: "w-11 h-6", thumb: "w-4 h-4", translate: "translate-x-5" }, lg: { track: "w-14 h-8", thumb: "w-6 h-6", translate: "translate-x-6" }, }; const s = sizes[size] || sizes.md; const toggle = (next) => { if (disabled) return; const newState = typeof next === "boolean" ? next : !current; if (!isControlled) setInternalChecked(newState); onChange?.(newState); }; return ( ); } export function LoadingSpinner({ size }) { return ( ); } function DatePickerButton({ next = false, date, setDate, pink = false }) { const { trigger } = useWebHaptics(); return ( { const d = new Date(date); d.setDate(d.getDate() + (next ? 1 : -1)); setDate(d); trigger([{ duration: 15 }], { intensity: 1 }); }} > {!next ? : } ); } export const DatePicker = (props) => { const dateTag = getDateTags(props.date); const { trigger } = useWebHaptics(); const layoutGroupId = useId(); return ( { if (apiFormatDate(props.date) != apiFormatDate(new Date())) trigger([ { duration: 10, intensity: 1 }, { delay: 40, duration: 20, intensity: 0.26 }, { delay: 90, duration: 20, intensity: 0.34 }, ]); props.setDate(new Date()); }} > {props.indicator && ( )} {formatDate(props.date)} {dateTag.length > 0 && ( <> {dateTag} )} ); }; export function DengiButton({ onClick, children, disabled = false, className = "", }) { const { trigger } = useWebHaptics(); return ( { onClick(); trigger([ { duration: 40, intensity: 0.8, }, ]); } } > {children} ); } const defaultDialogContent = { message: "?", yesBtn: "da", noBtn: "net", bgDissmis: true, yesBlocked: false, yesIcon: , noIcon: , noBtnStyle: "", yesBtnStyle: "", }; export function DengiYesOrNoDialog({ content = defaultDialogContent, show, onAnswer, }) { const { trigger } = useWebHaptics(); useEffect(() => { if (show) { trigger([ { duration: 40, intensity: 0.8, }, { delay: 15, duration: 170, intensity: 0.9, }, ]); } }, [show]); return ( <> {show && ( { if (e.target === e.currentTarget && content.bgDissmis) { onAnswer(false); trigger([{ duration: 40, intensity: 1 }]); } }} > {content.message}
onAnswer(true)} disabled={content.yesBlocked} > {content.yesIcon} {content.yesBtn} onAnswer(false)} > {content.noIcon} {content.noBtn}
)}
); } export function DengiEditable({ value, password = false, disWHidden = true, disabled = false, showLoading = true, minLenght = 1, // eslint-disable-next-line no-unused-vars onSubmit = ({ value, setIdle }) => {}, // eslint-disable-next-line no-unused-vars onInput = ({ value, setIdle }) => {}, pink = false, }) { const [val, setVal] = useState(value); const [hid, setHid] = useState(true); const [idle, setIdle] = useState(false); useEffect(() => { setVal(value); }, [value]); return (
{ if (idle) return; e.preventDefault(); onSubmit({ value: val, setIdle }); }} > {value !== false || !showLoading ? ( { setVal(e.target.value); onInput({ value: e.target.value, setIdle }); }} /> ) : ( )} {password && ( )} {val !== value && ( { e.preventDefault(); setVal(value); }} > {idle ? : } )}
); } export function TextPreloader({ width = "5rem" }) { return ( ); }