@optionfactory/ful 0.45.0 → 0.47.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.mjs CHANGED
@@ -586,14 +586,14 @@ class SyncEvent extends CustomEvent {
586
586
 
587
587
  class Fragments {
588
588
  static fromHtml(...html) {
589
- const el = document.createElement('div');
589
+ const el = document.createElement("div");
590
590
  el.innerHTML = html.join("");
591
591
  const fragment = new DocumentFragment();
592
592
  fragment.append(...el.childNodes);
593
593
  return fragment;
594
594
  }
595
595
  static toHtml(fragment) {
596
- var r = document.createElement("root");
596
+ var r = document.createElement("div");
597
597
  r.appendChild(fragment);
598
598
  return r.innerHTML;
599
599
  }
@@ -683,86 +683,85 @@ class UpgradeQueue {
683
683
 
684
684
  const upgradeQueue = new UpgradeQueue();
685
685
 
686
- class ParsedElement extends HTMLElement {
687
- #parsed;
688
- connectedCallback() {
689
- if (this.#parsed) {
690
- return;
691
- }
692
- if (this.ownerDocument.readyState === 'complete' || Nodes.isParsed(this)) {
693
- upgradeQueue.enqueue(this);
694
- return;
695
- }
696
- this.ownerDocument.addEventListener('DOMContentLoaded', () => {
697
- observer.disconnect();
698
- upgradeQueue.enqueue(this);
699
- });
700
- const observer = new MutationObserver(() => {
701
- if (!Nodes.isParsed(this)) {
702
- return;
703
- }
704
- observer.disconnect();
705
- upgradeQueue.enqueue(this);
706
- });
707
- observer.observe(this.parentNode, { childList: true, subtree: true });
708
- }
709
- attributeChangedCallback(name, oldValue, newValue) {
710
- if (!this.#parsed || oldValue === newValue) {
711
- return;
712
- }
713
- this[name] = newValue;
714
- }
715
- upgrade() {
716
- if (this.#parsed) {
717
- return;
718
- }
719
- this.#parsed = true;
720
- return this.ready();
721
- }
722
- }
723
-
724
-
725
- const Templated = (SuperClass, template) => {
726
- return class extends SuperClass {
727
- async ready() {
728
- const slotted = Slots.from(this);
729
- const fragment = await Promise.resolve(this.render(slotted, template));
730
- this.innerHTML = '';
731
- if (fragment) {
732
- this.appendChild(fragment);
733
- }
734
- }
735
- };
736
- };
737
-
738
- const Stateful = (SuperClass, flags, others) => {
686
+ const ParsedElement = (flags, others) => {
739
687
 
740
- const all = [].concat(flags).concat(others || []);
688
+ const observed_flags = flags || [];
689
+ const observed_others = others || [];
690
+ const observed = [].concat(observed_flags).concat(observed_others);
741
691
 
742
- const k = class extends SuperClass {
692
+ const k = class extends HTMLElement {
743
693
  static get observedAttributes() {
744
- return all;
694
+ return observed;
745
695
  }
696
+ #parsed;
697
+ #internals;
746
698
  constructor(...args) {
747
699
  super(...args);
748
- this.internals_ = this.internals_ || this.attachInternals();
700
+ this.#internals = this.attachInternals();
749
701
  }
702
+ get internals() {
703
+ return this.#internals;
704
+ }
705
+ connectedCallback() {
706
+ if (this.#parsed) {
707
+ return;
708
+ }
709
+ if (this.ownerDocument.readyState === 'complete' || Nodes.isParsed(this)) {
710
+ upgradeQueue.enqueue(this);
711
+ return;
712
+ }
713
+ this.ownerDocument.addEventListener('DOMContentLoaded', () => {
714
+ observer.disconnect();
715
+ upgradeQueue.enqueue(this);
716
+ });
717
+ const observer = new MutationObserver(() => {
718
+ if (!Nodes.isParsed(this)) {
719
+ return;
720
+ }
721
+ observer.disconnect();
722
+ upgradeQueue.enqueue(this);
723
+ });
724
+ observer.observe(this.parentNode, { childList: true, subtree: true });
725
+ }
726
+ attributeChangedCallback(name, oldValue, newValue) {
727
+ if (!this.#parsed || oldValue === newValue) {
728
+ return;
729
+ }
730
+ this[name] = newValue;
731
+ }
732
+ async upgrade() {
733
+ if (this.#parsed) {
734
+ return;
735
+ }
736
+ this.#parsed = true;
737
+ await this.render();
738
+ for (const flag of observed_flags) {
739
+ if(this.hasAttribute(flag)){
740
+ this[flag] = true;
741
+ }
742
+ }
743
+ for (const other of observed_others) {
744
+ if(this.hasAttribute(other)){
745
+ this[other] = this.getAttribute(other);
746
+ }
747
+ }
748
+ }
750
749
  };
751
750
 
752
- for (const flag of flags) {
751
+ for (const flag of observed_flags) {
753
752
  Object.defineProperty(k.prototype, flag, {
754
753
  enumerable: true,
755
754
  configurable: true,
756
755
  get() {
757
- return this.internals_.states.has(`--${flag}`);
756
+ return this.internals.states.has(`--${flag}`);
758
757
  },
759
758
  set(value) {
760
759
  //see https://developer.mozilla.org/en-US/docs/Web/API/CustomStateSet#using_double_dash_prefixed_idents
761
760
  if (Attributes.asBoolean(value)) {
762
- this.internals_.states.add(`--${flag}`);
761
+ this.internals.states.add(`--${flag}`);
763
762
  return;
764
763
  }
765
- this.internals_.states.delete(`--${flag}`);
764
+ this.internals.states.delete(`--${flag}`);
766
765
  }
767
766
  });
768
767
  }
@@ -839,12 +838,12 @@ function mutate(el, raw) {
839
838
  el.value = raw;
840
839
  }
841
840
 
842
- class Form extends Templated(ParsedElement) {
841
+ class Form extends ParsedElement() {
843
842
  static IGNORED_CHILDREN_SELECTOR = '.d-none, [hidden]';
844
843
  static SCROLL_OFFSET = 50;
845
- render(slotted) {
844
+ render() {
846
845
  const form = document.createElement('form');
847
- form.append(slotted.default);
846
+ form.replaceChildren(...this.childNodes);
848
847
  form.addEventListener('submit', async (e) => {
849
848
  e.preventDefault();
850
849
  this.spinner(true);
@@ -862,7 +861,7 @@ class Form extends Templated(ParsedElement) {
862
861
  this.spinner(false);
863
862
  }
864
863
  });
865
- return form;
864
+ this.replaceChildren(form);
866
865
  }
867
866
  spinner(spin) {
868
867
  this.querySelectorAll('ful-spinner').forEach(el => el.hidden = !spin);
@@ -890,7 +889,7 @@ class Form extends Templated(ParsedElement) {
890
889
  const globalErrors = es.filter((e) => e.type !== 'FIELD_ERROR' && e.type !== 'INVALID_FORMAT');
891
890
  this.querySelectorAll('.is-invalid').forEach(el => el.classList.remove('is-invalid'));
892
891
  this.querySelectorAll("ful-errors").forEach(el => {
893
- el.innerHTML = '';
892
+ el.replaceChildren();
894
893
  el.setAttribute('hidden', '');
895
894
  });
896
895
  fieldErrors.forEach((e) => {
@@ -923,7 +922,7 @@ const ful_input_ec = globalThis.ec || ftl.EvaluationContext.configure({
923
922
 
924
923
  });
925
924
 
926
- const ful_input_template_ = globalThis.ful_input_template || ftl.Template.fromHtml(`
925
+ const template$1 = globalThis.ful_input_template || ftl.Template.fromHtml(`
927
926
  <label data-tpl-for="id" class="form-label">{{{{ slotted.default }}}}</label>
928
927
  <div class="input-group">
929
928
  <span data-tpl-if="slotted.ibefore" class="input-group-text">{{{{ slotted.ibefore }}}}</span>
@@ -935,31 +934,34 @@ const ful_input_template_ = globalThis.ful_input_template || ftl.Template.fromHt
935
934
  <ful-field-error data-tpl-if="name" data-tpl-field="name"></ful-field-error>
936
935
  `, ful_input_ec);
937
936
 
938
- class StatelessInput extends Templated(ParsedElement, ful_input_template_) {
939
- render(slotted, template) {
940
- const input = this.input = slotted.input = slotted.input || (() => {
941
- const el = document.createElement("input");
942
- el.classList.add("form-control");
943
- return el;
944
- })();
945
- input.setAttribute('ful-validation-target', '');
937
+ const renderInput = (el) => {
938
+ const slotted = Slots.from(el);
939
+
940
+ const input = el.input = slotted.input = slotted.input || (() => {
941
+ const el = document.createElement("input");
942
+ el.classList.add("form-control");
943
+ return el;
944
+ })();
945
+ input.setAttribute('ful-validation-target', '');
946
+
947
+ const id = input.getAttribute('id') || el.getAttribute('input-id') || Attributes.uid('ful-input');
948
+ Attributes.forward('input-', el, slotted.input);
949
+ Attributes.defaultValue(slotted.input, "id", id);
950
+ Attributes.defaultValue(slotted.input, "type", "text");
951
+ Attributes.defaultValue(slotted.input, "placeholder", " ");
952
+ const name = el.getAttribute('name');
953
+ template$1.renderTo(el, { id, name, slotted });
954
+ };
946
955
 
947
- const id = input.getAttribute('id') || this.getAttribute('input-id') || Attributes.uid('ful-input');
948
- Attributes.forward('input-', this, slotted.input);
949
- Attributes.defaultValue(slotted.input, "id", id);
950
- Attributes.defaultValue(slotted.input, "type", "text");
951
- Attributes.defaultValue(slotted.input, "placeholder", " ");
952
- const name = this.getAttribute('name');
953
- return template.render({ id, name, slotted });
956
+ class StatelessInput extends ParsedElement() {
957
+ render() {
958
+ renderInput(this);
954
959
  }
955
-
956
960
  }
957
961
 
958
- class Input extends Stateful(StatelessInput, [], ['value']) {
959
- render(slotted, template) {
960
- const fragment = super.render(slotted, template);
961
- this.input.value = this.getAttribute('value');
962
- return fragment;
962
+ class Input extends ParsedElement([], ['value']) {
963
+ render() {
964
+ renderInput(this);
963
965
  }
964
966
  get value() {
965
967
  return this.input.value;
@@ -991,12 +993,14 @@ const ful_select_template_ = globalThis.ful_select_template || ftl.Template.from
991
993
  `, ful_select_ec);
992
994
 
993
995
 
994
- class Select extends Stateful(Templated(ParsedElement, ful_select_template_), [], ["value"]) {
996
+ class Select extends ParsedElement([], ["value"]) {
995
997
  constructor(tsConfig) {
996
998
  super();
997
999
  this.tsConfig = tsConfig;
998
1000
  }
999
- render(slotted, template) {
1001
+ render() {
1002
+ const slotted = Slots.from(this);
1003
+
1000
1004
  const type = this.getAttribute("type") || 'local';
1001
1005
  const remote = type != 'local';
1002
1006
  const loadOnce = this.getAttribute('load') != 'always';
@@ -1024,7 +1028,6 @@ class Select extends Stateful(Templated(ParsedElement, ful_select_template_), []
1024
1028
  }
1025
1029
  };
1026
1030
 
1027
-
1028
1031
  this._remote = remote;
1029
1032
  // we need to await this load in setValue when remote is configured and the option
1030
1033
  // is not loaded yet.
@@ -1039,7 +1042,7 @@ class Select extends Stateful(Templated(ParsedElement, ful_select_template_), []
1039
1042
  const type = query && query.hasOwnProperty('byId') ? 'id' : 'query';
1040
1043
  const qvalue = type === 'id' ? query.byId : query;
1041
1044
  const data = await (this.loader ? this.loader(qvalue, type) : []);
1042
- if(type !== 'id'){
1045
+ if (type !== 'id') {
1043
1046
  this.loaded = true;
1044
1047
  }
1045
1048
  callback(data);
@@ -1053,12 +1056,12 @@ class Select extends Stateful(Templated(ParsedElement, ful_select_template_), []
1053
1056
  } : {}, tsDefaultConfig, this.tsConfig));
1054
1057
  //we remove the input to move it
1055
1058
  input.remove();
1056
- return template.render({ id, tsId, name, input, slotted });
1059
+ ful_select_template_.renderTo(this, { id, tsId, name, input, slotted });
1057
1060
  }
1058
1061
  set value(v) {
1059
1062
  (async () => {
1060
- if(this._remote){
1061
- await this._unwrappedRemoteLoad({byId: v}, this.ts.loadCallback.bind(this.ts));
1063
+ if (this._remote) {
1064
+ await this._unwrappedRemoteLoad({ byId: v }, this.ts.loadCallback.bind(this.ts));
1062
1065
  }
1063
1066
  this.ts.setValue(v);
1064
1067
  })();
@@ -1095,8 +1098,9 @@ const ful_radiougroup_template_ = globalThis.ful_radiogroup_template || ftl.Temp
1095
1098
  `, ful_radiogroup_ec);
1096
1099
 
1097
1100
 
1098
- class RadioGroup extends Stateful(Templated(ParsedElement, ful_radiougroup_template_), ['disabled'], ['value']) {
1099
- render(slotted, template) {
1101
+ class RadioGroup extends ParsedElement(['disabled'], ['value']) {
1102
+ render() {
1103
+ const slotted = Slots.from(this);
1100
1104
  const name = this.getAttribute('name') || Attributes.uid('ful-radiogroup');
1101
1105
  const radioEls = Array.from(slotted.default.querySelectorAll('ful-radio'));
1102
1106
  const inputsAndLabels = radioEls.map(el => {
@@ -1111,19 +1115,18 @@ class RadioGroup extends Stateful(Templated(ParsedElement, ful_radiougroup_templ
1111
1115
  return [input, label];
1112
1116
  });
1113
1117
  radioEls.forEach(el => el.remove());
1114
-
1115
- const fragment = template.render({
1118
+
1119
+ ful_radiougroup_template_.renderTo(this, {
1116
1120
  name: name,
1117
1121
  slotted: slotted,
1118
1122
  inputsAndLabels: inputsAndLabels
1119
1123
  });
1120
- return fragment;
1121
1124
  }
1122
1125
  get value() {
1123
1126
  const checked = this.querySelector('input[type=radio]:checked');
1124
1127
  return checked ? checked.value : null;
1125
1128
  }
1126
- set value(value){
1129
+ set value(value) {
1127
1130
  this.querySelector(`input[type=radio][value=${CSS.escape(value)}]`).checked = true;
1128
1131
  }
1129
1132
  }
@@ -1132,7 +1135,7 @@ const ful_spinner_ec = globalThis.ec || ftl.EvaluationContext.configure({
1132
1135
 
1133
1136
  });
1134
1137
 
1135
- const ful_spinner_template_ = globalThis.ful_spinner_template || ftl.Template.fromHtml(`
1138
+ const template = globalThis.ful_spinner_template || ftl.Template.fromHtml(`
1136
1139
  <div class="ful-spinner-wrapper">
1137
1140
  <div class="ful-spinner-text">{{{{ slotted.default }}}}</div>
1138
1141
  <div class="ful-spinner-icon"></div>
@@ -1140,9 +1143,10 @@ const ful_spinner_template_ = globalThis.ful_spinner_template || ftl.Template.fr
1140
1143
  `, ful_spinner_ec);
1141
1144
 
1142
1145
 
1143
- class Spinner extends Templated(ParsedElement, ful_spinner_template_) {
1144
- render(slotted, template) {
1145
- return template.render({ slotted });
1146
+ class Spinner extends ParsedElement() {
1147
+ render() {
1148
+ const slotted = Slots.from(this);
1149
+ template.renderTo(this, { slotted });
1146
1150
  }
1147
1151
  }
1148
1152
 
@@ -1228,5 +1232,5 @@ class CustomElements {
1228
1232
  }
1229
1233
  }
1230
1234
 
1231
- export { Attributes, AuthorizationCodeFlow, AuthorizationCodeFlowInterceptor, AuthorizationCodeFlowSession, Base64, CustomElements, Failure, Form, Fragments, Hex, HttpClient, Input, LocalStorage, Nodes, ParsedElement, RadioGroup, Select, SessionStorage, Slots, Spinner, Stateful, StatelessInput, SyncEvent, Templated, VersionedStorage, Wizard, jsonPatch, jsonPost, jsonPut, jsonRequest, timing };
1235
+ export { Attributes, AuthorizationCodeFlow, AuthorizationCodeFlowInterceptor, AuthorizationCodeFlowSession, Base64, CustomElements, Failure, Form, Fragments, Hex, HttpClient, Input, LocalStorage, Nodes, ParsedElement, RadioGroup, Select, SessionStorage, Slots, Spinner, StatelessInput, SyncEvent, VersionedStorage, Wizard, jsonPatch, jsonPost, jsonPut, jsonRequest, timing };
1232
1236
  //# sourceMappingURL=ful.mjs.map