mirror of
https://dev.azure.com/globalhealthx/EMR/_git/helix-engage
synced 2026-04-11 18:28:15 +00:00
chore: initial Untitled UI Vite scaffold with FontAwesome Pro
This commit is contained in:
34
src/hooks/use-breakpoint.ts
Normal file
34
src/hooks/use-breakpoint.ts
Normal file
@@ -0,0 +1,34 @@
|
||||
import { useEffect, useState } from "react";
|
||||
|
||||
const screens = {
|
||||
sm: "640px",
|
||||
md: "768px",
|
||||
lg: "1024px",
|
||||
xl: "1280px",
|
||||
"2xl": "1536px",
|
||||
};
|
||||
|
||||
/**
|
||||
* Checks whether a particular Tailwind CSS viewport size applies.
|
||||
*
|
||||
* @param size The size to check, which must either be included in Tailwind CSS's
|
||||
* list of default screen sizes, or added to the Tailwind CSS config file.
|
||||
*
|
||||
* @returns A boolean indicating whether the viewport size applies.
|
||||
*/
|
||||
export const useBreakpoint = (size: "sm" | "md" | "lg" | "xl" | "2xl") => {
|
||||
const [matches, setMatches] = useState(typeof window !== "undefined" ? window.matchMedia(`(min-width: ${screens[size]})`).matches : true);
|
||||
|
||||
useEffect(() => {
|
||||
const breakpoint = window.matchMedia(`(min-width: ${screens[size]})`);
|
||||
|
||||
setMatches(breakpoint.matches);
|
||||
|
||||
const handleChange = (value: MediaQueryListEvent) => setMatches(value.matches);
|
||||
|
||||
breakpoint.addEventListener("change", handleChange);
|
||||
return () => breakpoint.removeEventListener("change", handleChange);
|
||||
}, [size]);
|
||||
|
||||
return matches;
|
||||
};
|
||||
77
src/hooks/use-clipboard.ts
Normal file
77
src/hooks/use-clipboard.ts
Normal file
@@ -0,0 +1,77 @@
|
||||
import { useCallback, useState } from "react";
|
||||
|
||||
const DEFAULT_TIMEOUT = 2000;
|
||||
|
||||
type UseClipboardReturnType = {
|
||||
/**
|
||||
* The state indicating whether the text has been copied.
|
||||
* If a string is provided, it will be used as the identifier for the copied state.
|
||||
*/
|
||||
copied: string | boolean;
|
||||
/**
|
||||
* Function to copy text to the clipboard using the modern clipboard API.
|
||||
* Falls back to the fallback function if the modern API fails.
|
||||
*
|
||||
* @param {string} text - The text to be copied.
|
||||
* @param {string} [id] - Optional identifier to set the copied state.
|
||||
* @returns {Promise<Object>} - A promise that resolves to an object containing:
|
||||
* - `success` (boolean): Whether the copy operation was successful.
|
||||
* - `error` (Error | undefined): The error object if the copy operation failed.
|
||||
*/
|
||||
copy: (text: string, id?: string) => Promise<{ success: boolean; error?: Error }>;
|
||||
};
|
||||
|
||||
/**
|
||||
* Custom hook to copy text to the clipboard.
|
||||
*
|
||||
* @returns {UseClipboardReturnType} - An object containing the copied state and the copy function.
|
||||
*/
|
||||
export const useClipboard = (): UseClipboardReturnType => {
|
||||
const [copied, setCopied] = useState<string | boolean>(false);
|
||||
|
||||
// Fallback function for older browsers
|
||||
const fallback = (text: string, id?: string) => {
|
||||
try {
|
||||
// Textarea to copy the text to the clipboard
|
||||
const textArea = document.createElement("textarea");
|
||||
textArea.value = text;
|
||||
textArea.style.position = "absolute";
|
||||
textArea.style.left = "-99999px";
|
||||
|
||||
document.body.appendChild(textArea);
|
||||
textArea.select();
|
||||
|
||||
const success = document.execCommand("copy");
|
||||
textArea.remove();
|
||||
|
||||
setCopied(id || true);
|
||||
setTimeout(() => setCopied(false), DEFAULT_TIMEOUT);
|
||||
|
||||
return success ? { success: true } : { success: false, error: new Error("execCommand returned false") };
|
||||
} catch (err) {
|
||||
return {
|
||||
success: false,
|
||||
error: err instanceof Error ? err : new Error("Fallback copy failed"),
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
const copy = useCallback(async (text: string, id?: string) => {
|
||||
if (navigator.clipboard && window.isSecureContext) {
|
||||
try {
|
||||
await navigator.clipboard.writeText(text);
|
||||
|
||||
setCopied(id || true);
|
||||
setTimeout(() => setCopied(false), DEFAULT_TIMEOUT);
|
||||
|
||||
return { success: true };
|
||||
} catch {
|
||||
// If modern method fails, try fallback
|
||||
return fallback(text, id);
|
||||
}
|
||||
}
|
||||
return fallback(text);
|
||||
}, []);
|
||||
|
||||
return { copied, copy };
|
||||
};
|
||||
67
src/hooks/use-resize-observer.ts
Normal file
67
src/hooks/use-resize-observer.ts
Normal file
@@ -0,0 +1,67 @@
|
||||
import { useEffect } from "react";
|
||||
import type { RefObject } from "@react-types/shared";
|
||||
|
||||
/**
|
||||
* Checks if the ResizeObserver API is supported.
|
||||
* @returns True if the ResizeObserver API is supported, false otherwise.
|
||||
*/
|
||||
function hasResizeObserver() {
|
||||
return typeof window.ResizeObserver !== "undefined";
|
||||
}
|
||||
|
||||
/**
|
||||
* The options for the useResizeObserver hook.
|
||||
*/
|
||||
type useResizeObserverOptionsType<T> = {
|
||||
/**
|
||||
* The ref to the element to observe.
|
||||
*/
|
||||
ref: RefObject<T | undefined | null> | undefined;
|
||||
/**
|
||||
* The box to observe.
|
||||
*/
|
||||
box?: ResizeObserverBoxOptions;
|
||||
/**
|
||||
* The callback function to call when the size changes.
|
||||
*/
|
||||
onResize: () => void;
|
||||
};
|
||||
|
||||
/**
|
||||
* A hook that observes the size of an element and calls a callback function when the size changes.
|
||||
* @param options - The options for the hook.
|
||||
*/
|
||||
export function useResizeObserver<T extends Element>(options: useResizeObserverOptionsType<T>) {
|
||||
const { ref, box, onResize } = options;
|
||||
|
||||
useEffect(() => {
|
||||
const element = ref?.current;
|
||||
if (!element) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!hasResizeObserver()) {
|
||||
window.addEventListener("resize", onResize, false);
|
||||
|
||||
return () => {
|
||||
window.removeEventListener("resize", onResize, false);
|
||||
};
|
||||
} else {
|
||||
const resizeObserverInstance = new window.ResizeObserver((entries) => {
|
||||
if (!entries.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
onResize();
|
||||
});
|
||||
|
||||
resizeObserverInstance.observe(element, { box });
|
||||
|
||||
return () => {
|
||||
if (element) {
|
||||
resizeObserverInstance.unobserve(element);
|
||||
}
|
||||
};
|
||||
}
|
||||
}, [onResize, ref, box]);
|
||||
}
|
||||
Reference in New Issue
Block a user