/** * KTUI - Free & Open-Source Tailwind UI Components by Keenthemes * Copyright 2025 by Keenthemes Inc */ import { KTOptionType } from '../types'; const KTUtils = { geUID(prefix: string = ''): string { return prefix + Math.floor(Math.random() * new Date().getTime()); }, getCssVar(variable: string): string { let hex = getComputedStyle(document.documentElement).getPropertyValue( variable, ); if (hex && hex.length > 0) { hex = hex.trim(); } return hex; }, parseDataAttribute(value: string): KTOptionType { if (value === 'true') { return true; } if (value === 'false') { return false; } if (value === Number(value).toString()) { return Number(value); } if (value === '' || value === 'null') { return null; } if (typeof value !== 'string') { return value; } try { return KTUtils.parseJson(value) as object; } catch { return value; } }, parseJson(value: string): unknown | null { return value && value.length > 0 ? JSON.parse(decodeURIComponent(value)) : null; }, parseSelector(selector: string): string { if (selector && window.CSS && window.CSS.escape) { // Escape any IDs in the selector using CSS.escape selector = selector.replace( /#([^\s"#']+)/g, (match, id) => `#${window.CSS.escape(id)}`, ); } return selector; }, capitalize(value: string): string { return value.charAt(0).toUpperCase() + value.slice(1); }, uncapitalize(value: string): string { return value.charAt(0).toLowerCase() + value.slice(1); }, camelCase(value: string): string { return value.replace(/-([a-z])/g, (match, letter) => { return letter.toUpperCase(); }); }, camelReverseCase(str: string): string { return str.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase(); }, isRTL(): boolean { const htmlElement = document.querySelector('html'); return Boolean( htmlElement && htmlElement.getAttribute('direction') === 'rtl', ); }, throttle( timer: undefined | ReturnType, func: CallableFunction, delay: number, ): void { // If setTimeout is already scheduled, no need to do anything if (timer) { return; } // Schedule a setTimeout after delay seconds timer = setTimeout(() => { func(); // Once setTimeout function execution is finished, timerId = undefined so that in
// the next scroll event function execution can be scheduled by the setTimeout clearTimeout(timer); }, delay); }, checksum(value: string): string { let hash = 0; for (let i = 0; i < value.length; i++) { hash = ((hash << 5) - hash + value.charCodeAt(i)) | 0; } return ('0000000' + (hash >>> 0).toString(16)).slice(-8); }, stringToBoolean: (value: KTOptionType): boolean | null => { if (typeof value === 'boolean') return value; if (typeof value !== 'string') return null; const cleanedStr = value.toLowerCase().trim(); if (cleanedStr === 'true') return true; if (cleanedStr === 'false') return false; return null; }, stringToObject: (value: KTOptionType): T | null => { if (value === null) { return null; } try { const parsed = JSON.parse(value.toString() as string); if (parsed && typeof parsed === 'object' && !Array.isArray(parsed)) { return parsed as T; } return null; } catch { return null; } }, stringToInteger: (value: KTOptionType | number): number | null => { // If already a number, return it as an integer if (typeof value === 'number' && !isNaN(value)) { return Math.floor(value); } // If not a string, return null if (typeof value !== 'string') return null; const cleanedStr = value.trim(); const num = parseInt(cleanedStr, 10); if (!isNaN(num) && cleanedStr !== '') { return num; } return null; }, stringToFloat: (value: KTOptionType | number): number | null => { // If already a number, return it as is if (typeof value === 'number' && !isNaN(value)) { return value; } // If not a string, return null if (typeof value !== 'string') return null; const cleanedStr = value.trim(); const num = parseFloat(cleanedStr); if (!isNaN(num) && cleanedStr !== '') { return num; } return null; }, }; export default KTUtils;