@maggioli-design-system/mds-table-row 1.1.1 → 1.4.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.
Files changed (75) hide show
  1. package/dist/cjs/{index-797b786c.js → index-b308d20f.js} +156 -371
  2. package/dist/cjs/loader.cjs.js +3 -3
  3. package/dist/cjs/mds-table-row.cjs.entry.js +3 -44
  4. package/dist/cjs/mds-table-row.cjs.js +3 -3
  5. package/dist/collection/collection-manifest.json +2 -2
  6. package/dist/collection/components/mds-table-row/mds-table-row.css +21 -31
  7. package/dist/collection/components/mds-table-row/mds-table-row.js +21 -5
  8. package/dist/collection/dictionary/icon.js +5 -2
  9. package/dist/collection/dictionary/typography.js +7 -1
  10. package/dist/collection/dictionary/variant.js +6 -1
  11. package/dist/{custom-elements → components}/index.d.ts +1 -20
  12. package/dist/components/index.js +1 -0
  13. package/dist/components/mds-table-row.d.ts +11 -0
  14. package/dist/components/mds-table-row.js +39 -0
  15. package/dist/esm/{index-7d849f54.js → index-7d3be39d.js} +156 -371
  16. package/dist/esm/loader.js +3 -3
  17. package/dist/esm/mds-table-row.entry.js +3 -44
  18. package/dist/esm/mds-table-row.js +3 -3
  19. package/dist/esm/polyfills/css-shim.js +1 -1
  20. package/dist/esm-es5/index-7d3be39d.js +1 -0
  21. package/dist/esm-es5/loader.js +1 -1
  22. package/dist/esm-es5/mds-table-row.entry.js +1 -1
  23. package/dist/esm-es5/mds-table-row.js +1 -1
  24. package/dist/mds-table-row/mds-table-row.esm.js +1 -1
  25. package/dist/mds-table-row/mds-table-row.js +1 -1
  26. package/dist/mds-table-row/p-24980e09.entry.js +1 -0
  27. package/dist/mds-table-row/p-5002b598.js +1 -0
  28. package/dist/mds-table-row/p-84058f8c.system.js +1 -0
  29. package/dist/mds-table-row/p-bfe52009.system.js +1 -0
  30. package/dist/mds-table-row/p-f2da3252.system.entry.js +1 -0
  31. package/dist/stats.json +109 -59
  32. package/dist/types/components/mds-table-row/mds-table-row.d.ts +1 -1
  33. package/dist/types/components.d.ts +2 -0
  34. package/dist/types/dictionary/icon.d.ts +1 -1
  35. package/dist/types/dictionary/typography.d.ts +2 -1
  36. package/dist/types/dictionary/variant.d.ts +2 -1
  37. package/dist/types/stencil-public-runtime.d.ts +6 -4
  38. package/dist/types/types/typography.d.ts +3 -2
  39. package/dist/types/types/variant.d.ts +2 -1
  40. package/package.json +12 -16
  41. package/readme.md +17 -0
  42. package/src/components/mds-table-row/mds-table-row.css +18 -21
  43. package/src/components/mds-table-row/mds-table-row.tsx +4 -5
  44. package/src/components/mds-table-row/readme.md +17 -0
  45. package/src/components.d.ts +2 -0
  46. package/src/dictionary/icon.ts +7 -2
  47. package/src/dictionary/typography.ts +8 -0
  48. package/src/dictionary/variant.ts +7 -0
  49. package/src/types/typography.ts +6 -0
  50. package/src/types/variant.ts +6 -1
  51. package/www/build/mds-table-row.esm.js +1 -1
  52. package/www/build/mds-table-row.js +1 -1
  53. package/www/build/p-24980e09.entry.js +1 -0
  54. package/www/build/p-5002b598.js +1 -0
  55. package/www/build/p-84058f8c.system.js +1 -0
  56. package/www/build/p-bfe52009.system.js +1 -0
  57. package/www/build/p-f2da3252.system.entry.js +1 -0
  58. package/dist/collection/dictionary/status.js +0 -7
  59. package/dist/collection/dictionary/tag.js +0 -53
  60. package/dist/custom-elements/index.js +0 -74
  61. package/dist/esm-es5/index-7d849f54.js +0 -1
  62. package/dist/mds-table-row/p-13e3a2cc.system.js +0 -1
  63. package/dist/mds-table-row/p-3619a466.js +0 -1
  64. package/dist/mds-table-row/p-c3576dff.system.entry.js +0 -1
  65. package/dist/mds-table-row/p-cc341cca.system.js +0 -1
  66. package/dist/mds-table-row/p-d6429c2e.entry.js +0 -1
  67. package/dist/types/dictionary/status.d.ts +0 -2
  68. package/dist/types/dictionary/tag.d.ts +0 -2
  69. package/src/dictionary/status.ts +0 -10
  70. package/src/dictionary/tag.ts +0 -57
  71. package/www/build/p-13e3a2cc.system.js +0 -1
  72. package/www/build/p-3619a466.js +0 -1
  73. package/www/build/p-c3576dff.system.entry.js +0 -1
  74. package/www/build/p-cc341cca.system.js +0 -1
  75. package/www/build/p-d6429c2e.entry.js +0 -1
@@ -22,11 +22,8 @@ function _interopNamespace(e) {
22
22
 
23
23
  const NAMESPACE = 'mds-table-row';
24
24
 
25
- let contentRef;
25
+ let scopeId;
26
26
  let hostTagName;
27
- let useNativeShadowDom = false;
28
- let checkSlotFallbackVisibility = false;
29
- let checkSlotRelocate = false;
30
27
  let isSvgMode = false;
31
28
  let queuePending = false;
32
29
  const win = typeof window !== 'undefined' ? window : {};
@@ -147,8 +144,20 @@ const addStyle = (styleContainerNode, cmpMeta, mode, hostElm) => {
147
144
  const attachStyles = (hostRef) => {
148
145
  const cmpMeta = hostRef.$cmpMeta$;
149
146
  const elm = hostRef.$hostElement$;
147
+ const flags = cmpMeta.$flags$;
150
148
  const endAttachStyles = createTime('attachStyles', cmpMeta.$tagName$);
151
- addStyle(elm.getRootNode(), cmpMeta);
149
+ const scopeId = addStyle(elm.shadowRoot ? elm.shadowRoot : elm.getRootNode(), cmpMeta);
150
+ if (flags & 10 /* needsScopedEncapsulation */) {
151
+ // only required when we're NOT using native shadow dom (slot)
152
+ // or this browser doesn't support native shadow dom
153
+ // and this host element was NOT created with SSR
154
+ // let's pick out the inner content for slot projection
155
+ // create a node to represent where the original
156
+ // content was first placed, which is useful later on
157
+ // DOM WRITE!!
158
+ elm['s-sc'] = scopeId;
159
+ elm.classList.add(scopeId + '-h');
160
+ }
152
161
  endAttachStyles();
153
162
  };
154
163
  const getScopeId = (cmp, mode) => 'sc-' + (cmp.$tagName$);
@@ -160,6 +169,7 @@ const getScopeId = (cmp, mode) => 'sc-' + (cmp.$tagName$);
160
169
  * Don't add values to these!!
161
170
  */
162
171
  const EMPTY_OBJ = {};
172
+ const isDef = (v) => v != null;
163
173
  const isComplexType = (o) => {
164
174
  // https://jsperf.com/typeof-fn-object/5
165
175
  o = typeof o;
@@ -178,7 +188,6 @@ const isComplexType = (o) => {
178
188
  // export function h(nodeName: string | d.FunctionalComponent, vnodeData: d.PropsType, ...children: d.ChildType[]): d.VNode;
179
189
  const h = (nodeName, vnodeData, ...children) => {
180
190
  let child = null;
181
- let slotName = null;
182
191
  let simple = false;
183
192
  let lastSimple = false;
184
193
  let vNodeChildren = [];
@@ -205,30 +214,11 @@ const h = (nodeName, vnodeData, ...children) => {
205
214
  }
206
215
  };
207
216
  walk(children);
208
- if (vnodeData) {
209
- if (vnodeData.name) {
210
- slotName = vnodeData.name;
211
- }
212
- {
213
- const classData = vnodeData.className || vnodeData.class;
214
- if (classData) {
215
- vnodeData.class =
216
- typeof classData !== 'object'
217
- ? classData
218
- : Object.keys(classData)
219
- .filter((k) => classData[k])
220
- .join(' ');
221
- }
222
- }
223
- }
224
217
  const vnode = newVNode(nodeName, null);
225
218
  vnode.$attrs$ = vnodeData;
226
219
  if (vNodeChildren.length > 0) {
227
220
  vnode.$children$ = vNodeChildren;
228
221
  }
229
- {
230
- vnode.$name$ = slotName;
231
- }
232
222
  return vnode;
233
223
  };
234
224
  const newVNode = (tag, text) => {
@@ -242,9 +232,6 @@ const newVNode = (tag, text) => {
242
232
  {
243
233
  vnode.$attrs$ = null;
244
234
  }
245
- {
246
- vnode.$name$ = null;
247
- }
248
235
  return vnode;
249
236
  };
250
237
  const Host = {};
@@ -261,14 +248,7 @@ const setAccessor = (elm, memberName, oldValue, newValue, isSvg, flags) => {
261
248
  if (oldValue !== newValue) {
262
249
  let isProp = isMemberInElement(elm, memberName);
263
250
  memberName.toLowerCase();
264
- if (memberName === 'class') {
265
- const classList = elm.classList;
266
- const oldClasses = parseClassList(oldValue);
267
- const newClasses = parseClassList(newValue);
268
- classList.remove(...oldClasses.filter((c) => c && !newClasses.includes(c)));
269
- classList.add(...newClasses.filter((c) => c && !oldClasses.includes(c)));
270
- }
271
- else {
251
+ {
272
252
  // Set property if it exists and it's not a SVG
273
253
  const isComplex = isComplexType(newValue);
274
254
  if ((isProp || (isComplex && newValue !== null)) && !isSvg) {
@@ -305,8 +285,6 @@ const setAccessor = (elm, memberName, oldValue, newValue, isSvg, flags) => {
305
285
  }
306
286
  }
307
287
  };
308
- const parseClassListRegex = /\s/;
309
- const parseClassList = (value) => (!value ? [] : value.split(parseClassListRegex));
310
288
  const updateElement = (oldVnode, newVnode, isSvgMode, memberName) => {
311
289
  // if the element passed in is a shadow root, which is a document fragment
312
290
  // then we want to be adding attrs/props to the shadow root's "host" element
@@ -335,32 +313,18 @@ const createElm = (oldParentVNode, newParentVNode, childIndex, parentElm) => {
335
313
  let i = 0;
336
314
  let elm;
337
315
  let childNode;
338
- let oldVNode;
339
- if (!useNativeShadowDom) {
340
- // remember for later we need to check to relocate nodes
341
- checkSlotRelocate = true;
342
- if (newVNode.$tag$ === 'slot') {
343
- newVNode.$flags$ |= newVNode.$children$
344
- ? // slot element has fallback content
345
- 2 /* isSlotFallback */
346
- : // slot element does not have fallback content
347
- 1 /* isSlotReference */;
348
- }
349
- }
350
- if (newVNode.$flags$ & 1 /* isSlotReference */) {
351
- // create a slot reference node
352
- elm = newVNode.$elm$ =
353
- doc.createTextNode('');
354
- }
355
- else {
316
+ {
356
317
  // create element
357
- elm = newVNode.$elm$ = (doc.createElement(newVNode.$flags$ & 2 /* isSlotFallback */
358
- ? 'slot-fb'
359
- : newVNode.$tag$));
318
+ elm = newVNode.$elm$ = (doc.createElement(newVNode.$tag$));
360
319
  // add css classes, attrs, props, listeners, etc.
361
320
  {
362
321
  updateElement(null, newVNode, isSvgMode);
363
322
  }
323
+ if (isDef(scopeId) && elm['s-si'] !== scopeId) {
324
+ // if there is a scopeId and this is the initial render
325
+ // then let's add the scopeId as a css class
326
+ elm.classList.add((elm['s-si'] = scopeId));
327
+ }
364
328
  if (newVNode.$children$) {
365
329
  for (i = 0; i < newVNode.$children$.length; ++i) {
366
330
  // create the node
@@ -373,59 +337,20 @@ const createElm = (oldParentVNode, newParentVNode, childIndex, parentElm) => {
373
337
  }
374
338
  }
375
339
  }
376
- {
377
- elm['s-hn'] = hostTagName;
378
- if (newVNode.$flags$ & (2 /* isSlotFallback */ | 1 /* isSlotReference */)) {
379
- // remember the content reference comment
380
- elm['s-sr'] = true;
381
- // remember the content reference comment
382
- elm['s-cr'] = contentRef;
383
- // remember the slot name, or empty string for default slot
384
- elm['s-sn'] = newVNode.$name$ || '';
385
- // check if we've got an old vnode for this slot
386
- oldVNode = oldParentVNode && oldParentVNode.$children$ && oldParentVNode.$children$[childIndex];
387
- if (oldVNode && oldVNode.$tag$ === newVNode.$tag$ && oldParentVNode.$elm$) {
388
- // we've got an old slot vnode and the wrapper is being replaced
389
- // so let's move the old slot content back to it's original location
390
- putBackInOriginalLocation(oldParentVNode.$elm$, false);
391
- }
392
- }
393
- }
394
340
  return elm;
395
341
  };
396
- const putBackInOriginalLocation = (parentElm, recursive) => {
397
- plt.$flags$ |= 1 /* isTmpDisconnected */;
398
- const oldSlotChildNodes = parentElm.childNodes;
399
- for (let i = oldSlotChildNodes.length - 1; i >= 0; i--) {
400
- const childNode = oldSlotChildNodes[i];
401
- if (childNode['s-hn'] !== hostTagName && childNode['s-ol']) {
402
- // // this child node in the old element is from another component
403
- // // remove this node from the old slot's parent
404
- // childNode.remove();
405
- // and relocate it back to it's original location
406
- parentReferenceNode(childNode).insertBefore(childNode, referenceNode(childNode));
407
- // remove the old original location comment entirely
408
- // later on the patch function will know what to do
409
- // and move this to the correct spot in need be
410
- childNode['s-ol'].remove();
411
- childNode['s-ol'] = undefined;
412
- checkSlotRelocate = true;
413
- }
414
- if (recursive) {
415
- putBackInOriginalLocation(childNode, recursive);
416
- }
417
- }
418
- plt.$flags$ &= ~1 /* isTmpDisconnected */;
419
- };
420
342
  const addVnodes = (parentElm, before, parentVNode, vnodes, startIdx, endIdx) => {
421
- let containerElm = ((parentElm['s-cr'] && parentElm['s-cr'].parentNode) || parentElm);
343
+ let containerElm = (parentElm);
422
344
  let childNode;
345
+ if (containerElm.shadowRoot && containerElm.tagName === hostTagName) {
346
+ containerElm = containerElm.shadowRoot;
347
+ }
423
348
  for (; startIdx <= endIdx; ++startIdx) {
424
349
  if (vnodes[startIdx]) {
425
350
  childNode = createElm(null, parentVNode, startIdx);
426
351
  if (childNode) {
427
352
  vnodes[startIdx].$elm$ = childNode;
428
- containerElm.insertBefore(childNode, referenceNode(before) );
353
+ containerElm.insertBefore(childNode, before);
429
354
  }
430
355
  }
431
356
  }
@@ -434,20 +359,6 @@ const removeVnodes = (vnodes, startIdx, endIdx, vnode, elm) => {
434
359
  for (; startIdx <= endIdx; ++startIdx) {
435
360
  if ((vnode = vnodes[startIdx])) {
436
361
  elm = vnode.$elm$;
437
- {
438
- // we're removing this element
439
- // so it's possible we need to show slot fallback content now
440
- checkSlotFallbackVisibility = true;
441
- if (elm['s-ol']) {
442
- // remove the original location comment
443
- elm['s-ol'].remove();
444
- }
445
- else {
446
- // it's possible that child nodes of the node
447
- // that's being removed are slot nodes
448
- putBackInOriginalLocation(elm, true);
449
- }
450
- }
451
362
  // remove the vnode's element from the dom
452
363
  elm.remove();
453
364
  }
@@ -488,20 +399,12 @@ const updateChildren = (parentElm, oldCh, newVNode, newCh) => {
488
399
  newEndVnode = newCh[--newEndIdx];
489
400
  }
490
401
  else if (isSameVnode(oldStartVnode, newEndVnode)) {
491
- // Vnode moved right
492
- if ((oldStartVnode.$tag$ === 'slot' || newEndVnode.$tag$ === 'slot')) {
493
- putBackInOriginalLocation(oldStartVnode.$elm$.parentNode, false);
494
- }
495
402
  patch(oldStartVnode, newEndVnode);
496
403
  parentElm.insertBefore(oldStartVnode.$elm$, oldEndVnode.$elm$.nextSibling);
497
404
  oldStartVnode = oldCh[++oldStartIdx];
498
405
  newEndVnode = newCh[--newEndIdx];
499
406
  }
500
407
  else if (isSameVnode(oldEndVnode, newStartVnode)) {
501
- // Vnode moved left
502
- if ((oldStartVnode.$tag$ === 'slot' || newEndVnode.$tag$ === 'slot')) {
503
- putBackInOriginalLocation(oldEndVnode.$elm$.parentNode, false);
504
- }
505
408
  patch(oldEndVnode, newStartVnode);
506
409
  parentElm.insertBefore(oldEndVnode.$elm$, oldStartVnode.$elm$);
507
410
  oldEndVnode = oldCh[--oldEndIdx];
@@ -515,7 +418,7 @@ const updateChildren = (parentElm, oldCh, newVNode, newCh) => {
515
418
  }
516
419
  if (node) {
517
420
  {
518
- parentReferenceNode(oldStartVnode.$elm$).insertBefore(node, referenceNode(oldStartVnode.$elm$));
421
+ oldStartVnode.$elm$.parentNode.insertBefore(node, oldStartVnode.$elm$);
519
422
  }
520
423
  }
521
424
  }
@@ -531,21 +434,10 @@ const isSameVnode = (vnode1, vnode2) => {
531
434
  // compare if two vnode to see if they're "technically" the same
532
435
  // need to have the same element tag, and same key to be the same
533
436
  if (vnode1.$tag$ === vnode2.$tag$) {
534
- if (vnode1.$tag$ === 'slot') {
535
- return vnode1.$name$ === vnode2.$name$;
536
- }
537
437
  return true;
538
438
  }
539
439
  return false;
540
440
  };
541
- const referenceNode = (node) => {
542
- // this node was relocated to a new location in the dom
543
- // because of some other component's slot
544
- // but we still have an html comment in place of where
545
- // it's original location was according to it's original vdom
546
- return (node && node['s-ol']) || node;
547
- };
548
- const parentReferenceNode = (node) => (node['s-ol'] ? node['s-ol'] : node).parentNode;
549
441
  const patch = (oldVNode, newVNode) => {
550
442
  const elm = (newVNode.$elm$ = oldVNode.$elm$);
551
443
  const oldChildren = oldVNode.$children$;
@@ -577,231 +469,25 @@ const patch = (oldVNode, newVNode) => {
577
469
  }
578
470
  }
579
471
  };
580
- const updateFallbackSlotVisibility = (elm) => {
581
- // tslint:disable-next-line: prefer-const
582
- let childNodes = elm.childNodes;
583
- let childNode;
584
- let i;
585
- let ilen;
586
- let j;
587
- let slotNameAttr;
588
- let nodeType;
589
- for (i = 0, ilen = childNodes.length; i < ilen; i++) {
590
- childNode = childNodes[i];
591
- if (childNode.nodeType === 1 /* ElementNode */) {
592
- if (childNode['s-sr']) {
593
- // this is a slot fallback node
594
- // get the slot name for this slot reference node
595
- slotNameAttr = childNode['s-sn'];
596
- // by default always show a fallback slot node
597
- // then hide it if there are other slots in the light dom
598
- childNode.hidden = false;
599
- for (j = 0; j < ilen; j++) {
600
- nodeType = childNodes[j].nodeType;
601
- if (childNodes[j]['s-hn'] !== childNode['s-hn'] || slotNameAttr !== '') {
602
- // this sibling node is from a different component OR is a named fallback slot node
603
- if (nodeType === 1 /* ElementNode */ && slotNameAttr === childNodes[j].getAttribute('slot')) {
604
- childNode.hidden = true;
605
- break;
606
- }
607
- }
608
- else {
609
- // this is a default fallback slot node
610
- // any element or text node (with content)
611
- // should hide the default fallback slot node
612
- if (nodeType === 1 /* ElementNode */ ||
613
- (nodeType === 3 /* TextNode */ && childNodes[j].textContent.trim() !== '')) {
614
- childNode.hidden = true;
615
- break;
616
- }
617
- }
618
- }
619
- }
620
- // keep drilling down
621
- updateFallbackSlotVisibility(childNode);
622
- }
623
- }
624
- };
625
- const relocateNodes = [];
626
- const relocateSlotContent = (elm) => {
627
- // tslint:disable-next-line: prefer-const
628
- let childNode;
629
- let node;
630
- let hostContentNodes;
631
- let slotNameAttr;
632
- let relocateNodeData;
633
- let j;
634
- let i = 0;
635
- let childNodes = elm.childNodes;
636
- let ilen = childNodes.length;
637
- for (; i < ilen; i++) {
638
- childNode = childNodes[i];
639
- if (childNode['s-sr'] && (node = childNode['s-cr']) && node.parentNode) {
640
- // first got the content reference comment node
641
- // then we got it's parent, which is where all the host content is in now
642
- hostContentNodes = node.parentNode.childNodes;
643
- slotNameAttr = childNode['s-sn'];
644
- for (j = hostContentNodes.length - 1; j >= 0; j--) {
645
- node = hostContentNodes[j];
646
- if (!node['s-cn'] && !node['s-nr'] && node['s-hn'] !== childNode['s-hn']) {
647
- // let's do some relocating to its new home
648
- // but never relocate a content reference node
649
- // that is suppose to always represent the original content location
650
- if (isNodeLocatedInSlot(node, slotNameAttr)) {
651
- // it's possible we've already decided to relocate this node
652
- relocateNodeData = relocateNodes.find((r) => r.$nodeToRelocate$ === node);
653
- // made some changes to slots
654
- // let's make sure we also double check
655
- // fallbacks are correctly hidden or shown
656
- checkSlotFallbackVisibility = true;
657
- node['s-sn'] = node['s-sn'] || slotNameAttr;
658
- if (relocateNodeData) {
659
- // previously we never found a slot home for this node
660
- // but turns out we did, so let's remember it now
661
- relocateNodeData.$slotRefNode$ = childNode;
662
- }
663
- else {
664
- // add to our list of nodes to relocate
665
- relocateNodes.push({
666
- $slotRefNode$: childNode,
667
- $nodeToRelocate$: node,
668
- });
669
- }
670
- if (node['s-sr']) {
671
- relocateNodes.map((relocateNode) => {
672
- if (isNodeLocatedInSlot(relocateNode.$nodeToRelocate$, node['s-sn'])) {
673
- relocateNodeData = relocateNodes.find((r) => r.$nodeToRelocate$ === node);
674
- if (relocateNodeData && !relocateNode.$slotRefNode$) {
675
- relocateNode.$slotRefNode$ = relocateNodeData.$slotRefNode$;
676
- }
677
- }
678
- });
679
- }
680
- }
681
- else if (!relocateNodes.some((r) => r.$nodeToRelocate$ === node)) {
682
- // so far this element does not have a slot home, not setting slotRefNode on purpose
683
- // if we never find a home for this element then we'll need to hide it
684
- relocateNodes.push({
685
- $nodeToRelocate$: node,
686
- });
687
- }
688
- }
689
- }
690
- }
691
- if (childNode.nodeType === 1 /* ElementNode */) {
692
- relocateSlotContent(childNode);
693
- }
694
- }
695
- };
696
- const isNodeLocatedInSlot = (nodeToRelocate, slotNameAttr) => {
697
- if (nodeToRelocate.nodeType === 1 /* ElementNode */) {
698
- if (nodeToRelocate.getAttribute('slot') === null && slotNameAttr === '') {
699
- return true;
700
- }
701
- if (nodeToRelocate.getAttribute('slot') === slotNameAttr) {
702
- return true;
703
- }
704
- return false;
705
- }
706
- if (nodeToRelocate['s-sn'] === slotNameAttr) {
707
- return true;
708
- }
709
- return slotNameAttr === '';
710
- };
711
472
  const renderVdom = (hostRef, renderFnResults) => {
712
473
  const hostElm = hostRef.$hostElement$;
713
474
  const cmpMeta = hostRef.$cmpMeta$;
714
475
  const oldVNode = hostRef.$vnode$ || newVNode(null, null);
715
476
  const rootVnode = isHost(renderFnResults) ? renderFnResults : h(null, null, renderFnResults);
716
477
  hostTagName = hostElm.tagName;
478
+ if (cmpMeta.$attrsToReflect$) {
479
+ rootVnode.$attrs$ = rootVnode.$attrs$ || {};
480
+ cmpMeta.$attrsToReflect$.map(([propName, attribute]) => (rootVnode.$attrs$[attribute] = hostElm[propName]));
481
+ }
717
482
  rootVnode.$tag$ = null;
718
483
  rootVnode.$flags$ |= 4 /* isHost */;
719
484
  hostRef.$vnode$ = rootVnode;
720
- rootVnode.$elm$ = oldVNode.$elm$ = (hostElm);
485
+ rootVnode.$elm$ = oldVNode.$elm$ = (hostElm.shadowRoot || hostElm );
721
486
  {
722
- contentRef = hostElm['s-cr'];
723
- useNativeShadowDom = (cmpMeta.$flags$ & 1 /* shadowDomEncapsulation */) !== 0;
724
- // always reset
725
- checkSlotFallbackVisibility = false;
487
+ scopeId = hostElm['s-sc'];
726
488
  }
727
489
  // synchronous patch
728
490
  patch(oldVNode, rootVnode);
729
- {
730
- // while we're moving nodes around existing nodes, temporarily disable
731
- // the disconnectCallback from working
732
- plt.$flags$ |= 1 /* isTmpDisconnected */;
733
- if (checkSlotRelocate) {
734
- relocateSlotContent(rootVnode.$elm$);
735
- let relocateData;
736
- let nodeToRelocate;
737
- let orgLocationNode;
738
- let parentNodeRef;
739
- let insertBeforeNode;
740
- let refNode;
741
- let i = 0;
742
- for (; i < relocateNodes.length; i++) {
743
- relocateData = relocateNodes[i];
744
- nodeToRelocate = relocateData.$nodeToRelocate$;
745
- if (!nodeToRelocate['s-ol']) {
746
- // add a reference node marking this node's original location
747
- // keep a reference to this node for later lookups
748
- orgLocationNode =
749
- doc.createTextNode('');
750
- orgLocationNode['s-nr'] = nodeToRelocate;
751
- nodeToRelocate.parentNode.insertBefore((nodeToRelocate['s-ol'] = orgLocationNode), nodeToRelocate);
752
- }
753
- }
754
- for (i = 0; i < relocateNodes.length; i++) {
755
- relocateData = relocateNodes[i];
756
- nodeToRelocate = relocateData.$nodeToRelocate$;
757
- if (relocateData.$slotRefNode$) {
758
- // by default we're just going to insert it directly
759
- // after the slot reference node
760
- parentNodeRef = relocateData.$slotRefNode$.parentNode;
761
- insertBeforeNode = relocateData.$slotRefNode$.nextSibling;
762
- orgLocationNode = nodeToRelocate['s-ol'];
763
- while ((orgLocationNode = orgLocationNode.previousSibling)) {
764
- refNode = orgLocationNode['s-nr'];
765
- if (refNode && refNode['s-sn'] === nodeToRelocate['s-sn'] && parentNodeRef === refNode.parentNode) {
766
- refNode = refNode.nextSibling;
767
- if (!refNode || !refNode['s-nr']) {
768
- insertBeforeNode = refNode;
769
- break;
770
- }
771
- }
772
- }
773
- if ((!insertBeforeNode && parentNodeRef !== nodeToRelocate.parentNode) ||
774
- nodeToRelocate.nextSibling !== insertBeforeNode) {
775
- // we've checked that it's worth while to relocate
776
- // since that the node to relocate
777
- // has a different next sibling or parent relocated
778
- if (nodeToRelocate !== insertBeforeNode) {
779
- if (!nodeToRelocate['s-hn'] && nodeToRelocate['s-ol']) {
780
- // probably a component in the index.html that doesn't have it's hostname set
781
- nodeToRelocate['s-hn'] = nodeToRelocate['s-ol'].parentNode.nodeName;
782
- }
783
- // add it back to the dom but in its new home
784
- parentNodeRef.insertBefore(nodeToRelocate, insertBeforeNode);
785
- }
786
- }
787
- }
788
- else {
789
- // this node doesn't have a slot home to go to, so let's hide it
790
- if (nodeToRelocate.nodeType === 1 /* ElementNode */) {
791
- nodeToRelocate.hidden = true;
792
- }
793
- }
794
- }
795
- }
796
- if (checkSlotFallbackVisibility) {
797
- updateFallbackSlotVisibility(rootVnode.$elm$);
798
- }
799
- // done moving nodes around
800
- // allow the disconnect callback to work again
801
- plt.$flags$ &= ~1 /* isTmpDisconnected */;
802
- // always reset
803
- relocateNodes.length = 0;
804
- }
805
491
  };
806
492
  /**
807
493
  * Helper function to create & dispatch a custom Event on a provided target
@@ -973,9 +659,37 @@ const then = (promise, thenFn) => {
973
659
  };
974
660
  const addHydratedFlag = (elm) => elm.classList.add('hydrated')
975
661
  ;
662
+ /**
663
+ * Parse a new property value for a given property type.
664
+ *
665
+ * While the prop value can reasonably be expected to be of `any` type as far as TypeScript's type checker is concerned,
666
+ * it is not safe to assume that the string returned by evaluating `typeof propValue` matches:
667
+ * 1. `any`, the type given to `propValue` in the function signature
668
+ * 2. the type stored from `propType`.
669
+ *
670
+ * This function provides the capability to parse/coerce a property's value to potentially any other JavaScript type.
671
+ *
672
+ * Property values represented in TSX preserve their type information. In the example below, the number 0 is passed to
673
+ * a component. This `propValue` will preserve its type information (`typeof propValue === 'number'`). Note that is
674
+ * based on the type of the value being passed in, not the type declared of the class member decorated with `@Prop`.
675
+ * ```tsx
676
+ * <my-cmp prop-val={0}></my-cmp>
677
+ * ```
678
+ *
679
+ * HTML prop values on the other hand, will always a string
680
+ *
681
+ * @param propValue the new value to coerce to some type
682
+ * @param propType the type of the prop, expressed as a binary number
683
+ * @returns the parsed/coerced value
684
+ */
976
685
  const parsePropertyValue = (propValue, propType) => {
977
686
  // ensure this value is of the correct prop type
978
687
  if (propValue != null && !isComplexType(propValue)) {
688
+ if (propType & 4 /* Boolean */) {
689
+ // per the HTML spec, any string value means it is a boolean true value
690
+ // but we'll cheat here and say that the string "false" is the boolean false
691
+ return propValue === 'false' ? false : propValue === '' || !!propValue;
692
+ }
979
693
  // redundant return here for better minification
980
694
  return propValue;
981
695
  }
@@ -990,7 +704,7 @@ const setValue = (ref, propName, newVal, cmpMeta) => {
990
704
  const oldVal = hostRef.$instanceValues$.get(propName);
991
705
  const flags = hostRef.$flags$;
992
706
  const instance = hostRef.$lazyInstance$ ;
993
- newVal = parsePropertyValue(newVal);
707
+ newVal = parsePropertyValue(newVal, cmpMeta.$members$[propName][0]);
994
708
  if ((!(flags & 8 /* isConstructingInstance */) || oldVal === undefined) && newVal !== oldVal) {
995
709
  // gadzooks! the property's value has changed!!
996
710
  // set our new value!
@@ -1022,13 +736,79 @@ const proxyComponent = (Cstr, cmpMeta, flags) => {
1022
736
  },
1023
737
  set(newValue) {
1024
738
  // proxyComponent, set value
1025
- setValue(this, memberName, newValue);
739
+ setValue(this, memberName, newValue, cmpMeta);
1026
740
  },
1027
741
  configurable: true,
1028
742
  enumerable: true,
1029
743
  });
1030
744
  }
1031
745
  });
746
+ if ((flags & 1 /* isElementConstructor */)) {
747
+ const attrNameToPropName = new Map();
748
+ prototype.attributeChangedCallback = function (attrName, _oldValue, newValue) {
749
+ plt.jmp(() => {
750
+ const propName = attrNameToPropName.get(attrName);
751
+ // In a web component lifecycle the attributeChangedCallback runs prior to connectedCallback
752
+ // in the case where an attribute was set inline.
753
+ // ```html
754
+ // <my-component some-attribute="some-value"></my-component>
755
+ // ```
756
+ //
757
+ // There is an edge case where a developer sets the attribute inline on a custom element and then
758
+ // programmatically changes it before it has been upgraded as shown below:
759
+ //
760
+ // ```html
761
+ // <!-- this component has _not_ been upgraded yet -->
762
+ // <my-component id="test" some-attribute="some-value"></my-component>
763
+ // <script>
764
+ // // grab non-upgraded component
765
+ // el = document.querySelector("#test");
766
+ // el.someAttribute = "another-value";
767
+ // // upgrade component
768
+ // customElements.define('my-component', MyComponent);
769
+ // </script>
770
+ // ```
771
+ // In this case if we do not unshadow here and use the value of the shadowing property, attributeChangedCallback
772
+ // will be called with `newValue = "some-value"` and will set the shadowed property (this.someAttribute = "another-value")
773
+ // to the value that was set inline i.e. "some-value" from above example. When
774
+ // the connectedCallback attempts to unshadow it will use "some-value" as the initial value rather than "another-value"
775
+ //
776
+ // The case where the attribute was NOT set inline but was not set programmatically shall be handled/unshadowed
777
+ // by connectedCallback as this attributeChangedCallback will not fire.
778
+ //
779
+ // https://developers.google.com/web/fundamentals/web-components/best-practices#lazy-properties
780
+ //
781
+ // TODO(STENCIL-16) we should think about whether or not we actually want to be reflecting the attributes to
782
+ // properties here given that this goes against best practices outlined here
783
+ // https://developers.google.com/web/fundamentals/web-components/best-practices#avoid-reentrancy
784
+ if (this.hasOwnProperty(propName)) {
785
+ newValue = this[propName];
786
+ delete this[propName];
787
+ }
788
+ else if (prototype.hasOwnProperty(propName) &&
789
+ typeof this[propName] === 'number' &&
790
+ this[propName] == newValue) {
791
+ // if the propName exists on the prototype of `Cstr`, this update may be a result of Stencil using native
792
+ // APIs to reflect props as attributes. Calls to `setAttribute(someElement, propName)` will result in
793
+ // `propName` to be converted to a `DOMString`, which may not be what we want for other primitive props.
794
+ return;
795
+ }
796
+ this[propName] = newValue === null && typeof this[propName] === 'boolean' ? false : newValue;
797
+ });
798
+ };
799
+ // create an array of attributes to observe
800
+ // and also create a map of html attribute name to js property name
801
+ Cstr.observedAttributes = members
802
+ .filter(([_, m]) => m[0] & 15 /* HasAttribute */) // filter to only keep props that should match attributes
803
+ .map(([propName, m]) => {
804
+ const attrName = m[1] || propName;
805
+ attrNameToPropName.set(attrName, propName);
806
+ if (m[0] & 512 /* ReflectAttr */) {
807
+ cmpMeta.$attrsToReflect$.push([propName, attrName]);
808
+ }
809
+ return attrName;
810
+ });
811
+ }
1032
812
  }
1033
813
  return Cstr;
1034
814
  };
@@ -1109,15 +889,6 @@ const connectedCallback = (elm) => {
1109
889
  if (!(hostRef.$flags$ & 1 /* hasConnected */)) {
1110
890
  // first time this component has connected
1111
891
  hostRef.$flags$ |= 1 /* hasConnected */;
1112
- {
1113
- // initUpdate
1114
- // if the slot polyfill is required we'll need to put some nodes
1115
- // in here to act as original content anchors as we move nodes around
1116
- // host element has been connected to the DOM
1117
- if ((cmpMeta.$flags$ & (4 /* hasSlotRelocation */ | 8 /* needsShadowDomShim */))) {
1118
- setContentReference(elm);
1119
- }
1120
- }
1121
892
  {
1122
893
  // find the first ancestor component (if there is one) and register
1123
894
  // this component as one of the actively loading child components for its ancestor
@@ -1133,6 +904,17 @@ const connectedCallback = (elm) => {
1133
904
  }
1134
905
  }
1135
906
  }
907
+ // Lazy properties
908
+ // https://developers.google.com/web/fundamentals/web-components/best-practices#lazy-properties
909
+ if (cmpMeta.$members$) {
910
+ Object.entries(cmpMeta.$members$).map(([memberName, [memberFlags]]) => {
911
+ if (memberFlags & 31 /* Prop */ && elm.hasOwnProperty(memberName)) {
912
+ const value = elm[memberName];
913
+ delete elm[memberName];
914
+ elm[memberName] = value;
915
+ }
916
+ });
917
+ }
1136
918
  {
1137
919
  initializeComponent(elm, hostRef, cmpMeta);
1138
920
  }
@@ -1146,17 +928,6 @@ const connectedCallback = (elm) => {
1146
928
  endConnected();
1147
929
  }
1148
930
  };
1149
- const setContentReference = (elm) => {
1150
- // only required when we're NOT using native shadow dom (slot)
1151
- // or this browser doesn't support native shadow dom
1152
- // and this host element was NOT created with SSR
1153
- // let's pick out the inner content for slot projection
1154
- // create a node to represent where the original
1155
- // content was first placed, which is useful later on
1156
- const contentRefElm = (elm['s-cr'] = doc.createComment(''));
1157
- contentRefElm['s-cn'] = true;
1158
- elm.insertBefore(contentRefElm, elm.firstChild);
1159
- };
1160
931
  const disconnectedCallback = (elm) => {
1161
932
  if ((plt.$flags$ & 1 /* isTmpDisconnected */) === 0) {
1162
933
  const hostRef = getHostRef(elm);
@@ -1195,6 +966,9 @@ const bootstrapLazy = (lazyBundles, options = {}) => {
1195
966
  {
1196
967
  cmpMeta.$listeners$ = compactMeta[3];
1197
968
  }
969
+ {
970
+ cmpMeta.$attrsToReflect$ = [];
971
+ }
1198
972
  const tagName = cmpMeta.$tagName$;
1199
973
  const HostElement = class extends HTMLElement {
1200
974
  // StencilLazyHost
@@ -1203,6 +977,17 @@ const bootstrapLazy = (lazyBundles, options = {}) => {
1203
977
  super(self);
1204
978
  self = this;
1205
979
  registerHost(self, cmpMeta);
980
+ if (cmpMeta.$flags$ & 1 /* shadowDomEncapsulation */) {
981
+ // this component is using shadow dom
982
+ // and this browser supports shadow dom
983
+ // add the read-only property "shadowRoot" to the host element
984
+ // adding the shadow root build conditionals to minimize runtime
985
+ {
986
+ {
987
+ self.attachShadow({ mode: 'open' });
988
+ }
989
+ }
990
+ }
1206
991
  }
1207
992
  connectedCallback() {
1208
993
  if (appLoadFallback) {