native-document 1.0.94 → 1.0.98

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.
Files changed (52) hide show
  1. package/{src/devtools/hrm → devtools}/ComponentRegistry.js +2 -2
  2. package/devtools/index.js +8 -0
  3. package/{src/devtools/plugin.js → devtools/plugin/dev-tools-plugin.js} +2 -2
  4. package/{src/devtools/hrm/nd-vite-hot-reload.js → devtools/transformers/nd-vite-devtools.js} +16 -6
  5. package/devtools/transformers/src/transformComponentForHrm.js +74 -0
  6. package/devtools/transformers/src/transformJsFile.js +9 -0
  7. package/devtools/transformers/src/utils.js +79 -0
  8. package/devtools/widget/Widget.js +48 -0
  9. package/devtools/widget/widget.css +81 -0
  10. package/devtools/widget.js +23 -0
  11. package/dist/native-document.components.min.js +2441 -1191
  12. package/dist/native-document.dev.js +2710 -1359
  13. package/dist/native-document.dev.js.map +1 -1
  14. package/dist/native-document.devtools.min.js +1 -1
  15. package/dist/native-document.min.js +1 -1
  16. package/docs/cache.md +1 -1
  17. package/docs/core-concepts.md +1 -1
  18. package/docs/native-document-element.md +51 -15
  19. package/docs/observables.md +310 -306
  20. package/docs/state-management.md +198 -193
  21. package/index.def.js +762 -26
  22. package/package.json +1 -1
  23. package/readme.md +1 -1
  24. package/src/core/data/ObservableChecker.js +2 -0
  25. package/src/core/data/ObservableItem.js +97 -0
  26. package/src/core/data/ObservableObject.js +182 -0
  27. package/src/core/data/Store.js +364 -34
  28. package/src/core/data/observable-helpers/object.js +2 -166
  29. package/src/core/elements/anchor.js +28 -20
  30. package/src/core/elements/control/for-each.js +1 -1
  31. package/src/core/utils/formatters.js +91 -0
  32. package/src/core/utils/localstorage.js +57 -0
  33. package/src/core/utils/validator.js +0 -2
  34. package/src/core/wrappers/DocumentObserver.js +102 -31
  35. package/src/core/wrappers/ElementCreator.js +5 -0
  36. package/src/core/wrappers/NDElement.js +32 -1
  37. package/src/core/wrappers/prototypes/nd-element.transition.extensions.js +83 -0
  38. package/src/devtools.js +9 -0
  39. package/src/fetch/NativeFetch.js +5 -2
  40. package/types/elements.d.ts +580 -2
  41. package/types/nd-element.d.ts +6 -0
  42. package/types/observable.d.ts +71 -15
  43. package/types/plugins-manager.d.ts +1 -1
  44. package/types/store.d.ts +33 -6
  45. package/hrm.js +0 -7
  46. package/src/devtools/app/App.js +0 -66
  47. package/src/devtools/app/app.css +0 -0
  48. package/src/devtools/hrm/transformComponent.js +0 -129
  49. package/src/devtools/index.js +0 -18
  50. package/src/devtools/widget/DevToolsWidget.js +0 -26
  51. /package/{src/devtools/hrm → devtools/transformers/templates}/hrm.hook.template.js +0 -0
  52. /package/{src/devtools/hrm → devtools/transformers/templates}/hrm.orbservable.hook.template.js +0 -0
@@ -15,6 +15,7 @@ export default function Anchor(name, isUniqueChild = false) {
15
15
 
16
16
  anchorFragment.nativeInsertBefore = anchorFragment.insertBefore;
17
17
  anchorFragment.nativeAppendChild = anchorFragment.appendChild;
18
+ anchorFragment.nativeAppend = anchorFragment.append;
18
19
 
19
20
  const isParentUniqueChild = (parent) => (isUniqueChild || (parent.firstChild === anchorStart && parent.lastChild === anchorEnd))
20
21
 
@@ -50,59 +51,66 @@ export default function Anchor(name, isUniqueChild = false) {
50
51
  before = before ?? anchorEnd;
51
52
  insertBefore(parent, child, before);
52
53
  };
54
+
53
55
  anchorFragment.append = function(...args ) {
54
56
  return anchorFragment.appendChild(args);
55
- }
57
+ };
56
58
 
57
- anchorFragment.removeChildren = function() {
59
+ anchorFragment.removeChildren = async function() {
58
60
  const parent = anchorEnd.parentNode;
59
61
  if(parent === anchorFragment) {
60
62
  return;
61
63
  }
62
- if(isParentUniqueChild(parent)) {
63
- parent.replaceChildren(anchorStart, anchorEnd);
64
- return;
65
- }
64
+ // if(isParentUniqueChild(parent)) {
65
+ // parent.replaceChildren(anchorStart, anchorEnd);
66
+ // return;
67
+ // }
66
68
 
67
69
  let itemToRemove = anchorStart.nextSibling, tempItem;
68
- const fragment = document.createDocumentFragment();
70
+ const removes = [];
69
71
  while(itemToRemove && itemToRemove !== anchorEnd) {
70
72
  tempItem = itemToRemove.nextSibling;
71
- fragment.append(itemToRemove);
73
+ removes.push(itemToRemove.remove());
72
74
  itemToRemove = tempItem;
73
75
  }
74
- fragment.replaceChildren();
75
- }
76
- anchorFragment.remove = function() {
76
+ await Promise.all(removes);
77
+ };
78
+
79
+ anchorFragment.remove = async function() {
77
80
  const parent = anchorEnd.parentNode;
78
81
  if(parent === anchorFragment) {
79
82
  return;
80
83
  }
81
84
  let itemToRemove = anchorStart.nextSibling, tempItem;
85
+ const allItemToRemove = [];
86
+ const removes = [];
82
87
  while(itemToRemove && itemToRemove !== anchorEnd) {
83
88
  tempItem = itemToRemove.nextSibling;
84
- anchorFragment.nativeAppendChild(itemToRemove);
89
+ allItemToRemove.push(itemToRemove);
90
+ removes.push(itemToRemove.remove());
85
91
  itemToRemove = tempItem;
86
92
  }
93
+ await Promise.all(removes);
94
+ anchorFragment.nativeAppend(...allItemToRemove);
87
95
  };
88
96
 
89
- anchorFragment.removeWithAnchors = function() {
90
- anchorFragment.removeChildren();
97
+ anchorFragment.removeWithAnchors = async function() {
98
+ await anchorFragment.removeChildren();
91
99
  anchorStart.remove();
92
100
  anchorEnd.remove();
93
101
  };
94
102
 
95
- anchorFragment.replaceContent = function(child) {
103
+ anchorFragment.replaceContent = async function(child) {
96
104
  const childElement = Validator.isElement(child) ? child : ElementCreator.getChild(child);
97
105
  const parent = anchorEnd.parentNode;
98
106
  if(!parent) {
99
107
  return;
100
108
  }
101
- if(isParentUniqueChild(parent)) {
102
- parent.replaceChildren(anchorStart, childElement, anchorEnd);
103
- return;
104
- }
105
- anchorFragment.removeChildren();
109
+ // if(isParentUniqueChild(parent)) {
110
+ // parent.replaceChildren(anchorStart, childElement, anchorEnd);
111
+ // return;
112
+ // }
113
+ await anchorFragment.removeChildren();
106
114
  parent.insertBefore(childElement, anchorEnd);
107
115
  };
108
116
 
@@ -50,7 +50,7 @@ export function ForEach(data, callback, key, { shouldKeepItemsInCache = false }
50
50
  }
51
51
  const child = cacheItem.child?.deref();
52
52
  if(parent && child) {
53
- parent.removeChild(child);
53
+ child.remove();
54
54
  }
55
55
  cacheItem.indexObserver?.cleanup();
56
56
  cacheItem.child = null;
@@ -0,0 +1,91 @@
1
+ const $parseDateParts = (value, locale) => {
2
+ const d = new Date(value);
3
+ return {
4
+ d,
5
+ parts: new Intl.DateTimeFormat(locale, {
6
+ year: 'numeric',
7
+ month: 'long',
8
+ day: '2-digit',
9
+ hour: '2-digit',
10
+ minute: '2-digit',
11
+ second: '2-digit',
12
+ }).formatToParts(d).reduce((acc, { type, value }) => {
13
+ acc[type] = value;
14
+ return acc;
15
+ }, {})
16
+ };
17
+ };
18
+
19
+ const $applyDatePattern = (pattern, d, parts) => {
20
+ const pad = n => String(n).padStart(2, '0');
21
+ return pattern
22
+ .replace('YYYY', parts.year)
23
+ .replace('YY', parts.year.slice(-2))
24
+ .replace('MMMM', parts.month)
25
+ .replace('MMM', parts.month.slice(0, 3))
26
+ .replace('MM', pad(d.getMonth() + 1))
27
+ .replace('DD', pad(d.getDate()))
28
+ .replace('D', d.getDate())
29
+ .replace('HH', parts.hour)
30
+ .replace('mm', parts.minute)
31
+ .replace('ss', parts.second);
32
+ };
33
+
34
+ export const Formatters = {
35
+
36
+ currency: (value, locale, { currency = 'XOF', notation, minimumFractionDigits, maximumFractionDigits } = {}) =>
37
+ new Intl.NumberFormat(locale, {
38
+ style: 'currency',
39
+ currency,
40
+ notation,
41
+ minimumFractionDigits,
42
+ maximumFractionDigits
43
+ }).format(value),
44
+
45
+ number: (value, locale, { notation, minimumFractionDigits, maximumFractionDigits } = {}) =>
46
+ new Intl.NumberFormat(locale, {
47
+ notation,
48
+ minimumFractionDigits,
49
+ maximumFractionDigits
50
+ }).format(value),
51
+
52
+ percent: (value, locale, { decimals = 1 } = {}) =>
53
+ new Intl.NumberFormat(locale, {
54
+ style: 'percent',
55
+ maximumFractionDigits: decimals
56
+ }).format(value),
57
+
58
+ date: (value, locale, { format, dateStyle = 'long' } = {}) => {
59
+ if (format) {
60
+ const { d, parts } = $parseDateParts(value, locale);
61
+ return $applyDatePattern(format, d, parts);
62
+ }
63
+ return new Intl.DateTimeFormat(locale, { dateStyle }).format(new Date(value));
64
+ },
65
+
66
+ time: (value, locale, { format, hour = '2-digit', minute = '2-digit', second } = {}) => {
67
+ if (format) {
68
+ const { d, parts } = $parseDateParts(value, locale);
69
+ return $applyDatePattern(format, d, parts);
70
+ }
71
+ return new Intl.DateTimeFormat(locale, { hour, minute, second }).format(new Date(value));
72
+ },
73
+
74
+ datetime: (value, locale, { format, dateStyle = 'long', hour = '2-digit', minute = '2-digit', second } = {}) => {
75
+ if (format) {
76
+ const { d, parts } = $parseDateParts(value, locale);
77
+ return $applyDatePattern(format, d, parts);
78
+ }
79
+ return new Intl.DateTimeFormat(locale, { dateStyle, hour, minute, second }).format(new Date(value));
80
+ },
81
+
82
+ relative: (value, locale, { unit = 'day', numeric = 'auto' } = {}) => {
83
+ const diff = Math.round((value - Date.now()) / (1000 * 60 * 60 * 24));
84
+ return new Intl.RelativeTimeFormat(locale, { numeric }).format(diff, unit);
85
+ },
86
+
87
+ plural: (value, locale, { singular, plural } = {}) => {
88
+ const rule = new Intl.PluralRules(locale).select(value);
89
+ return `${value} ${rule === 'one' ? singular : plural}`;
90
+ },
91
+ };
@@ -0,0 +1,57 @@
1
+ import NativeDocumentError from "../errors/NativeDocumentError";
2
+
3
+ export const LocalStorage = {
4
+ getJson(key) {
5
+ let value = localStorage.getItem(key);
6
+ try {
7
+ return JSON.parse(value);
8
+ } catch (e) {
9
+ throw new NativeDocumentError('invalid_json:'+key);
10
+ }
11
+ },
12
+ getNumber(key) {
13
+ return Number(this.get(key));
14
+ },
15
+ getBool(key) {
16
+ const value = this.get(key);
17
+ return value === 'true' || value === '1';
18
+ },
19
+ setJson(key, value) {
20
+ localStorage.setItem(key, JSON.stringify(value));
21
+ },
22
+ setBool(key, value) {
23
+ localStorage.setItem(key, value ? 'true' : 'false');
24
+ },
25
+ get(key, defaultValue = null) {
26
+ return localStorage.getItem(key) || defaultValue;
27
+ },
28
+ set(key, value) {
29
+ return localStorage.setItem(key, value);
30
+ },
31
+ remove(key) {
32
+ localStorage.removeItem(key);
33
+ },
34
+ has(key) {
35
+ return localStorage.getItem(key) != null;
36
+ }
37
+ }
38
+
39
+ export const $getFromStorage = (key, value) => {
40
+ if(!LocalStorage.has(key)) {
41
+ return value;
42
+ }
43
+ switch (typeof value) {
44
+ case 'object': return LocalStorage.getJson(key) ?? value;
45
+ case 'boolean': return LocalStorage.getBool(key) ?? value;
46
+ case 'number': return LocalStorage.getNumber(key) ?? value;
47
+ default: return LocalStorage.get(key, value) ?? value;
48
+ }
49
+ };
50
+
51
+ export const $saveToStorage = (value) => {
52
+ switch (typeof value) {
53
+ case 'object': return LocalStorage.setJson;
54
+ case 'boolean': return LocalStorage.setBool;
55
+ default: return LocalStorage.set;
56
+ }
57
+ };
@@ -1,9 +1,7 @@
1
- import ObservableItem from "../data/ObservableItem";
2
1
  import DebugManager from "./debug-manager";
3
2
  import NativeDocumentError from "../errors/NativeDocumentError";
4
3
  import ObservableChecker from "../data/ObservableChecker";
5
4
  import {NDElement} from "../wrappers/NDElement";
6
- import TemplateBinding from "../wrappers/TemplateBinding";
7
5
 
8
6
  const COMMON_NODE_TYPES = {
9
7
  ELEMENT: 1,
@@ -1,97 +1,167 @@
1
-
2
1
  const DocumentObserver = {
3
2
  mounted: new WeakMap(),
3
+ beforeUnmount: new WeakMap(),
4
4
  mountedSupposedSize: 0,
5
5
  unmounted: new WeakMap(),
6
6
  unmountedSupposedSize: 0,
7
7
  observer: null,
8
+
8
9
  executeMountedCallback(node) {
9
10
  const data = DocumentObserver.mounted.get(node);
10
11
  if(!data) {
11
12
  return;
12
13
  }
13
14
  data.inDom = true;
14
- data.mounted && data.mounted(node);
15
+ if(!data.mounted) {
16
+ return;
17
+ }
18
+ if(Array.isArray(data.mounted)) {
19
+ for(const cb of data.mounted) {
20
+ cb(node);
21
+ }
22
+ return;
23
+ }
24
+ data.mounted(node);
15
25
  },
26
+
16
27
  executeUnmountedCallback(node) {
17
28
  const data = DocumentObserver.unmounted.get(node);
18
29
  if(!data) {
19
30
  return;
20
31
  }
21
-
22
32
  data.inDom = false;
23
- if(data.unmounted && data.unmounted(node) === true) {
33
+ if(!data.unmounted) {
34
+ return;
35
+ }
36
+
37
+ let shouldRemove = false;
38
+ if(Array.isArray(data.unmounted)) {
39
+ for(const cb of data.unmounted) {
40
+ if(cb(node) === true) {
41
+ shouldRemove = true;
42
+ }
43
+ }
44
+ } else {
45
+ shouldRemove = data.unmounted(node) === true;
46
+ }
47
+
48
+ if(shouldRemove) {
24
49
  data.disconnect();
25
50
  node.nd?.remove();
26
51
  }
27
52
  },
53
+
28
54
  checkMutation: function(mutationsList) {
29
- let i = 0;
30
55
  for(const mutation of mutationsList) {
31
- if(DocumentObserver.mountedSupposedSize > 0 ) {
56
+ if(DocumentObserver.mountedSupposedSize > 0) {
32
57
  for(const node of mutation.addedNodes) {
33
58
  DocumentObserver.executeMountedCallback(node);
34
59
  if(!node.querySelectorAll) {
35
- return;
60
+ continue;
36
61
  }
37
62
  const children = node.querySelectorAll('[data--nd-mounted]');
38
- if(!children.length) {
39
- return;
40
- }
41
- for(const node of children) {
42
- DocumentObserver.executeMountedCallback(node);
63
+ for(const child of children) {
64
+ DocumentObserver.executeMountedCallback(child);
43
65
  }
44
66
  }
45
67
  }
46
68
 
47
- if(DocumentObserver.unmountedSupposedSize > 0 ) {
48
- for(const node of mutation.removedNodes) {
69
+ if (DocumentObserver.unmountedSupposedSize > 0) {
70
+ for (const node of mutation.removedNodes) {
49
71
  DocumentObserver.executeUnmountedCallback(node);
50
72
  if(!node.querySelectorAll) {
51
- return;
73
+ continue;
52
74
  }
53
75
  const children = node.querySelectorAll('[data--nd-unmounted]');
54
- if(!children.length) {
55
- return;
56
- }
57
- for(const node of children) {
58
- DocumentObserver.executeUnmountedCallback(node);
76
+ for(const child of children) {
77
+ DocumentObserver.executeUnmountedCallback(child);
59
78
  }
60
79
  }
61
80
  }
62
81
  }
63
82
  },
83
+
64
84
  /**
65
- *
66
85
  * @param {HTMLElement} element
67
86
  * @param {boolean} inDom
68
- * @returns {{watch: (function(): Map<any, any>), disconnect: (function(): boolean), mounted: (function(*): Set<any>), unmounted: (function(*): Set<any>)}}
87
+ * @returns {{ disconnect: Function, mounted: Function, unmounted: Function, off: Function }}
69
88
  */
70
89
  watch: function(element, inDom = false) {
90
+ let mountedRegistered = false;
91
+ let unmountedRegistered = false;
92
+
71
93
  let data = {
72
94
  inDom,
73
95
  mounted: null,
74
96
  unmounted: null,
75
97
  disconnect: () => {
76
- DocumentObserver.mounted.delete(element);
77
- DocumentObserver.unmounted.delete(element);
78
- DocumentObserver.mountedSupposedSize--;
79
- DocumentObserver.unmountedSupposedSize--;
98
+ if (mountedRegistered) {
99
+ DocumentObserver.mounted.delete(element);
100
+ DocumentObserver.mountedSupposedSize--;
101
+ }
102
+ if (unmountedRegistered) {
103
+ DocumentObserver.unmounted.delete(element);
104
+ DocumentObserver.unmountedSupposedSize--;
105
+ }
80
106
  data = null;
81
107
  }
82
108
  };
83
109
 
110
+ const addListener = (type, callback) => {
111
+ if (!data[type]) {
112
+ data[type] = callback;
113
+ return;
114
+ }
115
+ if (!Array.isArray(data[type])) {
116
+ data[type] = [data[type], callback];
117
+ return;
118
+ }
119
+ data[type].push(callback);
120
+ };
121
+
122
+ const removeListener = (type, callback) => {
123
+ if(!data?.[type]) {
124
+ return;
125
+ }
126
+ if(Array.isArray(data[type])) {
127
+ const index = data[type].indexOf(callback);
128
+ if(index > -1) {
129
+ data[type].splice(index, 1);
130
+ }
131
+ if(data[type].length === 1) {
132
+ data[type] = data[type][0];
133
+ }
134
+ if(data[type].length === 0) {
135
+ data[type] = null;
136
+ }
137
+ return;
138
+ }
139
+ data[type] = null;
140
+ };
141
+
84
142
  return {
85
- disconnect: data.disconnect,
143
+ disconnect: () => data?.disconnect(),
144
+
86
145
  mounted: (callback) => {
87
- data.mounted = callback;
146
+ addListener('mounted', callback);
88
147
  DocumentObserver.mounted.set(element, data);
89
- DocumentObserver.mountedSupposedSize++;
148
+ if (!mountedRegistered) {
149
+ DocumentObserver.mountedSupposedSize++;
150
+ mountedRegistered = true;
151
+ }
90
152
  },
153
+
91
154
  unmounted: (callback) => {
92
- data.unmounted = callback;
155
+ addListener('unmounted', callback);
93
156
  DocumentObserver.unmounted.set(element, data);
94
- DocumentObserver.unmountedSupposedSize++;
157
+ if (!unmountedRegistered) {
158
+ DocumentObserver.unmountedSupposedSize++;
159
+ unmountedRegistered = true;
160
+ }
161
+ },
162
+
163
+ off: (type, callback) => {
164
+ removeListener(type, callback);
95
165
  }
96
166
  };
97
167
  }
@@ -102,4 +172,5 @@ DocumentObserver.observer.observe(document.body, {
102
172
  childList: true,
103
173
  subtree: true,
104
174
  });
175
+
105
176
  export default DocumentObserver;
@@ -3,6 +3,7 @@ import Validator from "../utils/validator";
3
3
  import AttributesWrapper from "./AttributesWrapper";
4
4
  import PluginsManager from "../utils/plugins-manager";
5
5
  import './prototypes/nd-element-extensions';
6
+ import './prototypes/nd-element.transition.extensions';
6
7
  import './prototypes/attributes-extensions';
7
8
 
8
9
  const $nodeCache = new Map();
@@ -95,6 +96,10 @@ export const ElementCreator = {
95
96
  PluginsManager.emit('AfterProcessChildren', parent);
96
97
  }
97
98
  },
99
+ async safeRemove(element) {
100
+ await element.remove();
101
+
102
+ },
98
103
  getChild(child) {
99
104
  if(child == null) {
100
105
  return null;
@@ -73,6 +73,37 @@ NDElement.prototype.unmounted = function(callback) {
73
73
  return this.lifecycle({ unmounted: callback });
74
74
  };
75
75
 
76
+ NDElement.prototype.beforeUnmount = function(id, callback) {
77
+ const el = this.$element;
78
+
79
+ if(!DocumentObserver.beforeUnmount.has(el)) {
80
+ DocumentObserver.beforeUnmount.set(el, new Map());
81
+ const originalRemove = el.remove.bind(el);
82
+
83
+ let $isUnmounting = false
84
+
85
+ el.remove = async () => {
86
+ if($isUnmounting) {
87
+ return;
88
+ }
89
+ $isUnmounting = true;
90
+
91
+ try {
92
+ const callbacks = DocumentObserver.beforeUnmount.get(el);
93
+ for (const cb of callbacks.values()) {
94
+ await cb.call(this, el);
95
+ }
96
+ } finally {
97
+ originalRemove();
98
+ $isUnmounting = false;
99
+ }
100
+ };
101
+ }
102
+
103
+ DocumentObserver.beforeUnmount.get(el).set(id, callback);
104
+ return this;
105
+ };
106
+
76
107
  NDElement.prototype.htmlElement = function() {
77
108
  return this.$element;
78
109
  };
@@ -160,7 +191,7 @@ NDElement.prototype.with = function(methods) {
160
191
  }
161
192
 
162
193
  return this;
163
- }
194
+ };
164
195
 
165
196
  /**
166
197
  * Extends the NDElement prototype with new methods available to all NDElement instances.
@@ -0,0 +1,83 @@
1
+ import {NDElement} from "../NDElement";
2
+
3
+ /**
4
+ * @param {HTMLElement} el
5
+ * @param {number} timeout
6
+ */
7
+ const waitForVisualEnd = (el, timeout = 1000) => {
8
+ return new Promise((resolve) => {
9
+ let isResolved = false;
10
+
11
+ const cleanupAndResolve = (e) => {
12
+ if (e && e.target !== el) return;
13
+ if (isResolved) return;
14
+
15
+ isResolved = true;
16
+ el.removeEventListener('transitionend', cleanupAndResolve);
17
+ el.removeEventListener('animationend', cleanupAndResolve);
18
+ clearTimeout(timer);
19
+ resolve();
20
+ };
21
+
22
+ el.addEventListener('transitionend', cleanupAndResolve);
23
+ el.addEventListener('animationend', cleanupAndResolve);
24
+
25
+ const timer = setTimeout(cleanupAndResolve, timeout);
26
+
27
+ const style = window.getComputedStyle(el);
28
+ const hasTransition = style.transitionDuration !== '0s';
29
+ const hasAnimation = style.animationDuration !== '0s';
30
+
31
+ if (!hasTransition && !hasAnimation) {
32
+ cleanupAndResolve();
33
+ }
34
+ });
35
+ };
36
+
37
+ NDElement.prototype.transitionOut = function(transitionName) {
38
+ const exitClass = transitionName + '-exit';
39
+ this.beforeUnmount('transition-exit', async function() {
40
+ this.$element.classes.add(exitClass);
41
+ await waitForVisualEnd(this.$element);
42
+ this.$element.classes.remove(exitClass);
43
+ });
44
+ return this;
45
+ };
46
+
47
+ NDElement.prototype.transitionIn = function(transitionName) {
48
+ const startClass = transitionName + '-enter-from';
49
+ const endClass = transitionName + '-enter-to';
50
+
51
+ this.$element.classes.add(startClass);
52
+
53
+ this.mounted(() => {
54
+ requestAnimationFrame(() => {
55
+ requestAnimationFrame(() => {
56
+ this.$element.classes.remove(startClass);
57
+ this.$element.classes.add(endClass);
58
+
59
+ waitForVisualEnd(this.$element).then(() => {
60
+ this.$element.classes.remove(endClass);
61
+ });
62
+ });
63
+ });
64
+ });
65
+ return this;
66
+ };
67
+
68
+
69
+ NDElement.prototype.transition = function (transitionName) {
70
+ this.transitionIn(transitionName);
71
+ this.transitionOut(transitionName);
72
+ return this;
73
+ };
74
+
75
+ NDElement.prototype.animate = function(animationName) {
76
+ this.$element.classes.add(animationName);
77
+
78
+ waitForVisualEnd(this.$element).then(() => {
79
+ this.$element.classes.remove(animationName);
80
+ });
81
+
82
+ return this;
83
+ };
@@ -0,0 +1,9 @@
1
+ import Devtools from './devtools';
2
+ import NdViteDevtools from "../devtools/transformers/nd-vite-devtools.js";
3
+ import transformComponentForHrm from "../devtools/transformers/src/transformComponentForHrm.js";
4
+
5
+ export {
6
+ transformComponentForHrm,
7
+ NdViteDevtools,
8
+ Devtools,
9
+ };
@@ -36,11 +36,14 @@ export default function NativeFetch($baseUrl) {
36
36
  configs.body = params;
37
37
  }
38
38
  else {
39
- configs.headers['Content-Type'] = 'application/json';
40
39
  if(method !== 'GET') {
40
+ configs.headers['Content-Type'] = 'application/json';
41
41
  configs.body = JSON.stringify(params);
42
42
  } else {
43
- configs.params = params;
43
+ const queryString = new URLSearchParams(params).toString();
44
+ if (queryString) {
45
+ endpoint = endpoint + (endpoint.includes('?') ? '&' : '?') + queryString;
46
+ }
44
47
  }
45
48
  }
46
49
  }