UNPKG

@sikka/hawa

Version:

Modern UI Kit made with Tailwind

641 lines (619 loc) • 19.2 kB
"use client"; "use strict"; var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( // If the importer is in node compatibility mode or this is not an ESM // file that has been converted to a CommonJS file using a Babel- // compatible transform (i.e. "__esModule" has not been set), then set // "default" to the CommonJS "module.exports" for node compatibility. isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod )); var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // hooks/index.ts var hooks_exports = {}; __export(hooks_exports, { getHotkeyHandler: () => getHotkeyHandler, getHotkeyMatcher: () => getHotkeyMatcher, parseHotkey: () => parseHotkey, reducer: () => reducer, toast: () => toast, useBreakpoint: () => useBreakpoint, useClickOutside: () => useClickOutside, useClipboard: () => useClipboard, useDialogCarousel: () => useDialogCarousel, useFocusWithin: () => useFocusWithin, useIsomorphicEffect: () => useIsomorphicEffect, useMeasureDirty: () => useMeasureDirty, useMediaQuery: () => useMediaQuery, useMultiStepDialog: () => useMultiStepDialog, useShortcuts: () => useShortcuts, useTabs: () => useTabs, useToast: () => useToast, useViewportSize: () => useViewportSize, useWindowEvent: () => useWindowEvent, useWindowSize: () => useWindowSize }); module.exports = __toCommonJS(hooks_exports); // hooks/useIsomorphicEffect.ts var import_react = require("react"); var useIsomorphicEffect = typeof document !== "undefined" ? import_react.useLayoutEffect : import_react.useEffect; // hooks/useDiscloser.ts var import_react2 = require("react"); // hooks/useHover.ts var import_react3 = require("react"); // hooks/useToast.ts var React3 = __toESM(require("react")); var TOAST_LIMIT = 5; var TOAST_REMOVE_DELAY = 1e5; var count = 0; function genId() { count = (count + 1) % Number.MAX_VALUE; return count.toString(); } var toastTimeouts = /* @__PURE__ */ new Map(); var addToRemoveQueue = (toastId) => { if (toastTimeouts.has(toastId)) { return; } const timeout = setTimeout(() => { toastTimeouts.delete(toastId); dispatch({ type: "REMOVE_TOAST", toastId }); }, TOAST_REMOVE_DELAY); toastTimeouts.set(toastId, timeout); }; var reducer = (state, action) => { switch (action.type) { case "ADD_TOAST": return { ...state, toasts: [action.toast, ...state.toasts].slice(0, TOAST_LIMIT) }; case "UPDATE_TOAST": return { ...state, toasts: state.toasts.map( (t) => t.id === action.toast.id ? { ...t, ...action.toast } : t ) }; case "DISMISS_TOAST": { const { toastId } = action; if (toastId) { addToRemoveQueue(toastId); } else { state.toasts.forEach((toast2) => { addToRemoveQueue(toast2.id); }); } return { ...state, toasts: state.toasts.map( (t) => t.id === toastId || toastId === void 0 ? { ...t, open: false } : t ) }; } case "REMOVE_TOAST": if (action.toastId === void 0) { return { ...state, toasts: [] }; } return { ...state, toasts: state.toasts.filter((t) => t.id !== action.toastId) }; } }; var listeners = []; var memoryState = { toasts: [] }; function dispatch(action) { memoryState = reducer(memoryState, action); listeners.forEach((listener) => { listener(memoryState); }); } function toast({ ...props }) { const id = genId(); const update = (props2) => dispatch({ type: "UPDATE_TOAST", toast: { ...props2, id } }); const dismiss = () => dispatch({ type: "DISMISS_TOAST", toastId: id }); dispatch({ type: "ADD_TOAST", toast: { ...props, id, open: true, onOpenChange: (open) => { if (!open) dismiss(); } } }); return { id, dismiss, update }; } function useToast() { const [state, setState] = React3.useState(memoryState); React3.useEffect(() => { listeners.push(setState); return () => { const index = listeners.indexOf(setState); if (index > -1) { listeners.splice(index, 1); } }; }, [state]); return { ...state, toast, dismiss: (toastId) => dispatch({ type: "DISMISS_TOAST", toastId }) }; } // hooks/useCarousel.ts var import_react4 = require("react"); // hooks/useDialogCarousel.ts var import_react5 = require("react"); var import_embla_carousel_auto_height = __toESM(require("embla-carousel-auto-height")); var import_embla_carousel_react = __toESM(require("embla-carousel-react")); var useDialogCarousel = (options) => { const [emblaRef, emblaApi] = (0, import_embla_carousel_react.default)( { loop: false, watchDrag: false, startIndex: 0, ...options }, [(0, import_embla_carousel_auto_height.default)({ active: true })] ); const [canScrollPrev, setCanScrollPrev] = (0, import_react5.useState)(false); const checkCanScrollPrev = () => { if (emblaApi) { setCanScrollPrev(emblaApi.canScrollPrev()); } }; const nextStep = () => { if (emblaApi) { console.log("going to NEXT \u{1F449}"); emblaApi.scrollNext(); } }; const prevStep = () => { if (emblaApi) { console.log("going to BACK \u{1F448}"); emblaApi.scrollPrev(); } }; (0, import_react5.useEffect)(() => { checkCanScrollPrev(); emblaApi && emblaApi.on("select", checkCanScrollPrev); return () => { emblaApi && emblaApi.off("select", checkCanScrollPrev); }; }, [emblaApi]); return { emblaRef, emblaApi, nextStep, prevStep, canScrollPrev }; }; // hooks/useDialogSteps.ts var import_react6 = require("react"); var useMultiStepDialog = (initialStep, stepIds, setOpenDialog) => { const [currentStep, setCurrentStep] = (0, import_react6.useState)(initialStep); const [dialogHeight, setDialogHeight] = (0, import_react6.useState)(null); const visibleStepRef = (0, import_react6.useRef)(null); (0, import_react6.useEffect)(() => { if (visibleStepRef.current) { setDialogHeight(visibleStepRef.current.offsetHeight); } }, [currentStep, setOpenDialog]); const handleNext = () => { const currentIndex = stepIds.indexOf(currentStep); if (currentIndex < stepIds.length - 1) { setTimeout(() => { setCurrentStep(stepIds[currentIndex + 1]); }, 100); } }; const handleBack = () => { const currentIndex = stepIds.indexOf(currentStep); if (currentIndex > 0) { setTimeout(() => { setCurrentStep(stepIds[currentIndex - 1]); }, 100); } }; return { currentStep, dialogHeight, visibleStepRef, handleNext, handleBack }; }; // hooks/useClipboard.ts var import_react7 = require("react"); function useClipboard({ timeout = 2e3 } = {}) { const [error, setError] = (0, import_react7.useState)(null); const [copied, setCopied] = (0, import_react7.useState)(false); const [copyTimeout, setCopyTimeout] = (0, import_react7.useState)(null); const handleCopyResult = (value) => { clearTimeout(copyTimeout); setCopyTimeout(setTimeout(() => setCopied(false), timeout)); setCopied(value); }; const copy = (valueToCopy) => { if ("clipboard" in navigator) { navigator.clipboard.writeText(valueToCopy).then(() => handleCopyResult(true)).catch((err) => setError(err)); } else { setError(new Error("useClipboard: navigator.clipboard is not supported")); } }; const reset = () => { setCopied(false); setError(null); clearTimeout(copyTimeout); }; return { copy, reset, error, copied }; } // hooks/useBreakpoint.ts var import_react8 = require("react"); var useBreakpoint = () => { const [breakpoint, setBreakpoint] = (0, import_react8.useState)(null); (0, import_react8.useEffect)(() => { if (typeof window !== "undefined") { const resize = () => { setBreakpoint(window.innerWidth); }; resize(); window.addEventListener("resize", resize); return () => { window.removeEventListener("resize", resize); }; } }, []); return breakpoint; }; // hooks/useWindowSize.ts var import_react9 = require("react"); var useWindowSize = () => { const [windowSize, setWindowSize] = (0, import_react9.useState)({ width: void 0, height: void 0 }); (0, import_react9.useEffect)(() => { function handleResize() { setWindowSize({ width: window.innerWidth, height: window.innerHeight }); } window.addEventListener("resize", handleResize); handleResize(); return () => window.removeEventListener("resize", handleResize); }, []); return windowSize; }; // hooks/useFocusWithin.ts var import_react10 = require("react"); function containsRelatedTarget(event) { if (event.currentTarget instanceof HTMLElement && event.relatedTarget instanceof HTMLElement) { return event.currentTarget.contains(event.relatedTarget); } return false; } function useFocusWithin({ onBlur, onFocus } = {}) { const ref = (0, import_react10.useRef)(null); const [focused, _setFocused] = (0, import_react10.useState)(false); const focusedRef = (0, import_react10.useRef)(false); const setFocused = (value) => { _setFocused(value); focusedRef.current = value; }; const handleFocusIn = (event) => { if (!focusedRef.current) { setFocused(true); onFocus == null ? void 0 : onFocus(event); } }; const handleFocusOut = (event) => { if (focusedRef.current && !containsRelatedTarget(event)) { setFocused(false); onBlur == null ? void 0 : onBlur(event); } }; (0, import_react10.useEffect)(() => { if (ref.current) { ref.current.addEventListener("focusin", handleFocusIn); ref.current.addEventListener("focusout", handleFocusOut); return () => { var _a, _b; (_a = ref.current) == null ? void 0 : _a.removeEventListener("focusin", handleFocusIn); (_b = ref.current) == null ? void 0 : _b.removeEventListener("focusout", handleFocusOut); }; } return void 0; }, [handleFocusIn, handleFocusOut]); return { ref, focused }; } // hooks/useMediaQuery.ts var import_react11 = require("react"); function attachMediaListener(query, callback) { try { query.addEventListener("change", callback); return () => query.removeEventListener("change", callback); } catch (e) { query.addListener(callback); return () => query.removeListener(callback); } } function getInitialValue(query, initialValue) { if (typeof initialValue === "boolean") { return initialValue; } if (typeof window !== "undefined" && "matchMedia" in window) { return window.matchMedia(query).matches; } return false; } function useMediaQuery(query, initialValue, { getInitialValueInEffect } = { getInitialValueInEffect: true }) { const [matches, setMatches] = (0, import_react11.useState)( getInitialValueInEffect ? initialValue : getInitialValue(query, initialValue) ); const queryRef = (0, import_react11.useRef)(); (0, import_react11.useEffect)(() => { if ("matchMedia" in window) { queryRef.current = window.matchMedia(query); setMatches(queryRef.current.matches); return attachMediaListener( queryRef.current, (event) => setMatches(event.matches) ); } return void 0; }, [query]); return matches; } // hooks/useScrollPosition.ts var import_react12 = require("react"); // hooks/useTable.ts var import_react13 = require("react"); // hooks/useTabs.ts var import_react14 = require("react"); function useTabs(initialTab = "") { const [activeTab, setActiveTab] = (0, import_react14.useState)(initialTab); (0, import_react14.useEffect)(() => { const handleHashChange = () => { const hash = window.location.hash.substring(1); setActiveTab(hash || initialTab); }; window.addEventListener("hashchange", handleHashChange); handleHashChange(); return () => { window.removeEventListener("hashchange", handleHashChange); }; }, [initialTab]); const handleTabChange = (index) => { setActiveTab(index); window.location.hash = index; }; return { activeTab, handleTabChange }; } // hooks/useMeasureDirty.ts var import_react15 = require("react"); var useMeasureDirty = (ref) => { const frame = (0, import_react15.useRef)(0); const [rect, set] = (0, import_react15.useState)({ width: 0, height: 0, top: 0, left: 0, bottom: 0, right: 0 }); const [observer] = (0, import_react15.useState)( () => new ResizeObserver((entries) => { const entry = entries[0]; if (entry) { cancelAnimationFrame(frame.current); frame.current = requestAnimationFrame(() => { if (ref.current) { set(entry.contentRect); } }); } }) ); (0, import_react15.useEffect)(() => { observer.disconnect(); if (ref.current) { observer.observe(ref.current); } }, [ref]); return rect; }; // hooks/useClickOutside.ts var import_react16 = require("react"); var DEFAULT_EVENTS = ["mousedown", "touchstart"]; function useClickOutside(handler, events, nodes) { const ref = (0, import_react16.useRef)(); (0, import_react16.useEffect)(() => { const listener = (event) => { const { target } = event != null ? event : {}; if (Array.isArray(nodes)) { const shouldIgnore = (target == null ? void 0 : target.hasAttribute("data-ignore-outside-clicks")) || !document.body.contains(target) && target.tagName !== "HTML"; const shouldTrigger = nodes.every( (node) => !!node && !event.composedPath().includes(node) ); shouldTrigger && !shouldIgnore && handler(); } else if (ref.current && !ref.current.contains(target)) { handler(); } }; (events || DEFAULT_EVENTS).forEach( (fn) => document.addEventListener(fn, listener) ); return () => { (events || DEFAULT_EVENTS).forEach( (fn) => document.removeEventListener(fn, listener) ); }; }, [ref, handler, nodes]); return ref; } // hooks/useShortcuts.ts var import_react17 = require("react"); function parseHotkey(hotkey) { const keys = hotkey.toLowerCase().split("+").map((part) => part.trim()); const modifiers = { alt: keys.includes("alt"), ctrl: keys.includes("ctrl"), meta: keys.includes("meta"), mod: keys.includes("mod"), shift: keys.includes("shift") }; const reservedKeys = ["alt", "ctrl", "meta", "shift", "mod"]; const freeKey = keys.find((key) => !reservedKeys.includes(key)); return { ...modifiers, key: freeKey }; } function isExactHotkey(hotkey, event) { const { alt, ctrl, meta, mod, shift, key } = hotkey; const { altKey, ctrlKey, metaKey, shiftKey, key: pressedKey } = event; if (alt !== altKey) { return false; } if (mod) { if (!ctrlKey && !metaKey) { return false; } } else { if (ctrl !== ctrlKey) { return false; } if (meta !== metaKey) { return false; } } if (shift !== shiftKey) { return false; } if (key && (pressedKey.toLowerCase() === key.toLowerCase() || event.code.replace("Key", "").toLowerCase() === key.toLowerCase())) { return true; } return false; } function getHotkeyMatcher(hotkey) { return (event) => isExactHotkey(parseHotkey(hotkey), event); } function getHotkeyHandler(hotkeys) { return (event) => { const _event = "nativeEvent" in event ? event.nativeEvent : event; hotkeys.forEach(([hotkey, handler, options = { preventDefault: true }]) => { if (getHotkeyMatcher(hotkey)(_event)) { if (options.preventDefault) { event.preventDefault(); } handler(_event); } }); }; } function shouldFireEvent(event, tagsToIgnore, triggerOnContentEditable = false) { if (event.target instanceof HTMLElement) { if (triggerOnContentEditable) { return !tagsToIgnore.includes(event.target.tagName); } return !event.target.isContentEditable && !tagsToIgnore.includes(event.target.tagName); } return true; } function useShortcuts(hotkeys, tagsToIgnore = ["INPUT", "TEXTAREA", "SELECT"], triggerOnContentEditable = false) { (0, import_react17.useEffect)(() => { const keydownListener = (event) => { hotkeys.forEach( ([hotkey, handler, options = { preventDefault: true }]) => { if (getHotkeyMatcher(hotkey)(event) && shouldFireEvent(event, tagsToIgnore, triggerOnContentEditable)) { if (options.preventDefault) { event.preventDefault(); } handler(event); } } ); }; document.documentElement.addEventListener("keydown", keydownListener); return () => document.documentElement.removeEventListener("keydown", keydownListener); }, [hotkeys]); } // hooks/useWindowEvent.ts var import_react18 = require("react"); function useWindowEvent(type, listener, options) { (0, import_react18.useEffect)(() => { window.addEventListener(type, listener, options); return () => window.removeEventListener(type, listener, options); }, [type, listener]); } // hooks/useViewportSize.ts var import_react19 = require("react"); var eventListerOptions = { passive: true }; function useViewportSize() { const [windowSize, setWindowSize] = (0, import_react19.useState)({ width: 0, height: 0 }); const setSize = (0, import_react19.useCallback)(() => { setWindowSize({ width: window.innerWidth || 0, height: window.innerHeight || 0 }); }, []); useWindowEvent("resize", setSize, eventListerOptions); useWindowEvent("orientationchange", setSize, eventListerOptions); (0, import_react19.useEffect)(setSize, []); return windowSize; } // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { getHotkeyHandler, getHotkeyMatcher, parseHotkey, reducer, toast, useBreakpoint, useClickOutside, useClipboard, useDialogCarousel, useFocusWithin, useIsomorphicEffect, useMeasureDirty, useMediaQuery, useMultiStepDialog, useShortcuts, useTabs, useToast, useViewportSize, useWindowEvent, useWindowSize });