mirror of
https://github.com/zoriya/v10.git
synced 2026-08-16 02:45:09 +00:00
fix: add popover core, use in html and improve factory (#204)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
@@ -17,12 +17,24 @@ export function namedNodeMapToObject(namedNodeMap: NamedNodeMap): Record<string,
|
||||
* @param element - The element to set attributes on.
|
||||
* @param attributes - The attributes to set.
|
||||
*/
|
||||
export function setAttributes(element: HTMLElement, attributes: Record<string, string>): void {
|
||||
export function setAttributes(element: HTMLElement, attributes: Record<string, any>): void {
|
||||
for (const [key, value] of Object.entries(attributes)) {
|
||||
if (typeof value === 'boolean') {
|
||||
element.toggleAttribute(key, value);
|
||||
if (key === 'style' && typeof value === 'object') {
|
||||
for (const [styleKey, styleValue] of Object.entries(value)) {
|
||||
if (typeof styleValue === 'string') {
|
||||
element.style.setProperty(styleKey, styleValue);
|
||||
} else if (styleValue == null) {
|
||||
element.style.removeProperty(styleKey);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
element.setAttribute(key, value);
|
||||
if (typeof value === 'boolean') {
|
||||
element.toggleAttribute(key, value);
|
||||
} else if (value === undefined) {
|
||||
element.removeAttribute(key);
|
||||
} else {
|
||||
element.setAttribute(key, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
export * from './shared/console';
|
||||
export * from './shared/crypto';
|
||||
export * from './shared/memoize';
|
||||
export * from './shared/state';
|
||||
export * from './shared/string';
|
||||
export * from './shared/time';
|
||||
export * from './shared/unit';
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
// Adapted from https://github.com/caiogondim/fast-memoize.js - MIT License
|
||||
type MemoizedFunction<T extends (...args: any[]) => any> = (
|
||||
...args: Parameters<T>
|
||||
) => ReturnType<T>;
|
||||
|
||||
interface MemoizedId {
|
||||
$m: number;
|
||||
}
|
||||
|
||||
interface MemoizedWithId {
|
||||
$m?: number;
|
||||
}
|
||||
|
||||
function isNode(x: unknown): boolean {
|
||||
if (typeof globalThis === 'undefined') return false;
|
||||
const NodeConstructor = (globalThis as { Node?: new () => unknown }).Node;
|
||||
return NodeConstructor !== undefined && x instanceof NodeConstructor;
|
||||
}
|
||||
|
||||
export function memoize<T extends (...args: any[]) => any>(
|
||||
func: T,
|
||||
): MemoizedFunction<T> {
|
||||
const cache: Record<string, ReturnType<T>> = {};
|
||||
return function (this: unknown, ...args: Parameters<T>): ReturnType<T> {
|
||||
const argsWithFuncIds = args.map((x) => {
|
||||
if (isPlainObject(x) || Array.isArray(x)) {
|
||||
const obj: Record<string, unknown> = {};
|
||||
for (const key in x) {
|
||||
obj[key] = memoizedIdFunc((x as Record<string, unknown>)[key]);
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
return memoizedIdFunc(x);
|
||||
});
|
||||
|
||||
const cacheKey = JSON.stringify(argsWithFuncIds);
|
||||
const cachedValue = cache[cacheKey];
|
||||
if (cachedValue !== undefined) {
|
||||
return cachedValue;
|
||||
}
|
||||
const computedValue = func.apply(this, args);
|
||||
cache[cacheKey] = computedValue;
|
||||
return computedValue;
|
||||
};
|
||||
}
|
||||
|
||||
let id = 0;
|
||||
function memoizedIdFunc(x: unknown): unknown {
|
||||
if (typeof x === 'function' || isNode(x)) {
|
||||
const funcOrNode = x as MemoizedWithId;
|
||||
if (!funcOrNode.$m) funcOrNode.$m = ++id;
|
||||
return { $m: funcOrNode.$m } as MemoizedId;
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if this is a plain object.
|
||||
* @param {object} obj - The object to inspect.
|
||||
* @return {boolean}
|
||||
*/
|
||||
function isPlainObject(obj: unknown): obj is Record<string, unknown> {
|
||||
if (typeof obj !== 'object' || obj === null) return false;
|
||||
|
||||
let proto = obj;
|
||||
while (Object.getPrototypeOf(proto) !== null) {
|
||||
proto = Object.getPrototypeOf(proto);
|
||||
}
|
||||
|
||||
return Object.getPrototypeOf(obj) === proto;
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
/**
|
||||
* Converts a string to camel case.
|
||||
*
|
||||
* @param str - The string to convert.
|
||||
* @returns The camel case string.
|
||||
*/
|
||||
export function toCamelCase(str: string): string {
|
||||
return str
|
||||
.toLowerCase()
|
||||
.replace(/[-_]([a-z])/g, (_$0, $1) => $1.toUpperCase());
|
||||
}
|
||||
Reference in New Issue
Block a user