native-document 1.0.17-1.3 → 1.0.17-1.5

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "native-document",
3
- "version": "1.0.171.3",
3
+ "version": "1.0.171.5",
4
4
  "description": "A reactive JavaScript framework that preserves native DOM simplicity without sacrificing modern features",
5
5
  "author": "AfroCodeur <https://github.com/afrocodeur>",
6
6
  "license": "MIT",
@@ -160,6 +160,7 @@ ObservableItem.prototype.triggerWatchersAndFirstListener = function(operations)
160
160
  this.triggerFirstListener(operations);
161
161
  };
162
162
 
163
+
163
164
  /**
164
165
  * Selects and assigns the optimal trigger strategy based on the current
165
166
  * combination of listeners and watchers (internal).
@@ -167,31 +168,40 @@ ObservableItem.prototype.triggerWatchersAndFirstListener = function(operations)
167
168
  *
168
169
  * @internal
169
170
  */
170
- ObservableItem.prototype.assocTrigger = function() {
171
+ ObservableItem.prototype.$runAssocTrigger = function() {
171
172
  this.$firstListener = null;
172
173
  if(this.$watchers?.size && this.$listeners?.length) {
173
- this.$firstListener = this.$listeners[0];
174
- this.trigger = this.$firstListener.length === 0 ? this.$firstListener : this.triggerFirstListener;
175
- this.trigger = (this.$listeners.length === 1) ? this.triggerWatchersAndFirstListener : this.triggerAll;
174
+ this.$trigger = (this.$listeners.length === 1) ? this.triggerWatchersAndFirstListener : this.triggerAll;
176
175
  return;
177
176
  }
178
177
  if(this.$listeners?.length) {
179
178
  if(this.$listeners.length === 1) {
180
179
  this.$firstListener = this.$listeners[0];
181
- this.trigger = this.$firstListener.length === 0 ? this.$firstListener : this.triggerFirstListener;
180
+ this.$trigger = this.$firstListener.length === 0 ? this.$firstListener : this.triggerFirstListener;
182
181
  }
183
182
  else {
184
- this.trigger = this.triggerListeners;
183
+ this.$trigger = this.triggerListeners;
185
184
  }
186
185
  return;
187
186
  }
188
187
  if(this.$watchers?.size) {
189
- this.trigger = this.triggerWatchers;
188
+ this.$trigger = this.triggerWatchers;
190
189
  return;
191
190
  }
192
- this.trigger = noneTrigger;
191
+ this.$trigger = noneTrigger;
192
+ };
193
+ ObservableItem.prototype.assocTrigger = function() {
194
+ this.$trigger = null;
193
195
  };
194
- ObservableItem.prototype.trigger = noneTrigger;
196
+ Object.defineProperty(ObservableItem.prototype, 'trigger', {
197
+ value: function (operations) {
198
+ if(!this.$trigger) {
199
+ this.$runAssocTrigger();
200
+ }
201
+ return this.$trigger(operations);
202
+ },
203
+ configurable: false,
204
+ });
195
205
 
196
206
 
197
207
  const $setOperation = { action: 'set' };
@@ -2,6 +2,7 @@ import Validator from '../../utils/validator';
2
2
  import {ElementCreator} from '../../wrappers/ElementCreator';
3
3
  import AnchorWithSentinel from './anchor-with-sentinel';
4
4
  import oneChildAnchorOverwriting from './one-child-anchor-overwriting';
5
+ import DebugManager from '../../utils/debug-manager';
5
6
 
6
7
  /**
7
8
  * Creates an anchor fragment — a managed DocumentFragment delimited by comment sentinels.
@@ -34,7 +35,7 @@ export default function Anchor(name, isUniqueChild = false) {
34
35
  ? () => true: (parent) => (parent.firstChild === anchorStart && parent.lastChild === anchorEnd);
35
36
 
36
37
  const insertBefore = (parent, child, target) => {
37
- const childElement = Validator.isElement(child) ? child : ElementCreator.getChild(child);
38
+ const childElement = child.__$isNativeNode ? child : ElementCreator.getChild(child);
38
39
  insertBeforeRaw(parent, childElement, target);
39
40
  };
40
41
 
@@ -84,7 +85,7 @@ export default function Anchor(name, isUniqueChild = false) {
84
85
  anchorFragment.appendRaw = anchorFragment.appendChildRaw;
85
86
 
86
87
  anchorFragment.insertAtStart = function(child) {
87
- child = Validator.isElement(child) ? child : ElementCreator.getChild(child);
88
+ child = child.__$isNativeNode? child : ElementCreator.getChild(child);
88
89
  anchorFragment.insertAtStartRaw(child);
89
90
  };
90
91
 
@@ -141,7 +142,7 @@ export default function Anchor(name, isUniqueChild = false) {
141
142
  anchorFragment.delete = anchorFragment.removeWithAnchors;
142
143
 
143
144
  anchorFragment.replaceContent = function(child) {
144
- const childElement = Validator.isElement(child) ? child : ElementCreator.getChild(child);
145
+ const childElement = child.__$isNativeNode ? child : ElementCreator.getChild(child);
145
146
  anchorFragment.replaceContentRaw(childElement);
146
147
  };
147
148
 
@@ -10,7 +10,7 @@ export default function oneChildAnchorOverwriting(anchor, parent) {
10
10
  anchor.getParent = () => parent;
11
11
 
12
12
  anchor.appendChild = (child) => {
13
- child = Validator.isElement(child) ? child : ElementCreator.getChild(child);
13
+ child = child.__$isNativeNode ? child : ElementCreator.getChild(child);
14
14
  parent.appendChild(child);
15
15
  };
16
16
 
@@ -19,7 +19,7 @@ export default function oneChildAnchorOverwriting(anchor, parent) {
19
19
  anchor.appendRaw = anchor.appendChildRaw;
20
20
 
21
21
  anchor.insertAtStart = (child) => {
22
- child = Validator.isElement(child) ? child : ElementCreator.getChild(child);
22
+ child = child.__$isNativeNode ? child : ElementCreator.getChild(child);
23
23
  parent.firstChild ? parent.insertBefore(child, parent.firstChild) : parent.appendChild(child);
24
24
  };
25
25
  anchor.insertAtStartRaw = (child) => {
@@ -33,7 +33,7 @@ export default function oneChildAnchorOverwriting(anchor, parent) {
33
33
  };
34
34
 
35
35
  anchor.replaceContent = function(content) {
36
- const child = Validator.isElement(content) ? content : ElementCreator.getChild(content);
36
+ const child = (content && content.__$isNativeNode) ? content : ElementCreator.getChild(content);
37
37
  parent.replaceChildren(child);
38
38
  };
39
39
 
@@ -43,7 +43,7 @@ export default function oneChildAnchorOverwriting(anchor, parent) {
43
43
  anchor.setContent = anchor.replaceContent;
44
44
 
45
45
  anchor.insertBefore = (child, anchor) => {
46
- child = Validator.isElement(child) ? child : ElementCreator.getChild(child);
46
+ child = child.__$isNativeNode ? child : ElementCreator.getChild(child);
47
47
  parent.insertBefore(child, anchor);
48
48
  };
49
49
  anchor.insertBeforeRaw = (child, anchor) => {
@@ -0,0 +1,59 @@
1
+
2
+
3
+ export default function ForEachArrayCache(isIndexesRequired) {
4
+ this.$nodes = new Map();
5
+ this.$indexes = isIndexesRequired ? new Map() : null;
6
+
7
+ this.has = this.$nodes.has.bind(this.$nodes);
8
+
9
+ this.keys = function() {
10
+ return Array.from(this.$nodes.keys());
11
+ };
12
+
13
+ if(isIndexesRequired) {
14
+ this.delete = function(item) {
15
+ this.$nodes.get(item)?.nd.destroy();
16
+ this.$nodes.delete(item);
17
+ this.$indexes.delete(item);
18
+ };
19
+
20
+ this.set = function(item, child, index) {
21
+ this.$nodes.set(item, child);
22
+ this.$indexes.set(item, index);
23
+ };
24
+
25
+ this.clear = function() {
26
+ for(const [_, node] in this.$nodes.entries()) {
27
+ node.nd.destroy();
28
+ }
29
+ this.$nodes.clear();
30
+ this.$indexes.clear();
31
+ };
32
+
33
+ this.get = function(item) {
34
+ return {
35
+ child: this.$nodes.get(item),
36
+ indexObserver: this.$indexes.get(item),
37
+ };
38
+ };
39
+ } else {
40
+
41
+ this.delete = (item) => {
42
+ this.$nodes.get(item)?.nd.destroy();
43
+ this.$nodes.delete(item);
44
+ };
45
+ this.set = this.$nodes.set.bind(this.$nodes);
46
+ this.clear = function() {
47
+ for(const [_, node] in this.$nodes.entries()) {
48
+ node.nd.destroy();
49
+ }
50
+ this.$nodes.clear();
51
+ };
52
+
53
+ this.get = function(item) {
54
+ return { child: this.$nodes.get(item), indexObserver: null };
55
+ };
56
+ }
57
+
58
+ }
59
+
@@ -1,6 +1,7 @@
1
1
  import Anchor from '../anchor/anchor';
2
2
  import { ElementCreator } from '../../wrappers/ElementCreator';
3
3
  import NativeDocumentError from '../../errors/NativeDocumentError';
4
+ import ForEachArrayCache from './for-each-array-cache';
4
5
 
5
6
 
6
7
  const CREATE_AND_CACHE_ACTIONS = new Set(['clear', 'push', 'unshift', 'replace']);
@@ -30,9 +31,9 @@ export function ForEachArray(data, callback, configs = {}) {
30
31
  const element = Anchor('ForEach Array', configs.isParentUniqueChild);
31
32
  const blockEnd = element.endElement();
32
33
 
33
- const cache = new Map();
34
34
  let lastNumberOfItems = 0;
35
35
  const isIndexRequired = callback.length >= 2;
36
+ const cache = new ForEachArrayCache(isIndexRequired);
36
37
 
37
38
  const clear = (items) => {
38
39
  element.removeChildren();
@@ -99,7 +99,7 @@ export const bindBooleanAttribute = (element, attributeName, value) => {
99
99
  const isObservable = value.__$Observable;
100
100
  const defaultValue = isObservable? value.val() : value;
101
101
 
102
- const attributeRealName = BOOL_ATTRIBUTES_NAME[attributeName];
102
+ const attributeRealName = BOOL_ATTRIBUTES_NAME[attributeName] || attributeName;
103
103
 
104
104
  if(typeof defaultValue === 'boolean') {
105
105
  element[attributeRealName] = defaultValue;
@@ -145,29 +145,29 @@ export const bindAttributeWithObservable = (element, attributeName, value) => {
145
145
  * @param {HTMLElement} element
146
146
  * @param {Object} attributes
147
147
  */
148
- const AttributesWrapper = (element, attributes) => {
148
+ const AttributesWrapper = (element, attributes = {}) => {
149
149
 
150
150
  if(process.env.NODE_ENV === 'development') {
151
151
  Validator.validateAttributes(attributes);
152
152
  }
153
153
 
154
- for(const originalAttributeName in attributes) {
155
- const value = attributes[originalAttributeName];
154
+ for(const attributeName in attributes) {
155
+ const value = attributes[attributeName];
156
156
  if(value == null) {
157
157
  continue;
158
158
  }
159
159
  const type = typeof value;
160
160
  if(type === 'string' || type === 'number') {
161
- element.setAttribute(originalAttributeName, value);
161
+ element.setAttribute(attributeName, value);
162
162
  continue;
163
163
  }
164
- const attributeName = originalAttributeName.toLowerCase();
164
+ // const attributeName = originalAttributeName.toLowerCase();
165
165
  if(value.__$Observable) {
166
166
  if(BOOLEAN_ATTRIBUTES.has(attributeName)) {
167
167
  bindBooleanAttribute(element, attributeName, value);
168
168
  continue;
169
169
  }
170
- bindAttributeWithObservable(element, originalAttributeName, value);
170
+ bindAttributeWithObservable(element, attributeName, value);
171
171
  continue;
172
172
  }
173
173
  if(type === 'object') {
@@ -7,7 +7,7 @@ export const ElementCreator = {
7
7
  createTextNode() {
8
8
  if(!$textNodeCache) {
9
9
  $textNodeCache = document.createTextNode('');
10
- ElementCreator.createTextNode = () => $textNodeCache.cloneNode();
10
+ ElementCreator.createTextNode = $textNodeCache.cloneNode.bind($textNodeCache);
11
11
  }
12
12
  return $textNodeCache.cloneNode();
13
13
  },
@@ -57,6 +57,11 @@ export const ElementCreator = {
57
57
  parent && parent.appendChild(text);
58
58
  return text;
59
59
  },
60
+ createStaticTextNodeWithoutParent: (value) => {
61
+ const text = ElementCreator.createTextNode();
62
+ text.nodeValue = value;
63
+ return text;
64
+ },
60
65
  /**
61
66
  *
62
67
  * @param {string} name
@@ -80,29 +85,29 @@ export const ElementCreator = {
80
85
  * @param {HTMLElement|DocumentFragment} parent
81
86
  */
82
87
  processChildren: (children, parent) => {
83
- if(children === null) return;
84
88
  if(process.env.NODE_ENV === 'development') {
85
89
  PluginsManager.emit('BeforeProcessChildren', parent);
86
90
  }
87
91
  const child = ElementCreator.getChild(children);
88
- if(child) {
89
- parent.appendChild(child);
90
- }
92
+ parent.appendChild(child);
91
93
  if(process.env.NODE_ENV === 'development') {
92
94
  PluginsManager.emit('AfterProcessChildren', parent);
93
95
  }
94
96
  },
95
97
  async safeRemove(element) {
96
98
  await element.remove();
97
-
98
99
  },
99
100
  getChild: (child) => {
100
- if (child == null) return null;
101
+ if (child == null) {
102
+ return null;
103
+ }
101
104
 
102
105
  child = child.toNdElement();
103
- if (child instanceof Node) return child;
106
+ if (child && child.__$isNativeNode) {
107
+ return child;
108
+ }
104
109
 
105
- while (child != null && !(child instanceof Node)) {
110
+ while (child != null && !child.__$isNativeNode) {
106
111
  child = child.toNdElement?.();
107
112
  }
108
113
 
@@ -36,10 +36,11 @@ export const createTextNode = (value) => {
36
36
  * @returns {HTMLElement} The configured element
37
37
  */
38
38
  export const createVoidHtmlElement = (element, attributes) => {
39
- ElementCreator.processAttributes(element, attributes);
39
+ attributes && ElementCreator.processAttributes(element, attributes);
40
40
  return element;
41
41
  };
42
42
 
43
+
43
44
  const OBJECT_PROTOTYPE = Object.prototype;
44
45
  /**
45
46
  * Applies attributes and children to an existing HTMLElement.
@@ -53,13 +54,17 @@ const OBJECT_PROTOTYPE = Object.prototype;
53
54
  */
54
55
  export const createHtmlElement = (element, _attributes, _children = null) => {
55
56
  let attributes = _attributes, children = _children;
56
- if((!_attributes || !_children) && (typeof _attributes !== 'object' || Array.isArray(_attributes) || _attributes === null || Object.getPrototypeOf(_attributes) !== OBJECT_PROTOTYPE || _attributes.$hydrate)) { // IF it's not a JSON
57
+ if(_attributes.__$isValidNdChild) { // If attributes is a ValidChild
57
58
  attributes = _children;
58
59
  children = _attributes;
59
60
  }
60
61
 
61
- ElementCreator.processAttributes(element, attributes);
62
- ElementCreator.processChildren(children, element);
62
+ if(attributes) {
63
+ ElementCreator.processAttributes(element, attributes);
64
+ }
65
+ if(children) {
66
+ ElementCreator.processChildren(children, element);
67
+ }
63
68
  return element;
64
69
  };
65
70
 
@@ -195,19 +195,26 @@ NDElement.prototype.destroy = function() {
195
195
  observer.disconnect();
196
196
  }
197
197
 
198
- const children = this.$element?.querySelectorAll('[data--nd-before-unmount]');
198
+ const treewalk = document.createTreeWalker(this.$element, NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_TEXT);
199
+ const nodes = [];
200
+ while(treewalk.nextNode()) {
201
+ nodes.push(treewalk.currentNode);
202
+ }
199
203
 
200
- for(let i = 0, length = children.length; i < length; i++) {
201
- const child = children[i];
204
+ for(let i = 0, length = nodes.length; i < length; i++) {
205
+ const child = nodes[i];
202
206
  child.remove();
203
- child.__$controller?.abort();
204
- child.__$controller = null;
205
- $lifeCycleObservers.delete(child);
207
+ if(child.__$controller) {
208
+ child.__$controller.abort();
209
+ child.__$controller = null;
210
+ $lifeCycleObservers.delete(child);
211
+ }
206
212
  }
207
213
 
208
214
  this.$element.__$controller?.abort();
209
215
  this.$element.__$controller = null;
210
216
  $lifeCycleObservers.delete(this.$element);
217
+ this.$element.remove();
211
218
  this.$element = null;
212
219
  };
213
220
 
@@ -74,7 +74,7 @@ EVENTS_WITH_PREVENT.forEach(eventSourceName => {
74
74
  */
75
75
  NDElement.prototype.$getSignal = function() {
76
76
  if(!this.$element.__$controller) {
77
- this.$element.__$controller = new AbortController();
77
+ // this.$element.__$controller = new AbortController();
78
78
  }
79
79
  return this.$element.__$controller.signal;
80
80
  };
@@ -3,19 +3,19 @@ export const BOOLEAN_ATTRIBUTES = new Set([
3
3
  'checked',
4
4
  'selected',
5
5
  'disabled',
6
- 'readonly',
6
+ 'readonly', 'readOnly',
7
7
  'required',
8
- 'autofocus',
8
+ 'autofocus', 'autoFocus',
9
9
  'multiple',
10
- 'autocomplete',
10
+ 'autocomplete', 'autoComplete',
11
11
  'hidden',
12
- 'contenteditable',
13
- 'spellcheck',
12
+ 'contenteditable', 'contentEditable',
13
+ 'spellcheck', 'spellCheck',
14
14
  'translate',
15
15
  'draggable',
16
16
  'async',
17
17
  'defer',
18
- 'autoplay',
18
+ 'autoplay', 'autoPlay',
19
19
  'controls',
20
20
  'loop',
21
21
  'muted',
@@ -23,13 +23,13 @@ export const BOOLEAN_ATTRIBUTES = new Set([
23
23
  'reversed',
24
24
  'open',
25
25
  'default',
26
- 'formnovalidate',
27
- 'novalidate',
26
+ 'formnovalidate', 'formNoValidate',
27
+ 'novalidate', 'noValidate',
28
28
  'scoped',
29
- 'itemscope',
30
- 'allowfullscreen',
31
- 'allowpaymentrequest',
32
- 'playsinline',
29
+ 'itemscope', 'itemScope',
30
+ 'allowfullscreen', 'allowFullscreen',
31
+ 'allowpaymentrequest', 'allowPaymentRequest',
32
+ 'playsinline', 'playsInline',
33
33
  ]);
34
34
 
35
35
  export const BOOL_ATTRIBUTES_NAME = {
@@ -20,9 +20,62 @@ const defineToNdElement = (target, fn) => {
20
20
  });
21
21
  };
22
22
 
23
+ /**
24
+ * Marks a prototype as a valid NativeDocument child node.
25
+ *
26
+ * @param {object} target - The prototype to mark
27
+ */
28
+ const defineValidNdChild = (target) => {
29
+ Object.defineProperty(target, '__$isValidNdChild', {
30
+ value: true,
31
+ writable: true,
32
+ configurable: true,
33
+ enumerable: false,
34
+ });
35
+ };
36
+
37
+ /**
38
+ * Marks a prototype as a native DOM node.
39
+ * Faster alternative to instanceof Node for hot paths.
40
+ *
41
+ * @param {object} target - The prototype to mark
42
+ */
43
+ const defineNativeNode = (target) => {
44
+ Object.defineProperty(target, '__$isNativeNode', {
45
+ value: true,
46
+ writable: true,
47
+ configurable: true,
48
+ enumerable: false,
49
+ });
50
+ };
51
+
23
52
  NDElement.$getChild = ElementCreator.getChild;
24
53
 
25
- // -- String -------------------------------------------------------------------
54
+ // -- __$isNativeNode ----------------------------------------------------------
55
+
56
+ defineNativeNode(Element.prototype);
57
+ defineNativeNode(Text.prototype);
58
+ defineNativeNode(Comment.prototype);
59
+ defineNativeNode(Document.prototype);
60
+ defineNativeNode(DocumentFragment.prototype);
61
+
62
+ // -- __$isValidNdChild --------------------------------------------------------
63
+
64
+ defineValidNdChild(String.prototype);
65
+ defineValidNdChild(Number.prototype);
66
+ defineValidNdChild(Boolean.prototype);
67
+ defineValidNdChild(Array.prototype);
68
+ defineValidNdChild(Element.prototype);
69
+ defineValidNdChild(Text.prototype);
70
+ defineValidNdChild(Comment.prototype);
71
+ defineValidNdChild(DocumentFragment.prototype);
72
+ defineValidNdChild(NDElement.prototype);
73
+ defineValidNdChild(ObservableItem.prototype);
74
+ defineValidNdChild(ObservableChecker.prototype);
75
+ defineValidNdChild(TemplateBinding.prototype);
76
+ defineValidNdChild(Function.prototype);
77
+
78
+ // -- toNdElement --------------------------------------------------------------
26
79
 
27
80
  /**
28
81
  * Converts a string to a static text node.
@@ -30,22 +83,18 @@ NDElement.$getChild = ElementCreator.getChild;
30
83
  * @returns {Text}
31
84
  */
32
85
  defineToNdElement(String.prototype, function () {
33
- return ElementCreator.createStaticTextNode(null, this);
86
+ return ElementCreator.createStaticTextNodeWithoutParent(this);
34
87
  });
35
88
 
36
- // -- Number -------------------------------------------------------------------
37
-
38
89
  /**
39
90
  * Converts a number to a static text node.
40
91
  *
41
92
  * @returns {Text}
42
93
  */
43
94
  defineToNdElement(Number.prototype, function () {
44
- return ElementCreator.createStaticTextNode(null, this.toString());
95
+ return ElementCreator.createStaticTextNodeWithoutParent(this.toString());
45
96
  });
46
97
 
47
- // -- DOM nodes (identity) -----------------------------------------------------
48
-
49
98
  /**
50
99
  * Returns the DOM node itself (identity).
51
100
  *
@@ -57,8 +106,6 @@ defineToNdElement(Comment.prototype, function () { return this; });
57
106
  defineToNdElement(Document.prototype, function () { return this; });
58
107
  defineToNdElement(DocumentFragment.prototype, function () { return this; });
59
108
 
60
- // -- ObservableItem -----------------------------------------------------------
61
-
62
109
  /**
63
110
  * Converts an ObservableItem to a reactive text node that updates when the value changes.
64
111
  *
@@ -70,8 +117,6 @@ defineToNdElement(ObservableItem.prototype, function () {
70
117
 
71
118
  ObservableChecker.prototype.toNdElement = ObservableItem.prototype.toNdElement;
72
119
 
73
- // -- NDElement ----------------------------------------------------------------
74
-
75
120
  /**
76
121
  * Returns the underlying HTMLElement of this NDElement.
77
122
  *
@@ -81,8 +126,6 @@ defineToNdElement(NDElement.prototype, function () {
81
126
  return this.$element;
82
127
  });
83
128
 
84
- // -- Array --------------------------------------------------------------------
85
-
86
129
  /**
87
130
  * Converts the array to a DocumentFragment containing all child elements.
88
131
  *
@@ -98,8 +141,6 @@ defineToNdElement(Array.prototype, function () {
98
141
  return fragment;
99
142
  });
100
143
 
101
- // -- Function -----------------------------------------------------------------
102
-
103
144
  /**
104
145
  * Calls the function and converts its return value to a DOM node.
105
146
  *
@@ -113,8 +154,6 @@ defineToNdElement(Function.prototype, function () {
113
154
  return ElementCreator.getChild(child());
114
155
  });
115
156
 
116
- // -- TemplateBinding ----------------------------------------------------------
117
-
118
157
  /**
119
158
  * Converts the TemplateBinding to a hydratable DOM node.
120
159
  *
@@ -36,8 +36,8 @@ const buildHeader = ($desc, instance, headerId, panelId) => {
36
36
  ];
37
37
 
38
38
  const header = Div({
39
- class: 'accordion-header',
40
- id: headerId,
39
+ class: 'accordion-header',
40
+ id: headerId,
41
41
  // [a11y] aria-expanded reactive, aria-controls points to panel
42
42
  'aria-expanded': $desc.expanded.transform((v) => String(v)),
43
43
  'aria-controls': panelId,
@@ -64,12 +64,12 @@ const buildIndicator = ($desc) => {
64
64
  }, '▾');
65
65
  };
66
66
 
67
- const buildContent = ($desc, instance) => {
67
+ const buildContent = ($desc, instance, headerId, panelId) => {
68
68
  // [a11y] role=region + aria-labelledby on panel
69
69
  const panelProps = {
70
- class: 'accordion-content',
71
- id: panelId,
72
- role: 'region',
70
+ class: 'accordion-content',
71
+ id: panelId,
72
+ role: 'region',
73
73
  'aria-labelledby': headerId,
74
74
  };
75
75