dv-web-components 1.0.7 → 1.0.10

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.
@@ -4,8 +4,8 @@ export class AppSelect extends HTMLElement {
4
4
  connectedCallback(): void;
5
5
  disconnectedCallback(): void;
6
6
  attributeChangedCallback(name: any, oldValue: any, newValue: any): void;
7
- set value(val: any);
8
- get value(): any;
7
+ set value(val: string);
8
+ get value(): string;
9
9
  set options(val: any);
10
10
  get options(): any;
11
11
  set name(val: string);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dv-web-components",
3
- "version": "1.0.7",
3
+ "version": "1.0.10",
4
4
  "description": "Librería de Web Components nativos y accesibles",
5
5
  "type": "module",
6
6
  "main": "./index.js",
@@ -68,7 +68,6 @@ template.innerHTML = `
68
68
  justify-content: center;
69
69
  }
70
70
 
71
- /* Ocultamos el slot de opciones del light DOM para no duplicar la visualización */
72
71
  ::slotted(option) {
73
72
  display: none;
74
73
  }
@@ -100,7 +99,6 @@ template.innerHTML = `
100
99
  <polyline points="6 9 12 15 18 9"></polyline>
101
100
  </svg>
102
101
  </span>
103
- <!-- Slot para capturar las etiquetas <option> que pase el usuario -->
104
102
  <slot style="display: none;"></slot>
105
103
  </div>
106
104
  </div>
@@ -116,6 +114,7 @@ export class AppSelect extends HTMLElement {
116
114
  #observer = null;
117
115
  #initialValue = '';
118
116
  #optionsData = null;
117
+ #value = '';
119
118
 
120
119
  static get observedAttributes() {
121
120
  return ['value', 'name', 'disabled', 'required', 'placeholder', 'label'];
@@ -134,13 +133,16 @@ export class AppSelect extends HTMLElement {
134
133
 
135
134
  connectedCallback() {
136
135
  this.#initialValue = this.getAttribute('value') || '';
136
+ if (!this.#value) {
137
+ this.#value = this.#initialValue;
138
+ }
139
+
137
140
  this.#syncOptions();
138
141
  this.#updateState();
139
142
 
140
143
  this.#selectElement.addEventListener('change', this.#handleChange);
141
144
  this.#slotElement?.addEventListener('slotchange', this.#syncOptions);
142
145
 
143
- // Observar inserción dinámica de <option> en el Light DOM
144
146
  this.#observer = new MutationObserver(() => this.#syncOptions());
145
147
  this.#observer.observe(this, { childList: true, subtree: true, characterData: true });
146
148
  }
@@ -153,19 +155,23 @@ export class AppSelect extends HTMLElement {
153
155
 
154
156
  attributeChangedCallback(name, oldValue, newValue) {
155
157
  if (oldValue === newValue) return;
158
+
159
+ if (name === 'value') {
160
+ this.#value = newValue ?? '';
161
+ }
162
+
156
163
  this.#updateState();
164
+ this.#syncOptions();
157
165
  }
158
166
 
159
167
  #syncOptions = () => {
160
168
  if (!this.#selectElement) return;
161
169
 
162
- // Si las opciones vinieron por propiedad JS (array)
163
170
  if (Array.isArray(this.#optionsData)) {
164
171
  this.#renderOptionsFromArray(this.#optionsData);
165
172
  return;
166
173
  }
167
174
 
168
- // Si las opciones vienen por Light DOM (<option> hijos)
169
175
  const options = Array.from(this.querySelectorAll('option'));
170
176
  this.#selectElement.innerHTML = '';
171
177
 
@@ -175,7 +181,7 @@ export class AppSelect extends HTMLElement {
175
181
  phOption.value = '';
176
182
  phOption.textContent = placeholder;
177
183
  phOption.disabled = true;
178
- phOption.selected = !this.value;
184
+ phOption.selected = !this.#value;
179
185
  this.#selectElement.appendChild(phOption);
180
186
  }
181
187
 
@@ -184,17 +190,21 @@ export class AppSelect extends HTMLElement {
184
190
  clone.value = opt.value;
185
191
  clone.textContent = opt.textContent;
186
192
  clone.disabled = opt.disabled;
187
- if (opt.value === this.value) {
193
+
194
+ if (opt.value === this.#value) {
188
195
  clone.selected = true;
189
196
  }
197
+
190
198
  this.#selectElement.appendChild(clone);
191
199
  });
192
200
 
193
- if (this.value) {
194
- this.#selectElement.value = this.value;
201
+ if (this.#value) {
202
+ this.#selectElement.value = this.#value;
195
203
  } else if (this.#selectElement.value) {
196
- this.#internals.setFormValue(this.#selectElement.value);
204
+ this.#value = this.#selectElement.value;
197
205
  }
206
+
207
+ this.#internals.setFormValue(this.#value);
198
208
  };
199
209
 
200
210
  #renderOptionsFromArray(items) {
@@ -206,7 +216,7 @@ export class AppSelect extends HTMLElement {
206
216
  phOption.value = '';
207
217
  phOption.textContent = placeholder;
208
218
  phOption.disabled = true;
209
- phOption.selected = !this.value;
219
+ phOption.selected = !this.#value;
210
220
  this.#selectElement.appendChild(phOption);
211
221
  }
212
222
 
@@ -220,25 +230,30 @@ export class AppSelect extends HTMLElement {
220
230
  opt.textContent = item.label ?? item.value;
221
231
  opt.disabled = Boolean(item.disabled);
222
232
  }
223
- if (opt.value === this.value) {
233
+
234
+ if (opt.value === this.#value) {
224
235
  opt.selected = true;
225
236
  }
237
+
226
238
  this.#selectElement.appendChild(opt);
227
239
  });
228
240
 
229
- if (this.value) {
230
- this.#selectElement.value = this.value;
241
+ if (this.#value) {
242
+ this.#selectElement.value = this.#value;
243
+ } else if (this.#selectElement.value) {
244
+ this.#value = this.#selectElement.value;
231
245
  }
246
+
247
+ this.#internals.setFormValue(this.#value);
232
248
  }
233
249
 
234
250
  #updateState() {
235
251
  if (!this.#selectElement) return;
236
252
 
237
- const val = this.getAttribute('value') || '';
238
- if (val && this.#selectElement.value !== val) {
239
- this.#selectElement.value = val;
253
+ if (this.#value && this.#selectElement.value !== this.#value) {
254
+ this.#selectElement.value = this.#value;
240
255
  }
241
- this.#internals.setFormValue(this.#selectElement.value || val);
256
+ this.#internals.setFormValue(this.#value);
242
257
 
243
258
  this.#selectElement.disabled = this.hasAttribute('disabled');
244
259
  this.#selectElement.required = this.hasAttribute('required');
@@ -259,6 +274,7 @@ export class AppSelect extends HTMLElement {
259
274
  #handleChange = (event) => {
260
275
  event.stopPropagation();
261
276
  const val = this.#selectElement.value;
277
+ this.#value = val;
262
278
  this.#internals.setFormValue(val);
263
279
 
264
280
  this.dispatchEvent(
@@ -277,16 +293,21 @@ export class AppSelect extends HTMLElement {
277
293
  );
278
294
  };
279
295
 
280
- // Getters & Setters
281
296
  get value() {
282
- return this.#selectElement ? this.#selectElement.value : this.getAttribute('value') || '';
297
+ return this.#value;
283
298
  }
284
299
 
285
300
  set value(val) {
286
301
  const stringVal = val == null ? '' : String(val);
302
+ this.#value = stringVal;
303
+
287
304
  if (this.#selectElement) {
288
305
  this.#selectElement.value = stringVal;
306
+ Array.from(this.#selectElement.options).forEach((opt) => {
307
+ opt.selected = opt.value === stringVal;
308
+ });
289
309
  }
310
+
290
311
  this.#internals.setFormValue(stringVal);
291
312
  }
292
313
 
@@ -335,7 +356,6 @@ export class AppSelect extends HTMLElement {
335
356
  else this.removeAttribute('label');
336
357
  }
337
358
 
338
- // Soporte nativo de formularios
339
359
  formResetCallback() {
340
360
  this.value = this.#initialValue;
341
361
  }
@@ -371,4 +391,4 @@ export class AppSelect extends HTMLElement {
371
391
 
372
392
  if (!customElements.get('app-select')) {
373
393
  customElements.define('app-select', AppSelect);
374
- }
394
+ }