@oscarpalmer/toretto 0.42.0 → 0.44.0
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/data.mjs +1 -1
- package/dist/index.d.mts +6 -4
- package/dist/index.mjs +73 -57
- package/dist/internal/attribute.mjs +2 -1
- package/dist/internal/element-value.d.mts +2 -2
- package/dist/internal/element-value.mjs +16 -7
- package/dist/internal/get-value.mjs +3 -1
- package/dist/internal/property.mjs +4 -1
- package/dist/property/set.property.mjs +6 -8
- package/dist/style.d.mts +6 -4
- package/dist/style.mjs +12 -6
- package/package.json +5 -4
- package/src/internal/attribute.ts +2 -1
- package/src/internal/element-value.ts +27 -6
- package/src/internal/get-value.ts +6 -0
- package/src/internal/property.ts +1 -1
- package/src/property/set.property.ts +12 -11
- package/src/style.ts +35 -14
package/dist/data.mjs
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { isHTMLOrSVGElement } from "./internal/is.mjs";
|
|
2
2
|
import { setElementValues, updateElementValue } from "./internal/element-value.mjs";
|
|
3
3
|
import { EXPRESSION_DATA_PREFIX } from "./internal/get-value.mjs";
|
|
4
|
-
import { camelCase, kebabCase } from "@oscarpalmer/atoms/string/case";
|
|
5
4
|
import { parse } from "@oscarpalmer/atoms/string";
|
|
5
|
+
import { camelCase, kebabCase } from "@oscarpalmer/atoms/string/case";
|
|
6
6
|
//#region src/data.ts
|
|
7
7
|
function getData(element, keys, parseValues) {
|
|
8
8
|
if (!isHTMLOrSVGElement(element)) return;
|
package/dist/index.d.mts
CHANGED
|
@@ -530,6 +530,7 @@ declare function setProperty<Target extends Element, Property extends Dispatched
|
|
|
530
530
|
declare function setProperty<Target extends Element, Property extends keyof SetProperties<Target>>(target: Target, property: Property, value: SetProperties<Target>[Property]): void;
|
|
531
531
|
//#endregion
|
|
532
532
|
//#region src/style.d.ts
|
|
533
|
+
type CSSStyleValues = Variables & CSSStyleDeclaration;
|
|
533
534
|
type StyleToggler = {
|
|
534
535
|
/**
|
|
535
536
|
* Set the provided styles on the element
|
|
@@ -540,7 +541,8 @@ type StyleToggler = {
|
|
|
540
541
|
*/
|
|
541
542
|
remove(): void;
|
|
542
543
|
};
|
|
543
|
-
type Styles = Partial<Record<keyof
|
|
544
|
+
type Styles = Partial<Record<keyof CSSStyleValues, unknown>>;
|
|
545
|
+
type Variables<Value extends Record<string, string | undefined> = Record<string, string | undefined>> = { [property in keyof Value as `--${string & property}`]?: string | undefined };
|
|
544
546
|
/**
|
|
545
547
|
* Get a style from an element
|
|
546
548
|
* @param element Element to get the style from
|
|
@@ -548,7 +550,7 @@ type Styles = Partial<Record<keyof CSSStyleDeclaration, unknown>>;
|
|
|
548
550
|
* @param computed Get the computed style? _(defaults to `false`)_
|
|
549
551
|
* @returns Style value
|
|
550
552
|
*/
|
|
551
|
-
declare function getStyle(element: Element, property: keyof
|
|
553
|
+
declare function getStyle(element: Element, property: keyof CSSStyleValues, computed?: boolean): string | undefined;
|
|
552
554
|
/**
|
|
553
555
|
* Get styles from an element
|
|
554
556
|
* @param element Element to get the styles from
|
|
@@ -556,7 +558,7 @@ declare function getStyle(element: Element, property: keyof CSSStyleDeclaration,
|
|
|
556
558
|
* @param computed Get the computed styles? _(defaults to `false`)_
|
|
557
559
|
* @returns Style values
|
|
558
560
|
*/
|
|
559
|
-
declare function getStyles<Property extends keyof
|
|
561
|
+
declare function getStyles<Property extends keyof CSSStyleValues>(element: Element, properties: Property[], computed?: boolean): Record<Property, string | undefined>;
|
|
560
562
|
/**
|
|
561
563
|
* Get the text direction of a node or element _(or document, if element is invalid)_
|
|
562
564
|
* @param node Node or element to get the text direction from
|
|
@@ -574,7 +576,7 @@ declare function getTextDirection(): TextDirection;
|
|
|
574
576
|
* @param property Style name
|
|
575
577
|
* @param value Style value
|
|
576
578
|
*/
|
|
577
|
-
declare function setStyle(element: Element, property: keyof
|
|
579
|
+
declare function setStyle(element: Element, property: keyof CSSStyleValues, value?: unknown): void;
|
|
578
580
|
/**
|
|
579
581
|
* Set styles on an element
|
|
580
582
|
* @param element Element to set the styles on
|
package/dist/index.mjs
CHANGED
|
@@ -51,19 +51,6 @@ function isPlainObject(value) {
|
|
|
51
51
|
return prototype === null || prototype === Object.prototype || Object.getPrototypeOf(prototype) === null;
|
|
52
52
|
}
|
|
53
53
|
//#endregion
|
|
54
|
-
//#region node_modules/@oscarpalmer/atoms/dist/internal/array/compact.mjs
|
|
55
|
-
function compact(array, strict) {
|
|
56
|
-
if (!Array.isArray(array)) return [];
|
|
57
|
-
if (strict === true) return array.filter(Boolean);
|
|
58
|
-
const { length } = array;
|
|
59
|
-
const compacted = [];
|
|
60
|
-
for (let index = 0; index < length; index += 1) {
|
|
61
|
-
const item = array[index];
|
|
62
|
-
if (item != null) compacted.push(item);
|
|
63
|
-
}
|
|
64
|
-
return compacted;
|
|
65
|
-
}
|
|
66
|
-
//#endregion
|
|
67
54
|
//#region node_modules/@oscarpalmer/atoms/dist/internal/string.mjs
|
|
68
55
|
/**
|
|
69
56
|
* Get the string value from any value
|
|
@@ -79,13 +66,23 @@ function getString(value) {
|
|
|
79
66
|
return asString.startsWith("[object ") ? JSON.stringify(value) : asString;
|
|
80
67
|
}
|
|
81
68
|
/**
|
|
82
|
-
* Join an array of values into a string
|
|
83
|
-
*
|
|
69
|
+
* Join an array of values into a string _(while ignoring empty values)_
|
|
70
|
+
*
|
|
71
|
+
* _(`null`, `undefined`, and any values that become whitespace-only strings are considered empty)_
|
|
72
|
+
* @param array Array of values
|
|
84
73
|
* @param delimiter Delimiter to use between values
|
|
85
74
|
* @returns Joined string
|
|
86
75
|
*/
|
|
87
|
-
function join(
|
|
88
|
-
|
|
76
|
+
function join(array, delimiter) {
|
|
77
|
+
if (!Array.isArray(array)) return "";
|
|
78
|
+
const { length } = array;
|
|
79
|
+
if (length === 0) return "";
|
|
80
|
+
const values = [];
|
|
81
|
+
for (let index = 0; index < length; index += 1) {
|
|
82
|
+
const item = getString(array[index]);
|
|
83
|
+
if (item.trim().length > 0) values.push(item);
|
|
84
|
+
}
|
|
85
|
+
return values.join(typeof delimiter === "string" ? delimiter : "");
|
|
89
86
|
}
|
|
90
87
|
/**
|
|
91
88
|
* Split a string into words _(and other readable parts)_
|
|
@@ -99,15 +96,30 @@ const EXPRESSION_WORDS = /[^\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f]+/g;
|
|
|
99
96
|
//#endregion
|
|
100
97
|
//#region node_modules/@oscarpalmer/atoms/dist/is.mjs
|
|
101
98
|
/**
|
|
102
|
-
* Is the value `undefined`, `null`, or a whitespace-only string?
|
|
99
|
+
* Is the value `undefined`, `null`, or stringified as a whitespace-only string?
|
|
103
100
|
* @param value Value to check
|
|
104
|
-
* @returns `true` if the value is nullable or a whitespace-only string, otherwise `false`
|
|
101
|
+
* @returns `true` if the value is nullable or matches a whitespace-only string, otherwise `false`
|
|
105
102
|
*/
|
|
106
103
|
function isNullableOrWhitespace(value) {
|
|
107
104
|
return value == null || EXPRESSION_WHITESPACE$1.test(getString(value));
|
|
108
105
|
}
|
|
109
106
|
const EXPRESSION_WHITESPACE$1 = /^\s*$/;
|
|
110
107
|
//#endregion
|
|
108
|
+
//#region node_modules/@oscarpalmer/atoms/dist/string/index.mjs
|
|
109
|
+
/**
|
|
110
|
+
* Parse a JSON string into its proper value _(or `undefined` if it fails)_
|
|
111
|
+
* @param value JSON string to parse
|
|
112
|
+
* @param reviver Reviver function to transform the parsed values
|
|
113
|
+
* @returns Parsed value or `undefined` if parsing fails
|
|
114
|
+
*/
|
|
115
|
+
function parse(value, reviver) {
|
|
116
|
+
try {
|
|
117
|
+
return JSON.parse(value, reviver);
|
|
118
|
+
} catch {
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
//#endregion
|
|
111
123
|
//#region node_modules/@oscarpalmer/atoms/dist/internal/number.mjs
|
|
112
124
|
/**
|
|
113
125
|
* Clamp a number between a minimum and maximum value
|
|
@@ -192,6 +204,9 @@ var SizedMap = class extends Map {
|
|
|
192
204
|
};
|
|
193
205
|
//#endregion
|
|
194
206
|
//#region node_modules/@oscarpalmer/atoms/dist/function/memoize.mjs
|
|
207
|
+
/**
|
|
208
|
+
* A memoized function, caching and retrieving results based on the its parameters _(or a custom cache key)_
|
|
209
|
+
*/
|
|
195
210
|
var Memoized = class {
|
|
196
211
|
#state;
|
|
197
212
|
/**
|
|
@@ -406,16 +421,23 @@ const CHILD_NODE_TYPES = new Set([
|
|
|
406
421
|
]);
|
|
407
422
|
//#endregion
|
|
408
423
|
//#region src/internal/element-value.ts
|
|
409
|
-
function
|
|
424
|
+
function ignoreSetAttribute(element, name) {
|
|
425
|
+
if (element instanceof HTMLTextAreaElement && name === "value") return true;
|
|
426
|
+
return false;
|
|
427
|
+
}
|
|
428
|
+
function normalizeKey(key, style) {
|
|
429
|
+
return style && key.startsWith(CSS_VARIABLE_PREFIX$1) ? key : kebabCase(key);
|
|
430
|
+
}
|
|
431
|
+
function setElementValue(element, first, second, third, callback, style) {
|
|
410
432
|
if (!isHTMLOrSVGElement(element)) return;
|
|
411
|
-
if (typeof first === "string") setElementValues(element, first, second, third, callback);
|
|
412
|
-
else if (isAttribute(first)) setElementValues(element, first.name, first.value, third, callback);
|
|
433
|
+
if (typeof first === "string") setElementValues(element, first, second, third, callback, style);
|
|
434
|
+
else if (isAttribute(first)) setElementValues(element, first.name, first.value, third, callback, style);
|
|
413
435
|
}
|
|
414
|
-
function setElementValues(element, first, second, third, callback) {
|
|
436
|
+
function setElementValues(element, first, second, third, callback, style) {
|
|
415
437
|
if (!isHTMLOrSVGElement(element)) return;
|
|
416
438
|
const dispatch = third !== false;
|
|
417
439
|
if (typeof first === "string") {
|
|
418
|
-
callback(element,
|
|
440
|
+
callback(element, normalizeKey(first, style), second, dispatch);
|
|
419
441
|
return;
|
|
420
442
|
}
|
|
421
443
|
const isArray = Array.isArray(first);
|
|
@@ -427,13 +449,14 @@ function setElementValues(element, first, second, third, callback) {
|
|
|
427
449
|
const { length } = entries;
|
|
428
450
|
for (let index = 0; index < length; index += 1) {
|
|
429
451
|
const entry = entries[index];
|
|
430
|
-
if (typeof entry === "object" && typeof entry?.name === "string") callback(element,
|
|
452
|
+
if (typeof entry === "object" && typeof entry?.name === "string") callback(element, normalizeKey(entry.name, style), entry.value, dispatch);
|
|
431
453
|
}
|
|
432
454
|
}
|
|
433
455
|
function updateElementValue(element, key, value, set, remove, isBoolean, json) {
|
|
434
456
|
if (isBoolean ? value == null : isNullableOrWhitespace(value)) remove.call(element, key);
|
|
435
|
-
else set.call(element, key, json ? JSON.stringify(value) :
|
|
457
|
+
else if (!ignoreSetAttribute(element, key)) set.call(element, key, json ? JSON.stringify(value) : getString(value));
|
|
436
458
|
}
|
|
459
|
+
const CSS_VARIABLE_PREFIX$1 = "--";
|
|
437
460
|
//#endregion
|
|
438
461
|
//#region src/internal/property.ts
|
|
439
462
|
function updateProperty(element, name, value, dispatch) {
|
|
@@ -442,7 +465,10 @@ function updateProperty(element, name, value, dispatch) {
|
|
|
442
465
|
if (!(property in element) || Object.is(element[property], value)) return;
|
|
443
466
|
element[property] = value;
|
|
444
467
|
const event = dispatch && elementEvents[element.tagName]?.[property];
|
|
445
|
-
if (typeof event === "string") element.dispatchEvent(new Event(event, {
|
|
468
|
+
if (typeof event === "string") element.dispatchEvent(new Event(event, {
|
|
469
|
+
bubbles: true,
|
|
470
|
+
cancelable: true
|
|
471
|
+
}));
|
|
446
472
|
}
|
|
447
473
|
const elementEvents = {
|
|
448
474
|
DETAILS: { open: "toggle" },
|
|
@@ -478,7 +504,7 @@ function handleAttribute(callback, decode, first, second) {
|
|
|
478
504
|
let value;
|
|
479
505
|
if (isAttribute(first)) {
|
|
480
506
|
name = first.name;
|
|
481
|
-
value =
|
|
507
|
+
value = getString(first.value);
|
|
482
508
|
} else if (typeof first === "string" && typeof second === "string") {
|
|
483
509
|
name = first;
|
|
484
510
|
value = second;
|
|
@@ -555,21 +581,6 @@ const dispatchedAttributes = new Set([
|
|
|
555
581
|
const formElement = document.createElement("form");
|
|
556
582
|
let textArea;
|
|
557
583
|
//#endregion
|
|
558
|
-
//#region node_modules/@oscarpalmer/atoms/dist/string/index.mjs
|
|
559
|
-
/**
|
|
560
|
-
* Parse a JSON string into its proper value _(or `undefined` if it fails)_
|
|
561
|
-
* @param value JSON string to parse
|
|
562
|
-
* @param reviver Reviver function to transform the parsed values
|
|
563
|
-
* @returns Parsed value or `undefined` if parsing fails
|
|
564
|
-
*/
|
|
565
|
-
function parse(value, reviver) {
|
|
566
|
-
try {
|
|
567
|
-
return JSON.parse(value, reviver);
|
|
568
|
-
} catch {
|
|
569
|
-
return;
|
|
570
|
-
}
|
|
571
|
-
}
|
|
572
|
-
//#endregion
|
|
573
584
|
//#region src/internal/get-value.ts
|
|
574
585
|
function getBoolean(value, defaultValue) {
|
|
575
586
|
return typeof value === "boolean" ? value : defaultValue ?? false;
|
|
@@ -581,10 +592,12 @@ function getAttributeValue(element, name, parseValue) {
|
|
|
581
592
|
return EXPRESSION_DATA_PREFIX.test(normalized) && typeof value === "string" && parseValue ? parse(value) ?? value : value;
|
|
582
593
|
}
|
|
583
594
|
function getStyleValue(element, property, computed) {
|
|
595
|
+
if (property.startsWith(CSS_VARIABLE_PREFIX)) return element.style.getPropertyValue(property);
|
|
584
596
|
const name = camelCase(property);
|
|
585
597
|
return computed ? getComputedStyle(element)[name] : element.style[name];
|
|
586
598
|
}
|
|
587
599
|
const EXPRESSION_DATA_PREFIX = /^data-/i;
|
|
600
|
+
const CSS_VARIABLE_PREFIX = "--";
|
|
588
601
|
//#endregion
|
|
589
602
|
//#region src/attribute/get.attribute.ts
|
|
590
603
|
function getAttribute(element, name, parseValues) {
|
|
@@ -661,7 +674,7 @@ function getTextDirection(node) {
|
|
|
661
674
|
if (isHTMLOrSVGElement(node)) target = node;
|
|
662
675
|
else target = node instanceof Node ? node.ownerDocument?.documentElement ?? document.documentElement : document.documentElement;
|
|
663
676
|
let { direction } = target.style;
|
|
664
|
-
if (direction === "") direction = getStyleValue(target,
|
|
677
|
+
if (direction === "") direction = getStyleValue(target, PROPERTY_DIRECTION, true);
|
|
665
678
|
return direction === DIRECTION_RTL ? DIRECTION_RTL : DIRECTION_LTR;
|
|
666
679
|
}
|
|
667
680
|
/**
|
|
@@ -671,7 +684,7 @@ function getTextDirection(node) {
|
|
|
671
684
|
* @param value Style value
|
|
672
685
|
*/
|
|
673
686
|
function setStyle(element, property, value) {
|
|
674
|
-
setElementValues(element, property, value, null, updateStyleProperty);
|
|
687
|
+
setElementValues(element, property, value, null, updateStyleProperty, true);
|
|
675
688
|
}
|
|
676
689
|
/**
|
|
677
690
|
* Set styles on an element
|
|
@@ -679,7 +692,7 @@ function setStyle(element, property, value) {
|
|
|
679
692
|
* @param styles Styles to set
|
|
680
693
|
*/
|
|
681
694
|
function setStyles(element, styles) {
|
|
682
|
-
setElementValues(element, styles, null, null, updateStyleProperty);
|
|
695
|
+
setElementValues(element, styles, null, null, updateStyleProperty, true);
|
|
683
696
|
}
|
|
684
697
|
/**
|
|
685
698
|
* Toggle styles for an element
|
|
@@ -716,14 +729,19 @@ function toggleStyles(element, styles) {
|
|
|
716
729
|
}
|
|
717
730
|
function updateStyleProperty(element, key, value) {
|
|
718
731
|
updateElementValue(element, key, value, function(property, style) {
|
|
719
|
-
this.style
|
|
732
|
+
if (property.startsWith(VARIABLE_PREFIX)) this.style.setProperty(property, getString(style));
|
|
733
|
+
else this.style[property] = getString(style);
|
|
720
734
|
}, function(property) {
|
|
721
|
-
this.style
|
|
735
|
+
if (property.startsWith(VARIABLE_PREFIX)) this.style.removeProperty(property);
|
|
736
|
+
else this.style[property] = "";
|
|
737
|
+
if (this.getAttribute(ATTRIBUTE_STYLE) === "") this.removeAttribute(ATTRIBUTE_STYLE);
|
|
722
738
|
}, false, false);
|
|
723
739
|
}
|
|
740
|
+
const ATTRIBUTE_STYLE = "style";
|
|
724
741
|
const DIRECTION_LTR = "ltr";
|
|
725
742
|
const DIRECTION_RTL = "rtl";
|
|
726
|
-
const
|
|
743
|
+
const PROPERTY_DIRECTION = "direction";
|
|
744
|
+
const VARIABLE_PREFIX = "--";
|
|
727
745
|
//#endregion
|
|
728
746
|
//#region src/property/get.property.ts
|
|
729
747
|
/**
|
|
@@ -771,16 +789,14 @@ function setProperties(target, properties, dispatch) {
|
|
|
771
789
|
const shouldDispatch = dispatch !== false;
|
|
772
790
|
const keys = Object.keys(properties);
|
|
773
791
|
const { length } = keys;
|
|
774
|
-
for (let index = 0; index < length; index += 1)
|
|
775
|
-
const key = keys[index];
|
|
776
|
-
if (booleanAttributesSet.has(key.toLowerCase()) || dispatchedAttributes.has(key)) setAttribute(target, key, properties[key], shouldDispatch);
|
|
777
|
-
else updateProperty(target, key, properties[key], shouldDispatch);
|
|
778
|
-
}
|
|
792
|
+
for (let index = 0; index < length; index += 1) setPropertyValue(target, keys[index], properties[keys[index]], shouldDispatch);
|
|
779
793
|
}
|
|
780
794
|
function setProperty(target, property, value, dispatch) {
|
|
781
|
-
if (
|
|
782
|
-
|
|
783
|
-
|
|
795
|
+
if (isHTMLOrSVGElement(target) && typeof property === "string") setPropertyValue(target, property, value, dispatch !== false);
|
|
796
|
+
}
|
|
797
|
+
function setPropertyValue(element, property, value, dispatch) {
|
|
798
|
+
if (booleanAttributesSet.has(property.toLowerCase()) || dispatchedAttributes.has(property)) setAttribute(element, property, value, dispatch);
|
|
799
|
+
else updateProperty(element, property, value, dispatch);
|
|
784
800
|
}
|
|
785
801
|
//#endregion
|
|
786
802
|
//#region src/create.ts
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { updateElementValue } from "./element-value.mjs";
|
|
2
2
|
import { updateProperty } from "./property.mjs";
|
|
3
3
|
import { isPlainObject } from "@oscarpalmer/atoms/is";
|
|
4
|
+
import { getString } from "@oscarpalmer/atoms/string";
|
|
4
5
|
import { kebabCase } from "@oscarpalmer/atoms/string/case";
|
|
5
6
|
//#region src/internal/attribute.ts
|
|
6
7
|
function badAttributeHandler(name, value) {
|
|
@@ -26,7 +27,7 @@ function handleAttribute(callback, decode, first, second) {
|
|
|
26
27
|
let value;
|
|
27
28
|
if (isAttribute(first)) {
|
|
28
29
|
name = first.name;
|
|
29
|
-
value =
|
|
30
|
+
value = getString(first.value);
|
|
30
31
|
} else if (typeof first === "string" && typeof second === "string") {
|
|
31
32
|
name = first;
|
|
32
33
|
value = second;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
//#region src/internal/element-value.d.ts
|
|
2
|
-
declare function setElementValue(element: Element, first: unknown, second: unknown, third: unknown, callback: (element: Element, key: string, value: unknown, dispatch: boolean) => void): void;
|
|
3
|
-
declare function setElementValues(element: Element, first: unknown, second: unknown, third: unknown, callback: (element: Element, key: string, value: unknown, dispatch: boolean) => void): void;
|
|
2
|
+
declare function setElementValue(element: Element, first: unknown, second: unknown, third: unknown, callback: (element: Element, key: string, value: unknown, dispatch: boolean) => void, style?: boolean): void;
|
|
3
|
+
declare function setElementValues(element: Element, first: unknown, second: unknown, third: unknown, callback: (element: Element, key: string, value: unknown, dispatch: boolean) => void, style?: boolean): void;
|
|
4
4
|
declare function updateElementValue(element: Element, key: string, value: unknown, set: (key: string, value: string) => void, remove: (key: string) => void, isBoolean: boolean, json: boolean): void;
|
|
5
5
|
//#endregion
|
|
6
6
|
export { setElementValue, setElementValues, updateElementValue };
|
|
@@ -2,18 +2,26 @@ import { isHTMLOrSVGElement } from "./is.mjs";
|
|
|
2
2
|
import "../is.mjs";
|
|
3
3
|
import { isAttribute } from "./attribute.mjs";
|
|
4
4
|
import { isNullableOrWhitespace } from "@oscarpalmer/atoms/is";
|
|
5
|
+
import { getString } from "@oscarpalmer/atoms/string";
|
|
5
6
|
import { kebabCase } from "@oscarpalmer/atoms/string/case";
|
|
6
7
|
//#region src/internal/element-value.ts
|
|
7
|
-
function
|
|
8
|
+
function ignoreSetAttribute(element, name) {
|
|
9
|
+
if (element instanceof HTMLTextAreaElement && name === "value") return true;
|
|
10
|
+
return false;
|
|
11
|
+
}
|
|
12
|
+
function normalizeKey(key, style) {
|
|
13
|
+
return style && key.startsWith(CSS_VARIABLE_PREFIX) ? key : kebabCase(key);
|
|
14
|
+
}
|
|
15
|
+
function setElementValue(element, first, second, third, callback, style) {
|
|
8
16
|
if (!isHTMLOrSVGElement(element)) return;
|
|
9
|
-
if (typeof first === "string") setElementValues(element, first, second, third, callback);
|
|
10
|
-
else if (isAttribute(first)) setElementValues(element, first.name, first.value, third, callback);
|
|
17
|
+
if (typeof first === "string") setElementValues(element, first, second, third, callback, style);
|
|
18
|
+
else if (isAttribute(first)) setElementValues(element, first.name, first.value, third, callback, style);
|
|
11
19
|
}
|
|
12
|
-
function setElementValues(element, first, second, third, callback) {
|
|
20
|
+
function setElementValues(element, first, second, third, callback, style) {
|
|
13
21
|
if (!isHTMLOrSVGElement(element)) return;
|
|
14
22
|
const dispatch = third !== false;
|
|
15
23
|
if (typeof first === "string") {
|
|
16
|
-
callback(element,
|
|
24
|
+
callback(element, normalizeKey(first, style), second, dispatch);
|
|
17
25
|
return;
|
|
18
26
|
}
|
|
19
27
|
const isArray = Array.isArray(first);
|
|
@@ -25,12 +33,13 @@ function setElementValues(element, first, second, third, callback) {
|
|
|
25
33
|
const { length } = entries;
|
|
26
34
|
for (let index = 0; index < length; index += 1) {
|
|
27
35
|
const entry = entries[index];
|
|
28
|
-
if (typeof entry === "object" && typeof entry?.name === "string") callback(element,
|
|
36
|
+
if (typeof entry === "object" && typeof entry?.name === "string") callback(element, normalizeKey(entry.name, style), entry.value, dispatch);
|
|
29
37
|
}
|
|
30
38
|
}
|
|
31
39
|
function updateElementValue(element, key, value, set, remove, isBoolean, json) {
|
|
32
40
|
if (isBoolean ? value == null : isNullableOrWhitespace(value)) remove.call(element, key);
|
|
33
|
-
else set.call(element, key, json ? JSON.stringify(value) :
|
|
41
|
+
else if (!ignoreSetAttribute(element, key)) set.call(element, key, json ? JSON.stringify(value) : getString(value));
|
|
34
42
|
}
|
|
43
|
+
const CSS_VARIABLE_PREFIX = "--";
|
|
35
44
|
//#endregion
|
|
36
45
|
export { setElementValue, setElementValues, updateElementValue };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { camelCase, kebabCase } from "@oscarpalmer/atoms/string/case";
|
|
2
1
|
import { parse } from "@oscarpalmer/atoms/string";
|
|
2
|
+
import { camelCase, kebabCase } from "@oscarpalmer/atoms/string/case";
|
|
3
3
|
//#region src/internal/get-value.ts
|
|
4
4
|
function getBoolean(value, defaultValue) {
|
|
5
5
|
return typeof value === "boolean" ? value : defaultValue ?? false;
|
|
@@ -11,9 +11,11 @@ function getAttributeValue(element, name, parseValue) {
|
|
|
11
11
|
return EXPRESSION_DATA_PREFIX.test(normalized) && typeof value === "string" && parseValue ? parse(value) ?? value : value;
|
|
12
12
|
}
|
|
13
13
|
function getStyleValue(element, property, computed) {
|
|
14
|
+
if (property.startsWith(CSS_VARIABLE_PREFIX)) return element.style.getPropertyValue(property);
|
|
14
15
|
const name = camelCase(property);
|
|
15
16
|
return computed ? getComputedStyle(element)[name] : element.style[name];
|
|
16
17
|
}
|
|
17
18
|
const EXPRESSION_DATA_PREFIX = /^data-/i;
|
|
19
|
+
const CSS_VARIABLE_PREFIX = "--";
|
|
18
20
|
//#endregion
|
|
19
21
|
export { EXPRESSION_DATA_PREFIX, getAttributeValue, getBoolean, getStyleValue };
|
|
@@ -6,7 +6,10 @@ function updateProperty(element, name, value, dispatch) {
|
|
|
6
6
|
if (!(property in element) || Object.is(element[property], value)) return;
|
|
7
7
|
element[property] = value;
|
|
8
8
|
const event = dispatch && elementEvents[element.tagName]?.[property];
|
|
9
|
-
if (typeof event === "string") element.dispatchEvent(new Event(event, {
|
|
9
|
+
if (typeof event === "string") element.dispatchEvent(new Event(event, {
|
|
10
|
+
bubbles: true,
|
|
11
|
+
cancelable: true
|
|
12
|
+
}));
|
|
10
13
|
}
|
|
11
14
|
const elementEvents = {
|
|
12
15
|
DETAILS: { open: "toggle" },
|
|
@@ -19,16 +19,14 @@ function setProperties(target, properties, dispatch) {
|
|
|
19
19
|
const shouldDispatch = dispatch !== false;
|
|
20
20
|
const keys = Object.keys(properties);
|
|
21
21
|
const { length } = keys;
|
|
22
|
-
for (let index = 0; index < length; index += 1)
|
|
23
|
-
const key = keys[index];
|
|
24
|
-
if (booleanAttributesSet.has(key.toLowerCase()) || dispatchedAttributes.has(key)) setAttribute(target, key, properties[key], shouldDispatch);
|
|
25
|
-
else updateProperty(target, key, properties[key], shouldDispatch);
|
|
26
|
-
}
|
|
22
|
+
for (let index = 0; index < length; index += 1) setPropertyValue(target, keys[index], properties[keys[index]], shouldDispatch);
|
|
27
23
|
}
|
|
28
24
|
function setProperty(target, property, value, dispatch) {
|
|
29
|
-
if (
|
|
30
|
-
|
|
31
|
-
|
|
25
|
+
if (isHTMLOrSVGElement(target) && typeof property === "string") setPropertyValue(target, property, value, dispatch !== false);
|
|
26
|
+
}
|
|
27
|
+
function setPropertyValue(element, property, value, dispatch) {
|
|
28
|
+
if (booleanAttributesSet.has(property.toLowerCase()) || dispatchedAttributes.has(property)) setAttribute(element, property, value, dispatch);
|
|
29
|
+
else updateProperty(element, property, value, dispatch);
|
|
32
30
|
}
|
|
33
31
|
//#endregion
|
|
34
32
|
export { setProperties, setProperty };
|
package/dist/style.d.mts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { TextDirection } from "./models.mjs";
|
|
2
2
|
|
|
3
3
|
//#region src/style.d.ts
|
|
4
|
+
type CSSStyleValues = Variables & CSSStyleDeclaration;
|
|
4
5
|
type StyleToggler = {
|
|
5
6
|
/**
|
|
6
7
|
* Set the provided styles on the element
|
|
@@ -11,7 +12,8 @@ type StyleToggler = {
|
|
|
11
12
|
*/
|
|
12
13
|
remove(): void;
|
|
13
14
|
};
|
|
14
|
-
type Styles = Partial<Record<keyof
|
|
15
|
+
type Styles = Partial<Record<keyof CSSStyleValues, unknown>>;
|
|
16
|
+
type Variables<Value extends Record<string, string | undefined> = Record<string, string | undefined>> = { [property in keyof Value as `--${string & property}`]?: string | undefined };
|
|
15
17
|
/**
|
|
16
18
|
* Get a style from an element
|
|
17
19
|
* @param element Element to get the style from
|
|
@@ -19,7 +21,7 @@ type Styles = Partial<Record<keyof CSSStyleDeclaration, unknown>>;
|
|
|
19
21
|
* @param computed Get the computed style? _(defaults to `false`)_
|
|
20
22
|
* @returns Style value
|
|
21
23
|
*/
|
|
22
|
-
declare function getStyle(element: Element, property: keyof
|
|
24
|
+
declare function getStyle(element: Element, property: keyof CSSStyleValues, computed?: boolean): string | undefined;
|
|
23
25
|
/**
|
|
24
26
|
* Get styles from an element
|
|
25
27
|
* @param element Element to get the styles from
|
|
@@ -27,7 +29,7 @@ declare function getStyle(element: Element, property: keyof CSSStyleDeclaration,
|
|
|
27
29
|
* @param computed Get the computed styles? _(defaults to `false`)_
|
|
28
30
|
* @returns Style values
|
|
29
31
|
*/
|
|
30
|
-
declare function getStyles<Property extends keyof
|
|
32
|
+
declare function getStyles<Property extends keyof CSSStyleValues>(element: Element, properties: Property[], computed?: boolean): Record<Property, string | undefined>;
|
|
31
33
|
/**
|
|
32
34
|
* Get the text direction of a node or element _(or document, if element is invalid)_
|
|
33
35
|
* @param node Node or element to get the text direction from
|
|
@@ -45,7 +47,7 @@ declare function getTextDirection(): TextDirection;
|
|
|
45
47
|
* @param property Style name
|
|
46
48
|
* @param value Style value
|
|
47
49
|
*/
|
|
48
|
-
declare function setStyle(element: Element, property: keyof
|
|
50
|
+
declare function setStyle(element: Element, property: keyof CSSStyleValues, value?: unknown): void;
|
|
49
51
|
/**
|
|
50
52
|
* Set styles on an element
|
|
51
53
|
* @param element Element to set the styles on
|
package/dist/style.mjs
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { isHTMLOrSVGElement } from "./internal/is.mjs";
|
|
2
2
|
import { setElementValues, updateElementValue } from "./internal/element-value.mjs";
|
|
3
3
|
import { getStyleValue } from "./internal/get-value.mjs";
|
|
4
|
+
import { getString } from "@oscarpalmer/atoms/string";
|
|
4
5
|
//#region src/style.ts
|
|
5
6
|
/**
|
|
6
7
|
* Get a style from an element
|
|
@@ -34,7 +35,7 @@ function getTextDirection(node) {
|
|
|
34
35
|
if (isHTMLOrSVGElement(node)) target = node;
|
|
35
36
|
else target = node instanceof Node ? node.ownerDocument?.documentElement ?? document.documentElement : document.documentElement;
|
|
36
37
|
let { direction } = target.style;
|
|
37
|
-
if (direction === "") direction = getStyleValue(target,
|
|
38
|
+
if (direction === "") direction = getStyleValue(target, PROPERTY_DIRECTION, true);
|
|
38
39
|
return direction === DIRECTION_RTL ? DIRECTION_RTL : DIRECTION_LTR;
|
|
39
40
|
}
|
|
40
41
|
/**
|
|
@@ -44,7 +45,7 @@ function getTextDirection(node) {
|
|
|
44
45
|
* @param value Style value
|
|
45
46
|
*/
|
|
46
47
|
function setStyle(element, property, value) {
|
|
47
|
-
setElementValues(element, property, value, null, updateStyleProperty);
|
|
48
|
+
setElementValues(element, property, value, null, updateStyleProperty, true);
|
|
48
49
|
}
|
|
49
50
|
/**
|
|
50
51
|
* Set styles on an element
|
|
@@ -52,7 +53,7 @@ function setStyle(element, property, value) {
|
|
|
52
53
|
* @param styles Styles to set
|
|
53
54
|
*/
|
|
54
55
|
function setStyles(element, styles) {
|
|
55
|
-
setElementValues(element, styles, null, null, updateStyleProperty);
|
|
56
|
+
setElementValues(element, styles, null, null, updateStyleProperty, true);
|
|
56
57
|
}
|
|
57
58
|
/**
|
|
58
59
|
* Toggle styles for an element
|
|
@@ -89,13 +90,18 @@ function toggleStyles(element, styles) {
|
|
|
89
90
|
}
|
|
90
91
|
function updateStyleProperty(element, key, value) {
|
|
91
92
|
updateElementValue(element, key, value, function(property, style) {
|
|
92
|
-
this.style
|
|
93
|
+
if (property.startsWith(VARIABLE_PREFIX)) this.style.setProperty(property, getString(style));
|
|
94
|
+
else this.style[property] = getString(style);
|
|
93
95
|
}, function(property) {
|
|
94
|
-
this.style
|
|
96
|
+
if (property.startsWith(VARIABLE_PREFIX)) this.style.removeProperty(property);
|
|
97
|
+
else this.style[property] = "";
|
|
98
|
+
if (this.getAttribute(ATTRIBUTE_STYLE) === "") this.removeAttribute(ATTRIBUTE_STYLE);
|
|
95
99
|
}, false, false);
|
|
96
100
|
}
|
|
101
|
+
const ATTRIBUTE_STYLE = "style";
|
|
97
102
|
const DIRECTION_LTR = "ltr";
|
|
98
103
|
const DIRECTION_RTL = "rtl";
|
|
99
|
-
const
|
|
104
|
+
const PROPERTY_DIRECTION = "direction";
|
|
105
|
+
const VARIABLE_PREFIX = "--";
|
|
100
106
|
//#endregion
|
|
101
107
|
export { getStyle, getStyles, getTextDirection, setStyle, setStyles, toggleStyles };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@oscarpalmer/toretto",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.44.0",
|
|
4
4
|
"description": "A collection of badass DOM utilities.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"dom",
|
|
@@ -86,12 +86,13 @@
|
|
|
86
86
|
"test:leak": "npx vp test run --detect-async-leaks --coverage"
|
|
87
87
|
},
|
|
88
88
|
"dependencies": {
|
|
89
|
-
"@oscarpalmer/atoms": "^0.
|
|
89
|
+
"@oscarpalmer/atoms": "^0.185"
|
|
90
90
|
},
|
|
91
91
|
"devDependencies": {
|
|
92
|
-
"@
|
|
92
|
+
"@oxlint/plugins": "^1.62",
|
|
93
|
+
"@types/node": "^25.6",
|
|
93
94
|
"@vitest/coverage-istanbul": "^4.1",
|
|
94
|
-
"jsdom": "^29",
|
|
95
|
+
"jsdom": "^29.1",
|
|
95
96
|
"tsdown": "^0.21",
|
|
96
97
|
"typescript": "^5.9",
|
|
97
98
|
"vite": "npm:@voidzero-dev/vite-plus-core@latest",
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import {isPlainObject} from '@oscarpalmer/atoms/is';
|
|
2
2
|
import type {PlainObject} from '@oscarpalmer/atoms/models';
|
|
3
|
+
import {getString} from '@oscarpalmer/atoms/string';
|
|
3
4
|
import {kebabCase} from '@oscarpalmer/atoms/string/case';
|
|
4
5
|
import type {Attribute} from '../models';
|
|
5
6
|
import {updateElementValue} from './element-value';
|
|
@@ -65,7 +66,7 @@ function handleAttribute(
|
|
|
65
66
|
|
|
66
67
|
if (isAttribute(first)) {
|
|
67
68
|
name = first.name;
|
|
68
|
-
value =
|
|
69
|
+
value = getString(first.value);
|
|
69
70
|
} else if (typeof first === 'string' && typeof second === 'string') {
|
|
70
71
|
name = first;
|
|
71
72
|
value = second;
|
|
@@ -1,25 +1,39 @@
|
|
|
1
1
|
import {isNullableOrWhitespace} from '@oscarpalmer/atoms/is';
|
|
2
|
+
import {getString} from '@oscarpalmer/atoms/string';
|
|
2
3
|
import {kebabCase} from '@oscarpalmer/atoms/string/case';
|
|
3
4
|
import {isHTMLOrSVGElement} from '../is';
|
|
4
5
|
import {isAttribute} from './attribute';
|
|
5
6
|
|
|
6
7
|
// #region Functions
|
|
7
8
|
|
|
9
|
+
function ignoreSetAttribute(element: Element, name: string): boolean {
|
|
10
|
+
if (element instanceof HTMLTextAreaElement && name === 'value') {
|
|
11
|
+
return true;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
return false;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function normalizeKey(key: string, style?: boolean): string {
|
|
18
|
+
return style && key.startsWith(CSS_VARIABLE_PREFIX) ? key : kebabCase(key);
|
|
19
|
+
}
|
|
20
|
+
|
|
8
21
|
export function setElementValue(
|
|
9
22
|
element: Element,
|
|
10
23
|
first: unknown,
|
|
11
24
|
second: unknown,
|
|
12
25
|
third: unknown,
|
|
13
26
|
callback: (element: Element, key: string, value: unknown, dispatch: boolean) => void,
|
|
27
|
+
style?: boolean,
|
|
14
28
|
): void {
|
|
15
29
|
if (!isHTMLOrSVGElement(element)) {
|
|
16
30
|
return;
|
|
17
31
|
}
|
|
18
32
|
|
|
19
33
|
if (typeof first === 'string') {
|
|
20
|
-
setElementValues(element, first, second, third, callback);
|
|
34
|
+
setElementValues(element, first, second, third, callback, style);
|
|
21
35
|
} else if (isAttribute(first)) {
|
|
22
|
-
setElementValues(element, first.name, first.value, third, callback);
|
|
36
|
+
setElementValues(element, first.name, first.value, third, callback, style);
|
|
23
37
|
}
|
|
24
38
|
}
|
|
25
39
|
|
|
@@ -29,6 +43,7 @@ export function setElementValues(
|
|
|
29
43
|
second: unknown,
|
|
30
44
|
third: unknown,
|
|
31
45
|
callback: (element: Element, key: string, value: unknown, dispatch: boolean) => void,
|
|
46
|
+
style?: boolean,
|
|
32
47
|
): void {
|
|
33
48
|
if (!isHTMLOrSVGElement(element)) {
|
|
34
49
|
return;
|
|
@@ -37,7 +52,7 @@ export function setElementValues(
|
|
|
37
52
|
const dispatch = third !== false;
|
|
38
53
|
|
|
39
54
|
if (typeof first === 'string') {
|
|
40
|
-
callback(element,
|
|
55
|
+
callback(element, normalizeKey(first, style), second, dispatch);
|
|
41
56
|
|
|
42
57
|
return;
|
|
43
58
|
}
|
|
@@ -55,7 +70,7 @@ export function setElementValues(
|
|
|
55
70
|
const entry = entries[index];
|
|
56
71
|
|
|
57
72
|
if (typeof entry === 'object' && typeof entry?.name === 'string') {
|
|
58
|
-
callback(element,
|
|
73
|
+
callback(element, normalizeKey(entry.name, style), entry.value, dispatch);
|
|
59
74
|
}
|
|
60
75
|
}
|
|
61
76
|
}
|
|
@@ -71,9 +86,15 @@ export function updateElementValue(
|
|
|
71
86
|
): void {
|
|
72
87
|
if (isBoolean ? value == null : isNullableOrWhitespace(value)) {
|
|
73
88
|
remove.call(element, key);
|
|
74
|
-
} else {
|
|
75
|
-
set.call(element, key, json ? JSON.stringify(value) :
|
|
89
|
+
} else if (!ignoreSetAttribute(element, key)) {
|
|
90
|
+
set.call(element, key, json ? JSON.stringify(value) : getString(value));
|
|
76
91
|
}
|
|
77
92
|
}
|
|
78
93
|
|
|
79
94
|
// #endregion Functions
|
|
95
|
+
|
|
96
|
+
// #region Variables
|
|
97
|
+
|
|
98
|
+
const CSS_VARIABLE_PREFIX = '--';
|
|
99
|
+
|
|
100
|
+
// #endregion
|
|
@@ -22,6 +22,10 @@ export function getStyleValue(
|
|
|
22
22
|
property: string,
|
|
23
23
|
computed: boolean,
|
|
24
24
|
): string | undefined {
|
|
25
|
+
if (property.startsWith(CSS_VARIABLE_PREFIX)) {
|
|
26
|
+
return (element as HTMLElement).style.getPropertyValue(property);
|
|
27
|
+
}
|
|
28
|
+
|
|
25
29
|
const name = camelCase(property);
|
|
26
30
|
|
|
27
31
|
return computed
|
|
@@ -35,4 +39,6 @@ export function getStyleValue(
|
|
|
35
39
|
|
|
36
40
|
export const EXPRESSION_DATA_PREFIX = /^data-/i;
|
|
37
41
|
|
|
42
|
+
const CSS_VARIABLE_PREFIX = '--';
|
|
43
|
+
|
|
38
44
|
// #endregion
|
package/src/internal/property.ts
CHANGED
|
@@ -24,7 +24,7 @@ export function updateProperty(
|
|
|
24
24
|
const event = dispatch && elementEvents[element.tagName]?.[property];
|
|
25
25
|
|
|
26
26
|
if (typeof event === 'string') {
|
|
27
|
-
element.dispatchEvent(new Event(event, {bubbles: true}));
|
|
27
|
+
element.dispatchEvent(new Event(event, {bubbles: true, cancelable: true}));
|
|
28
28
|
}
|
|
29
29
|
}
|
|
30
30
|
|
|
@@ -46,13 +46,7 @@ export function setProperties<Target extends Element>(
|
|
|
46
46
|
const {length} = keys;
|
|
47
47
|
|
|
48
48
|
for (let index = 0; index < length; index += 1) {
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
if (booleanAttributesSet.has(key.toLowerCase()) || dispatchedAttributes.has(key)) {
|
|
52
|
-
setAttribute(target, key as never, (properties as PlainObject)[key], shouldDispatch);
|
|
53
|
-
} else {
|
|
54
|
-
updateProperty(target, key, (properties as PlainObject)[key], shouldDispatch);
|
|
55
|
-
}
|
|
49
|
+
setPropertyValue(target, keys[index], (properties as PlainObject)[keys[index]], shouldDispatch);
|
|
56
50
|
}
|
|
57
51
|
}
|
|
58
52
|
|
|
@@ -88,14 +82,21 @@ export function setProperty<Target extends Element, Property extends keyof SetPr
|
|
|
88
82
|
value: SetProperties<Target>[Property],
|
|
89
83
|
dispatch?: boolean,
|
|
90
84
|
): void {
|
|
91
|
-
if (
|
|
92
|
-
|
|
85
|
+
if (isHTMLOrSVGElement(target) && typeof property === 'string') {
|
|
86
|
+
setPropertyValue(target, property, value, dispatch !== false);
|
|
93
87
|
}
|
|
88
|
+
}
|
|
94
89
|
|
|
90
|
+
function setPropertyValue(
|
|
91
|
+
element: Element,
|
|
92
|
+
property: string,
|
|
93
|
+
value: unknown,
|
|
94
|
+
dispatch: boolean,
|
|
95
|
+
): void {
|
|
95
96
|
if (booleanAttributesSet.has(property.toLowerCase()) || dispatchedAttributes.has(property)) {
|
|
96
|
-
setAttribute(
|
|
97
|
+
setAttribute(element, property as never, value, dispatch);
|
|
97
98
|
} else {
|
|
98
|
-
updateProperty(
|
|
99
|
+
updateProperty(element, property, value, dispatch);
|
|
99
100
|
}
|
|
100
101
|
}
|
|
101
102
|
|
package/src/style.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import {getString} from '@oscarpalmer/atoms/string';
|
|
1
2
|
import {setElementValues, updateElementValue} from './internal/element-value';
|
|
2
3
|
import {getStyleValue} from './internal/get-value';
|
|
3
4
|
import {isHTMLOrSVGElement} from './internal/is';
|
|
@@ -5,6 +6,8 @@ import type {TextDirection} from './models';
|
|
|
5
6
|
|
|
6
7
|
// #region Types
|
|
7
8
|
|
|
9
|
+
type CSSStyleValues = Variables & CSSStyleDeclaration;
|
|
10
|
+
|
|
8
11
|
export type StyleToggler = {
|
|
9
12
|
/**
|
|
10
13
|
* Set the provided styles on the element
|
|
@@ -16,7 +19,13 @@ export type StyleToggler = {
|
|
|
16
19
|
remove(): void;
|
|
17
20
|
};
|
|
18
21
|
|
|
19
|
-
type Styles = Partial<Record<keyof
|
|
22
|
+
type Styles = Partial<Record<keyof CSSStyleValues, unknown>>;
|
|
23
|
+
|
|
24
|
+
type Variables<
|
|
25
|
+
Value extends Record<string, string | undefined> = Record<string, string | undefined>,
|
|
26
|
+
> = {
|
|
27
|
+
[property in keyof Value as `--${string & property}`]?: string | undefined;
|
|
28
|
+
};
|
|
20
29
|
|
|
21
30
|
// #endregion
|
|
22
31
|
|
|
@@ -31,7 +40,7 @@ type Styles = Partial<Record<keyof CSSStyleDeclaration, unknown>>;
|
|
|
31
40
|
*/
|
|
32
41
|
export function getStyle(
|
|
33
42
|
element: Element,
|
|
34
|
-
property: keyof
|
|
43
|
+
property: keyof CSSStyleValues,
|
|
35
44
|
computed?: boolean,
|
|
36
45
|
): string | undefined {
|
|
37
46
|
if (isHTMLOrSVGElement(element) && typeof property === 'string') {
|
|
@@ -46,7 +55,7 @@ export function getStyle(
|
|
|
46
55
|
* @param computed Get the computed styles? _(defaults to `false`)_
|
|
47
56
|
* @returns Style values
|
|
48
57
|
*/
|
|
49
|
-
export function getStyles<Property extends keyof
|
|
58
|
+
export function getStyles<Property extends keyof CSSStyleValues>(
|
|
50
59
|
element: Element,
|
|
51
60
|
properties: Property[],
|
|
52
61
|
computed?: boolean,
|
|
@@ -98,7 +107,7 @@ export function getTextDirection(node?: Element | Node): TextDirection {
|
|
|
98
107
|
let {direction} = target.style;
|
|
99
108
|
|
|
100
109
|
if (direction === '') {
|
|
101
|
-
direction = getStyleValue(target,
|
|
110
|
+
direction = getStyleValue(target, PROPERTY_DIRECTION, true)!;
|
|
102
111
|
}
|
|
103
112
|
|
|
104
113
|
return direction === DIRECTION_RTL ? DIRECTION_RTL : DIRECTION_LTR;
|
|
@@ -110,12 +119,8 @@ export function getTextDirection(node?: Element | Node): TextDirection {
|
|
|
110
119
|
* @param property Style name
|
|
111
120
|
* @param value Style value
|
|
112
121
|
*/
|
|
113
|
-
export function setStyle(
|
|
114
|
-
element
|
|
115
|
-
property: keyof CSSStyleDeclaration,
|
|
116
|
-
value?: unknown,
|
|
117
|
-
): void {
|
|
118
|
-
setElementValues(element, property as string, value, null, updateStyleProperty);
|
|
122
|
+
export function setStyle(element: Element, property: keyof CSSStyleValues, value?: unknown): void {
|
|
123
|
+
setElementValues(element, property as string, value, null, updateStyleProperty, true);
|
|
119
124
|
}
|
|
120
125
|
|
|
121
126
|
/**
|
|
@@ -124,7 +129,7 @@ export function setStyle(
|
|
|
124
129
|
* @param styles Styles to set
|
|
125
130
|
*/
|
|
126
131
|
export function setStyles(element: Element, styles: Styles): void {
|
|
127
|
-
setElementValues(element, styles as never, null, null, updateStyleProperty);
|
|
132
|
+
setElementValues(element, styles as never, null, null, updateStyleProperty, true);
|
|
128
133
|
}
|
|
129
134
|
|
|
130
135
|
/**
|
|
@@ -182,10 +187,22 @@ function updateStyleProperty(element: Element, key: string, value: unknown): voi
|
|
|
182
187
|
key,
|
|
183
188
|
value,
|
|
184
189
|
function (this: Element, property: string, style: unknown) {
|
|
185
|
-
(
|
|
190
|
+
if (property.startsWith(VARIABLE_PREFIX)) {
|
|
191
|
+
(this as HTMLElement).style.setProperty(property, getString(style));
|
|
192
|
+
} else {
|
|
193
|
+
(this as HTMLElement).style[property as never] = getString(style);
|
|
194
|
+
}
|
|
186
195
|
},
|
|
187
196
|
function (this: Element, property: string) {
|
|
188
|
-
(
|
|
197
|
+
if (property.startsWith(VARIABLE_PREFIX)) {
|
|
198
|
+
(this as HTMLElement).style.removeProperty(property);
|
|
199
|
+
} else {
|
|
200
|
+
(this as HTMLElement).style[property as never] = '';
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
if ((this as HTMLElement).getAttribute(ATTRIBUTE_STYLE) === '') {
|
|
204
|
+
(this as HTMLElement).removeAttribute(ATTRIBUTE_STYLE);
|
|
205
|
+
}
|
|
189
206
|
},
|
|
190
207
|
false,
|
|
191
208
|
false,
|
|
@@ -196,10 +213,14 @@ function updateStyleProperty(element: Element, key: string, value: unknown): voi
|
|
|
196
213
|
|
|
197
214
|
// #region Variables
|
|
198
215
|
|
|
216
|
+
const ATTRIBUTE_STYLE = 'style';
|
|
217
|
+
|
|
199
218
|
const DIRECTION_LTR = 'ltr';
|
|
200
219
|
|
|
201
220
|
const DIRECTION_RTL = 'rtl';
|
|
202
221
|
|
|
203
|
-
const
|
|
222
|
+
const PROPERTY_DIRECTION = 'direction';
|
|
223
|
+
|
|
224
|
+
const VARIABLE_PREFIX = '--';
|
|
204
225
|
|
|
205
226
|
// #endregion
|