mirror of
https://github.com/linsa-io/linsa.git
synced 2026-02-24 03:14:55 +01:00
78 lines
2.0 KiB
TypeScript
78 lines
2.0 KiB
TypeScript
import * as React from "react"
|
|
import { clsx, type ClassValue } from "clsx"
|
|
import { twMerge } from "tailwind-merge"
|
|
|
|
export function cn(...inputs: ClassValue[]) {
|
|
return twMerge(clsx(inputs))
|
|
}
|
|
|
|
function escapeRegExp(string: string) {
|
|
return string.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")
|
|
}
|
|
|
|
export const searchSafeRegExp = (inputValue: string) => {
|
|
const escapedChars = inputValue.split("").map(escapeRegExp)
|
|
return new RegExp(escapedChars.join(".*"), "i")
|
|
}
|
|
|
|
export function shuffleArray<T>(array: T[]): T[] {
|
|
const shuffled = [...array]
|
|
for (let i = shuffled.length - 1; i > 0; i--) {
|
|
const j = Math.floor(Math.random() * (i + 1))
|
|
;[shuffled[i], shuffled[j]] = [shuffled[j], shuffled[i]]
|
|
}
|
|
return shuffled
|
|
}
|
|
|
|
const inputs = ["input", "select", "button", "textarea"] // detect if node is a text input element
|
|
|
|
export function isTextInput(element: Element): boolean {
|
|
return !!(
|
|
element &&
|
|
element.tagName &&
|
|
(inputs.indexOf(element.tagName.toLowerCase()) !== -1 ||
|
|
element.attributes.getNamedItem("role")?.value === "textbox" ||
|
|
element.attributes.getNamedItem("contenteditable")?.value === "true")
|
|
)
|
|
}
|
|
|
|
export type HTMLAttributes = React.HTMLAttributes<HTMLElement> & {
|
|
[key: string]: any
|
|
}
|
|
|
|
export type HTMLLikeElement = {
|
|
tag: keyof JSX.IntrinsicElements
|
|
attributes?: HTMLAttributes
|
|
children?: (HTMLLikeElement | string)[]
|
|
}
|
|
|
|
export const renderHTMLLikeElement = (
|
|
element: HTMLLikeElement | string,
|
|
): React.ReactNode => {
|
|
if (typeof element === "string") {
|
|
return element
|
|
}
|
|
|
|
const { tag, attributes = {}, children = [] } = element
|
|
|
|
return React.createElement(
|
|
tag,
|
|
attributes,
|
|
...children.map((child) => renderHTMLLikeElement(child)),
|
|
)
|
|
}
|
|
|
|
export function calendarFormatDate(date: Date): string {
|
|
return date.toLocaleDateString("en-US", {
|
|
year: "numeric",
|
|
month: "long",
|
|
day: "numeric",
|
|
})
|
|
}
|
|
|
|
export * from "./force-graph"
|
|
export * from "./env"
|
|
export * from "./slug"
|
|
export * from "./url"
|
|
export * from "./jazz"
|