@optionfactory/ful 3.0.0 → 4.0.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/ful.css +1 -1
- package/dist/ful.css.map +1 -1
- package/dist/ful.iife.js +365 -159
- package/dist/ful.iife.js.map +1 -1
- package/dist/ful.iife.min.js +1 -1
- package/dist/ful.iife.min.js.map +1 -1
- package/dist/ful.min.mjs +1 -1
- package/dist/ful.min.mjs.map +1 -1
- package/dist/ful.mjs +358 -158
- package/dist/ful.mjs.map +1 -1
- package/package.json +2 -2
package/dist/ful.iife.js
CHANGED
|
@@ -722,69 +722,82 @@ var ful = (function (exports, ftl) {
|
|
|
722
722
|
}
|
|
723
723
|
}
|
|
724
724
|
|
|
725
|
-
class Storage {
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
this.storage = storage;
|
|
729
|
-
}
|
|
730
|
-
save(k, v) {
|
|
731
|
-
this.storage.setItem(`${this.prefix}-${k}`, JSON.stringify(v));
|
|
725
|
+
class LocalStorage extends Storage {
|
|
726
|
+
static save(k, v) {
|
|
727
|
+
localStorage.setItem(k, JSON.stringify(v));
|
|
732
728
|
}
|
|
733
|
-
load(k) {
|
|
734
|
-
const got =
|
|
735
|
-
return got ===
|
|
729
|
+
static load(k) {
|
|
730
|
+
const got = localStorage.getItem(k);
|
|
731
|
+
return got === null ? undefined : JSON.parse(got);
|
|
736
732
|
}
|
|
737
|
-
remove(k) {
|
|
738
|
-
|
|
733
|
+
static remove(k) {
|
|
734
|
+
localStorage.removeItem(k);
|
|
739
735
|
}
|
|
740
|
-
pop(k) {
|
|
741
|
-
const decoded =
|
|
742
|
-
|
|
736
|
+
static pop(k) {
|
|
737
|
+
const decoded = LocalStorage.load(k);
|
|
738
|
+
LocalStorage.remove(k);
|
|
743
739
|
return decoded;
|
|
744
740
|
}
|
|
745
|
-
}
|
|
746
741
|
|
|
747
|
-
class LocalStorage extends Storage {
|
|
748
|
-
constructor(prefix) {
|
|
749
|
-
super(prefix, localStorage);
|
|
750
|
-
}
|
|
751
742
|
}
|
|
752
743
|
|
|
744
|
+
|
|
745
|
+
|
|
753
746
|
class SessionStorage extends Storage {
|
|
754
|
-
|
|
755
|
-
|
|
747
|
+
static save(k, v) {
|
|
748
|
+
sessionStorage.setItem(k, JSON.stringify(v));
|
|
749
|
+
}
|
|
750
|
+
static load(k) {
|
|
751
|
+
const got = sessionStorage.getItem(k);
|
|
752
|
+
return got === null ? undefined : JSON.parse(got);
|
|
753
|
+
}
|
|
754
|
+
static remove(k) {
|
|
755
|
+
sessionStorage.removeItem(k);
|
|
756
|
+
}
|
|
757
|
+
static pop(k) {
|
|
758
|
+
const decoded = SessionStorage.load(k);
|
|
759
|
+
SessionStorage.remove(k);
|
|
760
|
+
return decoded;
|
|
756
761
|
}
|
|
757
762
|
}
|
|
758
763
|
|
|
759
|
-
class
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
async load(revision) {
|
|
768
|
-
const saved = this.storage.load(this.key);
|
|
769
|
-
if (!!saved && saved.revision === revision) {
|
|
770
|
-
this.cache = saved.value;
|
|
771
|
-
return;
|
|
764
|
+
class VersionedLocalStorage {
|
|
765
|
+
static save(key, revision, data){
|
|
766
|
+
LocalStorage.save(key, {revision, data});
|
|
767
|
+
}
|
|
768
|
+
static load(key, revision){
|
|
769
|
+
const stored = LocalStorage.load(key);
|
|
770
|
+
if(stored === undefined){
|
|
771
|
+
return undefined;
|
|
772
772
|
}
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
this.cache = freshData;
|
|
773
|
+
if(stored.revision !== revision){
|
|
774
|
+
localStorage.removeItem(key);
|
|
775
|
+
return undefined;
|
|
776
|
+
}
|
|
777
|
+
return stored.data;
|
|
779
778
|
}
|
|
780
|
-
|
|
781
|
-
|
|
779
|
+
}
|
|
780
|
+
|
|
781
|
+
class VersionedSessionStorage {
|
|
782
|
+
static save(key, revision, data){
|
|
783
|
+
SessionStorage.save(key, {revision, data});
|
|
784
|
+
}
|
|
785
|
+
static load(key, revision){
|
|
786
|
+
const stored = SessionStorage.load(key);
|
|
787
|
+
if(stored === undefined){
|
|
788
|
+
return undefined;
|
|
789
|
+
}
|
|
790
|
+
if(stored.revision !== revision){
|
|
791
|
+
localStorage.removeItem(key);
|
|
792
|
+
return undefined;
|
|
793
|
+
}
|
|
794
|
+
return stored.data;
|
|
782
795
|
}
|
|
783
796
|
}
|
|
784
797
|
|
|
785
798
|
class AuthorizationCodeFlow {
|
|
786
|
-
static forKeycloak(clientId, realmBaseUrl, redirectUri) {
|
|
787
|
-
const scope = "openid profile";
|
|
799
|
+
static forKeycloak(clientId, realmBaseUrl, redirectUri, maybeScope) {
|
|
800
|
+
const scope = maybeScope ?? "openid profile";
|
|
788
801
|
return new AuthorizationCodeFlow(clientId, scope, {
|
|
789
802
|
auth: new URL("protocol/openid-connect/auth", realmBaseUrl),
|
|
790
803
|
token: new URL("protocol/openid-connect/token", realmBaseUrl),
|
|
@@ -794,7 +807,6 @@ var ful = (function (exports, ftl) {
|
|
|
794
807
|
});
|
|
795
808
|
}
|
|
796
809
|
constructor(clientId, scope, { auth, token, registration, logout, redirect }) {
|
|
797
|
-
this.storage = new SessionStorage(clientId);
|
|
798
810
|
this.clientId = clientId;
|
|
799
811
|
this.scope = scope;
|
|
800
812
|
this.uri = { auth, token, registration, logout, redirect };
|
|
@@ -803,7 +815,7 @@ var ful = (function (exports, ftl) {
|
|
|
803
815
|
const pkceVerifier = Base64.encode(crypto.getRandomValues(new Uint8Array(32)).buffer);
|
|
804
816
|
const pkceChallenge = Base64.encode(await crypto.subtle.digest("SHA-256", new TextEncoder().encode(pkceVerifier)));
|
|
805
817
|
const state = this.clientId + Base64.encode(crypto.getRandomValues(new Uint8Array(16)).buffer);
|
|
806
|
-
|
|
818
|
+
SessionStorage.save(`${AuthorizationCodeFlow.PKCE_AND_STATE_KEY}-${this.clientId}`, {
|
|
807
819
|
state: state,
|
|
808
820
|
verifier: pkceVerifier
|
|
809
821
|
});
|
|
@@ -831,7 +843,7 @@ var ful = (function (exports, ftl) {
|
|
|
831
843
|
}
|
|
832
844
|
async #tokenExchange(code, state) {
|
|
833
845
|
window.history.replaceState('', "", this.uri.redirect);
|
|
834
|
-
const stateAndVerifier =
|
|
846
|
+
const stateAndVerifier = SessionStorage.pop(`${AuthorizationCodeFlow.PKCE_AND_STATE_KEY}-${this.clientId}`);
|
|
835
847
|
if (stateAndVerifier.state !== state) {
|
|
836
848
|
throw new Error("State mismatch");
|
|
837
849
|
}
|
|
@@ -859,7 +871,7 @@ var ful = (function (exports, ftl) {
|
|
|
859
871
|
async ensureLoggedIn() {
|
|
860
872
|
const url = new URL(window.location.href);
|
|
861
873
|
const code = url.searchParams.get("code");
|
|
862
|
-
if (code &&
|
|
874
|
+
if (code && SessionStorage.load(`${AuthorizationCodeFlow.PKCE_AND_STATE_KEY}-${this.clientId}`)) {
|
|
863
875
|
//if callback from keycloak and we have our state still stored
|
|
864
876
|
const state = url.searchParams.get("state");
|
|
865
877
|
return await this.#tokenExchange(code, state);
|
|
@@ -1024,24 +1036,22 @@ var ful = (function (exports, ftl) {
|
|
|
1024
1036
|
}
|
|
1025
1037
|
}
|
|
1026
1038
|
|
|
1027
|
-
|
|
1028
|
-
sleep(ms) {
|
|
1039
|
+
class Timing {
|
|
1040
|
+
static sleep(ms) {
|
|
1029
1041
|
return new Promise(resolve => setTimeout(resolve, ms));
|
|
1030
|
-
}
|
|
1031
|
-
DEBOUNCE_DEFAULT
|
|
1032
|
-
DEBOUNCE_IMMEDIATE
|
|
1042
|
+
}
|
|
1043
|
+
static DEBOUNCE_DEFAULT = 0;
|
|
1044
|
+
static DEBOUNCE_IMMEDIATE = 1;
|
|
1033
1045
|
/**
|
|
1034
1046
|
* Executes only after a period of inactivity (pause in events).
|
|
1035
|
-
* Delays execution until events stop for a set duration.
|
|
1036
|
-
* Consolidates multiple rapid events into a single execution.
|
|
1037
1047
|
* Respond to the "end" of a series of events.
|
|
1038
1048
|
* @param {*} timeoutMs
|
|
1039
1049
|
* @param {*} func
|
|
1040
1050
|
* @param {*} [options]
|
|
1041
1051
|
* @returns {[function, function]}
|
|
1042
1052
|
*/
|
|
1043
|
-
debounce(timeoutMs, func, options) {
|
|
1044
|
-
const opts = options ??
|
|
1053
|
+
static debounce(timeoutMs, func, options) {
|
|
1054
|
+
const opts = options ?? Timing.DEBOUNCE_DEFAULT;
|
|
1045
1055
|
let tid = null;
|
|
1046
1056
|
let args = [];
|
|
1047
1057
|
let previousTimestamp = 0;
|
|
@@ -1053,7 +1063,7 @@ var ful = (function (exports, ftl) {
|
|
|
1053
1063
|
return;
|
|
1054
1064
|
}
|
|
1055
1065
|
tid = null;
|
|
1056
|
-
if (opts !==
|
|
1066
|
+
if (opts !== Timing.DEBOUNCE_IMMEDIATE) {
|
|
1057
1067
|
func(...args);
|
|
1058
1068
|
}
|
|
1059
1069
|
// This check is needed because `func` can recursively invoke `debounced`.
|
|
@@ -1067,31 +1077,32 @@ var ful = (function (exports, ftl) {
|
|
|
1067
1077
|
previousTimestamp = new Date().getTime();
|
|
1068
1078
|
if (tid === null) {
|
|
1069
1079
|
tid = setTimeout(later, timeoutMs);
|
|
1070
|
-
if (opts ===
|
|
1080
|
+
if (opts === Timing.DEBOUNCE_IMMEDIATE) {
|
|
1071
1081
|
func(...args);
|
|
1072
1082
|
}
|
|
1073
1083
|
}
|
|
1074
1084
|
};
|
|
1075
1085
|
const abort = () => clearTimeout(tid);
|
|
1076
1086
|
return [debounced, abort];
|
|
1077
|
-
}
|
|
1078
|
-
THROTTLE_DEFAULT
|
|
1079
|
-
THROTTLE_NO_LEADING
|
|
1080
|
-
THROTTLE_NO_TRAILING
|
|
1087
|
+
}
|
|
1088
|
+
static THROTTLE_DEFAULT = 0;
|
|
1089
|
+
static THROTTLE_NO_LEADING = 1;
|
|
1090
|
+
static THROTTLE_NO_TRAILING = 2;
|
|
1081
1091
|
/**
|
|
1082
1092
|
* Executes at most once per specified time interval, regardless of ongoing events.
|
|
1083
|
-
*
|
|
1084
|
-
*
|
|
1085
|
-
*
|
|
1093
|
+
* @param {*} timeoutMs
|
|
1094
|
+
* @param {*} func
|
|
1095
|
+
* @param {*} [options]
|
|
1096
|
+
* @returns {[function, function]}
|
|
1086
1097
|
*/
|
|
1087
|
-
throttle(timeoutMs, func, options) {
|
|
1088
|
-
const opts = options ??
|
|
1098
|
+
static throttle(timeoutMs, func, options) {
|
|
1099
|
+
const opts = options ?? Timing.THROTTLE_DEFAULT;
|
|
1089
1100
|
let tid = null;
|
|
1090
1101
|
let args = [];
|
|
1091
1102
|
let previousTimestamp = 0;
|
|
1092
1103
|
|
|
1093
1104
|
const later = () => {
|
|
1094
|
-
previousTimestamp = (opts &
|
|
1105
|
+
previousTimestamp = (opts & Timing.THROTTLE_NO_LEADING) ? 0 : new Date().getTime();
|
|
1095
1106
|
tid = null;
|
|
1096
1107
|
func(...args);
|
|
1097
1108
|
if (tid === null) {
|
|
@@ -1100,7 +1111,7 @@ var ful = (function (exports, ftl) {
|
|
|
1100
1111
|
};
|
|
1101
1112
|
const throttled = function () {
|
|
1102
1113
|
const now = new Date().getTime();
|
|
1103
|
-
if (!previousTimestamp && (opts &
|
|
1114
|
+
if (!previousTimestamp && (opts & Timing.THROTTLE_NO_LEADING)) {
|
|
1104
1115
|
previousTimestamp = now;
|
|
1105
1116
|
}
|
|
1106
1117
|
const remaining = timeoutMs - (now - previousTimestamp);
|
|
@@ -1115,14 +1126,14 @@ var ful = (function (exports, ftl) {
|
|
|
1115
1126
|
if (tid === null) {
|
|
1116
1127
|
args = [];
|
|
1117
1128
|
}
|
|
1118
|
-
} else if (tid === null && !(opts &
|
|
1129
|
+
} else if (tid === null && !(opts & Timing.THROTTLE_NO_TRAILING)) {
|
|
1119
1130
|
tid = setTimeout(later, remaining);
|
|
1120
1131
|
}
|
|
1121
1132
|
};
|
|
1122
1133
|
const abort = () => clearTimeout(tid);
|
|
1123
1134
|
return [throttled, abort];
|
|
1124
1135
|
}
|
|
1125
|
-
}
|
|
1136
|
+
}
|
|
1126
1137
|
|
|
1127
1138
|
class Loaders {
|
|
1128
1139
|
static fromAttributes(el, defaultLoader, options) {
|
|
@@ -1437,24 +1448,30 @@ var ful = (function (exports, ftl) {
|
|
|
1437
1448
|
<ful-field-error></ful-field-error>
|
|
1438
1449
|
`;
|
|
1439
1450
|
static formAssociated = true;
|
|
1440
|
-
|
|
1441
|
-
|
|
1451
|
+
_input;
|
|
1452
|
+
_fieldError;
|
|
1442
1453
|
constructor() {
|
|
1443
1454
|
super();
|
|
1444
1455
|
this.internals = this.attachInternals();
|
|
1445
1456
|
this.internals.role = 'presentation';
|
|
1446
1457
|
}
|
|
1458
|
+
_type() {
|
|
1459
|
+
return this.getAttribute("type") ?? 'text';
|
|
1460
|
+
}
|
|
1461
|
+
_fragment(type, slots) {
|
|
1462
|
+
return this.template().withOverlay({ type, slots }).render();
|
|
1463
|
+
}
|
|
1447
1464
|
render({ slots, observed, disabled }) {
|
|
1448
|
-
const type = this.
|
|
1449
|
-
const fragment = this.
|
|
1450
|
-
this
|
|
1465
|
+
const type = this._type();
|
|
1466
|
+
const fragment = this._fragment(type, slots);
|
|
1467
|
+
this._input = fragment.querySelector("input,textarea");
|
|
1451
1468
|
|
|
1452
|
-
ftl.Attributes.forward('input-', this, this
|
|
1469
|
+
ftl.Attributes.forward('input-', this, this._input);
|
|
1453
1470
|
this.disabled = disabled;
|
|
1454
1471
|
this.readonly = observed.readonly;
|
|
1455
1472
|
this.value = observed.value;
|
|
1456
1473
|
|
|
1457
|
-
this
|
|
1474
|
+
this._input.addEventListener('change', (evt) => {
|
|
1458
1475
|
evt.stopPropagation();
|
|
1459
1476
|
this.dispatchEvent(new CustomEvent('change', {
|
|
1460
1477
|
bubbles: true,
|
|
@@ -1466,59 +1483,187 @@ var ful = (function (exports, ftl) {
|
|
|
1466
1483
|
});
|
|
1467
1484
|
const label = fragment.querySelector('label');
|
|
1468
1485
|
label.addEventListener('click', () => this.focus());
|
|
1469
|
-
this
|
|
1470
|
-
this
|
|
1471
|
-
this
|
|
1486
|
+
this._fieldError = fragment.querySelector('ful-field-error');
|
|
1487
|
+
this._input.ariaDescribedByElements = [this._fieldError];
|
|
1488
|
+
this._input.ariaLabelledByElements = [label];
|
|
1472
1489
|
this.replaceChildren(fragment);
|
|
1473
1490
|
}
|
|
1474
1491
|
get value() {
|
|
1475
|
-
return this
|
|
1492
|
+
return this._input.value === '' ? null : this._input.value;
|
|
1476
1493
|
}
|
|
1477
1494
|
set value(value) {
|
|
1478
|
-
this
|
|
1495
|
+
this._input.value = value === '' ? null : value;
|
|
1479
1496
|
}
|
|
1480
|
-
get readonly(){
|
|
1481
|
-
return this
|
|
1497
|
+
get readonly() {
|
|
1498
|
+
return this._input.readOnly;
|
|
1482
1499
|
}
|
|
1483
1500
|
set readonly(v) {
|
|
1484
|
-
this
|
|
1485
|
-
}
|
|
1486
|
-
get disabled(){
|
|
1487
|
-
return this.#input.hasAttribute('disabled');
|
|
1501
|
+
this._input.readOnly = v;
|
|
1488
1502
|
}
|
|
1489
|
-
|
|
1490
|
-
|
|
1503
|
+
//@ts-ignore
|
|
1504
|
+
get disabled() {
|
|
1505
|
+
return this._input.hasAttribute('disabled');
|
|
1506
|
+
}
|
|
1507
|
+
set disabled(d) {
|
|
1508
|
+
ftl.Attributes.toggle(this._input, 'disabled', d);
|
|
1491
1509
|
}
|
|
1492
1510
|
focus(options) {
|
|
1493
|
-
this
|
|
1511
|
+
this._input.focus(options);
|
|
1494
1512
|
}
|
|
1495
1513
|
setCustomValidity(error) {
|
|
1496
1514
|
if (!error) {
|
|
1497
1515
|
this.internals.setValidity({});
|
|
1498
|
-
this
|
|
1516
|
+
this._fieldError.innerText = "";
|
|
1499
1517
|
return;
|
|
1500
1518
|
}
|
|
1501
1519
|
this.internals.setValidity({ customError: true }, " ");
|
|
1502
|
-
this
|
|
1520
|
+
this._fieldError.innerText = error;
|
|
1503
1521
|
}
|
|
1504
|
-
formResetCallback(){
|
|
1522
|
+
formResetCallback() {
|
|
1505
1523
|
this.value = this.getAttribute("value");
|
|
1506
1524
|
}
|
|
1507
1525
|
}
|
|
1508
1526
|
|
|
1509
|
-
class
|
|
1527
|
+
class LocalDate extends ftl.ParsedElement {
|
|
1528
|
+
render() {
|
|
1529
|
+
const content = this.innerHTML.trim();
|
|
1530
|
+
if (content === '') {
|
|
1531
|
+
this.innerHTML = this.getAttribute('default') ?? '';
|
|
1532
|
+
return;
|
|
1533
|
+
}
|
|
1534
|
+
const locale = this.getAttribute("locale") ?? Intl.DateTimeFormat().resolvedOptions().locale;
|
|
1535
|
+
const formatter = new Intl.DateTimeFormat(locale, { year: 'numeric', month: 'numeric', day: 'numeric' });
|
|
1536
|
+
const [y, m, d] = content.split('-').map(Number);
|
|
1537
|
+
this.innerHTML = formatter.format(new Date(y, m - 1, d));
|
|
1538
|
+
}
|
|
1539
|
+
}
|
|
1540
|
+
|
|
1541
|
+
class Instant extends ftl.ParsedElement {
|
|
1542
|
+
render() {
|
|
1543
|
+
const content = this.innerHTML.trim();
|
|
1544
|
+
if (content === '') {
|
|
1545
|
+
this.innerHTML = this.getAttribute('default') ?? '';
|
|
1546
|
+
return;
|
|
1547
|
+
}
|
|
1548
|
+
const locale = this.getAttribute("locale") ?? Intl.DateTimeFormat().resolvedOptions().locale;
|
|
1549
|
+
const format = new Intl.DateTimeFormat(locale, {
|
|
1550
|
+
year: 'numeric',
|
|
1551
|
+
month: 'numeric',
|
|
1552
|
+
day: 'numeric',
|
|
1553
|
+
hour: 'numeric',
|
|
1554
|
+
minute: 'numeric',
|
|
1555
|
+
second: 'numeric',
|
|
1556
|
+
hour12: false
|
|
1557
|
+
});
|
|
1558
|
+
this.innerHTML = format.format(new Date(Instant.isoToLocal(content)));
|
|
1559
|
+
}
|
|
1560
|
+
static isoToLocal(iso) {
|
|
1561
|
+
//this is so sad
|
|
1562
|
+
const d = new Date(iso);
|
|
1563
|
+
const pad = (n, v) => String(v).padStart(n, '0');
|
|
1564
|
+
const date = `${d.getFullYear()}-${pad(2, d.getMonth() + 1)}-${pad(2, d.getDate())}`;
|
|
1565
|
+
const time = `${pad(2, d.getHours())}:${pad(2, d.getMinutes())}:${pad(2, d.getSeconds())}.${pad(3, d.getMilliseconds())}`;
|
|
1566
|
+
return `${date}T${time}`
|
|
1567
|
+
}
|
|
1568
|
+
}
|
|
1569
|
+
|
|
1570
|
+
|
|
1571
|
+
class InputLocalDate extends Input {
|
|
1572
|
+
static observed = ['value', 'readonly:presence', 'min', 'max', 'step'];
|
|
1573
|
+
_type() {
|
|
1574
|
+
return 'date';
|
|
1575
|
+
}
|
|
1576
|
+
get min() {
|
|
1577
|
+
const v = this._input.min;
|
|
1578
|
+
return v === '' ? null : v;
|
|
1579
|
+
}
|
|
1580
|
+
set min(v) {
|
|
1581
|
+
this._input.min = v;
|
|
1582
|
+
}
|
|
1583
|
+
get max() {
|
|
1584
|
+
const v = this._input.max;
|
|
1585
|
+
return v === '' ? null : v;
|
|
1586
|
+
}
|
|
1587
|
+
set max(v) {
|
|
1588
|
+
this._input.max = v;
|
|
1589
|
+
}
|
|
1590
|
+
get step() {
|
|
1591
|
+
const v = this._input.step;
|
|
1592
|
+
return v === '' ? null : v;
|
|
1593
|
+
}
|
|
1594
|
+
set step(v) {
|
|
1595
|
+
this._input.step = (v ?? '');
|
|
1596
|
+
}
|
|
1597
|
+
|
|
1598
|
+
}
|
|
1599
|
+
|
|
1600
|
+
class InputLocalTime extends InputLocalDate {
|
|
1601
|
+
_type() {
|
|
1602
|
+
return 'time';
|
|
1603
|
+
}
|
|
1604
|
+
}
|
|
1605
|
+
|
|
1606
|
+
|
|
1607
|
+
class InputInstant extends Input {
|
|
1608
|
+
static observed = ['value', 'readonly:presence', 'min', 'max', 'step'];
|
|
1609
|
+
_type() {
|
|
1610
|
+
return 'datetime-local';
|
|
1611
|
+
}
|
|
1612
|
+
get value() {
|
|
1613
|
+
const v = this._input.value;
|
|
1614
|
+
return v === '' ? null : new Date(v).toISOString();
|
|
1615
|
+
}
|
|
1616
|
+
set value(v) {
|
|
1617
|
+
this._input.value = v ? Instant.isoToLocal(v) : '';
|
|
1618
|
+
}
|
|
1619
|
+
get min() {
|
|
1620
|
+
const v = this._input.min;
|
|
1621
|
+
return v === '' ? null : new Date(v).toISOString();
|
|
1622
|
+
}
|
|
1623
|
+
set min(v) {
|
|
1624
|
+
this._input.min = v ? Instant.isoToLocal(v) : '';
|
|
1625
|
+
}
|
|
1626
|
+
get max() {
|
|
1627
|
+
const v = this._input.max;
|
|
1628
|
+
return v === '' ? null : new Date(v).toISOString();
|
|
1629
|
+
}
|
|
1630
|
+
set max(v) {
|
|
1631
|
+
this._input.max = v ? Instant.isoToLocal(v) : '';
|
|
1632
|
+
}
|
|
1633
|
+
get step() {
|
|
1634
|
+
const v = this._input.step;
|
|
1635
|
+
return v === '' ? null : v;
|
|
1636
|
+
}
|
|
1637
|
+
set step(v) {
|
|
1638
|
+
this._input.step = (v ?? '');
|
|
1639
|
+
}
|
|
1640
|
+
}
|
|
1641
|
+
|
|
1642
|
+
class RemoteLoader {
|
|
1510
1643
|
#http;
|
|
1511
1644
|
#url;
|
|
1512
1645
|
#method;
|
|
1513
1646
|
#responseMapper;
|
|
1514
1647
|
#prefetch;
|
|
1648
|
+
#revision;
|
|
1515
1649
|
#data;
|
|
1516
|
-
|
|
1650
|
+
static create({ el, http, responseMapper }) {
|
|
1651
|
+
return new RemoteLoader({
|
|
1652
|
+
http,
|
|
1653
|
+
url: el.getAttribute("src"),
|
|
1654
|
+
method: el.getAttribute("method") ?? 'POST',
|
|
1655
|
+
responseMapper,
|
|
1656
|
+
prefetch: el.hasAttribute("preload"),
|
|
1657
|
+
revision: el.getAttribute("revision")
|
|
1658
|
+
});
|
|
1659
|
+
}
|
|
1660
|
+
constructor({http, url, method, responseMapper, prefetch, revision}) {
|
|
1517
1661
|
this.#http = http;
|
|
1518
1662
|
this.#url = url;
|
|
1519
1663
|
this.#method = method;
|
|
1520
1664
|
this.#responseMapper = responseMapper;
|
|
1521
1665
|
this.#prefetch = prefetch;
|
|
1666
|
+
this.#revision = revision;
|
|
1522
1667
|
this.#data = null;
|
|
1523
1668
|
}
|
|
1524
1669
|
async prefetch() {
|
|
@@ -1529,37 +1674,47 @@ var ful = (function (exports, ftl) {
|
|
|
1529
1674
|
}
|
|
1530
1675
|
async exact(...keys) {
|
|
1531
1676
|
await this.#ensureFetched();
|
|
1532
|
-
return this.#data.filter(([k, v]) => keys.
|
|
1677
|
+
return this.#data.filter(([k, v]) => keys.some(r => r == k));
|
|
1533
1678
|
}
|
|
1534
1679
|
async load(needle) {
|
|
1535
1680
|
await this.#ensureFetched();
|
|
1536
|
-
return this.#data.filter(([k, v]) => v.includes(needle?.toLowerCase()));
|
|
1681
|
+
return this.#data.filter(([k, v]) => (v ?? '').includes(needle?.toLowerCase()));
|
|
1537
1682
|
}
|
|
1538
1683
|
async #ensureFetched() {
|
|
1539
1684
|
if (this.#data !== null) {
|
|
1540
1685
|
return
|
|
1541
1686
|
}
|
|
1687
|
+
const storageKey = `${this.#method}@${this.#url}`;
|
|
1688
|
+
if(this.#revision !== null){
|
|
1689
|
+
const data = VersionedLocalStorage.load(storageKey, this.#revision);
|
|
1690
|
+
if(data !== undefined){
|
|
1691
|
+
this.#data = data;
|
|
1692
|
+
return;
|
|
1693
|
+
}
|
|
1694
|
+
}
|
|
1542
1695
|
const data = await this.#http.request(this.#method, this.#url)
|
|
1543
1696
|
.fetchJson();
|
|
1544
1697
|
this.#data = this.#responseMapper(data);
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
http,
|
|
1549
|
-
el.getAttribute("src"),
|
|
1550
|
-
el.getAttribute("method") ?? 'POST',
|
|
1551
|
-
responseMapper,
|
|
1552
|
-
el.hasAttribute("preload")
|
|
1553
|
-
);
|
|
1698
|
+
if(this.#revision !== null){
|
|
1699
|
+
VersionedLocalStorage.save(storageKey, this.#revision, this.#data);
|
|
1700
|
+
}
|
|
1554
1701
|
}
|
|
1555
1702
|
}
|
|
1556
1703
|
|
|
1557
|
-
class
|
|
1704
|
+
class PartialRemoteLoader {
|
|
1558
1705
|
#http;
|
|
1559
1706
|
#url;
|
|
1560
1707
|
#method;
|
|
1561
1708
|
#responseMapper;
|
|
1562
|
-
|
|
1709
|
+
static create({ el, http, responseMapper }) {
|
|
1710
|
+
return new PartialRemoteLoader({
|
|
1711
|
+
http,
|
|
1712
|
+
url: el.getAttribute("src"),
|
|
1713
|
+
method: el.getAttribute("method") ?? 'POST',
|
|
1714
|
+
responseMapper
|
|
1715
|
+
});
|
|
1716
|
+
}
|
|
1717
|
+
constructor({http, url, method, responseMapper}) {
|
|
1563
1718
|
this.#http = http;
|
|
1564
1719
|
this.#url = url;
|
|
1565
1720
|
this.#method = method;
|
|
@@ -1577,26 +1732,21 @@ var ful = (function (exports, ftl) {
|
|
|
1577
1732
|
.fetchJson();
|
|
1578
1733
|
return this.#responseMapper(data);
|
|
1579
1734
|
}
|
|
1580
|
-
static create({ el, http, responseMapper }) {
|
|
1581
|
-
return new ChunkedSelectLoader(
|
|
1582
|
-
http,
|
|
1583
|
-
el.getAttribute("src"),
|
|
1584
|
-
el.getAttribute("method") ?? 'POST',
|
|
1585
|
-
responseMapper
|
|
1586
|
-
);
|
|
1587
|
-
}
|
|
1588
1735
|
}
|
|
1589
1736
|
|
|
1590
|
-
class
|
|
1737
|
+
class InMemoryLoader {
|
|
1591
1738
|
#data
|
|
1592
1739
|
constructor(data) {
|
|
1593
1740
|
this.#data = data;
|
|
1594
1741
|
}
|
|
1595
|
-
|
|
1596
|
-
|
|
1742
|
+
update(data) {
|
|
1743
|
+
this.#data = data;
|
|
1597
1744
|
}
|
|
1598
|
-
|
|
1599
|
-
return this.#data.filter(([k, v]) =>
|
|
1745
|
+
exact(...keys) {
|
|
1746
|
+
return this.#data.filter(([k, v]) => keys.some(r => r == k));
|
|
1747
|
+
}
|
|
1748
|
+
load(needle) {
|
|
1749
|
+
return this.#data.filter(([k, v]) => (v ?? '').includes(needle?.toLowerCase()));
|
|
1600
1750
|
}
|
|
1601
1751
|
}
|
|
1602
1752
|
|
|
@@ -1608,10 +1758,10 @@ var ful = (function (exports, ftl) {
|
|
|
1608
1758
|
const data = els.map(e => {
|
|
1609
1759
|
return [e.getAttribute("value") ?? e.innerText.trim(), e.innerText.trim()];
|
|
1610
1760
|
});
|
|
1611
|
-
return new
|
|
1761
|
+
return new InMemoryLoader(data);
|
|
1612
1762
|
}
|
|
1613
1763
|
const chunked = "chunked" == conf.el.getAttribute("mode");
|
|
1614
|
-
return chunked ?
|
|
1764
|
+
return chunked ? PartialRemoteLoader.create(conf) : RemoteLoader.create(conf);
|
|
1615
1765
|
}
|
|
1616
1766
|
}
|
|
1617
1767
|
|
|
@@ -1621,8 +1771,9 @@ var ful = (function (exports, ftl) {
|
|
|
1621
1771
|
<ful-spinner class="centered" hidden></ful-spinner>
|
|
1622
1772
|
<menu tabindex="-1" hidden></menu>
|
|
1623
1773
|
`;
|
|
1624
|
-
#spinner
|
|
1625
|
-
#menu
|
|
1774
|
+
#spinner;
|
|
1775
|
+
#menu;
|
|
1776
|
+
#options = new Map();
|
|
1626
1777
|
render({ slots }) {
|
|
1627
1778
|
const fragment = this.template().render();
|
|
1628
1779
|
this.#spinner = fragment.querySelector("ful-spinner");
|
|
@@ -1645,30 +1796,31 @@ var ful = (function (exports, ftl) {
|
|
|
1645
1796
|
if (values === undefined) {
|
|
1646
1797
|
throw new Error("null data");
|
|
1647
1798
|
}
|
|
1799
|
+
this.#options = new Map(values.map((v,i) => [String(i), v]));
|
|
1648
1800
|
if (values.length === 0) {
|
|
1649
1801
|
const el = document.createElement('div');
|
|
1650
1802
|
el.classList.add('text-center', 'py-2', 'bi', 'bi-database-slash');
|
|
1651
1803
|
this.#menu.replaceChildren(el);
|
|
1652
1804
|
return;
|
|
1653
1805
|
}
|
|
1654
|
-
this.#menu.replaceChildren(...values.map(([k, v], i) => {
|
|
1806
|
+
this.#menu.replaceChildren(...values.map(([k, v, m], i) => {
|
|
1655
1807
|
const el = document.createElement('li');
|
|
1656
1808
|
if (i === 0) {
|
|
1657
1809
|
el.setAttribute("selected", '');
|
|
1658
1810
|
}
|
|
1659
|
-
el.setAttribute("value",
|
|
1811
|
+
el.setAttribute("value", i);
|
|
1660
1812
|
el.innerText = v;
|
|
1661
1813
|
return el;
|
|
1662
1814
|
}));
|
|
1663
1815
|
}
|
|
1664
1816
|
#change(target) {
|
|
1665
|
-
const
|
|
1666
|
-
const
|
|
1817
|
+
const index = target.getAttribute('value');
|
|
1818
|
+
const data = this.#options.get(index);
|
|
1667
1819
|
this.hide();
|
|
1668
1820
|
this.dispatchEvent(new CustomEvent('change', {
|
|
1669
1821
|
bubbles: true,
|
|
1670
1822
|
cancelable: false,
|
|
1671
|
-
detail: {
|
|
1823
|
+
detail: { index, data }
|
|
1672
1824
|
}));
|
|
1673
1825
|
}
|
|
1674
1826
|
hide() {
|
|
@@ -1690,12 +1842,13 @@ var ful = (function (exports, ftl) {
|
|
|
1690
1842
|
}
|
|
1691
1843
|
}
|
|
1692
1844
|
async moveOrShow(forward, loader) {
|
|
1693
|
-
if (
|
|
1845
|
+
if (this.shown) {
|
|
1694
1846
|
const selected = this.#menu.querySelector('[selected]') ?? this.#menu.firstElementChild;
|
|
1695
1847
|
const candidate = selected[`${forward ? 'next' : 'previous'}ElementSibling`];
|
|
1696
1848
|
if (candidate) {
|
|
1697
1849
|
selected.removeAttribute('selected');
|
|
1698
1850
|
candidate.setAttribute("selected", "");
|
|
1851
|
+
candidate.scrollIntoView({block: "nearest", behavior: "smooth"});
|
|
1699
1852
|
}
|
|
1700
1853
|
return;
|
|
1701
1854
|
}
|
|
@@ -1714,14 +1867,16 @@ var ful = (function (exports, ftl) {
|
|
|
1714
1867
|
<div class="input-group flex-nowrap" tabindex="-1">
|
|
1715
1868
|
<span data-tpl-if="slots.ibefore" class="input-group-text">{{{{ slots.ibefore }}}}</span>
|
|
1716
1869
|
{{{{ slots.before }}}}
|
|
1717
|
-
<div class="ful-select-input">
|
|
1718
|
-
<
|
|
1719
|
-
|
|
1870
|
+
<div class="ful-select-input-container">
|
|
1871
|
+
<div class="ful-select-input">
|
|
1872
|
+
<badges></badges>
|
|
1873
|
+
<input type="text" form="">
|
|
1874
|
+
</div>
|
|
1875
|
+
<ful-dropdown hidden popover="manual"></ful-dropdown>
|
|
1720
1876
|
</div>
|
|
1721
1877
|
{{{{ slots.after }}}}
|
|
1722
1878
|
<span data-tpl-if="slots.iafter" class="input-group-text">{{{{ slots.iafter }}}}</span>
|
|
1723
1879
|
</div>
|
|
1724
|
-
<ful-dropdown hidden></ful-dropdown>
|
|
1725
1880
|
<ful-field-error></ful-field-error>
|
|
1726
1881
|
`;
|
|
1727
1882
|
static mappers = {
|
|
@@ -1749,6 +1904,7 @@ var ful = (function (exports, ftl) {
|
|
|
1749
1904
|
async render({ slots, observed, disabled }) {
|
|
1750
1905
|
const name = this.getAttribute("name");
|
|
1751
1906
|
this.#loader = Loaders.fromAttributes(this, 'loaders:select', { options: slots.options });
|
|
1907
|
+
this.#multiple = this.hasAttribute("multiple");
|
|
1752
1908
|
await this.#loader.prefetch?.();
|
|
1753
1909
|
const fragment = this.template().withOverlay({ slots, name }).render();
|
|
1754
1910
|
this.#input = fragment.querySelector('input');
|
|
@@ -1759,7 +1915,6 @@ var ful = (function (exports, ftl) {
|
|
|
1759
1915
|
this.readonly = observed.readonly;
|
|
1760
1916
|
|
|
1761
1917
|
this.#ddmenu = fragment.querySelector('ful-dropdown');
|
|
1762
|
-
this.#multiple = this.hasAttribute("multiple");
|
|
1763
1918
|
const label = fragment.querySelector('label');
|
|
1764
1919
|
label.addEventListener('click', () => this.focus());
|
|
1765
1920
|
this.#fieldError = fragment.querySelector('ful-field-error');
|
|
@@ -1767,12 +1922,14 @@ var ful = (function (exports, ftl) {
|
|
|
1767
1922
|
this.#input.ariaLabelledByElements = [label];
|
|
1768
1923
|
|
|
1769
1924
|
const self = this;
|
|
1770
|
-
const [dload, abortdload] =
|
|
1925
|
+
const [dload, abortdload] = Timing.throttle(400, () => self.#ddmenu.show(() => self.#loader.load(self.#input.value)));
|
|
1771
1926
|
this.addEventListener('click', (/** @type any */e) => {
|
|
1772
|
-
e.stopPropagation();
|
|
1773
1927
|
if (e.target.matches('input')) {
|
|
1774
1928
|
return;
|
|
1775
1929
|
}
|
|
1930
|
+
if(this.disabled || this.readonly){
|
|
1931
|
+
return;
|
|
1932
|
+
}
|
|
1776
1933
|
if (this.#ddmenu.shown) {
|
|
1777
1934
|
this.#ddmenu.hide();
|
|
1778
1935
|
return;
|
|
@@ -1782,15 +1939,20 @@ var ful = (function (exports, ftl) {
|
|
|
1782
1939
|
});
|
|
1783
1940
|
this.#badges.addEventListener('click', (e) => {
|
|
1784
1941
|
e.stopPropagation();
|
|
1942
|
+
if(this.disabled || this.readonly){
|
|
1943
|
+
return;
|
|
1944
|
+
}
|
|
1785
1945
|
const idx = [...this.#badges.children].indexOf(e.target);
|
|
1786
1946
|
if (idx === -1) {
|
|
1787
1947
|
return;
|
|
1788
1948
|
}
|
|
1789
1949
|
this.#values.delete(Array.from(this.#values.keys()).pop());
|
|
1950
|
+
this.#changed();
|
|
1790
1951
|
this.#syncBadges();
|
|
1791
1952
|
});
|
|
1792
1953
|
|
|
1793
1954
|
this.#input.addEventListener('blur', e => {
|
|
1955
|
+
e.stopPropagation();
|
|
1794
1956
|
if (e.relatedTarget && this.contains(e.relatedTarget)) {
|
|
1795
1957
|
return;
|
|
1796
1958
|
}
|
|
@@ -1799,6 +1961,10 @@ var ful = (function (exports, ftl) {
|
|
|
1799
1961
|
this.#input.value = '';
|
|
1800
1962
|
});
|
|
1801
1963
|
this.#input.addEventListener('keydown', e => {
|
|
1964
|
+
e.stopPropagation();
|
|
1965
|
+
if(this.disabled || this.readonly){
|
|
1966
|
+
return;
|
|
1967
|
+
}
|
|
1802
1968
|
switch (e.code) {
|
|
1803
1969
|
case 'ArrowUp': {
|
|
1804
1970
|
this.#ddmenu.moveOrShow(false, () => self.#loader.load(self.#input.value));
|
|
@@ -1821,6 +1987,7 @@ var ful = (function (exports, ftl) {
|
|
|
1821
1987
|
//remove last if caret a position 0
|
|
1822
1988
|
if (this.#values.size && this.#input.selectionStart === 0 && this.#input.selectionEnd === 0) {
|
|
1823
1989
|
this.#values.delete(Array.from(this.#values.keys()).pop());
|
|
1990
|
+
this.#changed();
|
|
1824
1991
|
this.#syncBadges();
|
|
1825
1992
|
}
|
|
1826
1993
|
break;
|
|
@@ -1833,19 +2000,37 @@ var ful = (function (exports, ftl) {
|
|
|
1833
2000
|
}
|
|
1834
2001
|
});
|
|
1835
2002
|
this.#input.addEventListener('input', e => {
|
|
2003
|
+
e.stopPropagation();
|
|
2004
|
+
if(this.disabled || this.readonly){
|
|
2005
|
+
return;
|
|
2006
|
+
}
|
|
1836
2007
|
dload();
|
|
1837
2008
|
});
|
|
1838
2009
|
this.#ddmenu.addEventListener('change', (e) => {
|
|
2010
|
+
e.stopPropagation();
|
|
1839
2011
|
if (!this.#multiple) {
|
|
1840
2012
|
this.#values.clear();
|
|
1841
2013
|
}
|
|
1842
|
-
this.#values.set(e.detail.
|
|
2014
|
+
this.#values.set(e.detail.data[0], e.detail.data.slice(1));
|
|
2015
|
+
this.#changed();
|
|
1843
2016
|
this.#syncBadges();
|
|
1844
2017
|
this.#input.focus();
|
|
1845
2018
|
this.#ddmenu.hide();
|
|
1846
2019
|
});
|
|
1847
2020
|
this.replaceChildren(fragment);
|
|
1848
2021
|
}
|
|
2022
|
+
withLoader(fn) {
|
|
2023
|
+
fn(this.#loader);
|
|
2024
|
+
}
|
|
2025
|
+
#changed() {
|
|
2026
|
+
const selection = [...this.#values.entries()].map(e => ({key: e[0], label: e[1][0], metadata: e[1].slice(1)}));
|
|
2027
|
+
const value = this.#multiple ? selection : (selection[0] ?? null);
|
|
2028
|
+
this.dispatchEvent(new CustomEvent('change', {
|
|
2029
|
+
bubbles: true,
|
|
2030
|
+
cancelable: false,
|
|
2031
|
+
detail: { value }
|
|
2032
|
+
}));
|
|
2033
|
+
}
|
|
1849
2034
|
#syncBadges() {
|
|
1850
2035
|
const badges = Array.from(this.#values.entries()).map(([k, v]) => {
|
|
1851
2036
|
const b = document.createElement('badge');
|
|
@@ -1857,14 +2042,14 @@ var ful = (function (exports, ftl) {
|
|
|
1857
2042
|
this.#badges.innerHTML = '';
|
|
1858
2043
|
this.#badges.append(...badges);
|
|
1859
2044
|
}
|
|
1860
|
-
set value(
|
|
1861
|
-
if(
|
|
2045
|
+
set value(vs) {
|
|
2046
|
+
if(vs === null){
|
|
1862
2047
|
this.#values = new Map();
|
|
1863
2048
|
this.#syncBadges();
|
|
1864
2049
|
return;
|
|
1865
2050
|
}
|
|
1866
2051
|
(async () => {
|
|
1867
|
-
const entries = await (this.#multiple ? this.#loader.exact(...
|
|
2052
|
+
const entries = await (this.#multiple ? this.#loader.exact(...vs) : this.#loader.exact(vs));
|
|
1868
2053
|
this.#values = new Map(entries);
|
|
1869
2054
|
this.#syncBadges();
|
|
1870
2055
|
})();
|
|
@@ -1875,6 +2060,25 @@ var ful = (function (exports, ftl) {
|
|
|
1875
2060
|
}
|
|
1876
2061
|
return [...this.#values.keys()][0] ?? null;
|
|
1877
2062
|
}
|
|
2063
|
+
get entry() {
|
|
2064
|
+
if (this.#multiple) {
|
|
2065
|
+
return [...this.#values.entries()];
|
|
2066
|
+
}
|
|
2067
|
+
return [...this.#values.entries()][0] ?? null;
|
|
2068
|
+
}
|
|
2069
|
+
//@ts-ignore
|
|
2070
|
+
get disabled(){
|
|
2071
|
+
return this.#input.hasAttribute('disabled');
|
|
2072
|
+
}
|
|
2073
|
+
set disabled(d){
|
|
2074
|
+
ftl.Attributes.toggle(this.#input, 'disabled', d);
|
|
2075
|
+
}
|
|
2076
|
+
get readonly(){
|
|
2077
|
+
return this.#input.readOnly;
|
|
2078
|
+
}
|
|
2079
|
+
set readonly(v) {
|
|
2080
|
+
this.#input.readOnly = v;
|
|
2081
|
+
}
|
|
1878
2082
|
focus(options) {
|
|
1879
2083
|
this.#input.focus(options);
|
|
1880
2084
|
}
|
|
@@ -2540,21 +2744,12 @@ var ful = (function (exports, ftl) {
|
|
|
2540
2744
|
}
|
|
2541
2745
|
const [operator, ...values] = v;
|
|
2542
2746
|
this.#operator.setAttribute('value', operator);
|
|
2543
|
-
this.#value1.value = values[0] ?
|
|
2544
|
-
this.#value2.value = values[1] ?
|
|
2747
|
+
this.#value1.value = values[0] ? Instant.isoToLocal(values[0]) : values[0];
|
|
2748
|
+
this.#value2.value = values[1] ? Instant.isoToLocal(values[1]) : values[1];
|
|
2545
2749
|
this.reflect(() => {
|
|
2546
2750
|
this.setAttribute('value', JSON.stringify(v));
|
|
2547
2751
|
});
|
|
2548
2752
|
}
|
|
2549
|
-
|
|
2550
|
-
static isoToLocal(iso) {
|
|
2551
|
-
//this is so sad
|
|
2552
|
-
const d = new Date(iso);
|
|
2553
|
-
const pad = (n, v) => String(v).padStart(n, '0');
|
|
2554
|
-
const date = `${d.getFullYear()}-${pad(2, d.getMonth() + 1)}-${pad(2, d.getDate())}`;
|
|
2555
|
-
const time = `${pad(2, d.getHours())}:${pad(2, d.getMinutes())}:${pad(2, d.getSeconds())}.${pad(3, d.getMilliseconds())}`;
|
|
2556
|
-
return `${date}T${time}`
|
|
2557
|
-
}
|
|
2558
2753
|
focus(options) {
|
|
2559
2754
|
this.#value1.focus(options);
|
|
2560
2755
|
}
|
|
@@ -2763,6 +2958,11 @@ var ful = (function (exports, ftl) {
|
|
|
2763
2958
|
.defineElement('ful-form', Form)
|
|
2764
2959
|
.defineElement('ful-checkbox', Checkbox)
|
|
2765
2960
|
.defineElement('ful-input', Input)
|
|
2961
|
+
.defineElement('ful-local-date', LocalDate)
|
|
2962
|
+
.defineElement('ful-instant', Instant)
|
|
2963
|
+
.defineElement('ful-input-local-date', InputLocalDate)
|
|
2964
|
+
.defineElement('ful-input-local-time', InputLocalTime)
|
|
2965
|
+
.defineElement('ful-input-instant', InputInstant)
|
|
2766
2966
|
.defineElement('ful-radio-group', RadioGroup)
|
|
2767
2967
|
.defineElement('ful-table', Table)
|
|
2768
2968
|
.defineElement('ful-pagination', Pagination)
|
|
@@ -2793,8 +2993,13 @@ var ful = (function (exports, ftl) {
|
|
|
2793
2993
|
exports.HttpClient = HttpClient;
|
|
2794
2994
|
exports.HttpClientError = HttpClientError;
|
|
2795
2995
|
exports.Input = Input;
|
|
2996
|
+
exports.InputInstant = InputInstant;
|
|
2997
|
+
exports.InputLocalDate = InputLocalDate;
|
|
2998
|
+
exports.InputLocalTime = InputLocalTime;
|
|
2999
|
+
exports.Instant = Instant;
|
|
2796
3000
|
exports.InstantFilter = InstantFilter;
|
|
2797
3001
|
exports.Loaders = Loaders;
|
|
3002
|
+
exports.LocalDate = LocalDate;
|
|
2798
3003
|
exports.LocalDateFilter = LocalDateFilter;
|
|
2799
3004
|
exports.LocalStorage = LocalStorage;
|
|
2800
3005
|
exports.MediaType = MediaType;
|
|
@@ -2809,8 +3014,9 @@ var ful = (function (exports, ftl) {
|
|
|
2809
3014
|
exports.Table = Table;
|
|
2810
3015
|
exports.TableSchemaParser = TableSchemaParser;
|
|
2811
3016
|
exports.TextFilter = TextFilter;
|
|
2812
|
-
exports.
|
|
2813
|
-
exports.
|
|
3017
|
+
exports.Timing = Timing;
|
|
3018
|
+
exports.VersionedLocalStorage = VersionedLocalStorage;
|
|
3019
|
+
exports.VersionedSessionStorage = VersionedSessionStorage;
|
|
2814
3020
|
|
|
2815
3021
|
return exports;
|
|
2816
3022
|
|