@nanoporetech-digital/components 4.5.2 → 4.6.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 (95) hide show
  1. package/CHANGELOG.md +32 -0
  2. package/dist/cjs/loader.cjs.js +1 -1
  3. package/dist/cjs/nano-alert.cjs.entry.js +3 -2
  4. package/dist/cjs/nano-alert.cjs.entry.js.map +1 -1
  5. package/dist/cjs/nano-checkbox-group.cjs.entry.js +6 -2
  6. package/dist/cjs/nano-checkbox-group.cjs.entry.js.map +1 -1
  7. package/dist/cjs/nano-components.cjs.js +1 -1
  8. package/dist/cjs/nano-dialog.cjs.entry.js +1 -1
  9. package/dist/cjs/nano-dialog.cjs.entry.js.map +1 -1
  10. package/dist/cjs/nano-field-validator.cjs.entry.js +43 -29
  11. package/dist/cjs/nano-field-validator.cjs.entry.js.map +1 -1
  12. package/dist/cjs/nano-global-nav.cjs.entry.js +1 -1
  13. package/dist/cjs/nano-global-nav.cjs.entry.js.map +1 -1
  14. package/dist/cjs/nano-icon-button_2.cjs.entry.js +7 -1
  15. package/dist/cjs/nano-icon-button_2.cjs.entry.js.map +1 -1
  16. package/dist/cjs/{nano-table-3740162c.js → nano-table-bd3f6030.js} +2 -2
  17. package/dist/cjs/{nano-table-3740162c.js.map → nano-table-bd3f6030.js.map} +1 -1
  18. package/dist/cjs/nano-table.cjs.entry.js +1 -1
  19. package/dist/cjs/{table.worker-ce12bd92.js → table.worker-6652af10.js} +2 -2
  20. package/dist/cjs/table.worker-6652af10.js.map +1 -0
  21. package/dist/collection/components/alert/alert.js +3 -2
  22. package/dist/collection/components/alert/alert.js.map +1 -1
  23. package/dist/collection/components/checkbox/checkbox-group.js +6 -2
  24. package/dist/collection/components/checkbox/checkbox-group.js.map +1 -1
  25. package/dist/collection/components/dialog/dialog.css +1 -0
  26. package/dist/collection/components/dialog/dialog.js +1 -1
  27. package/dist/collection/components/dialog/dialog.js.map +1 -1
  28. package/dist/collection/components/field-validator/field-validator.js +81 -33
  29. package/dist/collection/components/field-validator/field-validator.js.map +1 -1
  30. package/dist/collection/components/global-nav/global-nav.js +1 -1
  31. package/dist/collection/components/global-nav/global-nav.js.map +1 -1
  32. package/dist/collection/components/tooltip/tooltip.js +7 -1
  33. package/dist/collection/components/tooltip/tooltip.js.map +1 -1
  34. package/dist/components/nano-alert.js +3 -2
  35. package/dist/components/nano-alert.js.map +1 -1
  36. package/dist/components/nano-checkbox-group.js +6 -2
  37. package/dist/components/nano-checkbox-group.js.map +1 -1
  38. package/dist/components/nano-dialog.js +1 -1
  39. package/dist/components/nano-dialog.js.map +1 -1
  40. package/dist/components/nano-field-validator.js +45 -30
  41. package/dist/components/nano-field-validator.js.map +1 -1
  42. package/dist/components/nano-global-nav.js +1 -1
  43. package/dist/components/nano-global-nav.js.map +1 -1
  44. package/dist/components/tooltip.js +7 -1
  45. package/dist/components/tooltip.js.map +1 -1
  46. package/dist/esm/loader.js +1 -1
  47. package/dist/esm/nano-alert.entry.js +3 -2
  48. package/dist/esm/nano-alert.entry.js.map +1 -1
  49. package/dist/esm/nano-checkbox-group.entry.js +6 -2
  50. package/dist/esm/nano-checkbox-group.entry.js.map +1 -1
  51. package/dist/esm/nano-components.js +1 -1
  52. package/dist/esm/nano-dialog.entry.js +1 -1
  53. package/dist/esm/nano-dialog.entry.js.map +1 -1
  54. package/dist/esm/nano-field-validator.entry.js +43 -29
  55. package/dist/esm/nano-field-validator.entry.js.map +1 -1
  56. package/dist/esm/nano-global-nav.entry.js +1 -1
  57. package/dist/esm/nano-global-nav.entry.js.map +1 -1
  58. package/dist/esm/nano-icon-button_2.entry.js +7 -1
  59. package/dist/esm/nano-icon-button_2.entry.js.map +1 -1
  60. package/dist/esm/{nano-table-438fd94a.js → nano-table-f752a163.js} +2 -2
  61. package/dist/esm/{nano-table-438fd94a.js.map → nano-table-f752a163.js.map} +1 -1
  62. package/dist/esm/nano-table.entry.js +1 -1
  63. package/dist/esm/{table.worker-7c5b7b44.js → table.worker-031db1c8.js} +2 -2
  64. package/dist/esm/table.worker-031db1c8.js.map +1 -0
  65. package/dist/nano-components/nano-components.esm.js +1 -1
  66. package/dist/nano-components/nano-components.esm.js.map +1 -1
  67. package/dist/nano-components/{p-2b3aca3f.js → p-0d773484.js} +2 -2
  68. package/dist/nano-components/{p-0d1ca590.entry.js → p-2d43a82b.entry.js} +2 -2
  69. package/dist/nano-components/p-2d43a82b.entry.js.map +1 -0
  70. package/dist/nano-components/p-3dd8ae89.entry.js +5 -0
  71. package/dist/nano-components/p-3dd8ae89.entry.js.map +1 -0
  72. package/dist/nano-components/{p-25cb3889.entry.js → p-64b56ee6.entry.js} +2 -2
  73. package/dist/nano-components/{p-25cb3889.entry.js.map → p-64b56ee6.entry.js.map} +1 -1
  74. package/dist/nano-components/{p-27eb26ef.entry.js → p-937acbe2.entry.js} +2 -2
  75. package/dist/nano-components/{p-27eb26ef.entry.js.map → p-937acbe2.entry.js.map} +1 -1
  76. package/dist/nano-components/{p-ddd6b396.entry.js → p-bc835f84.entry.js} +2 -2
  77. package/dist/nano-components/{p-6f84aa85.entry.js → p-d5b63150.entry.js} +2 -2
  78. package/dist/nano-components/{p-6f84aa85.entry.js.map → p-d5b63150.entry.js.map} +1 -1
  79. package/dist/nano-components/{p-125d4ca8.entry.js → p-dc2c37d5.entry.js} +2 -2
  80. package/dist/nano-components/{p-125d4ca8.entry.js.map → p-dc2c37d5.entry.js.map} +1 -1
  81. package/dist/nano-components/{p-e39ce4e0.js → p-e2b004ce.js} +2 -2
  82. package/dist/types/components/checkbox/checkbox-group.d.ts +1 -1
  83. package/dist/types/components/field-validator/field-validator.d.ts +11 -3
  84. package/dist/types/components.d.ts +7 -1
  85. package/docs-json.json +28 -3
  86. package/hydrate/index.js +63 -37
  87. package/package.json +3 -2
  88. package/dist/cjs/table.worker-ce12bd92.js.map +0 -1
  89. package/dist/esm/table.worker-7c5b7b44.js.map +0 -1
  90. package/dist/nano-components/p-0d1ca590.entry.js.map +0 -1
  91. package/dist/nano-components/p-357a0a3f.entry.js +0 -5
  92. package/dist/nano-components/p-357a0a3f.entry.js.map +0 -1
  93. /package/dist/nano-components/{p-2b3aca3f.js.map → p-0d773484.js.map} +0 -0
  94. /package/dist/nano-components/{p-ddd6b396.entry.js.map → p-bc835f84.entry.js.map} +0 -0
  95. /package/dist/nano-components/{p-e39ce4e0.js.map → p-e2b004ce.js.map} +0 -0
@@ -1,5 +1,5 @@
1
1
  /*!
2
2
  * Web Components for Nanopore digital Web Apps
3
3
  */
4
- import{r as t,c as i,h as e,a,g as s}from"./p-f6a8467a.js";import{M as n}from"./p-e04f2333.js";import{l as r,u as o}from"./p-d7c34990.js";import{c as l}from"./p-411bb8f1.js";import"./p-45abbbdd.js";import"./p-257432ff.js";const h=":host{box-sizing:border-box}*,*::before,*::after{box-sizing:border-box}[hidden]{display:none !important}:host{--border-radius:var(--nano-layer-border-radius, var(--nano-border-radius-medium, 4px));--border-color:var(--nano-layer-border-color, rgba(0, 0, 0, 0.1));--border-width:var(--nano-layer-border-width, 1px);--background:var(--nano-layer-bg, #fff);--tint-color:var(--nano-color-base, var(--nano-color-primary, #007495));--icon-size:2rem;--scrim-color:var(--nano-layer-overlay-dark, rgb(74 74 74 / 50%));--close-button-color:#b5aea7;display:block}:host(.nano-color){--tint-color:var(--nano-color-base, var(--nano-color-primary, #007495))}.alert{position:relative;background-color:var(--background);border:solid var(--border-width) var(--border-color);border-block-start-width:4px;border-block-start-color:var(--tint-color);border-radius:var(--border-radius);opacity:0;transform:scale(0.9);transition:var(--nano-transition-medium, 0.5s) opacity ease, var(--nano-transition-fast, 0.3s) transform ease}.alert:focus{outline:none}.alert:not(.alert--showing){position:absolute;inline-size:1px;block-size:1px;clip:rect(0 0 0 0);-webkit-clip-path:inset(50%);clip-path:inset(50%);overflow:hidden;pointer-events:none;visibility:hidden}.alert--open{opacity:1;transform:none}.alert--toasty,.alert--modal{box-shadow:var(--nano-layer-shadow-large, 0 2px 8px rgba(0, 0, 0, 0.2));margin:var(--nano-spacing-medium, 16px)}.alert__content{display:flex;align-items:stretch}.alert__modal-wrap{position:fixed;display:flex;align-items:center;justify-content:center;inset:0;z-index:var(--nano-layer-index-alert, 800)}.alert__message{flex:1 1 auto;padding:var(--nano-spacing-medium, 16px);overflow:hidden;line-height:1.6}.alert__close{--color:var(--close-button-color);flex:0 0 auto;display:flex;align-items:center;font-size:1.1em;padding-inline:0 var(--nano-spacing-medium, 16px);padding-block:0}.alert__footer{padding:0 var(--nano-spacing-small, 8px) 0;display:flex;flex-direction:row;justify-content:space-around;align-items:center}.alert__footer ::slotted(*){flex:1;margin:0 var(--nano-spacing-small, 8px) var(--nano-spacing-medium, 16px) !important}.alert__overlay{position:fixed;inset:0;background-color:var(--scrim-color);opacity:0;transition:var(--nano-transition-fast, 0.3s) opacity;z-index:var(--nano-layer-index-alert, 800);-webkit-backdrop-filter:blur(var(--nano-layer-overlay-blur, 3px));backdrop-filter:blur(var(--nano-layer-overlay-blur, 3px))}.alert__overlay--open{opacity:1}.alert__icon{flex:0 0 auto;display:flex;align-items:center;font-size:var(--icon-size)}.alert__icon ::slotted(*){color:var(--tint-color);-webkit-margin-start:var(--nano-spacing-medium, 16px);margin-inline-start:var(--nano-spacing-medium, 16px)}";let c;let d;let f;let u;if(globalThis["document"]){c=Object.assign(document.createElement("div"),{className:"nano-toast-stack nano-toast-stack--tr"});d=Object.assign(document.createElement("div"),{className:"nano-toast-stack nano-toast-stack--tl"});f=Object.assign(document.createElement("div"),{className:"nano-toast-stack nano-toast-stack--bl"});u=Object.assign(document.createElement("div"),{className:"nano-toast-stack nano-toast-stack--br"})}const m=class{constructor(a){t(this,a);this.nanoShow=i(this,"nanoShow",7);this.nanoAfterShow=i(this,"nanoAfterShow",7);this.nanoHide=i(this,"nanoHide",7);this.nanoAfterHide=i(this,"nanoAfterHide",7);this.addedTransEnd=false;this.goingToHide=false;this.goingToShow=false;this.handleMouseMove=()=>{this.restartAutoHide()};this.handleCloseClick=()=>{this.hide()};this.handleTransitionEnd=t=>{if(t.propertyName==="opacity"&&(t.target===this.panel||t.target===this.overlay)){this.host.hidden=!this.open;this.isShowing=this.open;this.open?this.nanoAfterShow.emit():this.nanoAfterHide.emit()}};this.handleButtonClick=t=>{if(t.defaultPrevented)return;if(t.target.tagName&&t.target.tagName.toLowerCase()==="button")this.hide()};this.restartAutoHide=()=>{clearTimeout(this.autoHideTimeout);if(this.open&&this.duration<Infinity){this.autoHideTimeout=setTimeout((()=>this.hide()),this.duration)}};this.Panel=()=>e("div",{ref:t=>this.panel=t,part:"panel",class:{alert:true,"alert--open":this.open,"alert--toasty":this.isToast,"alert--modal":!!this.isModal,"alert--showing":this.isShowing},role:!!this.isModal?"alertdialog":"alert","aria-live":"assertive","aria-atomic":"true","aria-hidden":this.open?"false":"true","aria-modal":!!this.isModal?"true":undefined,"aria-label":this.label?this.label:undefined,onMouseMove:this.handleMouseMove,tabIndex:!!this.isModal?0:undefined},e("div",{class:"alert__content"},e("div",{part:"icon",class:"alert__icon"},e("slot",{name:"icon"})),e("div",{part:"message",class:"alert__message"},e("slot",null)),this.closable&&e("div",{class:"alert__close"},e("nano-icon-button",{class:"alert__close",iconName:"light/times",label:"close menu",onClick:this.handleCloseClick}))),e("div",{class:"alert__footer"},e("slot",{name:"footer"})));this.isModal=false;this.isToast=false;this.isShowing=false;this.label=undefined;this.open=false;this.closable=false;this.color=undefined;this.duration=Infinity;this.hoist=false}handleOpenChange(){this.open?this.show():this.hide()}handleDurationChange(){this.restartAutoHide()}handleHoistChange(){if(!this.hoist||document.body.children[0]===this.host)return;document.body.prepend(this.host)}async show(){if(this.goingToShow){return}const t=this.nanoShow.emit();if(t.defaultPrevented){this.open=false;return false}this.host.hidden=false;this.goingToShow=true;this.open=true;requestAnimationFrame((()=>{this.isShowing=true;this.goingToShow=false}));if(this.duration<Infinity){clearTimeout(this.autoHideTimeout);this.autoHideTimeout=setTimeout((()=>this.hide()),this.duration)}}async hide(){if(this.goingToHide){return}const t=this.nanoHide.emit();if(t.defaultPrevented){this.open=true;return false}this.goingToHide=true;this.open=false;requestAnimationFrame((()=>this.goingToHide=false));clearTimeout(this.autoHideTimeout)}async toast(t="tr"){this.isToast=true;return new Promise((i=>{let e;switch(t){case"tl":e=d;break;case"bl":e=f;break;case"br":e=u;break;default:e=c;break}if(!e.parentElement){document.body.appendChild(e)}e.appendChild(this.host);this.connectedCallback();this.show();const a=()=>{this.host.remove();this.isToast=false;i();if(!e.querySelector("nano-alert")){e.remove()}};this.host.addEventListener("nanoAfterHide",a,{once:true});this.host.addEventListener("nano-after-hide",a,{once:true})}))}async alert(t){this.isModal=true;this.label=t;return new Promise((t=>{if(!document.body.contains(this.host)){document.body.appendChild(this.host)}this.modal.activate();r(this.host);this.originalTrigger=document.activeElement;requestAnimationFrame((()=>{this.show()}));const i=()=>requestAnimationFrame((()=>this.panel.focus({preventScroll:true})));const e=()=>{this.modal.deactivate();this.host.remove();this.label=undefined;this.isModal=false;t();if(this.originalTrigger&&typeof this.originalTrigger.focus==="function"){setTimeout((()=>this.originalTrigger.focus()))}};this.host.addEventListener("nanoAfterShow",i,{once:true});this.host.addEventListener("nano-after-show",i,{once:true});this.host.addEventListener("nanoAfterHide",e,{once:true});this.host.addEventListener("nano-after-hide",e,{once:true})}))}connectedCallback(){this.handleHoistChange();this.modal=new n(this.host);this.host.addEventListener("click",this.handleButtonClick);if(this.panel){this.addedTransEnd=true;this.panel.addEventListener("transitionend",this.handleTransitionEnd)}}disconnectedCallback(){o(this.host);this.host.removeEventListener("click",this.handleButtonClick);this.addedTransEnd=false;this.panel.removeEventListener("transitionend",this.handleTransitionEnd)}componentDidLoad(){if(this.open){this.show()}if(!this.addedTransEnd){this.panel.addEventListener("transitionend",this.handleTransitionEnd)}}render(){return e(a,{class:Object.assign({},l(this.color)),showing:this.isShowing},this.isModal&&[e("div",{part:"overlay",class:{alert__overlay:true,"alert__overlay--open":this.open},ref:t=>this.overlay=t}),e("div",{class:"alert__modal-wrap"},e(this.Panel,null))],!this.isModal&&e(this.Panel,null))}get host(){return s(this)}static get watchers(){return{open:["handleOpenChange"],duration:["handleDurationChange"],hoist:["handleHoistChange"]}}};m.style=h;export{m as nano_alert};
5
- //# sourceMappingURL=p-125d4ca8.entry.js.map
4
+ import{r as t,c as i,h as e,a,g as s}from"./p-f6a8467a.js";import{M as n}from"./p-e04f2333.js";import{l as r,u as o}from"./p-d7c34990.js";import{c as l}from"./p-411bb8f1.js";import"./p-45abbbdd.js";import"./p-257432ff.js";const h=":host{box-sizing:border-box}*,*::before,*::after{box-sizing:border-box}[hidden]{display:none !important}:host{--border-radius:var(--nano-layer-border-radius, var(--nano-border-radius-medium, 4px));--border-color:var(--nano-layer-border-color, rgba(0, 0, 0, 0.1));--border-width:var(--nano-layer-border-width, 1px);--background:var(--nano-layer-bg, #fff);--tint-color:var(--nano-color-base, var(--nano-color-primary, #007495));--icon-size:2rem;--scrim-color:var(--nano-layer-overlay-dark, rgb(74 74 74 / 50%));--close-button-color:#b5aea7;display:block}:host(.nano-color){--tint-color:var(--nano-color-base, var(--nano-color-primary, #007495))}.alert{position:relative;background-color:var(--background);border:solid var(--border-width) var(--border-color);border-block-start-width:4px;border-block-start-color:var(--tint-color);border-radius:var(--border-radius);opacity:0;transform:scale(0.9);transition:var(--nano-transition-medium, 0.5s) opacity ease, var(--nano-transition-fast, 0.3s) transform ease}.alert:focus{outline:none}.alert:not(.alert--showing){position:absolute;inline-size:1px;block-size:1px;clip:rect(0 0 0 0);-webkit-clip-path:inset(50%);clip-path:inset(50%);overflow:hidden;pointer-events:none;visibility:hidden}.alert--open{opacity:1;transform:none}.alert--toasty,.alert--modal{box-shadow:var(--nano-layer-shadow-large, 0 2px 8px rgba(0, 0, 0, 0.2));margin:var(--nano-spacing-medium, 16px)}.alert__content{display:flex;align-items:stretch}.alert__modal-wrap{position:fixed;display:flex;align-items:center;justify-content:center;inset:0;z-index:var(--nano-layer-index-alert, 800)}.alert__message{flex:1 1 auto;padding:var(--nano-spacing-medium, 16px);overflow:hidden;line-height:1.6}.alert__close{--color:var(--close-button-color);flex:0 0 auto;display:flex;align-items:center;font-size:1.1em;padding-inline:0 var(--nano-spacing-medium, 16px);padding-block:0}.alert__footer{padding:0 var(--nano-spacing-small, 8px) 0;display:flex;flex-direction:row;justify-content:space-around;align-items:center}.alert__footer ::slotted(*){flex:1;margin:0 var(--nano-spacing-small, 8px) var(--nano-spacing-medium, 16px) !important}.alert__overlay{position:fixed;inset:0;background-color:var(--scrim-color);opacity:0;transition:var(--nano-transition-fast, 0.3s) opacity;z-index:var(--nano-layer-index-alert, 800);-webkit-backdrop-filter:blur(var(--nano-layer-overlay-blur, 3px));backdrop-filter:blur(var(--nano-layer-overlay-blur, 3px))}.alert__overlay--open{opacity:1}.alert__icon{flex:0 0 auto;display:flex;align-items:center;font-size:var(--icon-size)}.alert__icon ::slotted(*){color:var(--tint-color);-webkit-margin-start:var(--nano-spacing-medium, 16px);margin-inline-start:var(--nano-spacing-medium, 16px)}";let c;let d;let f;let u;if(globalThis["document"]){c=Object.assign(document.createElement("div"),{className:"nano-toast-stack nano-toast-stack--tr"});d=Object.assign(document.createElement("div"),{className:"nano-toast-stack nano-toast-stack--tl"});f=Object.assign(document.createElement("div"),{className:"nano-toast-stack nano-toast-stack--bl"});u=Object.assign(document.createElement("div"),{className:"nano-toast-stack nano-toast-stack--br"})}const m=class{constructor(a){t(this,a);this.nanoShow=i(this,"nanoShow",7);this.nanoAfterShow=i(this,"nanoAfterShow",7);this.nanoHide=i(this,"nanoHide",7);this.nanoAfterHide=i(this,"nanoAfterHide",7);this.addedTransEnd=false;this.goingToHide=false;this.goingToShow=false;this.handleMouseMove=()=>{this.restartAutoHide()};this.handleCloseClick=()=>{this.hide()};this.handleTransitionEnd=t=>{if(t.propertyName==="opacity"&&(t.target===this.panel||t.target===this.overlay)){this.host.hidden=!this.open;this.isShowing=this.open;this.open?this.nanoAfterShow.emit():this.nanoAfterHide.emit()}};this.handleButtonClick=t=>{if(t.defaultPrevented)return;if(t.target.tagName&&t.target.tagName.toLowerCase()==="button")this.hide()};this.restartAutoHide=()=>{clearTimeout(this.autoHideTimeout);if(this.open&&this.duration<Infinity){this.autoHideTimeout=setTimeout((()=>this.hide()),this.duration)}};this.Panel=()=>e("div",{ref:t=>this.panel=t,part:"panel",class:{alert:true,"alert--open":this.open,"alert--toasty":this.isToast,"alert--modal":!!this.isModal,"alert--showing":this.isShowing},role:!!this.isModal?"alertdialog":"alert","aria-live":"assertive","aria-atomic":"true","aria-hidden":this.open?"false":"true","aria-modal":!!this.isModal?"true":undefined,"aria-label":this.label?this.label:undefined,onMouseMove:this.handleMouseMove,tabIndex:!!this.isModal?0:undefined},e("div",{class:"alert__content"},e("div",{part:"icon",class:"alert__icon"},e("slot",{name:"icon"})),e("div",{part:"message",class:"alert__message"},e("slot",null)),this.closable&&e("div",{class:"alert__close"},e("nano-icon-button",{class:"alert__close",iconName:"light/times",label:"close menu",onClick:this.handleCloseClick}))),e("div",{class:"alert__footer"},e("slot",{name:"footer"})));this.isModal=false;this.isToast=false;this.isShowing=false;this.label=undefined;this.open=false;this.closable=false;this.color=undefined;this.duration=Infinity;this.hoist=false}handleOpenChange(){this.open?this.show():this.hide()}handleDurationChange(){this.restartAutoHide()}handleHoistChange(){if(!this.hoist||document.body.children[0]===this.host)return;document.body.prepend(this.host)}async show(){if(this.goingToShow){return}const t=this.nanoShow.emit();if(t.defaultPrevented){this.open=false;return false}this.host.hidden=false;this.goingToShow=true;this.open=true;requestAnimationFrame((()=>{this.isShowing=true;this.goingToShow=false}));if(this.duration<Infinity){clearTimeout(this.autoHideTimeout);this.autoHideTimeout=setTimeout((()=>this.hide()),this.duration)}}async hide(){if(this.goingToHide){return}const t=this.nanoHide.emit();if(t.defaultPrevented){this.open=true;return false}this.goingToHide=true;this.open=false;requestAnimationFrame((()=>this.goingToHide=false));clearTimeout(this.autoHideTimeout)}async toast(t="tr"){this.isToast=true;return new Promise((i=>{let e;switch(t){case"tl":e=d;break;case"bl":e=f;break;case"br":e=u;break;default:e=c;break}if(!e.parentElement){document.body.appendChild(e)}e.appendChild(this.host);this.connectedCallback();this.show();const a=()=>{this.host.remove();this.isToast=false;i();if(!e.querySelector("nano-alert")){e.remove()}};this.host.addEventListener("nanoAfterHide",a,{once:true});this.host.addEventListener("nano-after-hide",a,{once:true})}))}async alert(t){this.isModal=true;this.label=t;return new Promise((t=>{if(!document.body.contains(this.host)){document.body.appendChild(this.host)}this.modal.activate();r(this.host);this.originalTrigger=document.activeElement;requestAnimationFrame((()=>{this.show()}));const i=()=>requestAnimationFrame((()=>this.panel.focus({preventScroll:true})));const e=()=>{this.modal.deactivate();this.host.remove();this.label=undefined;this.isModal=false;t();if(this.originalTrigger&&typeof this.originalTrigger.focus==="function"){setTimeout((()=>this.originalTrigger.focus()))}};this.host.addEventListener("nanoAfterShow",i,{once:true});this.host.addEventListener("nano-after-show",i,{once:true});this.host.addEventListener("nanoAfterHide",e,{once:true});this.host.addEventListener("nano-after-hide",e,{once:true})}))}connectedCallback(){this.modal=new n(this.host);this.handleHoistChange();this.host.addEventListener("click",this.handleButtonClick);if(this.panel){this.addedTransEnd=true;this.panel.addEventListener("transitionend",this.handleTransitionEnd)}}disconnectedCallback(){o(this.host);this.host.removeEventListener("click",this.handleButtonClick);this.addedTransEnd=false;if(this.panel)this.panel.removeEventListener("transitionend",this.handleTransitionEnd)}componentDidLoad(){if(this.open){this.show()}if(!this.addedTransEnd){this.panel.addEventListener("transitionend",this.handleTransitionEnd)}}render(){return e(a,{class:Object.assign({},l(this.color)),showing:this.isShowing},this.isModal&&[e("div",{part:"overlay",class:{alert__overlay:true,"alert__overlay--open":this.open},ref:t=>this.overlay=t}),e("div",{class:"alert__modal-wrap"},e(this.Panel,null))],!this.isModal&&e(this.Panel,null))}get host(){return s(this)}static get watchers(){return{open:["handleOpenChange"],duration:["handleDurationChange"],hoist:["handleHoistChange"]}}};m.style=h;export{m as nano_alert};
5
+ //# sourceMappingURL=p-dc2c37d5.entry.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["alertCss","toastStackTr","toastStackTl","toastStackBl","toastStackBr","globalThis","Object","assign","document","createElement","className","Alert","this","addedTransEnd","goingToHide","goingToShow","handleMouseMove","restartAutoHide","handleCloseClick","hide","handleTransitionEnd","event","propertyName","target","panel","overlay","host","hidden","open","isShowing","nanoAfterShow","emit","nanoAfterHide","handleButtonClick","e","defaultPrevented","tagName","toLowerCase","clearTimeout","autoHideTimeout","duration","Infinity","setTimeout","Panel","h","ref","el","part","class","alert","isToast","isModal","role","undefined","label","onMouseMove","tabIndex","name","closable","iconName","onClick","handleOpenChange","show","handleDurationChange","handleHoistChange","hoist","body","children","prepend","async","nanoShow","requestAnimationFrame","nanoHide","position","Promise","resolve","toastStack","parentElement","appendChild","connectedCallback","onClose","remove","querySelector","addEventListener","once","contains","modal","activate","lockBodyScrolling","originalTrigger","activeElement","onOpen","focus","preventScroll","deactivate","Modal","disconnectedCallback","unlockBodyScrolling","removeEventListener","componentDidLoad","render","Host","createColorClasses","color","showing","alert__overlay","div"],"sources":["./src/components/alert/alert.scss?tag=nano-alert&encapsulation=shadow","./src/components/alert/alert.tsx"],"sourcesContent":["@use 'sass:map';\n@use 'sass:list';\n\n@import '../../global/style/nano-theme/base';\n@import '../../global/style/nano-theme/colours';\n@import '../../global/style/nano-theme/layers';\n\n:host {\n /**\n * @prop --border-radius: defaults to #{$layer-border-radius};\n * @prop --border-color: defaults to #{$layer-border-color};\n * @prop --border-width: defaults to #{$layer-border-width};\n * @prop --background: defaults to #{$layer-bg-color};\n * @prop --tint-color: defaults to var(--nano-color-base, #{nano-color(primary, base)});\n * @prop --icon-size: defaults to 1.5rem;\n * @prop --scrim-color: overlay colour of alert display. Defaults to #{$layer-overlay-dark};\n * @prop --close-button-color: defaults to #{map.get($colors, mediumgrey)} ;\n */\n\n --border-radius: #{$layer-border-radius};\n --border-color: #{$layer-border-color};\n --border-width: #{$layer-border-width};\n --background: #{$layer-bg-color};\n --tint-color: var(--nano-color-base, #{nano-color(primary, base)});\n --icon-size: 2rem;\n --scrim-color: #{$layer-overlay-dark};\n --close-button-color: #{map.get($colors, palegrey)};\n\n display: block;\n}\n\n:host(.nano-color) {\n --tint-color: var(--nano-color-base, #{nano-color(primary, base)});\n}\n\n.alert {\n position: relative;\n background-color: var(--background);\n border: solid var(--border-width) var(--border-color);\n border-block-start-width: 4px;\n border-block-start-color: var(--tint-color);\n border-radius: var(--border-radius);\n opacity: 0;\n transform: scale(0.9);\n transition:\n #{$transition-medium} opacity ease,\n #{$transition-fast} transform ease;\n\n &:focus {\n outline: none;\n }\n\n &:not(.alert--showing) {\n @include hidden;\n }\n\n &--open {\n opacity: 1;\n transform: none;\n }\n\n &--toasty,\n &--modal {\n box-shadow: #{$layer-shadow-large};\n margin: #{$spacing-medium};\n }\n}\n\n.alert__content {\n display: flex;\n align-items: stretch;\n}\n\n.alert__modal-wrap {\n position: fixed;\n display: flex;\n align-items: center;\n justify-content: center;\n inset: 0;\n z-index: #{$layer-index-alert};\n}\n\n.alert__message {\n flex: 1 1 auto;\n padding: #{$spacing-medium};\n overflow: hidden;\n line-height: 1.6;\n}\n\n.alert__close {\n --color: var(--close-button-color);\n\n flex: 0 0 auto;\n display: flex;\n align-items: center;\n font-size: 1.1em;\n padding-inline: 0 #{$spacing-medium};\n padding-block: 0;\n}\n\n.alert__footer {\n padding: 0 #{$spacing-small} 0;\n display: flex;\n flex-direction: row;\n justify-content: space-around;\n align-items: center;\n\n ::slotted(*) {\n flex: 1;\n margin: 0 #{$spacing-small} #{$spacing-medium} !important;\n }\n}\n\n.alert__overlay {\n position: fixed;\n inset: 0;\n background-color: var(--scrim-color);\n opacity: 0;\n transition: #{$transition-fast} opacity;\n z-index: #{$layer-index-alert};\n backdrop-filter: blur(#{$layer-overlay-blur});\n\n &--open {\n opacity: 1;\n }\n}\n\n.alert__icon {\n flex: 0 0 auto;\n display: flex;\n align-items: center;\n font-size: var(--icon-size);\n\n ::slotted(*) {\n color: var(--tint-color);\n margin-inline-start: #{$spacing-medium};\n }\n}\n","import {\n Component,\n ComponentInterface,\n Element,\n Event,\n EventEmitter,\n Method,\n Prop,\n State,\n Watch,\n h,\n Host,\n VNode,\n} from '@stencil/core';\nimport Modal from '../../utils/modal';\nimport { lockBodyScrolling, unlockBodyScrolling } from '../../utils/scroll';\nimport { createColorClasses } from '../../utils/theme';\nimport type { Color } from '../../interface';\n\nlet toastStackTr: HTMLElement;\nlet toastStackTl: HTMLElement;\nlet toastStackBl: HTMLElement;\nlet toastStackBr: HTMLElement;\n\nif (globalThis['document']) {\n toastStackTr = Object.assign(document.createElement('div'), {\n className: 'nano-toast-stack nano-toast-stack--tr',\n });\n toastStackTl = Object.assign(document.createElement('div'), {\n className: 'nano-toast-stack nano-toast-stack--tl',\n });\n toastStackBl = Object.assign(document.createElement('div'), {\n className: 'nano-toast-stack nano-toast-stack--bl',\n });\n toastStackBr = Object.assign(document.createElement('div'), {\n className: 'nano-toast-stack nano-toast-stack--br',\n });\n}\n\n/**\n * Alerts are used to display important messages either inline, as toast notifications or as modals requiring action.\n * @slot - The alert's content.\n * @slot icon - An icon to show in the alert.\n * @slot footer - Place items at the bottom of the alert. Best used with `button` elements - esp when used as with the `alert()` method.\n */\n@Component({\n tag: 'nano-alert',\n styleUrl: 'alert.scss',\n shadow: true,\n})\nexport class Alert implements ComponentInterface {\n private autoHideTimeout: ReturnType<typeof setTimeout>;\n private panel: HTMLElement;\n private overlay: HTMLElement;\n private modal: Modal;\n private originalTrigger: HTMLElement | null;\n private addedTransEnd = false;\n private goingToHide = false;\n private goingToShow = false;\n\n @State() isModal = false;\n @State() isToast = false;\n @State() isShowing = false;\n @State() label: string;\n\n @Element() host: HTMLNanoAlertElement;\n\n /** Indicates whether or not the alert is open. You can use this in lieu of the show/hide methods. */\n @Prop({ mutable: true, reflect: true }) open = false;\n\n @Watch('open')\n handleOpenChange() {\n this.open ? this.show() : this.hide();\n }\n\n /** Set to true to make the alert closable. */\n @Prop({ reflect: true }) closable = false;\n\n /** The color to use from the application's color palette. */\n @Prop({ reflect: true }) color?: Color;\n\n /**\n * The length of time, in milliseconds, the alert will show before closing itself. If the user interacts with the\n * alert before it closes (e.g. moves the mouse over it), the timer will restart.\n */\n @Prop() duration = Infinity;\n\n @Watch('duration')\n handleDurationChange() {\n this.restartAutoHide();\n }\n\n /**\n * Relocate the dialog to the root of the DOM.\n * Most useful in conjunction with `alert()` when parental elements\n * have css stacking constraints which don't allow for `position: fixed`\n */\n @Prop() hoist = false;\n\n @Watch('hoist')\n handleHoistChange() {\n if (!this.hoist || document.body.children[0] === this.host) return;\n document.body.prepend(this.host);\n }\n\n /** Emitted when the alert opens. Calling `event.preventDefault()` will prevent it from being opened. */\n @Event() nanoShow: EventEmitter;\n\n /** Emitted after the alert opens and all transitions are complete. */\n @Event() nanoAfterShow: EventEmitter;\n\n /** Emitted when the alert closes. Calling `event.preventDefault()` will prevent it from being closed. */\n @Event() nanoHide: EventEmitter;\n\n /** Emitted after the alert closes and all transitions are complete. */\n @Event() nanoAfterHide: EventEmitter;\n\n /** Shows the alert. */\n @Method()\n async show() {\n if (this.goingToShow) {\n return;\n }\n const nanoShow = this.nanoShow.emit();\n if (nanoShow.defaultPrevented) {\n this.open = false;\n return false;\n }\n\n this.host.hidden = false;\n this.goingToShow = true;\n this.open = true;\n requestAnimationFrame(() => {\n this.isShowing = true;\n this.goingToShow = false;\n });\n\n if (this.duration < Infinity) {\n clearTimeout(this.autoHideTimeout);\n this.autoHideTimeout = setTimeout(() => this.hide(), this.duration);\n }\n }\n\n /** Hides the alert */\n @Method()\n async hide() {\n if (this.goingToHide) {\n return;\n }\n const nanoHide = this.nanoHide.emit();\n\n if (nanoHide.defaultPrevented) {\n this.open = true;\n return false;\n }\n this.goingToHide = true;\n this.open = false;\n\n requestAnimationFrame(() => (this.goingToHide = false));\n clearTimeout(this.autoHideTimeout);\n }\n\n /**\n * Displays the alert as a toast notification. This will move the alert out of its position in the DOM and, when\n * dismissed, it will be removed from the DOM completely. By storing a reference to the alert, you can reuse it by\n * calling this method again. The returned promise will resolve after the alert is hidden.\n *\n * @param position options are tr (top-right - default), tl (top-left), br (bottom-right), bl (bottom-left)\n * @returns a promise which will resolve after the alert has hidden\n */\n @Method()\n async toast(position: 'tr' | 'tl' | 'bl' | 'br' = 'tr') {\n this.isToast = true;\n return new Promise<void>((resolve) => {\n let toastStack: HTMLElement;\n switch (position) {\n case 'tl':\n toastStack = toastStackTl;\n break;\n case 'bl':\n toastStack = toastStackBl;\n break;\n case 'br':\n toastStack = toastStackBr;\n break;\n default:\n toastStack = toastStackTr;\n break;\n }\n\n if (!toastStack.parentElement) {\n document.body.appendChild(toastStack);\n }\n\n toastStack.appendChild(this.host);\n this.connectedCallback();\n this.show();\n\n const onClose = () => {\n this.host.remove();\n this.isToast = false;\n resolve();\n\n // Remove the toast stack from the DOM when there are no more alerts\n if (!toastStack.querySelector('nano-alert')) {\n toastStack.remove();\n }\n };\n\n this.host.addEventListener('nanoAfterHide', onClose, { once: true });\n this.host.addEventListener('nano-after-hide', onClose, { once: true });\n });\n }\n\n /**\n * Displays the alert as a dialog / modal - more akin to a traditional js alert().\n * @param label a label for assistive technology\n */\n @Method()\n async alert(label: string) {\n this.isModal = true;\n this.label = label;\n\n return new Promise<void>((resolve) => {\n if (!document.body.contains(this.host)) {\n document.body.appendChild(this.host);\n }\n\n this.modal.activate();\n lockBodyScrolling(this.host);\n this.originalTrigger = document.activeElement as HTMLElement;\n\n requestAnimationFrame(() => {\n this.show();\n });\n\n const onOpen = () =>\n requestAnimationFrame(() => this.panel.focus({ preventScroll: true }));\n\n const onClose = () => {\n this.modal.deactivate();\n this.host.remove();\n this.label = undefined;\n this.isModal = false;\n resolve();\n\n // Restore focus to the original trigger\n if (\n this.originalTrigger &&\n typeof this.originalTrigger.focus === 'function'\n ) {\n setTimeout(() => this.originalTrigger.focus());\n }\n };\n\n this.host.addEventListener('nanoAfterShow', onOpen, { once: true });\n this.host.addEventListener('nano-after-show', onOpen, { once: true });\n\n this.host.addEventListener('nanoAfterHide', onClose, {\n once: true,\n });\n this.host.addEventListener('nano-after-hide', onClose, {\n once: true,\n });\n });\n }\n\n private handleMouseMove = () => {\n this.restartAutoHide();\n };\n\n private handleCloseClick = () => {\n this.hide();\n };\n\n private handleTransitionEnd = (event: TransitionEvent) => {\n if (\n event.propertyName === 'opacity' &&\n (event.target === this.panel || event.target === this.overlay)\n ) {\n this.host.hidden = !this.open;\n this.isShowing = this.open;\n this.open ? this.nanoAfterShow.emit() : this.nanoAfterHide.emit();\n }\n };\n\n private handleButtonClick = (e: PointerEvent & { target: HTMLElement }) => {\n if (e.defaultPrevented) return;\n if (e.target.tagName && e.target.tagName.toLowerCase() === 'button')\n this.hide();\n };\n\n private restartAutoHide = () => {\n clearTimeout(this.autoHideTimeout);\n if (this.open && this.duration < Infinity) {\n this.autoHideTimeout = setTimeout(() => this.hide(), this.duration);\n }\n };\n\n connectedCallback() {\n this.handleHoistChange();\n this.modal = new Modal(this.host);\n this.host.addEventListener('click', this.handleButtonClick);\n\n if (this.panel) {\n this.addedTransEnd = true;\n this.panel.addEventListener('transitionend', this.handleTransitionEnd);\n }\n }\n\n disconnectedCallback() {\n unlockBodyScrolling(this.host);\n this.host.removeEventListener('click', this.handleButtonClick);\n\n this.addedTransEnd = false;\n this.panel.removeEventListener('transitionend', this.handleTransitionEnd);\n }\n\n componentDidLoad() {\n // Show on init if open\n if (this.open) {\n this.show();\n }\n if (!this.addedTransEnd) {\n this.panel.addEventListener('transitionend', this.handleTransitionEnd);\n }\n }\n\n private Panel = (): VNode => {\n return (\n <div\n ref={(el) => (this.panel = el)}\n part=\"panel\"\n class={{\n alert: true,\n 'alert--open': this.open,\n 'alert--toasty': this.isToast,\n 'alert--modal': !!this.isModal,\n 'alert--showing': this.isShowing,\n }}\n role={!!this.isModal ? 'alertdialog' : 'alert'}\n aria-live=\"assertive\"\n aria-atomic=\"true\"\n aria-hidden={this.open ? 'false' : 'true'}\n aria-modal={!!this.isModal ? 'true' : undefined}\n aria-label={this.label ? this.label : undefined}\n onMouseMove={this.handleMouseMove}\n tabIndex={!!this.isModal ? 0 : undefined}\n >\n <div class=\"alert__content\">\n <div part=\"icon\" class=\"alert__icon\">\n <slot name=\"icon\" />\n </div>\n <div part=\"message\" class=\"alert__message\">\n <slot />\n </div>\n {this.closable && (\n <div class=\"alert__close\">\n <nano-icon-button\n class=\"alert__close\"\n iconName=\"light/times\"\n label=\"close menu\"\n onClick={this.handleCloseClick}\n ></nano-icon-button>\n </div>\n )}\n </div>\n <div class=\"alert__footer\">\n <slot name=\"footer\" />\n </div>\n </div>\n );\n };\n\n render() {\n return (\n <Host\n class={{ ...createColorClasses(this.color) }}\n showing={this.isShowing}\n >\n {this.isModal && [\n <div\n part=\"overlay\"\n class={{\n alert__overlay: true,\n 'alert__overlay--open': this.open,\n }}\n ref={(div) => (this.overlay = div)}\n />,\n <div class=\"alert__modal-wrap\">\n <this.Panel />\n </div>,\n ]}\n {!this.isModal && <this.Panel />}\n </Host>\n );\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"names":["alertCss","toastStackTr","toastStackTl","toastStackBl","toastStackBr","globalThis","Object","assign","document","createElement","className","Alert","this","addedTransEnd","goingToHide","goingToShow","handleMouseMove","restartAutoHide","handleCloseClick","hide","handleTransitionEnd","event","propertyName","target","panel","overlay","host","hidden","open","isShowing","nanoAfterShow","emit","nanoAfterHide","handleButtonClick","e","defaultPrevented","tagName","toLowerCase","clearTimeout","autoHideTimeout","duration","Infinity","setTimeout","Panel","h","ref","el","part","class","alert","isToast","isModal","role","undefined","label","onMouseMove","tabIndex","name","closable","iconName","onClick","handleOpenChange","show","handleDurationChange","handleHoistChange","hoist","body","children","prepend","async","nanoShow","requestAnimationFrame","nanoHide","position","Promise","resolve","toastStack","parentElement","appendChild","connectedCallback","onClose","remove","querySelector","addEventListener","once","contains","modal","activate","lockBodyScrolling","originalTrigger","activeElement","onOpen","focus","preventScroll","deactivate","Modal","disconnectedCallback","unlockBodyScrolling","removeEventListener","componentDidLoad","render","Host","createColorClasses","color","showing","alert__overlay","div"],"sources":["./src/components/alert/alert.scss?tag=nano-alert&encapsulation=shadow","./src/components/alert/alert.tsx"],"sourcesContent":["@use 'sass:map';\n@use 'sass:list';\n\n@import '../../global/style/nano-theme/base';\n@import '../../global/style/nano-theme/colours';\n@import '../../global/style/nano-theme/layers';\n\n:host {\n /**\n * @prop --border-radius: defaults to #{$layer-border-radius};\n * @prop --border-color: defaults to #{$layer-border-color};\n * @prop --border-width: defaults to #{$layer-border-width};\n * @prop --background: defaults to #{$layer-bg-color};\n * @prop --tint-color: defaults to var(--nano-color-base, #{nano-color(primary, base)});\n * @prop --icon-size: defaults to 1.5rem;\n * @prop --scrim-color: overlay colour of alert display. Defaults to #{$layer-overlay-dark};\n * @prop --close-button-color: defaults to #{map.get($colors, mediumgrey)} ;\n */\n\n --border-radius: #{$layer-border-radius};\n --border-color: #{$layer-border-color};\n --border-width: #{$layer-border-width};\n --background: #{$layer-bg-color};\n --tint-color: var(--nano-color-base, #{nano-color(primary, base)});\n --icon-size: 2rem;\n --scrim-color: #{$layer-overlay-dark};\n --close-button-color: #{map.get($colors, palegrey)};\n\n display: block;\n}\n\n:host(.nano-color) {\n --tint-color: var(--nano-color-base, #{nano-color(primary, base)});\n}\n\n.alert {\n position: relative;\n background-color: var(--background);\n border: solid var(--border-width) var(--border-color);\n border-block-start-width: 4px;\n border-block-start-color: var(--tint-color);\n border-radius: var(--border-radius);\n opacity: 0;\n transform: scale(0.9);\n transition:\n #{$transition-medium} opacity ease,\n #{$transition-fast} transform ease;\n\n &:focus {\n outline: none;\n }\n\n &:not(.alert--showing) {\n @include hidden;\n }\n\n &--open {\n opacity: 1;\n transform: none;\n }\n\n &--toasty,\n &--modal {\n box-shadow: #{$layer-shadow-large};\n margin: #{$spacing-medium};\n }\n}\n\n.alert__content {\n display: flex;\n align-items: stretch;\n}\n\n.alert__modal-wrap {\n position: fixed;\n display: flex;\n align-items: center;\n justify-content: center;\n inset: 0;\n z-index: #{$layer-index-alert};\n}\n\n.alert__message {\n flex: 1 1 auto;\n padding: #{$spacing-medium};\n overflow: hidden;\n line-height: 1.6;\n}\n\n.alert__close {\n --color: var(--close-button-color);\n\n flex: 0 0 auto;\n display: flex;\n align-items: center;\n font-size: 1.1em;\n padding-inline: 0 #{$spacing-medium};\n padding-block: 0;\n}\n\n.alert__footer {\n padding: 0 #{$spacing-small} 0;\n display: flex;\n flex-direction: row;\n justify-content: space-around;\n align-items: center;\n\n ::slotted(*) {\n flex: 1;\n margin: 0 #{$spacing-small} #{$spacing-medium} !important;\n }\n}\n\n.alert__overlay {\n position: fixed;\n inset: 0;\n background-color: var(--scrim-color);\n opacity: 0;\n transition: #{$transition-fast} opacity;\n z-index: #{$layer-index-alert};\n backdrop-filter: blur(#{$layer-overlay-blur});\n\n &--open {\n opacity: 1;\n }\n}\n\n.alert__icon {\n flex: 0 0 auto;\n display: flex;\n align-items: center;\n font-size: var(--icon-size);\n\n ::slotted(*) {\n color: var(--tint-color);\n margin-inline-start: #{$spacing-medium};\n }\n}\n","import {\n Component,\n ComponentInterface,\n Element,\n Event,\n EventEmitter,\n Method,\n Prop,\n State,\n Watch,\n h,\n Host,\n VNode,\n} from '@stencil/core';\nimport Modal from '../../utils/modal';\nimport { lockBodyScrolling, unlockBodyScrolling } from '../../utils/scroll';\nimport { createColorClasses } from '../../utils/theme';\nimport type { Color } from '../../interface';\n\nlet toastStackTr: HTMLElement;\nlet toastStackTl: HTMLElement;\nlet toastStackBl: HTMLElement;\nlet toastStackBr: HTMLElement;\n\nif (globalThis['document']) {\n toastStackTr = Object.assign(document.createElement('div'), {\n className: 'nano-toast-stack nano-toast-stack--tr',\n });\n toastStackTl = Object.assign(document.createElement('div'), {\n className: 'nano-toast-stack nano-toast-stack--tl',\n });\n toastStackBl = Object.assign(document.createElement('div'), {\n className: 'nano-toast-stack nano-toast-stack--bl',\n });\n toastStackBr = Object.assign(document.createElement('div'), {\n className: 'nano-toast-stack nano-toast-stack--br',\n });\n}\n\n/**\n * Alerts are used to display important messages either inline, as toast notifications or as modals requiring action.\n * @slot - The alert's content.\n * @slot icon - An icon to show in the alert.\n * @slot footer - Place items at the bottom of the alert. Best used with `button` elements - esp when used as with the `alert()` method.\n */\n@Component({\n tag: 'nano-alert',\n styleUrl: 'alert.scss',\n shadow: true,\n})\nexport class Alert implements ComponentInterface {\n private autoHideTimeout: ReturnType<typeof setTimeout>;\n private panel: HTMLElement;\n private overlay: HTMLElement;\n private modal: Modal;\n private originalTrigger: HTMLElement | null;\n private addedTransEnd = false;\n private goingToHide = false;\n private goingToShow = false;\n\n @State() isModal = false;\n @State() isToast = false;\n @State() isShowing = false;\n @State() label: string;\n\n @Element() host: HTMLNanoAlertElement;\n\n /** Indicates whether or not the alert is open. You can use this in lieu of the show/hide methods. */\n @Prop({ mutable: true, reflect: true }) open = false;\n\n @Watch('open')\n handleOpenChange() {\n this.open ? this.show() : this.hide();\n }\n\n /** Set to true to make the alert closable. */\n @Prop({ reflect: true }) closable = false;\n\n /** The color to use from the application's color palette. */\n @Prop({ reflect: true }) color?: Color;\n\n /**\n * The length of time, in milliseconds, the alert will show before closing itself. If the user interacts with the\n * alert before it closes (e.g. moves the mouse over it), the timer will restart.\n */\n @Prop() duration = Infinity;\n\n @Watch('duration')\n handleDurationChange() {\n this.restartAutoHide();\n }\n\n /**\n * Relocate the dialog to the root of the DOM.\n * Most useful in conjunction with `alert()` when parental elements\n * have css stacking constraints which don't allow for `position: fixed`\n */\n @Prop() hoist = false;\n\n @Watch('hoist')\n handleHoistChange() {\n if (!this.hoist || document.body.children[0] === this.host) return;\n document.body.prepend(this.host);\n }\n\n /** Emitted when the alert opens. Calling `event.preventDefault()` will prevent it from being opened. */\n @Event() nanoShow: EventEmitter;\n\n /** Emitted after the alert opens and all transitions are complete. */\n @Event() nanoAfterShow: EventEmitter;\n\n /** Emitted when the alert closes. Calling `event.preventDefault()` will prevent it from being closed. */\n @Event() nanoHide: EventEmitter;\n\n /** Emitted after the alert closes and all transitions are complete. */\n @Event() nanoAfterHide: EventEmitter;\n\n /** Shows the alert. */\n @Method()\n async show() {\n if (this.goingToShow) {\n return;\n }\n const nanoShow = this.nanoShow.emit();\n if (nanoShow.defaultPrevented) {\n this.open = false;\n return false;\n }\n\n this.host.hidden = false;\n this.goingToShow = true;\n this.open = true;\n requestAnimationFrame(() => {\n this.isShowing = true;\n this.goingToShow = false;\n });\n\n if (this.duration < Infinity) {\n clearTimeout(this.autoHideTimeout);\n this.autoHideTimeout = setTimeout(() => this.hide(), this.duration);\n }\n }\n\n /** Hides the alert */\n @Method()\n async hide() {\n if (this.goingToHide) {\n return;\n }\n const nanoHide = this.nanoHide.emit();\n\n if (nanoHide.defaultPrevented) {\n this.open = true;\n return false;\n }\n this.goingToHide = true;\n this.open = false;\n\n requestAnimationFrame(() => (this.goingToHide = false));\n clearTimeout(this.autoHideTimeout);\n }\n\n /**\n * Displays the alert as a toast notification. This will move the alert out of its position in the DOM and, when\n * dismissed, it will be removed from the DOM completely. By storing a reference to the alert, you can reuse it by\n * calling this method again. The returned promise will resolve after the alert is hidden.\n *\n * @param position options are tr (top-right - default), tl (top-left), br (bottom-right), bl (bottom-left)\n * @returns a promise which will resolve after the alert has hidden\n */\n @Method()\n async toast(position: 'tr' | 'tl' | 'bl' | 'br' = 'tr') {\n this.isToast = true;\n return new Promise<void>((resolve) => {\n let toastStack: HTMLElement;\n switch (position) {\n case 'tl':\n toastStack = toastStackTl;\n break;\n case 'bl':\n toastStack = toastStackBl;\n break;\n case 'br':\n toastStack = toastStackBr;\n break;\n default:\n toastStack = toastStackTr;\n break;\n }\n\n if (!toastStack.parentElement) {\n document.body.appendChild(toastStack);\n }\n\n toastStack.appendChild(this.host);\n this.connectedCallback();\n this.show();\n\n const onClose = () => {\n this.host.remove();\n this.isToast = false;\n resolve();\n\n // Remove the toast stack from the DOM when there are no more alerts\n if (!toastStack.querySelector('nano-alert')) {\n toastStack.remove();\n }\n };\n\n this.host.addEventListener('nanoAfterHide', onClose, { once: true });\n this.host.addEventListener('nano-after-hide', onClose, { once: true });\n });\n }\n\n /**\n * Displays the alert as a dialog / modal - more akin to a traditional js alert().\n * @param label a label for assistive technology\n */\n @Method()\n async alert(label: string) {\n this.isModal = true;\n this.label = label;\n\n return new Promise<void>((resolve) => {\n if (!document.body.contains(this.host)) {\n document.body.appendChild(this.host);\n }\n\n this.modal.activate();\n lockBodyScrolling(this.host);\n this.originalTrigger = document.activeElement as HTMLElement;\n\n requestAnimationFrame(() => {\n this.show();\n });\n\n const onOpen = () =>\n requestAnimationFrame(() => this.panel.focus({ preventScroll: true }));\n\n const onClose = () => {\n this.modal.deactivate();\n this.host.remove();\n this.label = undefined;\n this.isModal = false;\n resolve();\n\n // Restore focus to the original trigger\n if (\n this.originalTrigger &&\n typeof this.originalTrigger.focus === 'function'\n ) {\n setTimeout(() => this.originalTrigger.focus());\n }\n };\n\n this.host.addEventListener('nanoAfterShow', onOpen, { once: true });\n this.host.addEventListener('nano-after-show', onOpen, { once: true });\n\n this.host.addEventListener('nanoAfterHide', onClose, {\n once: true,\n });\n this.host.addEventListener('nano-after-hide', onClose, {\n once: true,\n });\n });\n }\n\n private handleMouseMove = () => {\n this.restartAutoHide();\n };\n\n private handleCloseClick = () => {\n this.hide();\n };\n\n private handleTransitionEnd = (event: TransitionEvent) => {\n if (\n event.propertyName === 'opacity' &&\n (event.target === this.panel || event.target === this.overlay)\n ) {\n this.host.hidden = !this.open;\n this.isShowing = this.open;\n this.open ? this.nanoAfterShow.emit() : this.nanoAfterHide.emit();\n }\n };\n\n private handleButtonClick = (e: PointerEvent & { target: HTMLElement }) => {\n if (e.defaultPrevented) return;\n if (e.target.tagName && e.target.tagName.toLowerCase() === 'button')\n this.hide();\n };\n\n private restartAutoHide = () => {\n clearTimeout(this.autoHideTimeout);\n if (this.open && this.duration < Infinity) {\n this.autoHideTimeout = setTimeout(() => this.hide(), this.duration);\n }\n };\n\n connectedCallback() {\n this.modal = new Modal(this.host);\n this.handleHoistChange();\n this.host.addEventListener('click', this.handleButtonClick);\n\n if (this.panel) {\n this.addedTransEnd = true;\n this.panel.addEventListener('transitionend', this.handleTransitionEnd);\n }\n }\n\n disconnectedCallback() {\n unlockBodyScrolling(this.host);\n this.host.removeEventListener('click', this.handleButtonClick);\n\n this.addedTransEnd = false;\n if (this.panel)\n this.panel.removeEventListener('transitionend', this.handleTransitionEnd);\n }\n\n componentDidLoad() {\n // Show on init if open\n if (this.open) {\n this.show();\n }\n if (!this.addedTransEnd) {\n this.panel.addEventListener('transitionend', this.handleTransitionEnd);\n }\n }\n\n private Panel = (): VNode => {\n return (\n <div\n ref={(el) => (this.panel = el)}\n part=\"panel\"\n class={{\n alert: true,\n 'alert--open': this.open,\n 'alert--toasty': this.isToast,\n 'alert--modal': !!this.isModal,\n 'alert--showing': this.isShowing,\n }}\n role={!!this.isModal ? 'alertdialog' : 'alert'}\n aria-live=\"assertive\"\n aria-atomic=\"true\"\n aria-hidden={this.open ? 'false' : 'true'}\n aria-modal={!!this.isModal ? 'true' : undefined}\n aria-label={this.label ? this.label : undefined}\n onMouseMove={this.handleMouseMove}\n tabIndex={!!this.isModal ? 0 : undefined}\n >\n <div class=\"alert__content\">\n <div part=\"icon\" class=\"alert__icon\">\n <slot name=\"icon\" />\n </div>\n <div part=\"message\" class=\"alert__message\">\n <slot />\n </div>\n {this.closable && (\n <div class=\"alert__close\">\n <nano-icon-button\n class=\"alert__close\"\n iconName=\"light/times\"\n label=\"close menu\"\n onClick={this.handleCloseClick}\n ></nano-icon-button>\n </div>\n )}\n </div>\n <div class=\"alert__footer\">\n <slot name=\"footer\" />\n </div>\n </div>\n );\n };\n\n render() {\n return (\n <Host\n class={{ ...createColorClasses(this.color) }}\n showing={this.isShowing}\n >\n {this.isModal && [\n <div\n part=\"overlay\"\n class={{\n alert__overlay: true,\n 'alert__overlay--open': this.open,\n }}\n ref={(div) => (this.overlay = div)}\n />,\n <div class=\"alert__modal-wrap\">\n <this.Panel />\n </div>,\n ]}\n {!this.isModal && <this.Panel />}\n </Host>\n );\n }\n}\n"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  /*!
2
2
  * Web Components for Nanopore digital Web Apps
3
3
  */
4
- import{c as t}from"./p-2b3aca3f.js";import"./p-f6a8467a.js";import"./p-ee045579.js";import"./p-9746b0a5.js";import"./p-9ebbb814.js";const o="table.worker";const p="stencil.table.worker";const s=new URL("p-e2f9ccfa.js",import.meta.url).href;const r=new Blob(['importScripts("'+s+'")'],{type:"text/javascript"});const e=URL.createObjectURL(r);const c=t(e,o,p);URL.revokeObjectURL(e);export{c as worker,p as workerMsgId,o as workerName,s as workerPath};
5
- //# sourceMappingURL=p-e39ce4e0.js.map
4
+ import{c as t}from"./p-0d773484.js";import"./p-f6a8467a.js";import"./p-ee045579.js";import"./p-9746b0a5.js";import"./p-9ebbb814.js";const o="table.worker";const p="stencil.table.worker";const s=new URL("p-e2f9ccfa.js",import.meta.url).href;const r=new Blob(['importScripts("'+s+'")'],{type:"text/javascript"});const e=URL.createObjectURL(r);const c=t(e,o,p);URL.revokeObjectURL(e);export{c as worker,p as workerMsgId,o as workerName,s as workerPath};
5
+ //# sourceMappingURL=p-e2b004ce.js.map
@@ -13,7 +13,7 @@ export declare class CheckboxGroup implements ComponentInterface {
13
13
  private grpId;
14
14
  private ignoreValueSet;
15
15
  host: HTMLNanoCheckboxGroupElement;
16
- checkboxes: HTMLNanoCheckboxElement[];
16
+ checkboxes?: HTMLNanoCheckboxElement[];
17
17
  nativeCbs: HTMLInputElement[];
18
18
  errorMessage: string;
19
19
  showErrorMsg: boolean;
@@ -83,16 +83,24 @@ export declare class FieldValidator implements ComponentInterface {
83
83
  setStore(state: ValidatorValueStore): Promise<void>;
84
84
  /**
85
85
  * Sets custom validity for all / some form fields.
86
- * @param validity - a validity object of `{fieldName: errorString}` pairs. Set as an empty string to clear the error.
86
+ * @param validity - a validity object of `{fieldName: errorString}` pairs.
87
+ * Set as an empty string to clear the error.
88
+ * @param scrollToInvalid - whether to scroll to the first invalid field.
89
+ * If not present, will follow the value set on `scrollToInvalid` prop.
87
90
  */
88
91
  setCustomValidity(validity: {
89
92
  [key: string]: string;
90
- }): Promise<void[]>;
93
+ }, scrollToInvalid?: boolean): Promise<void[]>;
91
94
  /**
92
95
  * Clear all custom validation.
93
96
  * @returns a promise, resolved when all errors are cleared
94
97
  */
95
98
  resetValidity(): Promise<void[]>;
99
+ /**
100
+ * Scrolls to first invalid form field.
101
+ * @param force - forces the scroll behaviour (default). Otherwise will use the default set in `scrollToInvalid` prop
102
+ */
103
+ scrollToFirstInvalid(force?: boolean): Promise<void>;
96
104
  /** Fired whenever the payload changes */
97
105
  nanoPayloadChange: EventEmitter<ValidatorValueStore>;
98
106
  /**
@@ -119,6 +127,7 @@ export declare class FieldValidator implements ComponentInterface {
119
127
  /** Checks for new `nano-...` fields and adds them to our watch array and value store */
120
128
  private setupFields;
121
129
  private storeToFields;
130
+ private getValidityTarget;
122
131
  /** Loops through all `nano-...` fields and extracts their values into our store */
123
132
  private fieldsToStore;
124
133
  /**
@@ -144,7 +153,6 @@ export declare class FieldValidator implements ComponentInterface {
144
153
  * @param msg
145
154
  */
146
155
  private setFieldError;
147
- private scrollToFirstInvalid;
148
156
  private submitForm;
149
157
  /**
150
158
  * Fired whenever store values change and potentially checks validity
@@ -846,6 +846,11 @@ export namespace Components {
846
846
  * @returns a promise, resolved when all errors are cleared
847
847
  */
848
848
  "resetValidity": () => Promise<void[]>;
849
+ /**
850
+ * Scrolls to first invalid form field.
851
+ * @param force - forces the scroll behaviour (default). Otherwise will use the default set in `scrollToInvalid` prop
852
+ */
853
+ "scrollToFirstInvalid": (force?: boolean) => Promise<void>;
849
854
  /**
850
855
  * Tries to scroll to the first invalid field on submit
851
856
  */
@@ -853,8 +858,9 @@ export namespace Components {
853
858
  /**
854
859
  * Sets custom validity for all / some form fields.
855
860
  * @param validity - a validity object of `{fieldName: errorString}` pairs. Set as an empty string to clear the error.
861
+ * @param scrollToInvalid - whether to scroll to the first invalid field. If not present, will follow the value set on `scrollToInvalid` prop.
856
862
  */
857
- "setCustomValidity": (validity: { [key: string]: string; }) => Promise<void[]>;
863
+ "setCustomValidity": (validity: { [key: string]: string; }, scrollToInvalid?: boolean) => Promise<void[]>;
858
864
  /**
859
865
  * Sets the state of the form using an object of key / value pairs.
860
866
  * @param state - the state to load in the store
package/docs-json.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "timestamp": "2023-04-21T16:42:35",
2
+ "timestamp": "2023-05-16T15:40:56",
3
3
  "compiler": {
4
4
  "name": "@stencil/core",
5
5
  "version": "2.23.0",
@@ -4668,6 +4668,11 @@
4668
4668
  "annotation": "prop",
4669
4669
  "docs": "defaults to #f0efed;"
4670
4670
  },
4671
+ {
4672
+ "name": "--nano-layer-overlay-blur",
4673
+ "annotation": "prop",
4674
+ "docs": "inheritable theme applied to backdrop. Default to var(--nano-layer-overlay-blur, 3px)"
4675
+ },
4671
4676
  {
4672
4677
  "name": "--scrim-color",
4673
4678
  "annotation": "prop",
@@ -5726,19 +5731,39 @@
5726
5731
  }
5727
5732
  ]
5728
5733
  },
5734
+ {
5735
+ "name": "scrollToFirstInvalid",
5736
+ "returns": {
5737
+ "type": "Promise<void>",
5738
+ "docs": ""
5739
+ },
5740
+ "signature": "scrollToFirstInvalid(force?: boolean) => Promise<void>",
5741
+ "parameters": [],
5742
+ "docs": "Scrolls to first invalid form field.",
5743
+ "docsTags": [
5744
+ {
5745
+ "name": "param",
5746
+ "text": "force - forces the scroll behaviour (default). Otherwise will use the default set in `scrollToInvalid` prop"
5747
+ }
5748
+ ]
5749
+ },
5729
5750
  {
5730
5751
  "name": "setCustomValidity",
5731
5752
  "returns": {
5732
5753
  "type": "Promise<void[]>",
5733
5754
  "docs": ""
5734
5755
  },
5735
- "signature": "setCustomValidity(validity: { [key: string]: string; }) => Promise<void[]>",
5756
+ "signature": "setCustomValidity(validity: { [key: string]: string; }, scrollToInvalid?: boolean) => Promise<void[]>",
5736
5757
  "parameters": [],
5737
5758
  "docs": "Sets custom validity for all / some form fields.",
5738
5759
  "docsTags": [
5739
5760
  {
5740
5761
  "name": "param",
5741
- "text": "validity - a validity object of `{fieldName: errorString}` pairs. Set as an empty string to clear the error."
5762
+ "text": "validity - a validity object of `{fieldName: errorString}` pairs.\nSet as an empty string to clear the error."
5763
+ },
5764
+ {
5765
+ "name": "param",
5766
+ "text": "scrollToInvalid - whether to scroll to the first invalid field.\nIf not present, will follow the value set on `scrollToInvalid` prop."
5742
5767
  }
5743
5768
  ]
5744
5769
  },
package/hydrate/index.js CHANGED
@@ -6723,8 +6723,8 @@ class Alert {
6723
6723
  });
6724
6724
  }
6725
6725
  connectedCallback() {
6726
- this.handleHoistChange();
6727
6726
  this.modal = new Modal(this.host);
6727
+ this.handleHoistChange();
6728
6728
  this.host.addEventListener('click', this.handleButtonClick);
6729
6729
  if (this.panel) {
6730
6730
  this.addedTransEnd = true;
@@ -6735,7 +6735,8 @@ class Alert {
6735
6735
  unlockBodyScrolling(this.host);
6736
6736
  this.host.removeEventListener('click', this.handleButtonClick);
6737
6737
  this.addedTransEnd = false;
6738
- this.panel.removeEventListener('transitionend', this.handleTransitionEnd);
6738
+ if (this.panel)
6739
+ this.panel.removeEventListener('transitionend', this.handleTransitionEnd);
6739
6740
  }
6740
6741
  componentDidLoad() {
6741
6742
  // Show on init if open
@@ -11172,6 +11173,8 @@ class CheckboxGroup {
11172
11173
  */
11173
11174
  async showError(message, optVal) {
11174
11175
  let cb;
11176
+ if (!this.checkboxes)
11177
+ return;
11175
11178
  if (optVal)
11176
11179
  cb = this.checkboxes.find((c) => c.value === optVal);
11177
11180
  if (!cb)
@@ -11250,12 +11253,14 @@ class CheckboxGroup {
11250
11253
  return invalid;
11251
11254
  }
11252
11255
  handleComponentChange() {
11253
- if (!this.checkboxes.length)
11256
+ var _a;
11257
+ if (!((_a = this.checkboxes) === null || _a === void 0 ? void 0 : _a.length))
11254
11258
  return;
11255
11259
  this.checkboxTypes = getClassMap(this.checkboxes.map((cb) => 'types-' + cb.type));
11256
11260
  }
11257
11261
  handleDisabledChange() {
11258
- if (this.disabled === null)
11262
+ var _a;
11263
+ if (this.disabled === null || !((_a = this.checkboxes) === null || _a === void 0 ? void 0 : _a.length))
11259
11264
  return;
11260
11265
  this.checkboxes.map((cb) => (cb.disabled = this.disabled));
11261
11266
  }
@@ -13549,7 +13554,7 @@ class Dialog {
13549
13554
  'dialog--has-header': !this.noHeader,
13550
13555
  'dialog--nodismiss': this.noDismiss,
13551
13556
  'dialog--with-ribbon': this.showRibbon,
13552
- }, onKeyDown: this.handleKeyDown }, hAsync("div", { part: "overlay", class: "dialog__overlay", ref: (el) => (this.overlay = el), onClick: this.requestClose }), hAsync("div", { ref: (el) => (this.panel = el), part: "panel", class: "dialog__panel", role: "dialog", "aria-modal": "true", "aria-hidden": this.open ? 'false' : 'true', "aria-label": this.noHeader ? this.label : null, "aria-labelledby": !this.noHeader ? `${this.componentId}-title` : null, tabIndex: 0 }, hAsync("div", { class: "dialog__body-wrap" }, !this.noHeader && (hAsync("nano-sticker", null, hAsync("header", { part: "header", class: "dialog__header" }, hAsync("span", { part: "title", class: "dialog__title", id: `${this.componentId}-title` }, hAsync("slot", { name: "label" }, this.label || String.fromCharCode(65279))), !this.noUserDismiss && (hAsync("nano-icon-button", { exportparts: "base:close-button", class: "dialog__close-icon", label: "close dialog", onClick: this.requestClose, iconName: "light/times" }))))), hAsync("div", { part: "body", class: "dialog__body" }, hAsync("slot", null)), !this.noFooter && (this.hasFooter || !this.noUserDismiss) && (hAsync("nano-sticker", { position: "bottom" }, hAsync("footer", { part: "footer", class: "dialog__footer" }, hAsync("slot", { name: "footer", onSlotchange: this.handleSlotChange }), !this.noUserDismiss && (hAsync("button", { class: "dialog__close-txt", onClick: this.requestClose }, "Close"))))))))));
13557
+ }, onKeyDown: this.handleKeyDown }, hAsync("div", { part: "overlay", class: "dialog__overlay", ref: (el) => (this.overlay = el), onClick: this.requestClose }), hAsync("div", { ref: (el) => (this.panel = el), part: "panel", class: "dialog__panel", role: "dialog", "aria-modal": "true", "aria-hidden": this.open ? 'false' : 'true', "aria-label": this.noHeader ? this.label : null, "aria-labelledby": !this.noHeader ? `${this.componentId}-title` : null, tabIndex: 0 }, hAsync("div", { class: "dialog__body-wrap" }, !this.noHeader && (hAsync("nano-sticker", null, hAsync("header", { part: "header", class: "dialog__header" }, hAsync("span", { part: "title", class: "dialog__title", id: `${this.componentId}-title` }, hAsync("slot", { name: "label" }, this.label || String.fromCharCode(65279))), !this.noUserDismiss && (hAsync("nano-icon-button", { exportparts: "base:close-button", class: "dialog__close-icon", label: "close dialog", onClick: this.requestClose, iconName: "light/times" }))))), hAsync("div", { part: "body", class: "dialog__body", style: { display: !this.isVisible ? 'none' : '' } }, hAsync("slot", null)), !this.noFooter && (this.hasFooter || !this.noUserDismiss) && (hAsync("nano-sticker", { position: "bottom" }, hAsync("footer", { part: "footer", class: "dialog__footer" }, hAsync("slot", { name: "footer", onSlotchange: this.handleSlotChange }), !this.noUserDismiss && (hAsync("button", { class: "dialog__close-txt", onClick: this.requestClose }, "Close"))))))))));
13553
13558
  }
13554
13559
  get host() { return getElement(this); }
13555
13560
  static get watchers() { return {
@@ -16259,7 +16264,7 @@ class FieldValidator {
16259
16264
  return;
16260
16265
  }
16261
16266
  }
16262
- this.scrollToFirstInvalid();
16267
+ this.scrollToFirstInvalid(false);
16263
16268
  this.nanoInvalid.emit();
16264
16269
  };
16265
16270
  this.submitted = false;
@@ -16406,14 +16411,19 @@ class FieldValidator {
16406
16411
  }
16407
16412
  /**
16408
16413
  * Sets custom validity for all / some form fields.
16409
- * @param validity - a validity object of `{fieldName: errorString}` pairs. Set as an empty string to clear the error.
16414
+ * @param validity - a validity object of `{fieldName: errorString}` pairs.
16415
+ * Set as an empty string to clear the error.
16416
+ * @param scrollToInvalid - whether to scroll to the first invalid field.
16417
+ * If not present, will follow the value set on `scrollToInvalid` prop.
16410
16418
  */
16411
- async setCustomValidity(validity) {
16419
+ async setCustomValidity(validity, scrollToInvalid) {
16412
16420
  return await Promise.all(Object.entries(validity).map(async ([key, err]) => {
16413
16421
  const field = this.allFields.find((f) => this.getName(f) === key);
16414
16422
  if (!!field)
16415
16423
  await this.setFieldError(field, err);
16416
- }));
16424
+ })).finally(() => {
16425
+ this.scrollToFirstInvalid(scrollToInvalid);
16426
+ });
16417
16427
  }
16418
16428
  /**
16419
16429
  * Clear all custom validation.
@@ -16422,6 +16432,23 @@ class FieldValidator {
16422
16432
  async resetValidity() {
16423
16433
  return await Promise.all(this.allFields.map(async (field) => await this.setFieldError(field, '')));
16424
16434
  }
16435
+ /**
16436
+ * Scrolls to first invalid form field.
16437
+ * @param force - forces the scroll behaviour (default). Otherwise will use the default set in `scrollToInvalid` prop
16438
+ */
16439
+ async scrollToFirstInvalid(force = true) {
16440
+ if (!force && !this.scrollToInvalid)
16441
+ return;
16442
+ setTimeout(() => {
16443
+ const invalidField = this.validationState.find((f) => !f.valid);
16444
+ if (!invalidField)
16445
+ return;
16446
+ invalidField.fields[0].scrollIntoView({
16447
+ behavior: 'smooth',
16448
+ block: 'nearest',
16449
+ });
16450
+ }, 200);
16451
+ }
16425
16452
  // private methods
16426
16453
  attachSlotObserver() {
16427
16454
  if (!!this.mo)
@@ -16518,6 +16545,15 @@ class FieldValidator {
16518
16545
  field.value = this._store.state[fieldName];
16519
16546
  });
16520
16547
  }
16548
+ getValidityTarget(field) {
16549
+ let validityTarget = field;
16550
+ if (field.tagName === 'NANO-CHECKBOX') {
16551
+ // if we have a checkbox-group, set the validation message there
16552
+ const cbg = field.closest('nano-checkbox-group');
16553
+ validityTarget = cbg || field;
16554
+ }
16555
+ return validityTarget;
16556
+ }
16521
16557
  /** Loops through all `nano-...` fields and extracts their values into our store */
16522
16558
  fieldsToStore(fields, init = false) {
16523
16559
  fields.forEach((field) => {
@@ -16609,12 +16645,7 @@ class FieldValidator {
16609
16645
  return validityState.fields.map(async (fieldName) => {
16610
16646
  // switch on/off validation messages
16611
16647
  const field = this.allFields.find((f) => this.getName(f) === fieldName);
16612
- let validityTarget = field;
16613
- if (field.tagName === 'NANO-CHECKBOX') {
16614
- // if we have a checkbox-group, set the validation message there
16615
- const cbg = field.closest('nano-checkbox-group');
16616
- validityTarget = cbg || field;
16617
- }
16648
+ const validityTarget = this.getValidityTarget(field);
16618
16649
  if ((validityTarget.validityMessage ||
16619
16650
  validityTarget.validationMessage) === msg &&
16620
16651
  validityState.valid) {
@@ -16643,26 +16674,14 @@ class FieldValidator {
16643
16674
  * @param msg
16644
16675
  */
16645
16676
  async setFieldError(field, msg) {
16646
- if (field['showError']) {
16647
- await field.showError(msg);
16677
+ const validityTarget = this.getValidityTarget(field);
16678
+ if (validityTarget['showError']) {
16679
+ await validityTarget.showError(msg);
16648
16680
  }
16649
- else if (field['setError'])
16650
- await field.setError(msg);
16681
+ else if (validityTarget['setError'])
16682
+ await validityTarget.setError(msg);
16651
16683
  else
16652
- field.setCustomValidity(msg);
16653
- }
16654
- scrollToFirstInvalid() {
16655
- if (!this.scrollToInvalid)
16656
- return;
16657
- setTimeout(() => {
16658
- const invalidField = this.validationState.find((f) => !f.valid);
16659
- if (!invalidField)
16660
- return;
16661
- invalidField.fields[0].scrollIntoView({
16662
- behavior: 'smooth',
16663
- block: 'nearest',
16664
- });
16665
- }, 200);
16684
+ validityTarget.setCustomValidity(msg);
16666
16685
  }
16667
16686
  submitForm() {
16668
16687
  const nanoSubmit = this.nanoSubmit.emit();
@@ -16703,7 +16722,7 @@ class FieldValidator {
16703
16722
  this._valid = this.activeForm.checkValidity();
16704
16723
  this.internalValidate = false;
16705
16724
  if (!this._valid) {
16706
- this.scrollToFirstInvalid();
16725
+ this.scrollToFirstInvalid(false);
16707
16726
  return;
16708
16727
  }
16709
16728
  this.submitForm();
@@ -16756,7 +16775,8 @@ class FieldValidator {
16756
16775
  "_store": [32],
16757
16776
  "setStore": [64],
16758
16777
  "setCustomValidity": [64],
16759
- "resetValidity": [64]
16778
+ "resetValidity": [64],
16779
+ "scrollToFirstInvalid": [64]
16760
16780
  },
16761
16781
  "$listeners$": [[0, "nanoChange", "handleFieldChange"], [0, "input", "handlePlainFieldChange"], [0, "change", "handlePlainFieldChange"], [0, "submit", "handleSubmit"]],
16762
16782
  "$lazyBundleId$": "-",
@@ -18103,7 +18123,7 @@ class GlobalNav {
18103
18123
  'search-auto-complete-shown': this.showAutocomplete && this.scrollingUp,
18104
18124
  'modal-open': this.modalIsOpen,
18105
18125
  resizing: this.isResizing,
18106
- }, dir: isRtl ? 'rtl' : null, role: "navigation" }, hAsync("div", { class: {
18126
+ }, dir: isRtl ? 'rtl' : null }, hAsync("div", { class: {
18107
18127
  'global-nav': true,
18108
18128
  'scrolling-down': !this.scrollingUp,
18109
18129
  } }, hAsync("nav", { id: "global-nav-menu", class: {
@@ -31205,6 +31225,11 @@ class Tooltip {
31205
31225
  .map((node) => node.textContent)
31206
31226
  .join(' ')
31207
31227
  .trim();
31228
+ if (!this.target) {
31229
+ this.target = this.getTarget();
31230
+ if (!this.target)
31231
+ return;
31232
+ }
31208
31233
  this.label = textContent || this.content;
31209
31234
  this.target.setAttribute('aria-label', this.label);
31210
31235
  }
@@ -31283,7 +31308,8 @@ class Tooltip {
31283
31308
  this.syncOptions();
31284
31309
  }
31285
31310
  disconnectedCallback() {
31286
- this.popover.destroy();
31311
+ if (this.popover)
31312
+ this.popover.destroy();
31287
31313
  }
31288
31314
  render() {
31289
31315
  return (hAsync(Host, { onKeyDown: this.handleKeyDown, onMouseOver: this.handleMouseOver, onMouseOut: this.handleMouseOut, onBlur: this.handleBlur, onFocus: this.handleFocus, onClick: this.handleClick }, hAsync("slot", { onSlotchange: this.handleSlotChange }), hAsync("div", { ref: (el) => (this.tooltipPositioner = el), class: "tooltip-positioner" }, hAsync("div", { part: "base", ref: (el) => (this.tooltip = el), class: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nanoporetech-digital/components",
3
- "version": "4.5.2",
3
+ "version": "4.6.0",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://git.oxfordnanolabs.local/Digital/nano-components"
@@ -101,6 +101,7 @@
101
101
  "npm-run-all": "^4.1.5",
102
102
  "prettier": "^2.3.2",
103
103
  "puppeteer": "^11.0.0",
104
+ "rollup-plugin-analyzer": "^4.0.0",
104
105
  "rollup-plugin-sass-variables": "^0.1.1",
105
106
  "sass": "^1.33.0",
106
107
  "stylelint": "^15.1.0",
@@ -130,7 +131,7 @@
130
131
  "nanopore",
131
132
  "digital"
132
133
  ],
133
- "gitHead": "405ca4de097690efa0c95f8a23304eeaefbefe79",
134
+ "gitHead": "fe20f8fdee99bc6f0a3e0861c08acf76ebcfe928",
134
135
  "volta": {
135
136
  "node": "14.18.1",
136
137
  "npm": "8.6.0"
@@ -1 +0,0 @@
1
- {"file":"table.worker-ce12bd92.js","mappings":";;;;;;;;;;;;;;;;;;;;;;;;","names":[],"sources":[],"sourcesContent":[],"version":3}
@@ -1 +0,0 @@
1
- {"file":"table.worker-7c5b7b44.js","mappings":";;;;;;;;;;;;;;;;;;;","names":[],"sources":[],"sourcesContent":[],"version":3}
@@ -1 +0,0 @@
1
- {"version":3,"names":["checkboxGroupCss","CheckboxGroup","this","grpId","grpIds","ignoreValueSet","handleInvalid","ev","_invalid","validateOn","showErrorMsg","customValidate","showInlineError","preventDefault","showInlineValidation","nativeCbs","length","forEach","cb","_i","validity","valid","errorMessage","validationMessage","nanoValidate","emit","isValid","invalid","originalEvent","validityMessage","handleValuePropChange","nanoChange","value","setCbValue","async","validateFirst","Promise","resolve","setTimeout","message","optVal","checkboxes","find","c","setError","handleValueChange","target","host","setInteralValue","handleCbChange","onlyRadios","filter","type","required","checked","rd","reportValidity","onlyCbs","i","nativeCb","setCustomValidity","min","max","handleComponentChange","checkboxTypes","getClassMap","map","handleDisabledChange","disabled","radios","_a","flatMap","requestAnimationFrame","Array","isArray","includes","attachSlotObserver","mo","window","MutationObserver","handleSlotChange","observe","childList","from","querySelectorAll","hasHelperSlot","querySelector","all","reduce","acc","push","getInputElement","addEventListener","componentWillLoad","debounce","bind","connectedCallback","disconnectedCallback","disconnect","componentDidLoad","render","legendId","moreId","h","Host","Object","assign","class","nanogroupcb","id","legend","role","name"],"sources":["./src/components/checkbox/checkbox-group.scss?tag=nano-checkbox-group&encapsulation=scoped","./src/components/checkbox/checkbox-group.tsx"],"sourcesContent":["@import '../../global/style/utilities/globals';\n@import '../../global/style/nano-theme/form';\n@import '../../global/style/nano-theme/base';\n\n:host {\n /**\n * @prop --control-margin-top: Margin between controls. Default depends on control type;\n * @prop --control-margin-end: Margin between controls. Default depends on control type;\n * @prop --control-margin-bottom: Margin between controls. Default depends on control type;\n * @prop --control-margin-start: Margin between controls. Default depends on control type;\n\n * @prop --invalid-msg-color: Default #{nano-color(danger, base)};\n * @prop --invalid-msg-font-size: Default #{$input-help-font-size};\n\n * @prop --help-msg-color: Font color applied to slot=\"helper\". Default #{$input-help-color};\n\n * @prop --label-color: Default #{$label-color};\n * @prop --label-color--invalid: Default #{$label-color-invalid};\n * @prop --label-font-size: Default #{$label-font-size};\n * @prop --label-padding: space between legend and control. Default #{$input-padding-bottom};\n */\n\n --control-margin-top: 0;\n --control-margin-end: 0;\n --control-margin-bottom: 0;\n --control-margin-start: 0;\n --invalid-msg-color: #{nano-color(danger, base)};\n --invalid-msg-font-size: #{$input-help-font-size};\n --help-msg-color: #{$input-help-color};\n --label-color: #{$label-color};\n --label-color--invalid: #{$label-color-invalid};\n --label-font-size: #{$label-font-size};\n --label-padding: #{$input-padding-bottom};\n\n display: block;\n\n * {\n box-sizing: inherit;\n }\n}\n\n:host([types-tag]),\n:host([types-segment]) {\n --control-margin-top: 0;\n --control-margin-end: 8px;\n --control-margin-bottom: 6px;\n --control-margin-start: 0;\n}\n\n:host([types-checkbox]),\n:host([types-radio]) {\n --control-margin-top: 0;\n --control-margin-end: 10px;\n --control-margin-bottom: 6px;\n --control-margin-start: 0;\n}\n\n.nanogroupcb {\n border: none;\n margin: 0;\n padding: 0;\n\n &__error,\n &__help,\n &__more {\n display: block;\n width: 100%;\n overflow: hidden;\n white-space: nowrap;\n text-overflow: ellipsis;\n }\n\n &__legend {\n font-size: var(--label-font-size);\n padding: 0 0 var(--label-padding);\n margin: 0;\n line-height: 1.5;\n white-space: normal;\n display: block;\n width: 100%;\n\n :host([invalid]:not([invalid='false'])) & {\n color: var(--label-color--invalid);\n }\n }\n\n &__more {\n height: 1em;\n margin-block-start:\n calc(\n var(--label-padding) - var(--control-margin-bottom)\n );\n margin-inline-end: 0;\n margin-block-end: var(--label-padding);\n margin-inline-start: 3px;\n position: relative;\n }\n\n &__error,\n &__help {\n inset-block-start: 0;\n inset-inline-start: 0;\n position: absolute;\n font-size: var(--invalid-msg-font-size);\n line-height: 1.2;\n transition: 0.3s ease-out opacity;\n\n .show-error & {\n opacity: 1;\n }\n }\n\n &__error {\n color: var(--invalid-msg-color);\n font-stretch: condensed;\n opacity: 0;\n\n .show-error & {\n opacity: 1;\n }\n }\n\n &__help {\n font-style: italic;\n opacity: 1;\n color: var(--help-msg-color);\n\n .show-error & {\n opacity: 0;\n }\n }\n\n &__cbs {\n margin: 0;\n padding: 0;\n line-height: 1;\n display: flex;\n flex-wrap: wrap;\n\n ::slotted(*:not([type='tag']):not([type='segment']):not([type='segment-pill'])) {\n --check-base-size: 1.2em;\n\n font-size: 0.85em;\n }\n\n ::slotted(*) {\n margin-inline: var(--control-margin-start) var(--control-margin-end);\n margin-block: var(--control-margin-top) var(--control-margin-bottom);\n }\n }\n}\n\n/* autoprefixer: ignore next */\n@supports ((margin-inline-start: 0) or (-webkit-margin-start: 0)) {\n .nanogroupcb__cbs {\n &::slotted(*),\n ::slotted(*) {\n margin-inline-start: var(--control-margin-start);\n margin-inline-end: var(--control-margin-end);\n }\n }\n}\n","import {\n Component,\n Prop,\n Element,\n h,\n ComponentInterface,\n State,\n Listen,\n Watch,\n Host,\n Method,\n Event,\n EventEmitter,\n} from '@stencil/core';\nimport { getClassMap } from '../../utils/theme';\nimport { debounce } from '../../utils/throttle';\nimport type {\n CssClassMap,\n ControlValidityEventDetail,\n ControlValidity,\n} from '../../interface';\n\n/**\n * `nano-checkbox-group` is an optional wrapper for all `nano-checkbox` controls.\n * It provides a convenient place to anchor a collective label and any validation issues.\n *\n * @slot - Used for grouping checkboxes inside the group wrapper\n * @slot helper - helper text to accompany the form field underneath.\n */\n@Component({\n tag: 'nano-checkbox-group',\n styleUrl: 'checkbox-group.scss',\n scoped: true,\n})\nexport class CheckboxGroup implements ComponentInterface {\n private mo?: MutationObserver;\n private checkboxTypes: CssClassMap;\n private grpId = `nano-checkbox-group-${grpIds++}`;\n private ignoreValueSet = false;\n\n @Element() host: HTMLNanoCheckboxGroupElement;\n\n // internal state\n\n @State() checkboxes: HTMLNanoCheckboxElement[];\n @State() nativeCbs: HTMLInputElement[];\n @State() errorMessage: string = '';\n @State() showErrorMsg = false;\n @State() hasHelperSlot = false;\n\n // public properties\n\n /**\n * When should the field perform validation\n */\n @Prop({ mutable: true }) validateOn?: 'dirty' | 'submit' | 'submitThenDirty' =\n 'submitThenDirty';\n\n /**\n * Whether to show validation errors underneath input\n */\n @Prop() showInlineError = true;\n\n /**\n * The minimum number of checkboxes required to be valid. Only relevant for checkbox type controls.\n * A validation error will be thrown if not enough controls are checked.\n */\n @Prop() min: number = 0;\n\n /**\n * The maximum number of checkboxes allowed. Only relevant for checkbox type controls.\n * Other controls will automatically be disabled upon reaching this number.\n */\n @Prop() max: number = null;\n\n /**\n * Disable all the nested form controls\n */\n @Prop({ reflect: true }) disabled: boolean | null = null;\n\n /**\n * A common label for children controls\n */\n @Prop() legend: string = '';\n\n /**\n * This will be true when the control is in an invalid state.\n * Validity is determined by the `required` prop. Or if custom validity message is set. @readonly\n */\n @Prop({ reflect: true })\n get invalid() {\n return this._invalid;\n }\n @State() _invalid = false;\n\n /**\n * Current validation message - if any. @readonly\n */\n @Prop()\n get validityMessage() {\n return this.errorMessage;\n }\n\n /** The current, collective checkbox value */\n @Prop({ mutable: true }) value: string[] | string;\n\n @Watch('value')\n handleValuePropChange() {\n this.nanoChange.emit(this.value);\n\n // this change is coming from a checkbox being checked\n // so don't then change the checkbox state\n // (would cause an infinite loop)\n if (this.ignoreValueSet) return;\n\n // value has changed via prop directly, so update the checkbox's state\n this.setCbValue();\n }\n\n // Public methods\n\n /**\n * Get the current state of the control.\n * @param validateFirst - perform validation first before reporting\n * @returns `{ isValid: boolean, errorMessage: string }`\n */\n @Method()\n async reportValidity(validateFirst: boolean): Promise<ControlValidity> {\n return new Promise((resolve) => {\n if (validateFirst) {\n this.customValidate();\n this.showInlineValidation();\n }\n setTimeout(() => {\n resolve({\n isValid: !this.invalid,\n errorMessage: this.errorMessage,\n });\n }, 50);\n });\n }\n\n /**\n * Invalidate the field and show a custom error message.\n * To clear the error you will need to re-call this method with an empty string.\n * @param message - the error message to show\n * @param optVal - optionally supply an option value to target which checkbox to show invalidate against (default is the first)\n */\n @Method()\n async showError(message: string, optVal?: string) {\n let cb: HTMLNanoCheckboxElement;\n if (optVal) cb = this.checkboxes.find((c) => c.value === optVal);\n if (!cb) cb = this.checkboxes[0];\n if (!cb) return;\n\n this.errorMessage = message;\n await cb.setError(message);\n if (!!this.showInlineError) this.showInlineValidation();\n }\n\n // Events\n\n /**\n * Called when a nested checkbox changes\n */\n @Event() nanoChange: EventEmitter<string | string[]>;\n\n /**\n * Called when validation is performed (which depends on `validateOn`).\n * @returns event.detail: `{ isValid: boolean, errorMessage: string, originalEvent: Event }`.\n */\n @Event() nanoValidate: EventEmitter<ControlValidityEventDetail>;\n\n // listeners & watchers\n\n @Listen('nanoChange')\n handleValueChange(ev: CustomEvent) {\n if (ev.target === this.host) return;\n this.setInteralValue();\n }\n\n /**\n * Notes on validation... custom validation messages should be set\n * no matter whether we show inline messages or native html5.\n * this will mean forms cannot submit when there are pending validation issues.\n */\n @Listen('nanoChange')\n @Watch('min')\n @Watch('max')\n handleCbChange() {\n if (this.invalid) this.showErrorMsg = this._invalid = false;\n this.customValidate();\n\n if (this.validateOn !== 'dirty') return;\n this.showInlineValidation();\n }\n\n @Watch('nativeCbs')\n customValidate() {\n if (!this.nativeCbs || !this.nativeCbs.length || !this.checkboxes) return;\n\n const onlyRadios = this.nativeCbs.filter((cb) => cb?.type === 'radio');\n\n if (\n onlyRadios &&\n onlyRadios.length &&\n (this.showErrorMsg || this.validateOn === 'dirty')\n ) {\n const required = onlyRadios.find((cb) => cb.required);\n const checked = onlyRadios.filter((cb) => cb.checked);\n\n if (required && checked) {\n this.checkboxes.forEach((rd) => rd.reportValidity(false));\n return false;\n } else if (required && !checked) return true;\n }\n\n // we only care about checkbox controls.\n const onlyCbs = this.nativeCbs.filter((cb) => cb?.type === 'checkbox');\n if (!onlyCbs || !onlyCbs.length) return;\n\n const checked = onlyCbs.filter((cb) => cb.checked);\n const required = onlyCbs.find((cb) => cb.required);\n let invalid = false;\n\n if (required && !checked.find((cb) => cb === required)) return true;\n\n this.checkboxes.forEach((cb, i) => {\n const nativeCb = this.nativeCbs[i];\n cb.setError('');\n nativeCb.setCustomValidity('');\n\n if (this.min && checked.length < this.min) {\n this.errorMessage = `You must select a minimum of ${this.min} values.`;\n invalid = true;\n }\n if (this.max && checked.length > this.max) {\n this.errorMessage = `Only up to ${this.max} values are allowed.`;\n invalid = true;\n }\n\n if (invalid) {\n cb.setError(this.errorMessage, this.showErrorMsg);\n // bit fugly. We're just doing this 'cos stencil\n // methods are async and we want the validity message\n // asap to keep things in sync\n nativeCb.setCustomValidity(this.errorMessage);\n }\n });\n return invalid;\n }\n\n @Watch('checkboxes')\n handleComponentChange() {\n if (!this.checkboxes.length) return;\n\n this.checkboxTypes = getClassMap(\n this.checkboxes.map((cb) => 'types-' + cb.type)\n );\n }\n\n @Watch('disabled')\n @Watch('checkboxes')\n handleDisabledChange() {\n if (this.disabled === null) return;\n this.checkboxes.map((cb) => (cb.disabled = this.disabled));\n }\n\n // private methods\n\n private setInteralValue() {\n this.ignoreValueSet = true;\n const radios = this.nativeCbs.filter((cb) => cb?.type === 'radio');\n if (radios?.length) {\n this.value = radios.find((cb) => cb.checked)?.value || null;\n return;\n }\n this.value = this.checkboxes.flatMap((cb) =>\n cb.checked ? [cb.value] : []\n );\n requestAnimationFrame(() => (this.ignoreValueSet = false));\n }\n\n private setCbValue() {\n this.checkboxes.forEach((cb) => {\n if (\n cb.value === this.value ||\n (Array.isArray(this.value) && this.value.includes(cb.value))\n ) {\n cb.checked = true;\n }\n });\n }\n\n private attachSlotObserver() {\n if (!!this.mo || !window['MutationObserver']) return;\n const mo = (this.mo = new MutationObserver(() => this.handleSlotChange()));\n mo.observe(this.host, { childList: true });\n }\n\n private async handleSlotChange() {\n this.checkboxes = Array.from(this.host.querySelectorAll('nano-checkbox'));\n this.hasHelperSlot = !!this.host.querySelector('[slot=\"helper\"]');\n\n this.nativeCbs = await Promise.all(\n this.checkboxes.reduce((acc: Array<Promise<HTMLInputElement>>, cb) => {\n acc.push(cb.getInputElement());\n return acc;\n }, [])\n );\n\n this.nativeCbs.forEach((cb) => {\n if (cb) cb.addEventListener('invalid', this.handleInvalid);\n });\n }\n\n private handleInvalid = (ev: Event) => {\n this._invalid = true;\n\n if (this.validateOn === 'submit') {\n this._invalid = this.showErrorMsg = this.customValidate();\n }\n if (!!this.showInlineError) ev.preventDefault();\n\n this.showInlineValidation(ev);\n };\n\n private showInlineValidation = (ev?: Event) => {\n if (!this.nativeCbs || !this.nativeCbs.length) return;\n if (this.validateOn === 'submitThenDirty') this.validateOn = 'dirty';\n this.showErrorMsg = false;\n this._invalid = false;\n\n this.nativeCbs.forEach((cb, _i) => {\n if (!cb.validity.valid) {\n this.errorMessage = cb.validationMessage;\n this.showErrorMsg = true;\n this._invalid = true;\n }\n });\n\n this.nanoValidate.emit({\n isValid: !this.invalid,\n errorMessage: this.errorMessage,\n originalEvent: ev,\n });\n };\n\n // stencil hooks\n\n componentWillLoad() {\n this.showInlineValidation = debounce(this.showInlineValidation, 50);\n this.customValidate = this.customValidate.bind(this);\n this.handleDisabledChange();\n this.handleSlotChange();\n }\n\n connectedCallback() {\n this.attachSlotObserver();\n }\n\n disconnectedCallback() {\n if (this.mo) this.mo.disconnect();\n }\n\n componentDidLoad() {\n this.handleComponentChange();\n }\n\n render() {\n const legendId = this.grpId + '-lbl';\n const moreId =\n this.showInlineError || this.hasHelperSlot ? this.grpId + '-more' : '';\n\n return (\n <Host {...this.checkboxTypes}>\n <fieldset\n disabled={this.disabled}\n class={{ nanogroupcb: true, 'show-error': this.showErrorMsg }}\n >\n <legend class=\"nanogroupcb__legend\" id={legendId}>\n {this.legend}\n </legend>\n <div\n class=\"nanogroupcb__cbs\"\n role=\"group\"\n aria-labelledby={legendId + ' ' + moreId}\n >\n <slot />\n </div>\n {(this.showInlineError || this.hasHelperSlot) && (\n <div class=\"nanogroupcb__more\" id={moreId}>\n {!!this.showInlineError ? (\n <div class=\"nanogroupcb__error\">{this.errorMessage}</div>\n ) : (\n ''\n )}\n <div class=\"nanogroupcb__help\">\n <slot name=\"helper\" />\n </div>\n </div>\n )}\n </fieldset>\n </Host>\n );\n }\n}\n\nlet grpIds = 0;\n"],"mappings":"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"}