@studiocubics/utils 0.0.2 → 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- "use strict";Object.defineProperty(exports, "__esModule", {value: true});// src/API/apiRes.ts
1
+ // src/API/apiRes.ts
2
2
  var apiRes = {
3
3
  actionFail: (error, fieldErrors) => ({
4
4
  success: false,
@@ -326,22 +326,22 @@ function cssSafeString(str) {
326
326
  }
327
327
  return encoded;
328
328
  }
329
-
330
-
331
-
332
-
333
-
334
-
335
-
336
-
337
-
338
-
339
-
340
-
341
-
342
-
343
-
344
-
345
-
346
- exports.apiRes = apiRes; exports.calculateSafePosition = calculateSafePosition; exports.cn = cn; exports.cssSafeString = cssSafeString; exports.delay = delay; exports.formatDate = formatDate; exports.initialiseForm = initialiseForm; exports.mergeRefs = mergeRefs; exports.relativeTime = relativeTime; exports.remap = remap; exports.toCamelCase = toCamelCase; exports.toCapitalCase = toCapitalCase; exports.toCapitalised = toCapitalised; exports.toConstantCase = toConstantCase; exports.toKebabCase = toKebabCase; exports.toSnakeCase = toSnakeCase;
329
+ export {
330
+ apiRes,
331
+ calculateSafePosition,
332
+ cn,
333
+ cssSafeString,
334
+ delay,
335
+ formatDate,
336
+ initialiseForm,
337
+ mergeRefs,
338
+ relativeTime,
339
+ remap,
340
+ toCamelCase,
341
+ toCapitalCase,
342
+ toCapitalised,
343
+ toConstantCase,
344
+ toKebabCase,
345
+ toSnakeCase
346
+ };
347
347
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["/home/runner/work/StudioCubics/StudioCubics/packages/utils/dist/index.js","../src/API/apiRes.ts","../src/Calculations/calculateSafePosition.ts","../src/Code/delay.ts","../src/Dates/relativeTime.ts","../src/Dates/formateDate.ts","../src/Forms/initialiseForm.ts","../src/Numbers/remap.ts","../src/React/mergeRefs.ts","../src/Strings/cn.ts","../src/Strings/stringCases.ts","../src/Strings/cssSafeString.ts"],"names":[],"mappings":"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","file":"/home/runner/work/StudioCubics/StudioCubics/packages/utils/dist/index.js","sourcesContent":[null,"export type ActionResponse<K extends string = string, E extends K[] = K[]> = {\n success: boolean;\n payload?: unknown;\n error?: string;\n fieldErrors?: Record<K, E>;\n};\n\nexport const apiRes = {\n actionFail: <K extends string = string>(\n error: ActionResponse<K>[\"error\"],\n fieldErrors?: Record<string, string[]>\n ): ActionResponse<K> => ({\n success: false,\n error,\n fieldErrors: fieldErrors as ActionResponse<K>[\"fieldErrors\"],\n }),\n actionSuccess: <K extends string = string>(\n payload?: unknown\n ): ActionResponse<K> => ({\n success: true,\n payload,\n }),\n /**\n * \"Failed to fetch data!\"\n */\n apiError: (message?: string) => (message ? message : \"Failed to fetch data!\"),\n /**\n * \"You are not authenticated to access this resource.\"\n */\n unauthorised: \"You are not authenticated to access this resource.\",\n /**\n * \"You do not have the necessary permissions to access this resource.\"\n */\n forbidden:\n \"You do not have the necessary permissions to access this resource.\",\n /**\n * \"${item} is of wrong type, expected type: ${expectedType}\"\n */\n wrongType: (item: string, expectedType?: string) =>\n `${item} is of wrong type${expectedType ? `, expected type: ${expectedType}` : \"\"}.`,\n /**\n * \"An error occured trying to read the formdata in these fields:\n * ${fields}.\"\n */\n formdataError: (fields: string | string[]) =>\n `An error occured trying to read the formdata in these fields:\\n${JSON.stringify(fields)}.`,\n /**\n * \"Missing parameter: ${param}.\"\n */\n missingParams: (param: string | string[]) =>\n `Missing parameter: ${JSON.stringify(param)}.`,\n /**\n * \"${item} not found!\"\n */\n notFound: (item: string) => `${item} not found!`,\n /**\n * \"${item} already exists!\"\n */\n alreadyExists: (item: string) => `${item} already exists!`,\n /**\n * \"${contentName} size exceeded the maximum of ${maxSize}\"\n */\n contentTooLarge: (contentName: string, maxSize?: string) =>\n `${contentName} size exceeded${\n maxSize ? ` the maximum of ${maxSize}` : \"\"\n }.`,\n /**\n * An API Error has occurred:\n * Check here => ${location}\n * More Info: ${errorMessage}\n */\n generalError: (location: string, errorMessage: string = \"\") =>\n `An API Error has occurred:\\nCheck here => ${location}\\nMore Info: ${errorMessage}`,\n};\n","type VerticalOrigin = \"top\" | \"center\" | \"bottom\";\ntype HorizontalOrigin = \"left\" | \"center\" | \"right\";\n\ninterface ParsedOrigin {\n vertical: VerticalOrigin;\n horizontal: HorizontalOrigin;\n}\n\nexport interface SafePositionOptions {\n anchorOrigin?: string;\n transformOrigin?: string;\n margin?: number;\n}\n\nexport interface Position {\n x: number;\n y: number;\n}\n\n/**\n * Calculates safe position of an element within viewport relative to an anchor element\n * Works like Material UI Popover positioning:\n * - anchorOrigin: point on the anchor element (e.g., \"top center\" = top-center of anchor)\n * - transformOrigin: point on the positioned element that attaches to anchor (e.g., \"bottom center\" = bottom-center of popup attaches to anchor point)\n *\n * Example: anchorOrigin \"top center\" + transformOrigin \"bottom center\" positions popup above and centered\n *\n * @param element - The element to position\n * @param anchorElement - The anchor element to position relative to\n * @param options - Configuration options\n * @returns Safe x, y coordinates\n */\nexport function calculateSafePosition(\n element: HTMLElement | null,\n anchorElement: HTMLElement | null,\n options: SafePositionOptions = {}\n): Position {\n const {\n anchorOrigin = \"top left\",\n transformOrigin = \"top left\",\n margin = 0,\n } = options;\n\n if (!element || !anchorElement) return { x: 0, y: 0 };\n\n const parseOrigin = (origin: string): ParsedOrigin => {\n const parts = origin.toLowerCase().trim().split(/\\s+/);\n let vertical: VerticalOrigin = \"top\";\n let horizontal: HorizontalOrigin = \"left\";\n\n for (const part of parts) {\n if ([\"top\", \"bottom\"].includes(part)) vertical = part as VerticalOrigin;\n else if ([\"left\", \"right\"].includes(part))\n horizontal = part as HorizontalOrigin;\n else if (part === \"center\") {\n // Assign center depending on position in string\n if (parts.length === 1) {\n vertical = \"center\";\n horizontal = \"center\";\n } else if ([\"top\", \"bottom\"].includes(parts[0])) horizontal = \"center\";\n else vertical = \"center\";\n }\n }\n\n return { vertical, horizontal };\n };\n\n const getAnchorOffset = (\n size: number,\n origin: VerticalOrigin | HorizontalOrigin\n ): number => {\n if (origin === \"center\") return size / 2;\n if (origin === \"bottom\" || origin === \"right\") return size;\n return 0; // top or left\n };\n\n const getTransformOffset = (\n size: number,\n origin: VerticalOrigin | HorizontalOrigin\n ): number => {\n if (origin === \"center\") return size / 2;\n if (origin === \"bottom\" || origin === \"right\") return size;\n return 0; // top or left\n };\n\n const elementRect = element.getBoundingClientRect();\n const anchorRect = anchorElement.getBoundingClientRect();\n const viewportWidth = window.innerWidth;\n const viewportHeight = window.innerHeight;\n\n const anchor = parseOrigin(anchorOrigin);\n const transform = parseOrigin(transformOrigin);\n\n // Calculate anchor point on the anchor element\n const anchorX =\n anchorRect.left + getAnchorOffset(anchorRect.width, anchor.horizontal);\n const anchorY =\n anchorRect.top + getAnchorOffset(anchorRect.height, anchor.vertical);\n\n // Calculate where on the element we're attaching (transform origin point)\n const elementOriginX = getTransformOffset(\n elementRect.width,\n transform.horizontal\n );\n const elementOriginY = getTransformOffset(\n elementRect.height,\n transform.vertical\n );\n\n // Position the element so its transform origin aligns with the anchor point\n let x = anchorX - elementOriginX;\n let y = anchorY - elementOriginY;\n\n // Check and adjust for viewport boundaries with margin\n // Right boundary\n if (x + elementRect.width > viewportWidth - margin) {\n x = viewportWidth - elementRect.width - margin;\n }\n // Left boundary\n if (x < margin) {\n x = margin;\n }\n\n // Bottom boundary\n if (y + elementRect.height > viewportHeight - margin) {\n y = viewportHeight - elementRect.height - margin;\n }\n // Top boundary\n if (y < margin) {\n y = margin;\n }\n\n return {\n x: Math.max(margin, x),\n y: Math.max(margin, y),\n };\n}\n","/**\n * Delays the program loop for the given amount of milliseconds\n */\nexport const delay = (ms: number) =>\n new Promise((resolve) => setTimeout(resolve, ms));\n","/**\n * Returns a human-readable relative time string vs Date.now().\n * Accepts Date | number (ms) | date-string.\n * Fast, allocation-light, no Intl.\n */\nexport function relativeTime(\n input: Date | number | string\n): string {\n const t: number =\n input instanceof Date\n ? input.getTime()\n : typeof input === \"number\"\n ? input\n : Date.parse(input);\n\n if (!Number.isFinite(t)) return \"invalid date\";\n\n const now = Date.now();\n const diffMs = t - now;\n const absMs = Math.abs(diffMs);\n const isFuture = diffMs > 0;\n\n // time constants (ms)\n const MIN = 60_000;\n const HOUR = 3_600_000;\n const DAY = 86_400_000;\n const WEEK = 604_800_000;\n const YEAR = 31_536_000_000;\n\n // very far away → coarse wording\n if (absMs > 5 * YEAR) {\n return isFuture ? \"a long time from now\" : \"a long time ago\";\n }\n\n if (absMs < MIN) {\n return \"just now\";\n }\n\n let value: number;\n let unit: \"minute\" | \"hour\" | \"day\" | \"week\" | \"year\";\n\n if (absMs < HOUR) {\n value = Math.round(absMs / MIN);\n unit = \"minute\";\n } else if (absMs < DAY) {\n value = Math.round(absMs / HOUR);\n unit = \"hour\";\n } else if (absMs < WEEK) {\n value = Math.round(absMs / DAY);\n unit = \"day\";\n } else if (absMs < YEAR) {\n value = Math.round(absMs / WEEK);\n unit = \"week\";\n } else {\n value = Math.round(absMs / YEAR);\n unit = \"year\";\n }\n\n if (value !== 1) unit += \"s\";\n\n return isFuture\n ? `in ${value} ${unit}`\n : `${value} ${unit} ago`;\n}\n","type DateToken =\n | \"Day\"\n | \"day\"\n | \"DD\"\n | \"D\"\n | \"MMMM\"\n | \"MMM\"\n | \"MM\"\n | \"YYYY\"\n | \"YY\"\n | \"HH\"\n | \"H\"\n | \"hh\"\n | \"h\"\n | \"mm\"\n | \"m\"\n | \"ss\"\n | \"s\"\n | \"A\"\n | \"a\";\n\n/**\n * Formats a date according to the provided format string.\n *\n * @param dateInput - The date to format (as Date object, timestamp, or date string)\n * @param format - The format string using tokens (default: \"day D MMM, YYYY\")\n *\n * @returns The formatted date string\n *\n * @example\n * formatDate(new Date(), \"Day, DD MMMM YYYY\")\n * // => \"Thursday, 02 January 2026\"\n *\n * @example\n * formatDate(new Date(), \"DD/MM/YYYY HH:mm:ss\")\n * // => \"02/01/2026 14:30:45\"\n *\n * @example\n * formatDate(new Date(), \"h:mm A\")\n * // => \"2:30 PM\"\n *\n * Available tokens:\n * - Day: Full day name (e.g., \"Monday\")\n * - day: Short day name (e.g., \"Mon\")\n * - DD: Day of month, zero-padded (e.g., \"05\")\n * - D: Day of month (e.g., \"5\")\n * - MMMM: Full month name (e.g., \"January\")\n * - MMM: Short month name (e.g., \"Jan\")\n * - MM: Month number, zero-padded (e.g., \"01\")\n * - YYYY: Full year (e.g., \"2026\")\n * - YY: Two-digit year (e.g., \"26\")\n * - HH: Hours (24-hour), zero-padded (e.g., \"14\")\n * - H: Hours (24-hour) (e.g., \"14\")\n * - hh: Hours (12-hour), zero-padded (e.g., \"02\")\n * - h: Hours (12-hour) (e.g., \"2\")\n * - mm: Minutes, zero-padded (e.g., \"05\")\n * - m: Minutes (e.g., \"5\")\n * - ss: Seconds, zero-padded (e.g., \"09\")\n * - s: Seconds (e.g., \"9\")\n * - A: AM/PM uppercase (e.g., \"PM\")\n * - a: am/pm lowercase (e.g., \"pm\")\n */\nexport function formatDate(\n dateInput: number | string | Date,\n format: string = \"HH:mm:ss day D MMM, YYYY\"\n) {\n const date = new Date(dateInput);\n\n const pad = (n: number) => String(n).padStart(2, \"0\");\n\n const daysFull = [\n \"Sunday\",\n \"Monday\",\n \"Tuesday\",\n \"Wednesday\",\n \"Thursday\",\n \"Friday\",\n \"Saturday\",\n ];\n const daysShort = [\"Sun\", \"Mon\", \"Tue\", \"Wed\", \"Thu\", \"Fri\", \"Sat\"];\n const monthsFull = [\n \"January\",\n \"February\",\n \"March\",\n \"April\",\n \"May\",\n \"June\",\n \"July\",\n \"August\",\n \"September\",\n \"October\",\n \"November\",\n \"December\",\n ];\n const monthsShort = monthsFull.map((m) => m.slice(0, 3));\n\n // Extract all values once\n const dayIndex = date.getDay();\n const dateNum = date.getDate();\n const monthIndex = date.getMonth();\n const year = date.getFullYear();\n const hours24 = date.getHours();\n const minutes = date.getMinutes();\n const seconds = date.getSeconds();\n\n const hours12 = hours24 % 12 || 12;\n const isPM = hours24 >= 12;\n const yearStr = String(year);\n\n const replacements: Record<DateToken, string> = {\n Day: daysFull[dayIndex],\n day: daysShort[dayIndex],\n DD: pad(dateNum),\n D: String(dateNum),\n MMMM: monthsFull[monthIndex],\n MMM: monthsShort[monthIndex],\n MM: pad(monthIndex + 1),\n YYYY: yearStr,\n YY: yearStr.slice(-2),\n HH: pad(hours24),\n H: String(hours24),\n hh: pad(hours12),\n h: String(hours12),\n mm: pad(minutes),\n m: String(minutes),\n ss: pad(seconds),\n s: String(seconds),\n A: isPM ? \"PM\" : \"AM\",\n a: isPM ? \"pm\" : \"am\",\n };\n\n // Sort tokens by length (longest first) to avoid partial replacements\n const tokens = (Object.keys(replacements) as DateToken[]).sort(\n (a, b) => b.length - a.length\n );\n\n // Use a single regex replacement to avoid overlapping matches\n const pattern = new RegExp(tokens.join(\"|\"), \"g\");\n return format.replace(pattern, (match) => replacements[match as DateToken]);\n}\n","import type { ActionResponse } from \"../API/apiRes\";\n\nexport function initialiseForm<T extends string = string>(\n ...fieldNames: T[]\n): ActionResponse<T, T[]> {\n let fieldErrors = {} as Record<T, T[]>;\n for (const fieldName of fieldNames) {\n fieldErrors[fieldName] = [] as T[];\n }\n return {\n success: false,\n fieldErrors,\n };\n}\n","/**\n * This function returns the rounded corresponding value in the target range using linear interpolation.\n *\n * @param value - The input value to remap.\n * @param from - The source range as a tuple [min, max].\n * @param to - The target range as a tuple [min, max].\n * @returns The remapped value in the target range.\n *\n * @example\n * remap(3, [1, 10], [1, 5]); // 2\n */\nexport function remap(\n value: number,\n from: [number, number],\n to: [number, number],\n roundTo: \"floor\" | \"ceil\" = \"floor\",\n): number {\n const [fromMin, fromMax] = from;\n const [toMin, toMax] = to;\n\n if (roundTo == \"ceil\")\n return Math.ceil(\n toMin + ((value - fromMin) * (toMax - toMin)) / (fromMax - fromMin),\n );\n return Math.floor(\n toMin + ((value - fromMin) * (toMax - toMin)) / (fromMax - fromMin),\n );\n}\n","import type { RefObject, Ref } from \"react\";\n\nexport function mergeRefs<T>(\n ...refs: (Ref<T> | undefined)[]\n): (instance: T | null) => void {\n return (instance) => {\n for (const ref of refs) {\n if (!ref) continue;\n if (typeof ref === \"function\") {\n ref(instance);\n } else {\n (ref as RefObject<T | null>).current = instance;\n }\n }\n };\n}\n","export function cn(...classNames: (string | undefined)[]) {\n return classNames.filter((c) => c).join(\" \");\n}\n","function toWords(str: string): string[] {\n return str\n .replace(/([a-z])([A-Z])/g, \"$1 $2\") // camelCase → camel Case\n .replace(/[_\\-]+/g, \" \") // snake_case, kebab-case → spaces\n .trim()\n .split(/\\s+/)\n .filter(Boolean)\n .map((w) => w.toLowerCase());\n}\n\nexport function toCapitalCase(str: string | undefined): string {\n if (!str) return \"\";\n const words = toWords(str);\n return words.map((w) => w[0].toUpperCase() + w.slice(1)).join(\"\");\n}\n\nexport function toCamelCase(str: string | undefined): string {\n if (!str) return \"\";\n\n const words = toWords(str);\n return words\n .map((w, i) => (i === 0 ? w : w[0].toUpperCase() + w.slice(1)))\n .join(\"\");\n}\n\nexport function toKebabCase(str: string | undefined): string {\n if (!str) return \"\";\n\n return toWords(str).join(\"-\");\n}\n\nexport function toSnakeCase(str: string | undefined): string {\n if (!str) return \"\";\n\n return toWords(str).join(\"_\");\n}\n\nexport function toConstantCase(str: string | undefined): string {\n if (!str) return \"\";\n\n return toWords(str).join(\"_\").toUpperCase();\n}\n\nexport function toCapitalised(str: string | undefined): string {\n if (!str) return \"\";\n\n const words = toWords(str);\n if (words.length === 0) return \"\";\n return words.map((w) => w[0].toUpperCase() + w.slice(1)).join(\" \");\n}\n","export function cssSafeString(str: string) {\n const encoded = encodeURIComponent(str)\n .toLowerCase()\n .replace(/\\.|%[0-9a-z]{2}/gi, \"\");\n\n const firstChar = encoded.charAt(0);\n if (firstChar.match(/^[0-9-]/)) {\n // Check if the first character is a number or hyphen\n return \"_\" + encoded;\n }\n\n return encoded;\n}\n"]}
1
+ {"version":3,"sources":["../src/API/apiRes.ts","../src/Calculations/calculateSafePosition.ts","../src/Code/delay.ts","../src/Dates/relativeTime.ts","../src/Dates/formateDate.ts","../src/Forms/initialiseForm.ts","../src/Numbers/remap.ts","../src/React/mergeRefs.ts","../src/Strings/cn.ts","../src/Strings/stringCases.ts","../src/Strings/cssSafeString.ts"],"sourcesContent":["export type ActionResponse<K extends string = string, E extends K[] = K[]> = {\n success: boolean;\n payload?: unknown;\n error?: string;\n fieldErrors?: Record<K, E>;\n};\n\nexport const apiRes = {\n actionFail: <K extends string = string>(\n error: ActionResponse<K>[\"error\"],\n fieldErrors?: Record<string, string[]>\n ): ActionResponse<K> => ({\n success: false,\n error,\n fieldErrors: fieldErrors as ActionResponse<K>[\"fieldErrors\"],\n }),\n actionSuccess: <K extends string = string>(\n payload?: unknown\n ): ActionResponse<K> => ({\n success: true,\n payload,\n }),\n /**\n * \"Failed to fetch data!\"\n */\n apiError: (message?: string) => (message ? message : \"Failed to fetch data!\"),\n /**\n * \"You are not authenticated to access this resource.\"\n */\n unauthorised: \"You are not authenticated to access this resource.\",\n /**\n * \"You do not have the necessary permissions to access this resource.\"\n */\n forbidden:\n \"You do not have the necessary permissions to access this resource.\",\n /**\n * \"${item} is of wrong type, expected type: ${expectedType}\"\n */\n wrongType: (item: string, expectedType?: string) =>\n `${item} is of wrong type${expectedType ? `, expected type: ${expectedType}` : \"\"}.`,\n /**\n * \"An error occured trying to read the formdata in these fields:\n * ${fields}.\"\n */\n formdataError: (fields: string | string[]) =>\n `An error occured trying to read the formdata in these fields:\\n${JSON.stringify(fields)}.`,\n /**\n * \"Missing parameter: ${param}.\"\n */\n missingParams: (param: string | string[]) =>\n `Missing parameter: ${JSON.stringify(param)}.`,\n /**\n * \"${item} not found!\"\n */\n notFound: (item: string) => `${item} not found!`,\n /**\n * \"${item} already exists!\"\n */\n alreadyExists: (item: string) => `${item} already exists!`,\n /**\n * \"${contentName} size exceeded the maximum of ${maxSize}\"\n */\n contentTooLarge: (contentName: string, maxSize?: string) =>\n `${contentName} size exceeded${\n maxSize ? ` the maximum of ${maxSize}` : \"\"\n }.`,\n /**\n * An API Error has occurred:\n * Check here => ${location}\n * More Info: ${errorMessage}\n */\n generalError: (location: string, errorMessage: string = \"\") =>\n `An API Error has occurred:\\nCheck here => ${location}\\nMore Info: ${errorMessage}`,\n};\n","type VerticalOrigin = \"top\" | \"center\" | \"bottom\";\ntype HorizontalOrigin = \"left\" | \"center\" | \"right\";\n\ninterface ParsedOrigin {\n vertical: VerticalOrigin;\n horizontal: HorizontalOrigin;\n}\n\nexport interface SafePositionOptions {\n anchorOrigin?: string;\n transformOrigin?: string;\n margin?: number;\n}\n\nexport interface Position {\n x: number;\n y: number;\n}\n\n/**\n * Calculates safe position of an element within viewport relative to an anchor element\n * Works like Material UI Popover positioning:\n * - anchorOrigin: point on the anchor element (e.g., \"top center\" = top-center of anchor)\n * - transformOrigin: point on the positioned element that attaches to anchor (e.g., \"bottom center\" = bottom-center of popup attaches to anchor point)\n *\n * Example: anchorOrigin \"top center\" + transformOrigin \"bottom center\" positions popup above and centered\n *\n * @param element - The element to position\n * @param anchorElement - The anchor element to position relative to\n * @param options - Configuration options\n * @returns Safe x, y coordinates\n */\nexport function calculateSafePosition(\n element: HTMLElement | null,\n anchorElement: HTMLElement | null,\n options: SafePositionOptions = {}\n): Position {\n const {\n anchorOrigin = \"top left\",\n transformOrigin = \"top left\",\n margin = 0,\n } = options;\n\n if (!element || !anchorElement) return { x: 0, y: 0 };\n\n const parseOrigin = (origin: string): ParsedOrigin => {\n const parts = origin.toLowerCase().trim().split(/\\s+/);\n let vertical: VerticalOrigin = \"top\";\n let horizontal: HorizontalOrigin = \"left\";\n\n for (const part of parts) {\n if ([\"top\", \"bottom\"].includes(part)) vertical = part as VerticalOrigin;\n else if ([\"left\", \"right\"].includes(part))\n horizontal = part as HorizontalOrigin;\n else if (part === \"center\") {\n // Assign center depending on position in string\n if (parts.length === 1) {\n vertical = \"center\";\n horizontal = \"center\";\n } else if ([\"top\", \"bottom\"].includes(parts[0])) horizontal = \"center\";\n else vertical = \"center\";\n }\n }\n\n return { vertical, horizontal };\n };\n\n const getAnchorOffset = (\n size: number,\n origin: VerticalOrigin | HorizontalOrigin\n ): number => {\n if (origin === \"center\") return size / 2;\n if (origin === \"bottom\" || origin === \"right\") return size;\n return 0; // top or left\n };\n\n const getTransformOffset = (\n size: number,\n origin: VerticalOrigin | HorizontalOrigin\n ): number => {\n if (origin === \"center\") return size / 2;\n if (origin === \"bottom\" || origin === \"right\") return size;\n return 0; // top or left\n };\n\n const elementRect = element.getBoundingClientRect();\n const anchorRect = anchorElement.getBoundingClientRect();\n const viewportWidth = window.innerWidth;\n const viewportHeight = window.innerHeight;\n\n const anchor = parseOrigin(anchorOrigin);\n const transform = parseOrigin(transformOrigin);\n\n // Calculate anchor point on the anchor element\n const anchorX =\n anchorRect.left + getAnchorOffset(anchorRect.width, anchor.horizontal);\n const anchorY =\n anchorRect.top + getAnchorOffset(anchorRect.height, anchor.vertical);\n\n // Calculate where on the element we're attaching (transform origin point)\n const elementOriginX = getTransformOffset(\n elementRect.width,\n transform.horizontal\n );\n const elementOriginY = getTransformOffset(\n elementRect.height,\n transform.vertical\n );\n\n // Position the element so its transform origin aligns with the anchor point\n let x = anchorX - elementOriginX;\n let y = anchorY - elementOriginY;\n\n // Check and adjust for viewport boundaries with margin\n // Right boundary\n if (x + elementRect.width > viewportWidth - margin) {\n x = viewportWidth - elementRect.width - margin;\n }\n // Left boundary\n if (x < margin) {\n x = margin;\n }\n\n // Bottom boundary\n if (y + elementRect.height > viewportHeight - margin) {\n y = viewportHeight - elementRect.height - margin;\n }\n // Top boundary\n if (y < margin) {\n y = margin;\n }\n\n return {\n x: Math.max(margin, x),\n y: Math.max(margin, y),\n };\n}\n","/**\n * Delays the program loop for the given amount of milliseconds\n */\nexport const delay = (ms: number) =>\n new Promise((resolve) => setTimeout(resolve, ms));\n","/**\n * Returns a human-readable relative time string vs Date.now().\n * Accepts Date | number (ms) | date-string.\n * Fast, allocation-light, no Intl.\n */\nexport function relativeTime(\n input: Date | number | string\n): string {\n const t: number =\n input instanceof Date\n ? input.getTime()\n : typeof input === \"number\"\n ? input\n : Date.parse(input);\n\n if (!Number.isFinite(t)) return \"invalid date\";\n\n const now = Date.now();\n const diffMs = t - now;\n const absMs = Math.abs(diffMs);\n const isFuture = diffMs > 0;\n\n // time constants (ms)\n const MIN = 60_000;\n const HOUR = 3_600_000;\n const DAY = 86_400_000;\n const WEEK = 604_800_000;\n const YEAR = 31_536_000_000;\n\n // very far away → coarse wording\n if (absMs > 5 * YEAR) {\n return isFuture ? \"a long time from now\" : \"a long time ago\";\n }\n\n if (absMs < MIN) {\n return \"just now\";\n }\n\n let value: number;\n let unit: \"minute\" | \"hour\" | \"day\" | \"week\" | \"year\";\n\n if (absMs < HOUR) {\n value = Math.round(absMs / MIN);\n unit = \"minute\";\n } else if (absMs < DAY) {\n value = Math.round(absMs / HOUR);\n unit = \"hour\";\n } else if (absMs < WEEK) {\n value = Math.round(absMs / DAY);\n unit = \"day\";\n } else if (absMs < YEAR) {\n value = Math.round(absMs / WEEK);\n unit = \"week\";\n } else {\n value = Math.round(absMs / YEAR);\n unit = \"year\";\n }\n\n if (value !== 1) unit += \"s\";\n\n return isFuture\n ? `in ${value} ${unit}`\n : `${value} ${unit} ago`;\n}\n","type DateToken =\n | \"Day\"\n | \"day\"\n | \"DD\"\n | \"D\"\n | \"MMMM\"\n | \"MMM\"\n | \"MM\"\n | \"YYYY\"\n | \"YY\"\n | \"HH\"\n | \"H\"\n | \"hh\"\n | \"h\"\n | \"mm\"\n | \"m\"\n | \"ss\"\n | \"s\"\n | \"A\"\n | \"a\";\n\n/**\n * Formats a date according to the provided format string.\n *\n * @param dateInput - The date to format (as Date object, timestamp, or date string)\n * @param format - The format string using tokens (default: \"day D MMM, YYYY\")\n *\n * @returns The formatted date string\n *\n * @example\n * formatDate(new Date(), \"Day, DD MMMM YYYY\")\n * // => \"Thursday, 02 January 2026\"\n *\n * @example\n * formatDate(new Date(), \"DD/MM/YYYY HH:mm:ss\")\n * // => \"02/01/2026 14:30:45\"\n *\n * @example\n * formatDate(new Date(), \"h:mm A\")\n * // => \"2:30 PM\"\n *\n * Available tokens:\n * - Day: Full day name (e.g., \"Monday\")\n * - day: Short day name (e.g., \"Mon\")\n * - DD: Day of month, zero-padded (e.g., \"05\")\n * - D: Day of month (e.g., \"5\")\n * - MMMM: Full month name (e.g., \"January\")\n * - MMM: Short month name (e.g., \"Jan\")\n * - MM: Month number, zero-padded (e.g., \"01\")\n * - YYYY: Full year (e.g., \"2026\")\n * - YY: Two-digit year (e.g., \"26\")\n * - HH: Hours (24-hour), zero-padded (e.g., \"14\")\n * - H: Hours (24-hour) (e.g., \"14\")\n * - hh: Hours (12-hour), zero-padded (e.g., \"02\")\n * - h: Hours (12-hour) (e.g., \"2\")\n * - mm: Minutes, zero-padded (e.g., \"05\")\n * - m: Minutes (e.g., \"5\")\n * - ss: Seconds, zero-padded (e.g., \"09\")\n * - s: Seconds (e.g., \"9\")\n * - A: AM/PM uppercase (e.g., \"PM\")\n * - a: am/pm lowercase (e.g., \"pm\")\n */\nexport function formatDate(\n dateInput: number | string | Date,\n format: string = \"HH:mm:ss day D MMM, YYYY\"\n) {\n const date = new Date(dateInput);\n\n const pad = (n: number) => String(n).padStart(2, \"0\");\n\n const daysFull = [\n \"Sunday\",\n \"Monday\",\n \"Tuesday\",\n \"Wednesday\",\n \"Thursday\",\n \"Friday\",\n \"Saturday\",\n ];\n const daysShort = [\"Sun\", \"Mon\", \"Tue\", \"Wed\", \"Thu\", \"Fri\", \"Sat\"];\n const monthsFull = [\n \"January\",\n \"February\",\n \"March\",\n \"April\",\n \"May\",\n \"June\",\n \"July\",\n \"August\",\n \"September\",\n \"October\",\n \"November\",\n \"December\",\n ];\n const monthsShort = monthsFull.map((m) => m.slice(0, 3));\n\n // Extract all values once\n const dayIndex = date.getDay();\n const dateNum = date.getDate();\n const monthIndex = date.getMonth();\n const year = date.getFullYear();\n const hours24 = date.getHours();\n const minutes = date.getMinutes();\n const seconds = date.getSeconds();\n\n const hours12 = hours24 % 12 || 12;\n const isPM = hours24 >= 12;\n const yearStr = String(year);\n\n const replacements: Record<DateToken, string> = {\n Day: daysFull[dayIndex],\n day: daysShort[dayIndex],\n DD: pad(dateNum),\n D: String(dateNum),\n MMMM: monthsFull[monthIndex],\n MMM: monthsShort[monthIndex],\n MM: pad(monthIndex + 1),\n YYYY: yearStr,\n YY: yearStr.slice(-2),\n HH: pad(hours24),\n H: String(hours24),\n hh: pad(hours12),\n h: String(hours12),\n mm: pad(minutes),\n m: String(minutes),\n ss: pad(seconds),\n s: String(seconds),\n A: isPM ? \"PM\" : \"AM\",\n a: isPM ? \"pm\" : \"am\",\n };\n\n // Sort tokens by length (longest first) to avoid partial replacements\n const tokens = (Object.keys(replacements) as DateToken[]).sort(\n (a, b) => b.length - a.length\n );\n\n // Use a single regex replacement to avoid overlapping matches\n const pattern = new RegExp(tokens.join(\"|\"), \"g\");\n return format.replace(pattern, (match) => replacements[match as DateToken]);\n}\n","import type { ActionResponse } from \"../API/apiRes\";\n\nexport function initialiseForm<T extends string = string>(\n ...fieldNames: T[]\n): ActionResponse<T, T[]> {\n let fieldErrors = {} as Record<T, T[]>;\n for (const fieldName of fieldNames) {\n fieldErrors[fieldName] = [] as T[];\n }\n return {\n success: false,\n fieldErrors,\n };\n}\n","/**\n * This function returns the rounded corresponding value in the target range using linear interpolation.\n *\n * @param value - The input value to remap.\n * @param from - The source range as a tuple [min, max].\n * @param to - The target range as a tuple [min, max].\n * @returns The remapped value in the target range.\n *\n * @example\n * remap(3, [1, 10], [1, 5]); // 2\n */\nexport function remap(\n value: number,\n from: [number, number],\n to: [number, number],\n roundTo: \"floor\" | \"ceil\" = \"floor\",\n): number {\n const [fromMin, fromMax] = from;\n const [toMin, toMax] = to;\n\n if (roundTo == \"ceil\")\n return Math.ceil(\n toMin + ((value - fromMin) * (toMax - toMin)) / (fromMax - fromMin),\n );\n return Math.floor(\n toMin + ((value - fromMin) * (toMax - toMin)) / (fromMax - fromMin),\n );\n}\n","import type { RefObject, Ref } from \"react\";\n\nexport function mergeRefs<T>(\n ...refs: (Ref<T> | undefined)[]\n): (instance: T | null) => void {\n return (instance) => {\n for (const ref of refs) {\n if (!ref) continue;\n if (typeof ref === \"function\") {\n ref(instance);\n } else {\n (ref as RefObject<T | null>).current = instance;\n }\n }\n };\n}\n","export function cn(...classNames: (string | undefined)[]) {\n return classNames.filter((c) => c).join(\" \");\n}\n","function toWords(str: string): string[] {\n return str\n .replace(/([a-z])([A-Z])/g, \"$1 $2\") // camelCase → camel Case\n .replace(/[_\\-]+/g, \" \") // snake_case, kebab-case → spaces\n .trim()\n .split(/\\s+/)\n .filter(Boolean)\n .map((w) => w.toLowerCase());\n}\n\nexport function toCapitalCase(str: string | undefined): string {\n if (!str) return \"\";\n const words = toWords(str);\n return words.map((w) => w[0].toUpperCase() + w.slice(1)).join(\"\");\n}\n\nexport function toCamelCase(str: string | undefined): string {\n if (!str) return \"\";\n\n const words = toWords(str);\n return words\n .map((w, i) => (i === 0 ? w : w[0].toUpperCase() + w.slice(1)))\n .join(\"\");\n}\n\nexport function toKebabCase(str: string | undefined): string {\n if (!str) return \"\";\n\n return toWords(str).join(\"-\");\n}\n\nexport function toSnakeCase(str: string | undefined): string {\n if (!str) return \"\";\n\n return toWords(str).join(\"_\");\n}\n\nexport function toConstantCase(str: string | undefined): string {\n if (!str) return \"\";\n\n return toWords(str).join(\"_\").toUpperCase();\n}\n\nexport function toCapitalised(str: string | undefined): string {\n if (!str) return \"\";\n\n const words = toWords(str);\n if (words.length === 0) return \"\";\n return words.map((w) => w[0].toUpperCase() + w.slice(1)).join(\" \");\n}\n","export function cssSafeString(str: string) {\n const encoded = encodeURIComponent(str)\n .toLowerCase()\n .replace(/\\.|%[0-9a-z]{2}/gi, \"\");\n\n const firstChar = encoded.charAt(0);\n if (firstChar.match(/^[0-9-]/)) {\n // Check if the first character is a number or hyphen\n return \"_\" + encoded;\n }\n\n return encoded;\n}\n"],"mappings":"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","names":[]}
package/package.json CHANGED
@@ -5,12 +5,14 @@
5
5
  "access": "public"
6
6
  },
7
7
  "private": false,
8
- "version": "0.0.2",
9
- "main": "./dist/index.js",
8
+ "version": "0.0.3",
9
+ "type": "module",
10
10
  "exports": {
11
- ".": "./dist/index.js"
11
+ ".": {
12
+ "types": "./dist/index.d.ts",
13
+ "default": "./dist/index.js"
14
+ }
12
15
  },
13
- "types": "./dist/index.d.ts",
14
16
  "peerDependencies": {
15
17
  "react": ">= 19"
16
18
  },
package/tsup.config.ts CHANGED
@@ -2,6 +2,7 @@ import { defineConfig } from "tsup";
2
2
 
3
3
  export default defineConfig({
4
4
  entry: ["src/index.ts"],
5
+ format: ["esm"],
5
6
  splitting: true,
6
7
  sourcemap: true,
7
8
  clean: true,