@graupl/core 1.0.0-beta.20 → 1.0.0-beta.22
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/js/component/disclosure.cjs.js +2 -2
- package/dist/js/component/disclosure.cjs.js.map +1 -1
- package/dist/js/component/disclosure.es.js +2 -2
- package/dist/js/component/disclosure.es.js.map +1 -1
- package/dist/js/component/disclosure.iife.js +2 -2
- package/dist/js/component/disclosure.iife.js.map +1 -1
- package/dist/js/disclosure.js +5 -0
- package/dist/js/disclosure.js.map +1 -0
- package/dist/js/generator/disclosure.cjs.js +2 -2
- package/dist/js/generator/disclosure.cjs.js.map +1 -1
- package/dist/js/generator/disclosure.es.js +2 -2
- package/dist/js/generator/disclosure.es.js.map +1 -1
- package/dist/js/generator/disclosure.iife.js +2 -2
- package/dist/js/generator/disclosure.iife.js.map +1 -1
- package/dist/js/graupl.js +5 -5
- package/dist/js/graupl.js.map +1 -1
- package/package.json +1 -1
- package/src/js/disclosure/Disclosure.js +127 -44
package/package.json
CHANGED
|
@@ -120,6 +120,15 @@ class Disclosure {
|
|
|
120
120
|
*/
|
|
121
121
|
_open = new TransactionalValue(false);
|
|
122
122
|
|
|
123
|
+
/**
|
|
124
|
+
* A value to force the disclosure open when the breakpoint width is passed.
|
|
125
|
+
*
|
|
126
|
+
* @protected
|
|
127
|
+
*
|
|
128
|
+
* @type {boolean}
|
|
129
|
+
*/
|
|
130
|
+
_shouldOpen = false;
|
|
131
|
+
|
|
123
132
|
/**
|
|
124
133
|
* Whether or not to close the disclosure when it loses focus in the DOM.
|
|
125
134
|
*
|
|
@@ -190,6 +199,15 @@ class Disclosure {
|
|
|
190
199
|
*/
|
|
191
200
|
_prefix = "graupl-";
|
|
192
201
|
|
|
202
|
+
/**
|
|
203
|
+
* The key used to generate IDs throughout the disclosure.
|
|
204
|
+
*
|
|
205
|
+
* @protected
|
|
206
|
+
*
|
|
207
|
+
* @type {string}
|
|
208
|
+
*/
|
|
209
|
+
_key = "";
|
|
210
|
+
|
|
193
211
|
/**
|
|
194
212
|
* An array of error messages generated by the disclosure.
|
|
195
213
|
*
|
|
@@ -213,7 +231,8 @@ class Disclosure {
|
|
|
213
231
|
* @param {boolean} [options.openDuration = -1] - The duration of the transition from "closed" to "open" states (in milliseconds).
|
|
214
232
|
* @param {boolean} [options.closeDuration = -1] - The duration of the transition from "open" to "closed" states (in milliseconds).
|
|
215
233
|
* @param {boolean} [options.closeOnBlur = false] - Whether to close the disclosure when it loses focus in the dom.
|
|
216
|
-
* @param {boolean} [options.minWidth = -1]
|
|
234
|
+
* @param {boolean} [options.minWidth = -1] - The width of the screen (in pixels) that the disclosure will automatically open/close itself.
|
|
235
|
+
* @param {boolean} [options.autoOpen = false] - Whether to automatically open when above the minWidth.
|
|
217
236
|
* @param {?string} [options.prefix = graupl-] - The prefix to use for CSS custom properties.
|
|
218
237
|
* @param {?(string|string[])} [options.initializeClass = initializing] - The class to apply when a disclosure is initialzing.
|
|
219
238
|
* @param {boolean} [options.initialize = false] - Whether to initialize the disclosure upon construction.
|
|
@@ -230,6 +249,7 @@ class Disclosure {
|
|
|
230
249
|
closeDuration = -1,
|
|
231
250
|
closeOnBlur = false,
|
|
232
251
|
minWidth = -1,
|
|
252
|
+
autoOpen = false,
|
|
233
253
|
prefix = "graupl-",
|
|
234
254
|
initializeClass = "initializing",
|
|
235
255
|
initialize = false,
|
|
@@ -255,8 +275,9 @@ class Disclosure {
|
|
|
255
275
|
// Set close on blur.
|
|
256
276
|
this._closeOnBlur = closeOnBlur;
|
|
257
277
|
|
|
258
|
-
// Set collapse width.
|
|
278
|
+
// Set collapse width and auto open functionality.
|
|
259
279
|
this._breakpointWidth = minWidth;
|
|
280
|
+
this._shouldOpen = autoOpen;
|
|
260
281
|
|
|
261
282
|
// Set the prefix.
|
|
262
283
|
this._prefix = prefix;
|
|
@@ -301,10 +322,13 @@ class Disclosure {
|
|
|
301
322
|
storage.initializeStorage("disclosures");
|
|
302
323
|
storage.pushToStorage("disclosures", this.dom.disclosure.id, this);
|
|
303
324
|
|
|
304
|
-
if (
|
|
305
|
-
this.
|
|
325
|
+
if (
|
|
326
|
+
this.dom.controller.getAttribute("aria-expanded") === "true" ||
|
|
327
|
+
(this.shouldOpen && window.matchMedia(this.openQuery).matches)
|
|
328
|
+
) {
|
|
329
|
+
this._expand({ emit: false, transition: false });
|
|
306
330
|
} else {
|
|
307
|
-
this._collapse(false, false);
|
|
331
|
+
this._collapse({ emit: false, transition: false });
|
|
308
332
|
}
|
|
309
333
|
|
|
310
334
|
requestAnimationFrame(() => {
|
|
@@ -613,6 +637,59 @@ class Disclosure {
|
|
|
613
637
|
return this._open.committed;
|
|
614
638
|
}
|
|
615
639
|
|
|
640
|
+
/**
|
|
641
|
+
* A value to force opening reguardless of user interaction.
|
|
642
|
+
*
|
|
643
|
+
* @type {boolean}
|
|
644
|
+
*
|
|
645
|
+
* @see _shouldOpen
|
|
646
|
+
*/
|
|
647
|
+
get shouldOpen() {
|
|
648
|
+
return this._shouldOpen;
|
|
649
|
+
}
|
|
650
|
+
|
|
651
|
+
set shouldOpen(value) {
|
|
652
|
+
isValidType("boolean", { value });
|
|
653
|
+
|
|
654
|
+
if (this._shouldOpen !== value) {
|
|
655
|
+
this._shouldOpen = value;
|
|
656
|
+
}
|
|
657
|
+
}
|
|
658
|
+
|
|
659
|
+
/**
|
|
660
|
+
* A media query for when the disclosure should open.
|
|
661
|
+
*
|
|
662
|
+
* Will return an empty string if no min width is set.
|
|
663
|
+
*
|
|
664
|
+
* @readonly
|
|
665
|
+
*
|
|
666
|
+
* @type {string}
|
|
667
|
+
*/
|
|
668
|
+
get openQuery() {
|
|
669
|
+
if (this.minWidth === -1) {
|
|
670
|
+
return "";
|
|
671
|
+
}
|
|
672
|
+
|
|
673
|
+
return `(width > ${this.minWidth}px)`;
|
|
674
|
+
}
|
|
675
|
+
|
|
676
|
+
/**
|
|
677
|
+
* A media query for when the disclosure should close.
|
|
678
|
+
*
|
|
679
|
+
* Will return an empty string if no min width is set.
|
|
680
|
+
*
|
|
681
|
+
* @readonly
|
|
682
|
+
*
|
|
683
|
+
* @type {string}
|
|
684
|
+
*/
|
|
685
|
+
get closeQuery() {
|
|
686
|
+
if (this.minWidth === -1) {
|
|
687
|
+
return "";
|
|
688
|
+
}
|
|
689
|
+
|
|
690
|
+
return `(width <= ${this.minWidth}px)`;
|
|
691
|
+
}
|
|
692
|
+
|
|
616
693
|
/**
|
|
617
694
|
* A flag to check if the disclosure's focus methods should _actually_ move the focus in the DOM.
|
|
618
695
|
*
|
|
@@ -633,6 +710,17 @@ class Disclosure {
|
|
|
633
710
|
return check;
|
|
634
711
|
}
|
|
635
712
|
|
|
713
|
+
/**
|
|
714
|
+
* The key used to generate IDs throughout the disclosure.
|
|
715
|
+
*
|
|
716
|
+
* @type {string}
|
|
717
|
+
*
|
|
718
|
+
* @see _key
|
|
719
|
+
*/
|
|
720
|
+
get key() {
|
|
721
|
+
return this._key;
|
|
722
|
+
}
|
|
723
|
+
|
|
636
724
|
/**
|
|
637
725
|
* An array of error messages generated by the disclosure.
|
|
638
726
|
*
|
|
@@ -668,12 +756,17 @@ class Disclosure {
|
|
|
668
756
|
}
|
|
669
757
|
|
|
670
758
|
// Query selector checks.
|
|
671
|
-
const
|
|
672
|
-
disclosureContentSelector: this._selectors.content,
|
|
673
|
-
});
|
|
759
|
+
const querySelectors = {};
|
|
674
760
|
|
|
675
|
-
|
|
676
|
-
|
|
761
|
+
for (const querySelector of Object.keys(this._selectors)) {
|
|
762
|
+
querySelectors[`${querySelector}Selector`] =
|
|
763
|
+
this._selectors[querySelector];
|
|
764
|
+
}
|
|
765
|
+
|
|
766
|
+
const querySelectorChecks = isQuerySelector(querySelectors);
|
|
767
|
+
|
|
768
|
+
if (!querySelectorChecks) {
|
|
769
|
+
this._errors.push(querySelectorChecks.message);
|
|
677
770
|
check = false;
|
|
678
771
|
}
|
|
679
772
|
|
|
@@ -721,13 +814,14 @@ class Disclosure {
|
|
|
721
814
|
}
|
|
722
815
|
|
|
723
816
|
/**
|
|
724
|
-
* Generates a key for the
|
|
817
|
+
* Generates a key for the tabs.
|
|
725
818
|
*
|
|
726
|
-
* @param {boolean} [
|
|
819
|
+
* @param {Object<boolean>} [options = {}] - Options for generating the key.
|
|
820
|
+
* @param {boolean} [options.regenerate = false] - A flag to determine if the key should be regenerated.
|
|
727
821
|
*/
|
|
728
|
-
_generateKey(regenerate = false) {
|
|
822
|
+
_generateKey({ regenerate = false } = {}) {
|
|
729
823
|
if (this.key === "" || regenerate) {
|
|
730
|
-
this.
|
|
824
|
+
this._key = Math.random()
|
|
731
825
|
.toString(36)
|
|
732
826
|
.replace(/[^a-z]+/g, "")
|
|
733
827
|
.substring(0, 10);
|
|
@@ -916,38 +1010,28 @@ class Disclosure {
|
|
|
916
1010
|
*
|
|
917
1011
|
* @fires grauplDisclosureExpand
|
|
918
1012
|
*
|
|
919
|
-
* @param {boolean} [
|
|
920
|
-
* @param {boolean}
|
|
1013
|
+
* @param {Object<boolean>} [options = {}] - Options for expanding the disclosure.
|
|
1014
|
+
* @param {boolean} [options.emit = true] - Emit the expand event once expanded.
|
|
1015
|
+
* @param {boolean} [options.transition = true] - Respect the transition class.
|
|
921
1016
|
*/
|
|
922
|
-
_expand(emit = true, transition = true) {
|
|
1017
|
+
_expand({ emit = true, transition = true } = {}) {
|
|
923
1018
|
this.dom.controller.setAttribute("aria-expanded", "true");
|
|
924
1019
|
|
|
925
1020
|
// If we're dealing with transition classes, then we need to utilize
|
|
926
1021
|
// requestAnimationFrame to add the transition class, remove the close class,
|
|
927
1022
|
// add the open class, and finally remove the transition class.
|
|
928
1023
|
if (transition && this.transitionlass !== "") {
|
|
929
|
-
// this.dom.disclosure.style.height = `${this.dom.disclosure.getBoundingClientRect().height}px`;
|
|
930
|
-
// console.log(this.dom.disclosure.style.height);
|
|
931
1024
|
addClass(this.transitionClass, this.dom.disclosure);
|
|
932
1025
|
|
|
933
1026
|
requestAnimationFrame(() => {
|
|
934
1027
|
removeClass(this.closeClass, this.dom.disclosure);
|
|
935
1028
|
|
|
936
|
-
// this.dom.disclosure.style.height = `${this.dom.disclosure.getBoundingClientRect().height}px`;
|
|
937
|
-
// console.log(this.dom.disclosure.style.height);
|
|
938
|
-
|
|
939
1029
|
requestAnimationFrame(() => {
|
|
940
1030
|
addClass(this.openClass, this.dom.disclosure);
|
|
941
1031
|
|
|
942
|
-
// this.dom.disclosure.style.height = `${this.dom.content.getBoundingClientRect().height}px`;
|
|
943
|
-
// console.log(this.dom.disclosure.style.height);
|
|
944
|
-
|
|
945
1032
|
requestAnimationFrame(() => {
|
|
946
1033
|
setTimeout(() => {
|
|
947
1034
|
removeClass(this.transitionClass, this.dom.disclosure);
|
|
948
|
-
|
|
949
|
-
// this.dom.disclosure.style.height = "";
|
|
950
|
-
// console.log(this.dom.disclosure.style.height);
|
|
951
1035
|
}, this.openDuration);
|
|
952
1036
|
});
|
|
953
1037
|
});
|
|
@@ -977,41 +1061,30 @@ class Disclosure {
|
|
|
977
1061
|
*
|
|
978
1062
|
* @fires grauplDisclosureCollapse
|
|
979
1063
|
*
|
|
980
|
-
* @param {boolean} [
|
|
981
|
-
* @param {boolean}
|
|
1064
|
+
* @param {Object<boolean>} [options = {}] - Options for collapsing the disclosure.
|
|
1065
|
+
* @param {boolean} [options.emit = true] - Emit the collapse event once collapsed.
|
|
1066
|
+
* @param {boolean} [options.transition = true] - Respect the transition class.
|
|
982
1067
|
*/
|
|
983
|
-
_collapse(emit = true, transition = true) {
|
|
1068
|
+
_collapse({ emit = true, transition = true } = {}) {
|
|
984
1069
|
this.dom.controller.setAttribute("aria-expanded", "false");
|
|
985
1070
|
|
|
986
1071
|
// If we're dealing with transition classes, then we need to utilize
|
|
987
1072
|
// requestAnimationFrame to add the transition class, remove the open class,
|
|
988
1073
|
// add the close class, and finally remove the transition class.
|
|
989
1074
|
if (transition && this.transitionClass !== "") {
|
|
990
|
-
// this.dom.disclosure.style.height = `${this.dom.content.getBoundingClientRect().height}px`;
|
|
991
|
-
// console.log(this.dom.disclosure.style.height);
|
|
992
|
-
|
|
993
1075
|
addClass(this.transitionClass, this.dom.disclosure);
|
|
994
1076
|
|
|
995
1077
|
requestAnimationFrame(() => {
|
|
996
1078
|
removeClass(this.openClass, this.dom.disclosure);
|
|
997
1079
|
|
|
998
|
-
// this.dom.disclosure.style.height = `${this.dom.content.getBoundingClientRect().height}px`;
|
|
999
|
-
// console.log(this.dom.disclosure.style.height);
|
|
1000
|
-
|
|
1001
1080
|
requestAnimationFrame(() => {
|
|
1002
1081
|
addClass(this.closeClass, this.dom.disclosure);
|
|
1003
1082
|
|
|
1004
|
-
// this.dom.disclosure.style.height = `${this.dom.disclosure.getBoundingClientRect().height}px`;
|
|
1005
|
-
// console.log(this.dom.disclosure.style.height);
|
|
1006
|
-
|
|
1007
1083
|
requestAnimationFrame(() => {
|
|
1008
1084
|
setTimeout(() => {
|
|
1009
1085
|
removeClass(this.transitionClass, this.dom.disclosure);
|
|
1010
1086
|
|
|
1011
1087
|
this.dom.content.innert = true;
|
|
1012
|
-
|
|
1013
|
-
// this.dom.disclosure.style.height = "";
|
|
1014
|
-
// console.log(this.dom.disclosure.style.height);
|
|
1015
1088
|
}, this.closeDuration);
|
|
1016
1089
|
});
|
|
1017
1090
|
});
|
|
@@ -1036,6 +1109,8 @@ class Disclosure {
|
|
|
1036
1109
|
return;
|
|
1037
1110
|
}
|
|
1038
1111
|
|
|
1112
|
+
let width = 0;
|
|
1113
|
+
|
|
1039
1114
|
this._observer = new ResizeObserver((entries) => {
|
|
1040
1115
|
requestAnimationFrame(() => {
|
|
1041
1116
|
for (const entry of entries) {
|
|
@@ -1049,14 +1124,22 @@ class Disclosure {
|
|
|
1049
1124
|
|
|
1050
1125
|
if (typeof inlineSize !== "number") continue;
|
|
1051
1126
|
|
|
1127
|
+
if (width === inlineSize) continue;
|
|
1128
|
+
|
|
1052
1129
|
const belowBreakpoint = inlineSize <= this.minWidth;
|
|
1053
1130
|
const aboveBreakpoint = inlineSize > this.minWidth;
|
|
1054
1131
|
|
|
1055
1132
|
if (belowBreakpoint && this.isOpen) {
|
|
1056
1133
|
this.close({ preserveState: true });
|
|
1057
|
-
} else if (
|
|
1134
|
+
} else if (
|
|
1135
|
+
aboveBreakpoint &&
|
|
1136
|
+
!this.isOpen &&
|
|
1137
|
+
(this.hasOpened || this.shouldOpen)
|
|
1138
|
+
) {
|
|
1058
1139
|
this.open();
|
|
1059
1140
|
}
|
|
1141
|
+
|
|
1142
|
+
width = inlineSize;
|
|
1060
1143
|
}
|
|
1061
1144
|
});
|
|
1062
1145
|
});
|