@oscarpalmer/toretto 0.48.0 → 0.49.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/aria.d.mts +36 -11
- package/dist/aria.mjs +35 -3
- package/dist/create.d.mts +14 -10
- package/dist/create.mjs +20 -4
- package/dist/data.d.mts +22 -6
- package/dist/index.d.mts +108 -39
- package/dist/index.mjs +100 -55
- package/dist/models.d.mts +31 -3
- package/dist/style.d.mts +9 -12
- package/dist/style.mjs +18 -18
- package/package.json +3 -3
- package/src/aria.ts +102 -22
- package/src/create.ts +45 -30
- package/src/data.ts +25 -7
- package/src/models.ts +57 -2
- package/src/style.ts +30 -40
package/dist/index.mjs
CHANGED
|
@@ -627,7 +627,10 @@ function getAria(element, value) {
|
|
|
627
627
|
return arias;
|
|
628
628
|
}
|
|
629
629
|
function getAriaValue(element, attribute) {
|
|
630
|
-
|
|
630
|
+
const name = getName$1(attribute);
|
|
631
|
+
const value = element.getAttribute(name) ?? void 0;
|
|
632
|
+
if (ariaBooleanAttributesSet.has(name) && typeof value === "string" && EXPRESSION_BOOLEAN.test(value)) return value.toLowerCase() === "true";
|
|
633
|
+
return value;
|
|
631
634
|
}
|
|
632
635
|
function getName$1(value) {
|
|
633
636
|
return EXPRESSION_ARIA_PREFIX.test(value) ? value : `${ATTRIBUTE_ARIA_PREFIX}${value}`;
|
|
@@ -656,10 +659,39 @@ function setRole(element, role) {
|
|
|
656
659
|
else element.removeAttribute("role");
|
|
657
660
|
}
|
|
658
661
|
function updateAriaAttribute(element, key, value) {
|
|
659
|
-
|
|
662
|
+
const name = getName$1(key);
|
|
663
|
+
let actual = value;
|
|
664
|
+
if (ariaBooleanAttributesSet.has(name) && typeof value === "string" && EXPRESSION_BOOLEAN.test(value)) actual = value.toLowerCase() === "true";
|
|
665
|
+
updateElementValue(element, name, actual, element.setAttribute, element.removeAttribute, false, false);
|
|
660
666
|
}
|
|
661
667
|
const ATTRIBUTE_ARIA_PREFIX = "aria-";
|
|
662
668
|
const EXPRESSION_ARIA_PREFIX = /^aria-/i;
|
|
669
|
+
const EXPRESSION_BOOLEAN = /^(true|false)$/i;
|
|
670
|
+
/**
|
|
671
|
+
* List of _ARIA_ attributes that can be treated as boolean values
|
|
672
|
+
*/
|
|
673
|
+
const ariaBooleanAttributes = Object.freeze([
|
|
674
|
+
"aria-atomic",
|
|
675
|
+
"aria-busy",
|
|
676
|
+
"aria-checked",
|
|
677
|
+
"aria-current",
|
|
678
|
+
"aria-disabled",
|
|
679
|
+
"aria-expanded",
|
|
680
|
+
"aria-haspopup",
|
|
681
|
+
"aria-hidden",
|
|
682
|
+
"aria-invalid",
|
|
683
|
+
"aria-modal",
|
|
684
|
+
"aria-multiline",
|
|
685
|
+
"aria-multiselectable",
|
|
686
|
+
"aria-pressed",
|
|
687
|
+
"aria-readonly",
|
|
688
|
+
"aria-required",
|
|
689
|
+
"aria-selected"
|
|
690
|
+
]);
|
|
691
|
+
/**
|
|
692
|
+
* Set of _ARIA_ attributes that can be treated as boolean values
|
|
693
|
+
*/
|
|
694
|
+
const ariaBooleanAttributesSet = new Set(ariaBooleanAttributes);
|
|
663
695
|
//#endregion
|
|
664
696
|
//#region src/internal/get-value.ts
|
|
665
697
|
function getBoolean(value, defaultValue) {
|
|
@@ -722,6 +754,36 @@ function isInvalidBooleanAttribute(first, second) {
|
|
|
722
754
|
return _isInvalidBooleanAttribute(first, second, true);
|
|
723
755
|
}
|
|
724
756
|
//#endregion
|
|
757
|
+
//#region src/data.ts
|
|
758
|
+
function getData(element, keys, parseValues) {
|
|
759
|
+
if (!(element instanceof Element)) return;
|
|
760
|
+
const noParse = parseValues === false;
|
|
761
|
+
if (typeof keys === "string") {
|
|
762
|
+
const value = element.dataset[camelCase(keys)];
|
|
763
|
+
if (value === void 0) return;
|
|
764
|
+
return noParse ? value : parse(value);
|
|
765
|
+
}
|
|
766
|
+
const { length } = keys;
|
|
767
|
+
const data = {};
|
|
768
|
+
for (let index = 0; index < length; index += 1) {
|
|
769
|
+
const key = keys[index];
|
|
770
|
+
const value = element.dataset[camelCase(key)];
|
|
771
|
+
if (value == null) data[key] = void 0;
|
|
772
|
+
else data[key] = noParse ? value : parse(value);
|
|
773
|
+
}
|
|
774
|
+
return data;
|
|
775
|
+
}
|
|
776
|
+
function getName(original) {
|
|
777
|
+
return `${ATTRIBUTE_DATA_PREFIX}${kebabCase(original.replace(EXPRESSION_DATA_PREFIX, ""))}`;
|
|
778
|
+
}
|
|
779
|
+
function setData(element, first, second) {
|
|
780
|
+
setElementValues(element, first, second, null, updateDataAttribute);
|
|
781
|
+
}
|
|
782
|
+
function updateDataAttribute(element, key, value) {
|
|
783
|
+
updateElementValue(element, getName(key), value, element.setAttribute, element.removeAttribute, false, true);
|
|
784
|
+
}
|
|
785
|
+
const ATTRIBUTE_DATA_PREFIX = "data-";
|
|
786
|
+
//#endregion
|
|
725
787
|
//#region src/property/get.property.ts
|
|
726
788
|
/**
|
|
727
789
|
* Get the values of one or more properties on an element
|
|
@@ -786,28 +848,28 @@ function setPropertyValue(element, property, value, dispatch) {
|
|
|
786
848
|
* Get a style from an element
|
|
787
849
|
*
|
|
788
850
|
* @param element Element to get the style from
|
|
789
|
-
* @param
|
|
851
|
+
* @param name Style name
|
|
790
852
|
* @param computed Get the computed style? _(defaults to `false`)_
|
|
791
853
|
* @returns Style value
|
|
792
854
|
*/
|
|
793
|
-
function getStyle(element,
|
|
794
|
-
if (element instanceof Element && typeof
|
|
855
|
+
function getStyle(element, name, computed) {
|
|
856
|
+
if (element instanceof Element && typeof name === "string") return getStyleValue(element, name, computed === true);
|
|
795
857
|
}
|
|
796
858
|
/**
|
|
797
859
|
* Get styles from an element
|
|
798
860
|
*
|
|
799
861
|
* @param element Element to get the styles from
|
|
800
|
-
* @param
|
|
862
|
+
* @param names Styles to get
|
|
801
863
|
* @param computed Get the computed styles? _(defaults to `false`)_
|
|
802
864
|
* @returns Style values
|
|
803
865
|
*/
|
|
804
|
-
function getStyles(element,
|
|
866
|
+
function getStyles(element, names, computed) {
|
|
805
867
|
const styles = {};
|
|
806
|
-
if (!(element instanceof Element && Array.isArray(
|
|
807
|
-
const { length } =
|
|
868
|
+
if (!(element instanceof Element && Array.isArray(names))) return styles;
|
|
869
|
+
const { length } = names;
|
|
808
870
|
for (let index = 0; index < length; index += 1) {
|
|
809
|
-
const
|
|
810
|
-
if (typeof
|
|
871
|
+
const name = names[index];
|
|
872
|
+
if (typeof name === "string") styles[name] = getStyleValue(element, name, computed === true);
|
|
811
873
|
}
|
|
812
874
|
return styles;
|
|
813
875
|
}
|
|
@@ -823,11 +885,11 @@ function getTextDirection(node) {
|
|
|
823
885
|
* Set a style on an element
|
|
824
886
|
*
|
|
825
887
|
* @param element Element to set the style on
|
|
826
|
-
* @param
|
|
888
|
+
* @param name Style name
|
|
827
889
|
* @param value Style value
|
|
828
890
|
*/
|
|
829
|
-
function setStyle(element,
|
|
830
|
-
setElementValues(element,
|
|
891
|
+
function setStyle(element, name, value) {
|
|
892
|
+
setElementValues(element, name, value, null, updateStyleProperty, true);
|
|
831
893
|
}
|
|
832
894
|
/**
|
|
833
895
|
* Set styles on an element
|
|
@@ -873,12 +935,12 @@ function toggleStyles(element, styles) {
|
|
|
873
935
|
};
|
|
874
936
|
}
|
|
875
937
|
function updateStyleProperty(element, key, value) {
|
|
876
|
-
updateElementValue(element, key, value, function(
|
|
877
|
-
if (
|
|
878
|
-
else this.style[
|
|
879
|
-
}, function(
|
|
880
|
-
if (
|
|
881
|
-
else this.style[
|
|
938
|
+
updateElementValue(element, key, value, function(name, style) {
|
|
939
|
+
if (name.startsWith(VARIABLE_PREFIX)) this.style.setProperty(name, getString(style));
|
|
940
|
+
else this.style[name] = getString(style);
|
|
941
|
+
}, function(name) {
|
|
942
|
+
if (name.startsWith(VARIABLE_PREFIX)) this.style.removeProperty(name);
|
|
943
|
+
else this.style[name] = "";
|
|
882
944
|
if (this.getAttribute(ATTRIBUTE_STYLE) === "") this.removeAttribute(ATTRIBUTE_STYLE);
|
|
883
945
|
}, false, false);
|
|
884
946
|
}
|
|
@@ -889,45 +951,28 @@ const PROPERTY_DIRECTION = "direction";
|
|
|
889
951
|
const VARIABLE_PREFIX = "--";
|
|
890
952
|
//#endregion
|
|
891
953
|
//#region src/create.ts
|
|
892
|
-
function createElement(tag,
|
|
954
|
+
function createElement(tag, values) {
|
|
893
955
|
if (typeof tag !== "string") throw new TypeError(MESSAGE);
|
|
894
956
|
const element = document.createElement(tag);
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
957
|
+
const { aria, attribute, data, property, style } = getElementValues(values);
|
|
958
|
+
setAria(element, aria ?? {});
|
|
959
|
+
setAttributes(element, attribute ?? {});
|
|
960
|
+
setData(element, data ?? {});
|
|
961
|
+
setProperties(element, property ?? {});
|
|
962
|
+
setStyles(element, style ?? {});
|
|
898
963
|
return element;
|
|
899
964
|
}
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
return noParse ? value : parse(value);
|
|
910
|
-
}
|
|
911
|
-
const { length } = keys;
|
|
912
|
-
const data = {};
|
|
913
|
-
for (let index = 0; index < length; index += 1) {
|
|
914
|
-
const key = keys[index];
|
|
915
|
-
const value = element.dataset[camelCase(key)];
|
|
916
|
-
if (value == null) data[key] = void 0;
|
|
917
|
-
else data[key] = noParse ? value : parse(value);
|
|
918
|
-
}
|
|
919
|
-
return data;
|
|
920
|
-
}
|
|
921
|
-
function getName(original) {
|
|
922
|
-
return `${ATTRIBUTE_DATA_PREFIX}${kebabCase(original.replace(EXPRESSION_DATA_PREFIX, ""))}`;
|
|
923
|
-
}
|
|
924
|
-
function setData(element, first, second) {
|
|
925
|
-
setElementValues(element, first, second, null, updateDataAttribute);
|
|
926
|
-
}
|
|
927
|
-
function updateDataAttribute(element, key, value) {
|
|
928
|
-
updateElementValue(element, getName(key), value, element.setAttribute, element.removeAttribute, false, true);
|
|
965
|
+
function getElementValues(input) {
|
|
966
|
+
if (!isPlainObject(input)) return {};
|
|
967
|
+
return {
|
|
968
|
+
aria: isPlainObject(input.aria) ? input.aria : void 0,
|
|
969
|
+
attribute: isPlainObject(input.attribute) ? input.attribute : void 0,
|
|
970
|
+
data: isPlainObject(input.data) ? input.data : void 0,
|
|
971
|
+
property: isPlainObject(input.property) ? input.property : void 0,
|
|
972
|
+
style: isPlainObject(input.style) ? input.style : void 0
|
|
973
|
+
};
|
|
929
974
|
}
|
|
930
|
-
const
|
|
975
|
+
const MESSAGE = "Tag name must be a string";
|
|
931
976
|
//#endregion
|
|
932
977
|
//#region node_modules/@oscarpalmer/atoms/dist/internal/function/misc.mjs
|
|
933
978
|
/**
|
|
@@ -1673,4 +1718,4 @@ const CHILD_NODE_TYPES = /* @__PURE__ */ new Set([
|
|
|
1673
1718
|
Node.DOCUMENT_TYPE_NODE
|
|
1674
1719
|
]);
|
|
1675
1720
|
//#endregion
|
|
1676
|
-
export { findElement as $, findElement, findElements as $$, findElements, booleanAttributes, createElement, dispatch, findAncestor, findRelatives, getAria, getAttribute, getAttributes, getData, getDistance, getElementFromPosition, getElementUnderPointer, getFocusable, getPosition, getProperties, getProperty, getRole, getStyle, getStyles, getTabbable, getTextDirection, html, isBadAttribute, isBooleanAttribute, isChildNode, isEventPosition, isEventTarget, isFocusable, isHTMLOrSVGElement, isInDocument, isInputElement, isInvalidBooleanAttribute, isTabbable, off, on, sanitize, setAria, setAttribute, setAttributes, setData, setProperties, setProperty, setRole, setStyle, setStyles, supportsTouch, toggleStyles };
|
|
1721
|
+
export { findElement as $, findElement, findElements as $$, findElements, ariaBooleanAttributes, ariaBooleanAttributesSet, booleanAttributes, createElement, dispatch, findAncestor, findRelatives, getAria, getAttribute, getAttributes, getData, getDistance, getElementFromPosition, getElementUnderPointer, getFocusable, getPosition, getProperties, getProperty, getRole, getStyle, getStyles, getTabbable, getTextDirection, html, isBadAttribute, isBooleanAttribute, isChildNode, isEventPosition, isEventTarget, isFocusable, isHTMLOrSVGElement, isInDocument, isInputElement, isInvalidBooleanAttribute, isTabbable, off, on, sanitize, setAria, setAttribute, setAttributes, setData, setProperties, setProperty, setRole, setStyle, setStyles, supportsTouch, toggleStyles };
|
package/dist/models.d.mts
CHANGED
|
@@ -1,4 +1,12 @@
|
|
|
1
1
|
//#region src/models.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Any _ARIA_ attribute for an element _(both prefixed and unprefixed)_
|
|
4
|
+
*/
|
|
5
|
+
type AnyAriaAttribute = AriaAttribute | AriaAttributeUnprefixed;
|
|
6
|
+
/**
|
|
7
|
+
* Any _ARIA_ attribute for an element that can be set to a boolean value _(both prefixed and unprefixed)_
|
|
8
|
+
*/
|
|
9
|
+
type AnyAriaBooleanAttribute = AriaBooleanAttribute | AriaBooleanAttributeUnprefixed;
|
|
2
10
|
/**
|
|
3
11
|
* _ARIA_ attribute for an element
|
|
4
12
|
*
|
|
@@ -10,8 +18,16 @@ type AriaAttribute = keyof AriaAttributes;
|
|
|
10
18
|
*
|
|
11
19
|
* _(https://www.w3.org/TR/wai-aria-1.3/#aria-attributes)_
|
|
12
20
|
*/
|
|
13
|
-
type AriaAttributeUnprefixed = keyof { [Key in AriaAttribute as Key extends `aria-${infer Name}` ? Name : never]:
|
|
14
|
-
type AriaAttributes = { [Key in keyof ARIAMixin as NormalizedName<Key>]:
|
|
21
|
+
type AriaAttributeUnprefixed = keyof { [Key in AriaAttribute as Key extends `aria-${infer Name}` ? Name : never]: unknown; };
|
|
22
|
+
type AriaAttributes = { [Key in keyof ARIAMixin as NormalizedName<Key>]: unknown; };
|
|
23
|
+
/**
|
|
24
|
+
* _ARIA_ attribute for an element that can be set to a boolean value
|
|
25
|
+
*/
|
|
26
|
+
type AriaBooleanAttribute = 'aria-atomic' | 'aria-busy' | 'aria-checked' | 'aria-current' | 'aria-disabled' | 'aria-expanded' | 'aria-haspopup' | 'aria-hidden' | 'aria-invalid' | 'aria-modal' | 'aria-multiline' | 'aria-multiselectable' | 'aria-pressed' | 'aria-readonly' | 'aria-required' | 'aria-selected';
|
|
27
|
+
/**
|
|
28
|
+
* _ARIA_ attribute for an element that can be set to a boolean value, without the `aria-` prefix
|
|
29
|
+
*/
|
|
30
|
+
type AriaBooleanAttributeUnprefixed = keyof { [Key in AriaBooleanAttribute as Key extends `aria-${infer Name}` ? Name : never]: string | null; };
|
|
15
31
|
type NormalizedName<Key extends string> = Key extends `aria${infer Name}` ? Name extends `${infer Part}Element` ? `aria-${Lowercase<Part>}` : Name extends `${infer Part}Elements` ? `aria-${Lowercase<Part>}` : `aria-${Lowercase<Name>}` : never;
|
|
16
32
|
/**
|
|
17
33
|
* _ARIA_ role for an element
|
|
@@ -26,6 +42,18 @@ type Attribute = {
|
|
|
26
42
|
name: string;
|
|
27
43
|
value: unknown;
|
|
28
44
|
};
|
|
45
|
+
/**
|
|
46
|
+
* CSS styles for an element
|
|
47
|
+
*/
|
|
48
|
+
type CSSStyles = Record<keyof CSSStyleDeclaration, unknown>;
|
|
49
|
+
/**
|
|
50
|
+
* CSSS values for an element _(both styles and variables)_
|
|
51
|
+
*/
|
|
52
|
+
type CSSValues = CSSVariables & CSSStyles;
|
|
53
|
+
/**
|
|
54
|
+
* CSS variables for an element
|
|
55
|
+
*/
|
|
56
|
+
type CSSVariables<Value extends Record<string, unknown> = Record<string, unknown>> = { [Property in keyof Value as `--${string & Property}`]?: unknown; };
|
|
29
57
|
/**
|
|
30
58
|
* Event listener for custom events
|
|
31
59
|
*/
|
|
@@ -43,4 +71,4 @@ type Selector = string | Node | Node[] | NodeList;
|
|
|
43
71
|
*/
|
|
44
72
|
type TextDirection = 'ltr' | 'rtl';
|
|
45
73
|
//#endregion
|
|
46
|
-
export { AriaAttribute, AriaAttributeUnprefixed, AriaRole, Attribute, CustomEventListener, RemovableEventListener, Selector, TextDirection };
|
|
74
|
+
export { AnyAriaAttribute, AnyAriaBooleanAttribute, AriaAttribute, AriaAttributeUnprefixed, AriaBooleanAttribute, AriaBooleanAttributeUnprefixed, AriaRole, Attribute, CSSStyles, CSSValues, CSSVariables, CustomEventListener, RemovableEventListener, Selector, TextDirection };
|
package/dist/style.d.mts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import { TextDirection } from "./models.mjs";
|
|
1
|
+
import { CSSValues, TextDirection } from "./models.mjs";
|
|
2
2
|
//#region src/style.d.ts
|
|
3
|
-
type CSSStyleValues = Variables & CSSStyleDeclaration;
|
|
4
3
|
type StyleToggler = {
|
|
5
4
|
/**
|
|
6
5
|
* Set the provided styles on the element
|
|
@@ -11,26 +10,24 @@ type StyleToggler = {
|
|
|
11
10
|
*/
|
|
12
11
|
remove(): void;
|
|
13
12
|
};
|
|
14
|
-
type Styles = Partial<Record<keyof CSSStyleValues, unknown>>;
|
|
15
|
-
type Variables<Value extends Record<string, string | undefined> = Record<string, string | undefined>> = { [property in keyof Value as `--${string & property}`]?: string | undefined; };
|
|
16
13
|
/**
|
|
17
14
|
* Get a style from an element
|
|
18
15
|
*
|
|
19
16
|
* @param element Element to get the style from
|
|
20
|
-
* @param
|
|
17
|
+
* @param name Style name
|
|
21
18
|
* @param computed Get the computed style? _(defaults to `false`)_
|
|
22
19
|
* @returns Style value
|
|
23
20
|
*/
|
|
24
|
-
declare function getStyle(element: Element,
|
|
21
|
+
declare function getStyle(element: Element, name: keyof CSSValues, computed?: boolean): string | undefined;
|
|
25
22
|
/**
|
|
26
23
|
* Get styles from an element
|
|
27
24
|
*
|
|
28
25
|
* @param element Element to get the styles from
|
|
29
|
-
* @param
|
|
26
|
+
* @param names Styles to get
|
|
30
27
|
* @param computed Get the computed styles? _(defaults to `false`)_
|
|
31
28
|
* @returns Style values
|
|
32
29
|
*/
|
|
33
|
-
declare function getStyles<
|
|
30
|
+
declare function getStyles<Name extends keyof CSSValues>(element: Element, names: Name[], computed?: boolean): Record<Name, string | undefined>;
|
|
34
31
|
/**
|
|
35
32
|
* Get the text direction of a node or element _(or document, if element is invalid)_
|
|
36
33
|
*
|
|
@@ -48,17 +45,17 @@ declare function getTextDirection(): TextDirection;
|
|
|
48
45
|
* Set a style on an element
|
|
49
46
|
*
|
|
50
47
|
* @param element Element to set the style on
|
|
51
|
-
* @param
|
|
48
|
+
* @param name Style name
|
|
52
49
|
* @param value Style value
|
|
53
50
|
*/
|
|
54
|
-
declare function setStyle(element: Element,
|
|
51
|
+
declare function setStyle(element: Element, name: keyof CSSValues, value?: unknown): void;
|
|
55
52
|
/**
|
|
56
53
|
* Set styles on an element
|
|
57
54
|
*
|
|
58
55
|
* @param element Element to set the styles on
|
|
59
56
|
* @param styles Styles to set
|
|
60
57
|
*/
|
|
61
|
-
declare function setStyles(element: Element, styles:
|
|
58
|
+
declare function setStyles(element: Element, styles: Partial<CSSValues>): void;
|
|
62
59
|
/**
|
|
63
60
|
* Toggle styles for an element
|
|
64
61
|
*
|
|
@@ -66,6 +63,6 @@ declare function setStyles(element: Element, styles: Styles): void;
|
|
|
66
63
|
* @param styles Styles to be set or removed
|
|
67
64
|
* @returns Style toggler
|
|
68
65
|
*/
|
|
69
|
-
declare function toggleStyles(element: Element, styles:
|
|
66
|
+
declare function toggleStyles(element: Element, styles: Partial<CSSValues>): StyleToggler;
|
|
70
67
|
//#endregion
|
|
71
68
|
export { StyleToggler, getStyle, getStyles, getTextDirection, setStyle, setStyles, toggleStyles };
|
package/dist/style.mjs
CHANGED
|
@@ -6,28 +6,28 @@ import { getString } from "@oscarpalmer/atoms/string";
|
|
|
6
6
|
* Get a style from an element
|
|
7
7
|
*
|
|
8
8
|
* @param element Element to get the style from
|
|
9
|
-
* @param
|
|
9
|
+
* @param name Style name
|
|
10
10
|
* @param computed Get the computed style? _(defaults to `false`)_
|
|
11
11
|
* @returns Style value
|
|
12
12
|
*/
|
|
13
|
-
function getStyle(element,
|
|
14
|
-
if (element instanceof Element && typeof
|
|
13
|
+
function getStyle(element, name, computed) {
|
|
14
|
+
if (element instanceof Element && typeof name === "string") return getStyleValue(element, name, computed === true);
|
|
15
15
|
}
|
|
16
16
|
/**
|
|
17
17
|
* Get styles from an element
|
|
18
18
|
*
|
|
19
19
|
* @param element Element to get the styles from
|
|
20
|
-
* @param
|
|
20
|
+
* @param names Styles to get
|
|
21
21
|
* @param computed Get the computed styles? _(defaults to `false`)_
|
|
22
22
|
* @returns Style values
|
|
23
23
|
*/
|
|
24
|
-
function getStyles(element,
|
|
24
|
+
function getStyles(element, names, computed) {
|
|
25
25
|
const styles = {};
|
|
26
|
-
if (!(element instanceof Element && Array.isArray(
|
|
27
|
-
const { length } =
|
|
26
|
+
if (!(element instanceof Element && Array.isArray(names))) return styles;
|
|
27
|
+
const { length } = names;
|
|
28
28
|
for (let index = 0; index < length; index += 1) {
|
|
29
|
-
const
|
|
30
|
-
if (typeof
|
|
29
|
+
const name = names[index];
|
|
30
|
+
if (typeof name === "string") styles[name] = getStyleValue(element, name, computed === true);
|
|
31
31
|
}
|
|
32
32
|
return styles;
|
|
33
33
|
}
|
|
@@ -43,11 +43,11 @@ function getTextDirection(node) {
|
|
|
43
43
|
* Set a style on an element
|
|
44
44
|
*
|
|
45
45
|
* @param element Element to set the style on
|
|
46
|
-
* @param
|
|
46
|
+
* @param name Style name
|
|
47
47
|
* @param value Style value
|
|
48
48
|
*/
|
|
49
|
-
function setStyle(element,
|
|
50
|
-
setElementValues(element,
|
|
49
|
+
function setStyle(element, name, value) {
|
|
50
|
+
setElementValues(element, name, value, null, updateStyleProperty, true);
|
|
51
51
|
}
|
|
52
52
|
/**
|
|
53
53
|
* Set styles on an element
|
|
@@ -93,12 +93,12 @@ function toggleStyles(element, styles) {
|
|
|
93
93
|
};
|
|
94
94
|
}
|
|
95
95
|
function updateStyleProperty(element, key, value) {
|
|
96
|
-
updateElementValue(element, key, value, function(
|
|
97
|
-
if (
|
|
98
|
-
else this.style[
|
|
99
|
-
}, function(
|
|
100
|
-
if (
|
|
101
|
-
else this.style[
|
|
96
|
+
updateElementValue(element, key, value, function(name, style) {
|
|
97
|
+
if (name.startsWith(VARIABLE_PREFIX)) this.style.setProperty(name, getString(style));
|
|
98
|
+
else this.style[name] = getString(style);
|
|
99
|
+
}, function(name) {
|
|
100
|
+
if (name.startsWith(VARIABLE_PREFIX)) this.style.removeProperty(name);
|
|
101
|
+
else this.style[name] = "";
|
|
102
102
|
if (this.getAttribute(ATTRIBUTE_STYLE) === "") this.removeAttribute(ATTRIBUTE_STYLE);
|
|
103
103
|
}, false, false);
|
|
104
104
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@oscarpalmer/toretto",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.49.0",
|
|
4
4
|
"description": "A collection of badass DOM utilities.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"dom",
|
|
@@ -93,10 +93,10 @@
|
|
|
93
93
|
"@oscarpalmer/atoms": "^0.188.1"
|
|
94
94
|
},
|
|
95
95
|
"devDependencies": {
|
|
96
|
-
"@oxlint/plugins": "^1.
|
|
96
|
+
"@oxlint/plugins": "^1.76",
|
|
97
97
|
"@types/node": "^26.1",
|
|
98
98
|
"@vitest/coverage-istanbul": "^4.1",
|
|
99
|
-
"jsdom": "^
|
|
99
|
+
"jsdom": "^30",
|
|
100
100
|
"tsdown": "^0.22",
|
|
101
101
|
"typescript": "^6",
|
|
102
102
|
"vite": "npm:@voidzero-dev/vite-plus-core@latest",
|
package/src/aria.ts
CHANGED
|
@@ -1,13 +1,11 @@
|
|
|
1
1
|
import {setElementValues, updateElementValue} from './internal/element-value';
|
|
2
|
-
import type {
|
|
2
|
+
import type {AnyAriaAttribute, AnyAriaBooleanAttribute, AriaRole} from './models';
|
|
3
3
|
|
|
4
4
|
// #region Types
|
|
5
5
|
|
|
6
|
-
type AnyAriaAttribute =
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
name: AnyAriaAttribute;
|
|
10
|
-
value?: string;
|
|
6
|
+
type AriaAttributeItem<Name extends AnyAriaAttribute = AnyAriaAttribute> = {
|
|
7
|
+
name: Name;
|
|
8
|
+
value?: Name extends AnyAriaBooleanAttribute ? boolean | string : string;
|
|
11
9
|
};
|
|
12
10
|
|
|
13
11
|
// #endregion
|
|
@@ -18,10 +16,22 @@ type AriaAttributeItem = {
|
|
|
18
16
|
* Get the value of a specific _ARIA_ attribute from an element
|
|
19
17
|
*
|
|
20
18
|
* @param element Element to get _ARIA_ attribute from
|
|
21
|
-
* @param name _ARIA_ name
|
|
19
|
+
* @param name _ARIA_ attribute name
|
|
20
|
+
* @returns _ARIA_ value _(or `undefined`)_
|
|
21
|
+
*/
|
|
22
|
+
export function getAria(
|
|
23
|
+
element: Element,
|
|
24
|
+
name: AnyAriaBooleanAttribute,
|
|
25
|
+
): boolean | string | undefined;
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Get the value of a specific _ARIA_ attribute from an element
|
|
29
|
+
*
|
|
30
|
+
* @param element Element to get _ARIA_ attribute from
|
|
31
|
+
* @param name _ARIA_ attribute name
|
|
22
32
|
* @returns _ARIA_ value _(or `undefined`)_
|
|
23
33
|
*/
|
|
24
|
-
export function getAria(element: Element,
|
|
34
|
+
export function getAria(element: Element, name: AnyAriaAttribute): string | undefined;
|
|
25
35
|
|
|
26
36
|
/**
|
|
27
37
|
* Get specific _ARIA_ attributes from an element
|
|
@@ -32,8 +42,12 @@ export function getAria(element: Element, attribute: AnyAriaAttribute): string |
|
|
|
32
42
|
*/
|
|
33
43
|
export function getAria<Attribute extends AnyAriaAttribute>(
|
|
34
44
|
element: Element,
|
|
35
|
-
|
|
36
|
-
):
|
|
45
|
+
names: Attribute[],
|
|
46
|
+
): {
|
|
47
|
+
[Key in Attribute as Key extends `aria-${infer Name}`
|
|
48
|
+
? Name
|
|
49
|
+
: Key]: Key extends AnyAriaBooleanAttribute ? boolean | string | undefined : string | undefined;
|
|
50
|
+
};
|
|
37
51
|
|
|
38
52
|
export function getAria(element: Element, value: string | string[]): unknown {
|
|
39
53
|
if (!(element instanceof Element)) {
|
|
@@ -44,7 +58,7 @@ export function getAria(element: Element, value: string | string[]): unknown {
|
|
|
44
58
|
return typeof value === 'string' ? getAriaValue(element, value) : undefined;
|
|
45
59
|
}
|
|
46
60
|
|
|
47
|
-
const arias = {} as Record<string,
|
|
61
|
+
const arias = {} as Record<string, unknown>;
|
|
48
62
|
|
|
49
63
|
const {length} = value;
|
|
50
64
|
|
|
@@ -59,8 +73,20 @@ export function getAria(element: Element, value: string | string[]): unknown {
|
|
|
59
73
|
return arias;
|
|
60
74
|
}
|
|
61
75
|
|
|
62
|
-
function getAriaValue(element: Element, attribute: string):
|
|
63
|
-
|
|
76
|
+
function getAriaValue(element: Element, attribute: string): unknown {
|
|
77
|
+
const name = getName(attribute);
|
|
78
|
+
|
|
79
|
+
const value = element.getAttribute(name) ?? undefined;
|
|
80
|
+
|
|
81
|
+
if (
|
|
82
|
+
ariaBooleanAttributesSet.has(name as never) &&
|
|
83
|
+
typeof value === 'string' &&
|
|
84
|
+
EXPRESSION_BOOLEAN.test(value)
|
|
85
|
+
) {
|
|
86
|
+
return value.toLowerCase() === 'true';
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
return value;
|
|
64
90
|
}
|
|
65
91
|
|
|
66
92
|
function getName(value: string): string {
|
|
@@ -88,7 +114,22 @@ export function getRole(element: Element): string | undefined {
|
|
|
88
114
|
* @param attribute _ARIA_ attribute to set
|
|
89
115
|
* @param value _ARIA_ attribute value
|
|
90
116
|
*/
|
|
91
|
-
export function setAria(
|
|
117
|
+
export function setAria(
|
|
118
|
+
element: Element,
|
|
119
|
+
attribute: AnyAriaBooleanAttribute,
|
|
120
|
+
value?: boolean | string,
|
|
121
|
+
): void;
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Set an _ARIA_ attribute on an element
|
|
125
|
+
*
|
|
126
|
+
* _(Or remove it, if value is `null` or `undefined`)_
|
|
127
|
+
*
|
|
128
|
+
* @param element Element for _ARIA_ attribute
|
|
129
|
+
* @param attribute _ARIA_ attribute to set
|
|
130
|
+
* @param value _ARIA_ attribute value
|
|
131
|
+
*/
|
|
132
|
+
export function setAria(element: Element, attribute: AnyAriaAttribute, value?: string): void;
|
|
92
133
|
|
|
93
134
|
/**
|
|
94
135
|
* Set one or more _ARIA_ attributes on an element
|
|
@@ -110,14 +151,12 @@ export function setAria(element: Element, attributes: AriaAttributeItem[]): void
|
|
|
110
151
|
*/
|
|
111
152
|
export function setAria(
|
|
112
153
|
element: Element,
|
|
113
|
-
attributes:
|
|
154
|
+
attributes: {
|
|
155
|
+
[Key in AnyAriaAttribute]?: Key extends AnyAriaBooleanAttribute ? boolean | string : string;
|
|
156
|
+
},
|
|
114
157
|
): void;
|
|
115
158
|
|
|
116
|
-
export function setAria(
|
|
117
|
-
element: Element,
|
|
118
|
-
first: AnyAriaAttribute | AriaAttributeItem[] | Partial<Record<AnyAriaAttribute, unknown>>,
|
|
119
|
-
second?: unknown,
|
|
120
|
-
): void {
|
|
159
|
+
export function setAria(element: Element, first: unknown, second?: unknown): void {
|
|
121
160
|
setElementValues(element, first, second, null, updateAriaAttribute);
|
|
122
161
|
}
|
|
123
162
|
|
|
@@ -140,10 +179,22 @@ export function setRole(element: Element, role?: AriaRole): void {
|
|
|
140
179
|
}
|
|
141
180
|
|
|
142
181
|
function updateAriaAttribute(element: Element, key: string, value: unknown): void {
|
|
182
|
+
const name = getName(key);
|
|
183
|
+
|
|
184
|
+
let actual = value;
|
|
185
|
+
|
|
186
|
+
if (
|
|
187
|
+
ariaBooleanAttributesSet.has(name as never) &&
|
|
188
|
+
typeof value === 'string' &&
|
|
189
|
+
EXPRESSION_BOOLEAN.test(value)
|
|
190
|
+
) {
|
|
191
|
+
actual = value.toLowerCase() === 'true';
|
|
192
|
+
}
|
|
193
|
+
|
|
143
194
|
updateElementValue(
|
|
144
195
|
element,
|
|
145
|
-
|
|
146
|
-
|
|
196
|
+
name,
|
|
197
|
+
actual,
|
|
147
198
|
// Using `.call` in `updateElementValue`
|
|
148
199
|
// oxlint-disable-next-line typescript/unbound-method
|
|
149
200
|
element.setAttribute,
|
|
@@ -163,4 +214,33 @@ const ATTRIBUTE_ARIA_PREFIX = 'aria-';
|
|
|
163
214
|
|
|
164
215
|
const EXPRESSION_ARIA_PREFIX = /^aria-/i;
|
|
165
216
|
|
|
217
|
+
const EXPRESSION_BOOLEAN = /^(true|false)$/i;
|
|
218
|
+
|
|
219
|
+
/**
|
|
220
|
+
* List of _ARIA_ attributes that can be treated as boolean values
|
|
221
|
+
*/
|
|
222
|
+
export const ariaBooleanAttributes: readonly AnyAriaBooleanAttribute[] = Object.freeze([
|
|
223
|
+
'aria-atomic',
|
|
224
|
+
'aria-busy',
|
|
225
|
+
'aria-checked',
|
|
226
|
+
'aria-current',
|
|
227
|
+
'aria-disabled',
|
|
228
|
+
'aria-expanded',
|
|
229
|
+
'aria-haspopup',
|
|
230
|
+
'aria-hidden',
|
|
231
|
+
'aria-invalid',
|
|
232
|
+
'aria-modal',
|
|
233
|
+
'aria-multiline',
|
|
234
|
+
'aria-multiselectable',
|
|
235
|
+
'aria-pressed',
|
|
236
|
+
'aria-readonly',
|
|
237
|
+
'aria-required',
|
|
238
|
+
'aria-selected',
|
|
239
|
+
]);
|
|
240
|
+
|
|
241
|
+
/**
|
|
242
|
+
* Set of _ARIA_ attributes that can be treated as boolean values
|
|
243
|
+
*/
|
|
244
|
+
export const ariaBooleanAttributesSet = new Set(ariaBooleanAttributes);
|
|
245
|
+
|
|
166
246
|
// #endregion
|