@nova-design-system/nova-react 3.9.0 → 3.10.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 (51) hide show
  1. package/dist/cjs/{constants-4faa1fae-BzFAKCkR.js → constants-23aaef7b-Cj2b-su0.js} +12 -0
  2. package/dist/cjs/{index-BPZo04LR.js → index-Cm4m8MM1.js} +1509 -552
  3. package/dist/cjs/index.js +4 -1
  4. package/dist/cjs/{nv-accordion-item.entry-igHq6GcV.js → nv-accordion-item.entry-CnpS6CGa.js} +2 -2
  5. package/dist/cjs/{nv-accordion.entry-CjUtVUBZ.js → nv-accordion.entry-8UIjQG0P.js} +1 -1
  6. package/dist/cjs/{nv-alert.entry-NETR8Q1I.js → nv-alert.entry-96FaJ9yM.js} +8 -8
  7. package/dist/cjs/{nv-avatar.entry-B75vfd1u.js → nv-avatar.entry-BcLkxe35.js} +7 -7
  8. package/dist/cjs/nv-badge_2.entry-CzDec_7j.js +206 -0
  9. package/dist/cjs/{nv-breadcrumb.entry-21ZDbr-x.js → nv-breadcrumb.entry-BvnO7tGb.js} +2 -2
  10. package/dist/cjs/{nv-breadcrumbs.entry-CrqqjIzx.js → nv-breadcrumbs.entry-Du98f0lC.js} +1 -1
  11. package/dist/cjs/{nv-button.entry-D-2Zt42f.js → nv-button.entry-D8Ob5YDg.js} +8 -8
  12. package/dist/cjs/nv-buttongroup.entry-BGpQpMD_.js +195 -0
  13. package/dist/cjs/{nv-calendar.entry-BHT-inlG.js → nv-calendar.entry-CAINTAPB.js} +127 -44
  14. package/dist/cjs/{nv-col.entry-AHfSMqc1.js → nv-col.entry-5trkPEIg.js} +2 -2
  15. package/dist/cjs/{nv-datagrid.entry-BRT5wQGR.js → nv-datagrid.entry-DqbLtkI4.js} +9 -9
  16. package/dist/cjs/{nv-datagridcolumn.entry-BMDydM-l.js → nv-datagridcolumn.entry-Dn1u3PFr.js} +2 -2
  17. package/dist/cjs/{nv-dialog.entry-NPDVQdjH.js → nv-dialog.entry-pibB_NBe.js} +3 -3
  18. package/dist/cjs/{nv-dialogfooter_2.entry-CyHKMRiZ.js → nv-dialogfooter_2.entry-0MTTK7Y2.js} +5 -5
  19. package/dist/cjs/{nv-fieldcheckbox.entry-DyoNGs60.js → nv-fieldcheckbox.entry-DBSUOWI_.js} +6 -6
  20. package/dist/cjs/{nv-fielddate.entry-CgnVYTZx.js → nv-fielddate.entry-DM6ap-c_.js} +63 -95
  21. package/dist/cjs/{nv-fielddaterange.entry-DVcNJ2nO.js → nv-fielddaterange.entry-DJEbpwlV.js} +53 -34
  22. package/dist/cjs/{nv-fielddropdown.entry-D1Gb5Lvr.js → nv-fielddropdown.entry-COGswgIv.js} +4 -4
  23. package/dist/cjs/{nv-fielddropdownitem.entry-D1YDyF8i.js → nv-fielddropdownitem.entry-m6TjyMp3.js} +2 -2
  24. package/dist/cjs/{nv-fieldmultiselect.entry-eOD0Tk6H.js → nv-fieldmultiselect.entry-PhmD9JYp.js} +378 -28
  25. package/dist/cjs/{nv-fieldnumber.entry-C0S5sB8-.js → nv-fieldnumber.entry-dR0KzTa9.js} +4 -4
  26. package/dist/cjs/{nv-fieldpassword.entry-BwK_EseD.js → nv-fieldpassword.entry-CuQO_qjq.js} +4 -4
  27. package/dist/cjs/{nv-fieldradio.entry-DseYLmZY.js → nv-fieldradio.entry-UvL5fKFQ.js} +5 -5
  28. package/dist/cjs/{nv-fieldselect.entry-CO4wZVq5.js → nv-fieldselect.entry-DKMYBCaJ.js} +6 -6
  29. package/dist/cjs/{nv-fieldslider.entry-Bd_ntnN9.js → nv-fieldslider.entry-tOUuTb46.js} +4 -4
  30. package/dist/cjs/{nv-fieldtext.entry-BomXuhfy.js → nv-fieldtext.entry-m9XbYLZW.js} +4 -4
  31. package/dist/cjs/{nv-fieldtextarea.entry-COUlp8L8.js → nv-fieldtextarea.entry-DQpfF5ME.js} +4 -4
  32. package/dist/cjs/{nv-fieldtime.entry-Ejb66NjT.js → nv-fieldtime.entry-Pmt1E_Hm.js} +66 -66
  33. package/dist/cjs/{nv-icon.entry-DZgf515j.js → nv-icon.entry-C4VmFtRW.js} +9 -9
  34. package/dist/cjs/{nv-iconbutton_2.entry-C7cXslTK.js → nv-iconbutton_2.entry-Cc2xKJb5.js} +4 -4
  35. package/dist/cjs/{nv-menu.entry-Bd2VP2mz.js → nv-menu.entry-B6kxLiip.js} +2 -2
  36. package/dist/cjs/{nv-menuitem.entry-COtjh76S.js → nv-menuitem.entry-rYbCnY7o.js} +2 -2
  37. package/dist/cjs/{nv-popover.entry-BNDaFpW5.js → nv-popover.entry-CJJjW4Pv.js} +2 -2
  38. package/dist/cjs/{nv-row.entry-Aae5W4O5.js → nv-row.entry-BMMoJvjb.js} +2 -2
  39. package/dist/cjs/{nv-stack.entry-sV1xr1W5.js → nv-stack.entry-DI6QCSbS.js} +2 -2
  40. package/dist/cjs/{nv-table.entry-Dwq9q1W7.js → nv-table.entry-BPWQIWyg.js} +3 -3
  41. package/dist/cjs/{nv-tablecolumn.entry-_lJgMLCe.js → nv-tablecolumn.entry-De81f1e9.js} +1 -1
  42. package/dist/cjs/{nv-toggle.entry-COR80n7Q.js → nv-toggle.entry-BTNtBXGR.js} +4 -4
  43. package/dist/cjs/nv-togglebutton.entry-vWKwWiQe.js +55 -0
  44. package/dist/cjs/nv-togglebuttongroup.entry-BmpHIXnd.js +169 -0
  45. package/dist/cjs/{nv-tooltip.entry-BOB0Y-Wc.js → nv-tooltip.entry-BJHXydMC.js} +2 -2
  46. package/dist/generated/components.js +24 -0
  47. package/dist/generated/components.server.js +41 -4
  48. package/dist/types/generated/components.d.ts +16 -0
  49. package/dist/types/generated/components.server.d.ts +16 -0
  50. package/package.json +1 -1
  51. package/dist/cjs/nv-badge_2.entry-CAvYBnR-.js +0 -206
@@ -1,10 +1,10 @@
1
1
  'use strict';
2
2
 
3
- var index = require('./index-BPZo04LR.js');
3
+ var index = require('./index-Cm4m8MM1.js');
4
4
  var v4A79185f4 = require('./v4-a79185f4-2n0dOd_Y.js');
5
5
  require('react');
6
6
 
7
- const nvFieldmultiselectCss = "nv-fieldslider .slider-container .track-container:has(.thumb:hover) .track-range{background:var(--components-slider-track-filled-hover)}nv-fieldslider .slider-container .track-container:has(.thumb:hover) .thumb{border-color:var(--components-slider-track-filled-hover)}nv-fieldslider .slider-container .track-container:has(.thumb:focus) .track-range{background:var(--components-slider-track-filled-focus)}nv-fieldslider .slider-container .track-container:has(.thumb:focus) .thumb{border-color:var(--components-slider-track-filled-focus)}nv-fieldslider[error] .slider-container .track-container .track .track-range{background:var(--components-slider-track-filled-error)}nv-fieldslider[error] .slider-container .track-container .track .thumb{border-color:var(--components-slider-track-filled-error)}nv-fieldslider[error] .slider-container .track-container .track .thumb:hover{border-color:var(--components-slider-track-filled-error);outline:calc(var(--focus-outline-stroke) * 1) solid var(--components-slider-track-filled-error);outline-offset:calc(var(--focus-outline-offset) * 1);background-color:var(--components-slider-handler-background-error)}nv-fieldslider[error] .slider-container .track-container .track .thumb:focus{border-color:var(--components-slider-track-filled-error);outline:calc(var(--focus-outline-stroke) * 1) solid var(--components-slider-track-filled-error);outline-offset:calc(var(--focus-outline-offset) * 1);background-color:var(--components-slider-track-filled-error)}nv-fieldslider[error] .slider-container .track-container:has(.thumb:hover) .track-range{background:var(--components-slider-track-filled-error)}nv-fieldslider[error] .slider-container .track-container:has(.thumb:hover) .thumb{border-color:var(--components-slider-track-filled-error)}nv-fieldmultiselect{--nv-field-border-default:var(--components-form-field-border-default);--nv-field-border-hover:var(--components-form-field-border-hover);--nv-field-border-focus:var(--components-form-field-border-focus);--nv-field-border-disabled:var(--components-form-field-border-default);--nv-field-border-readonly:var(--components-form-field-border-default);--nv-field-focus-box-shadow:var(--color-focus-brand);--nv-field-background:var(--components-form-field-background-default);display:flex;flex-direction:column;align-items:flex-start;gap:var(--form-gap-y);box-sizing:border-box;max-width:480px}nv-fieldmultiselect[fluid]:not([fluid=false]){max-width:unset}nv-fieldmultiselect[readonly]:not([readonly=false]){--nv-field-border-default:var(--components-form-field-border-readonly);--nv-field-border-hover:var(--nv-field-border-default);--nv-field-border-focus:var(--components-form-field-border-focus);--nv-field-border-disabled:var(--nv-field-border-default);--nv-field-border-readonly:var(--nv-field-border-default);--nv-field-background:var(--components-form-field-background-readonly)}nv-fieldmultiselect[error]:not([error=false]){--nv-field-border-default:var(--components-form-field-border-error);--nv-field-border-hover:var(--nv-field-border-default);--nv-field-border-focus:var(--nv-field-border-default);--nv-field-border-disabled:var(--nv-field-border-default);--nv-field-border-readonly:var(--nv-field-border-default);--nv-field-focus-box-shadow:var(--color-focus-destructive-in-field)}nv-fieldmultiselect[required]:not([required=false])>label::after{content:\"*\";color:var(--components-form-text-required);font-weight:700}nv-fieldmultiselect label{display:flex;align-items:center;gap:var(--form-label-gap);align-self:stretch;color:var(--components-form-text-label-default);font-family:\"TT Norms Pro\", sans-serif;font-size:var(--form-label-font-size);font-style:normal;font-weight:500;line-height:var(--form-label-line-height)}nv-fieldmultiselect nv-popover{width:100%;display:block}nv-fieldmultiselect nv-popover [data-scope=popover]{width:100%;padding:var(--list-dropdown-padding);border-radius:var(--list-dropdown-radius);background-color:var(--components-list-dropdown-background);border:1px solid var(--components-list-dropdown-border)}nv-fieldmultiselect nv-popover [slot=content]{gap:var(--list-dropdown-gap-y);display:flex;flex-direction:column}nv-fieldmultiselect nv-popover hr{color:var(--components-list-dropdown-separator)}nv-fieldmultiselect nv-popover div[slot=content]{max-height:calc(90vh - var(--list-dropdown-padding) * 2);overflow-y:auto;position:relative}nv-fieldmultiselect nv-popover div[slot=content]::-webkit-scrollbar{width:6px;height:6px}nv-fieldmultiselect nv-popover div[slot=content]::-webkit-scrollbar-track{background-color:var(--color-level-10-background);border-radius:9999px}nv-fieldmultiselect nv-popover div[slot=content]::-webkit-scrollbar-thumb{background-color:var(--color-gray-200);border-radius:9999px}nv-fieldmultiselect .input-wrapper-multiselect{display:flex;flex-wrap:wrap;gap:var(--form-gap-x);align-items:stretch;align-self:stretch;width:100%}nv-fieldmultiselect .input-container-multiselect{display:flex;flex-grow:1;justify-content:center;align-items:center;align-self:stretch;border-radius:var(--form-field-radius);border-width:1px;border-style:solid;border-color:var(--nv-field-border-default);opacity:var(--components-form-opacity-default, 1);background:var(--nv-field-background);transition:all 150ms ease-out;position:relative;width:100%;min-height:40px;}nv-fieldmultiselect .input-container-multiselect:hover{border-color:var(--nv-field-border-hover)}nv-fieldmultiselect .input-container-multiselect:focus-within,nv-fieldmultiselect .input-container-multiselect:focus-within:hover,nv-fieldmultiselect .input-container-multiselect:focus,nv-fieldmultiselect .input-container-multiselect:focus:hover{border-color:var(--nv-field-border-focus);box-shadow:0px 0px 0px var(--focus-field-stroke) var(--nv-field-focus-box-shadow)}nv-fieldmultiselect .input-container-multiselect:has(input:read-only){opacity:0.5;background-color:var(--components-form-field-background-readonly);border-color:var(--nv-field-border-readonly)}nv-fieldmultiselect .input-container-multiselect:has(input:disabled){opacity:0.5;background-color:var(--components-form-field-background-disabled);border-color:var(--nv-field-border-disabled)}nv-fieldmultiselect .input-container-multiselect>nv-badge{margin-left:var(--form-field-padding-x)}nv-fieldmultiselect .input-container-multiselect input,nv-fieldmultiselect .input-container-multiselect p.non-filterable-text{display:flex;align-items:center;flex:1 0 0;overflow:hidden;background-color:transparent;color:var(--components-form-field-content-text);padding:var(--form-field-padding-y) var(--form-field-padding-x);font-size:var(--form-field-font-size);font-style:normal;font-weight:500;line-height:var(--form-field-line-height);width:100%;width:100%;flex-grow:1;margin:0;min-height:100%;box-sizing:border-box}nv-fieldmultiselect .input-container-multiselect input:focus,nv-fieldmultiselect .input-container-multiselect p.non-filterable-text:focus{outline:none}nv-fieldmultiselect .input-container-multiselect input::placeholder,nv-fieldmultiselect .input-container-multiselect p.non-filterable-text::placeholder{overflow:hidden;color:var(--components-form-field-content-placeholder);text-overflow:ellipsis;font-family:\"TT Norms Pro\", sans-serif;font-size:var(--form-field-font-size);font-style:normal;font-weight:400;line-height:var(--form-field-line-height)}nv-fieldmultiselect .input-container-multiselect input[type=password]::-ms-clear,nv-fieldmultiselect .input-container-multiselect input[type=password]::-ms-reveal,nv-fieldmultiselect .input-container-multiselect p.non-filterable-text[type=password]::-ms-clear,nv-fieldmultiselect .input-container-multiselect p.non-filterable-text[type=password]::-ms-reveal{display:none;width:0;height:0}nv-fieldmultiselect .input-container-multiselect>nv-iconbutton{border:0px;border-radius:0px}nv-fieldmultiselect .input-container-multiselect>nv-iconbutton:focus-visible{border-radius:var(--button-md-border-radius);outline-offset:-3px}nv-fieldmultiselect .input-container-multiselect nv-icon.validation{color:var(--nv-field-border-default)}nv-fieldmultiselect .non-filterable-text{display:block;border-radius:var(--form-field-radius);background-color:var(--nv-field-background);color:var(--components-form-field-content-text);font-size:var(--form-field-font-size);font-weight:500;line-height:var(--form-field-line-height);box-sizing:border-box;cursor:pointer;height:100%;min-height:40px}nv-fieldmultiselect .non-filterable-text span{display:inline-block;width:100%;overflow:hidden;text-overflow:ellipsis}nv-fieldmultiselect .description{display:flex;align-items:center;align-self:stretch;gap:var(--spacing-1);color:var(--components-form-text-description-default);font-family:\"TT Norms Pro\", sans-serif;font-size:var(--form-description-font-size);font-style:normal;line-height:var(--form-description-line-height)}nv-fieldmultiselect .error-description{display:flex;align-items:center;align-self:stretch;gap:var(--spacing-1);color:var(--components-form-text-description-default);font-family:\"TT Norms Pro\", sans-serif;font-size:var(--form-description-font-size);font-style:normal;line-height:var(--form-description-line-height);color:var(--components-form-text-description-error)}.no-results-message{text-align:center;padding:10px;color:var(--components-form-text-description-error)}.multiselect-divider{display:block;width:100%;height:1px;background-color:var(--components-list-dropdown-separator);margin:var(--list-dropdown-item-padding-y) 0;border:0}";
7
+ const nvFieldmultiselectCss = "nv-fieldslider .slider-container .track-container:has(.thumb:hover) .track-range{background:var(--components-slider-track-filled-hover)}nv-fieldslider .slider-container .track-container:has(.thumb:hover) .thumb{border-color:var(--components-slider-track-filled-hover)}nv-fieldslider .slider-container .track-container:has(.thumb:focus) .track-range{background:var(--components-slider-track-filled-focus)}nv-fieldslider .slider-container .track-container:has(.thumb:focus) .thumb{border-color:var(--components-slider-track-filled-focus)}nv-fieldslider[error] .slider-container .track-container .track .track-range{background:var(--components-slider-track-filled-error)}nv-fieldslider[error] .slider-container .track-container .track .thumb{border-color:var(--components-slider-track-filled-error)}nv-fieldslider[error] .slider-container .track-container .track .thumb:hover{border-color:var(--components-slider-track-filled-error);outline:calc(var(--focus-outline-stroke) * 1) solid var(--components-slider-track-filled-error);outline-offset:calc(var(--focus-outline-offset) * 1);background-color:var(--components-slider-handler-background-error)}nv-fieldslider[error] .slider-container .track-container .track .thumb:focus{border-color:var(--components-slider-track-filled-error);outline:calc(var(--focus-outline-stroke) * 1) solid var(--components-slider-track-filled-error);outline-offset:calc(var(--focus-outline-offset) * 1);background-color:var(--components-slider-track-filled-error)}nv-fieldslider[error] .slider-container .track-container:has(.thumb:hover) .track-range{background:var(--components-slider-track-filled-error)}nv-fieldslider[error] .slider-container .track-container:has(.thumb:hover) .thumb{border-color:var(--components-slider-track-filled-error)}nv-fieldslider .slider-container .track-container:has(.thumb:hover) .track-range{background:var(--components-slider-track-filled-hover)}nv-fieldslider .slider-container .track-container:has(.thumb:hover) .thumb{border-color:var(--components-slider-track-filled-hover)}nv-fieldslider .slider-container .track-container:has(.thumb:focus) .track-range{background:var(--components-slider-track-filled-focus)}nv-fieldslider .slider-container .track-container:has(.thumb:focus) .thumb{border-color:var(--components-slider-track-filled-focus)}nv-fieldslider[error] .slider-container .track-container .track .track-range{background:var(--components-slider-track-filled-error)}nv-fieldslider[error] .slider-container .track-container .track .thumb{border-color:var(--components-slider-track-filled-error)}nv-fieldslider[error] .slider-container .track-container .track .thumb:hover{border-color:var(--components-slider-track-filled-error);outline:calc(var(--focus-outline-stroke) * 1) solid var(--components-slider-track-filled-error);outline-offset:calc(var(--focus-outline-offset) * 1);background-color:var(--components-slider-handler-background-error)}nv-fieldslider[error] .slider-container .track-container .track .thumb:focus{border-color:var(--components-slider-track-filled-error);outline:calc(var(--focus-outline-stroke) * 1) solid var(--components-slider-track-filled-error);outline-offset:calc(var(--focus-outline-offset) * 1);background-color:var(--components-slider-track-filled-error)}nv-fieldslider[error] .slider-container .track-container:has(.thumb:hover) .track-range{background:var(--components-slider-track-filled-error)}nv-fieldslider[error] .slider-container .track-container:has(.thumb:hover) .thumb{border-color:var(--components-slider-track-filled-error)}nv-fieldmultiselect{--nv-field-border-default:var(--components-form-field-border-default);--nv-field-border-hover:var(--components-form-field-border-hover);--nv-field-border-focus:var(--components-form-field-border-focus);--nv-field-border-disabled:var(--components-form-field-border-default);--nv-field-border-readonly:var(--components-form-field-border-default);--nv-field-focus-box-shadow:var(--color-focus-brand);--nv-field-background:var(--components-form-field-background-default);display:flex;flex-direction:column;align-items:flex-start;gap:var(--form-gap-y);box-sizing:border-box;max-width:480px}nv-fieldmultiselect[fluid]:not([fluid=false]){max-width:unset}nv-fieldmultiselect[readonly]:not([readonly=false]){--nv-field-border-default:var(--components-form-field-border-readonly);--nv-field-border-hover:var(--nv-field-border-default);--nv-field-border-focus:var(--components-form-field-border-focus);--nv-field-border-disabled:var(--nv-field-border-default);--nv-field-border-readonly:var(--nv-field-border-default);--nv-field-background:var(--components-form-field-background-readonly)}nv-fieldmultiselect[error]:not([error=false]){--nv-field-border-default:var(--components-form-field-border-error);--nv-field-border-hover:var(--nv-field-border-default);--nv-field-border-focus:var(--nv-field-border-default);--nv-field-border-disabled:var(--nv-field-border-default);--nv-field-border-readonly:var(--nv-field-border-default);--nv-field-focus-box-shadow:var(--color-focus-destructive-in-field)}nv-fieldmultiselect[required]:not([required=false]) label::after{content:\"*\";color:var(--components-form-text-required);font-weight:700}nv-fieldmultiselect label{display:flex;align-items:center;gap:var(--form-label-gap);align-self:stretch;color:var(--components-form-text-label-default);font-family:\"TT Norms Pro\", sans-serif;font-size:var(--form-label-font-size);font-style:normal;font-weight:500;line-height:var(--form-label-line-height)}nv-fieldmultiselect nv-popover{width:100%;display:block}nv-fieldmultiselect nv-popover [data-scope=popover]{width:100%;padding:var(--list-dropdown-padding);border-radius:var(--list-dropdown-radius);background-color:var(--components-list-dropdown-background);border:1px solid var(--components-list-dropdown-border)}nv-fieldmultiselect nv-popover [slot=content]{gap:var(--list-dropdown-gap-y);display:flex;flex-direction:column}nv-fieldmultiselect nv-popover hr{color:var(--components-list-dropdown-separator)}nv-fieldmultiselect nv-popover div[slot=content]{max-height:calc(90vh - var(--list-dropdown-padding) * 2);overflow-y:auto;position:relative}nv-fieldmultiselect nv-popover div[slot=content]::-webkit-scrollbar{width:6px;height:6px}nv-fieldmultiselect nv-popover div[slot=content]::-webkit-scrollbar-track{background-color:var(--color-level-10-background);border-radius:9999px}nv-fieldmultiselect nv-popover div[slot=content]::-webkit-scrollbar-thumb{background-color:var(--color-gray-200);border-radius:9999px}nv-fieldmultiselect .input-wrapper-multiselect{display:flex;flex-wrap:wrap;gap:var(--form-gap-x);align-items:stretch;align-self:stretch;width:100%}nv-fieldmultiselect .input-container-multiselect{display:flex;flex-grow:1;justify-content:center;align-items:center;align-self:stretch;border-radius:var(--form-field-radius);border-width:1px;border-style:solid;border-color:var(--nv-field-border-default);opacity:var(--components-form-opacity-default, 1);background:var(--nv-field-background);transition:all 150ms ease-out;position:relative;width:100%;min-height:40px}nv-fieldmultiselect .input-container-multiselect:hover{border-color:var(--nv-field-border-hover)}nv-fieldmultiselect .input-container-multiselect:focus-within,nv-fieldmultiselect .input-container-multiselect:focus-within:hover,nv-fieldmultiselect .input-container-multiselect:focus,nv-fieldmultiselect .input-container-multiselect:focus:hover{border-color:var(--nv-field-border-focus);box-shadow:0px 0px 0px var(--focus-field-stroke) var(--nv-field-focus-box-shadow)}nv-fieldmultiselect .input-container-multiselect:has(input:read-only){opacity:0.5;background-color:var(--components-form-field-background-readonly);border-color:var(--nv-field-border-readonly)}nv-fieldmultiselect .input-container-multiselect:has(input:disabled){opacity:0.5;background-color:var(--components-form-field-background-disabled);border-color:var(--nv-field-border-disabled)}nv-fieldmultiselect .input-container-multiselect>nv-badge{margin-left:var(--form-field-padding-x)}nv-fieldmultiselect .input-container-multiselect input,nv-fieldmultiselect .input-container-multiselect p.non-filterable-text{display:flex;align-items:center;flex:1 0 0;overflow:hidden;background-color:transparent;color:var(--components-form-field-content-text);padding:var(--form-field-padding-y) var(--form-field-padding-x);font-size:var(--form-field-font-size);font-style:normal;font-weight:500;line-height:var(--form-field-line-height);width:100%;width:100%;flex-grow:1;margin:0;min-height:100%;box-sizing:border-box}nv-fieldmultiselect .input-container-multiselect input:focus,nv-fieldmultiselect .input-container-multiselect p.non-filterable-text:focus{outline:none}nv-fieldmultiselect .input-container-multiselect input::placeholder,nv-fieldmultiselect .input-container-multiselect p.non-filterable-text::placeholder{overflow:hidden;color:var(--components-form-field-content-placeholder);text-overflow:ellipsis;font-family:\"TT Norms Pro\", sans-serif;font-size:var(--form-field-font-size);font-style:normal;font-weight:400;line-height:var(--form-field-line-height)}nv-fieldmultiselect .input-container-multiselect input[type=password]::-ms-clear,nv-fieldmultiselect .input-container-multiselect input[type=password]::-ms-reveal,nv-fieldmultiselect .input-container-multiselect p.non-filterable-text[type=password]::-ms-clear,nv-fieldmultiselect .input-container-multiselect p.non-filterable-text[type=password]::-ms-reveal{display:none;width:0;height:0}nv-fieldmultiselect .input-container-multiselect>nv-iconbutton{border:0px;border-radius:0px}nv-fieldmultiselect .input-container-multiselect>nv-iconbutton:focus-visible{border-radius:var(--button-md-border-radius);outline-offset:-3px}nv-fieldmultiselect .input-container-multiselect nv-icon.validation{color:var(--nv-field-border-default)}nv-fieldmultiselect .non-filterable-text{display:block;border-radius:var(--form-field-radius);background-color:var(--nv-field-background);color:var(--components-form-field-content-text);font-size:var(--form-field-font-size);font-weight:500;line-height:var(--form-field-line-height);box-sizing:border-box;cursor:pointer;height:100%;min-height:40px}nv-fieldmultiselect .non-filterable-text span{display:inline-block;width:100%;overflow:hidden;text-overflow:ellipsis}nv-fieldmultiselect .description{display:flex;align-items:center;align-self:stretch;gap:var(--spacing-1);color:var(--components-form-text-description-default);font-family:\"TT Norms Pro\", sans-serif;font-size:var(--form-description-font-size);font-style:normal;line-height:var(--form-description-line-height)}nv-fieldmultiselect .error-description{display:flex;align-items:center;align-self:stretch;gap:var(--spacing-1);color:var(--components-form-text-description-default);font-family:\"TT Norms Pro\", sans-serif;font-size:var(--form-description-font-size);font-style:normal;line-height:var(--form-description-line-height);color:var(--components-form-text-description-error)}.no-results-message{cursor:not-allowed;background-color:unset;color:var(--components-menu-contextual-item-content-disabled);padding:var(--list-dropdown-item-padding-y) var(--list-dropdown-item-padding-x)}.multiselect-divider{display:block;width:100%;height:1px;background-color:var(--components-list-dropdown-separator);margin:var(--list-dropdown-item-padding-y) 0;border:0}.select-all-container{position:sticky;top:0;background-color:var(--components-list-dropdown-background);border-bottom:1px solid var(--components-list-dropdown-separator);padding:var(--list-dropdown-item-padding-y) var(--list-dropdown-item-padding-x);z-index:10;margin-bottom:0}.select-all-container .select-all-header{display:flex;align-items:center;gap:var(--form-field-gap)}.select-all-container .select-all-header nv-fieldcheckbox{flex:1;margin:0}.select-all-container .select-all-header nv-iconbutton,.select-all-container .select-all-header nv-button{flex-shrink:0;margin-left:auto}.select-all-container .select-all-header nv-button{justify-content:center}";
8
8
  const NvFieldmultiselectStyle0 = nvFieldmultiselectCss;
9
9
 
10
10
  const NvFieldmultiselect = class {
@@ -12,8 +12,6 @@ const NvFieldmultiselect = class {
12
12
  index.registerInstance(this, hostRef);
13
13
  this.valueChanged = index.createEvent(this, "valueChanged");
14
14
  this.filterTextChanged = index.createEvent(this, "filterTextChanged");
15
- /****************************************************************************/
16
- //#region PROPERTIES
17
15
  /**
18
16
  * Sets the ID for the input element and the for attribute of the associated
19
17
  * label. If no ID is provided, a random one will be automatically generated
@@ -28,11 +26,6 @@ const NvFieldmultiselect = class {
28
26
  * always type in fresh data.
29
27
  */
30
28
  this.autocomplete = 'off';
31
- /**
32
- * Specifies the selected values of the multiselect field.
33
- * This is the canonical value for the component and is used for form submission.
34
- */
35
- this.value = [];
36
29
  /**
37
30
  * Marks the input field as required.
38
31
  */
@@ -60,13 +53,22 @@ const NvFieldmultiselect = class {
60
53
  */
61
54
  this.open = false;
62
55
  /**
63
- * The text to display when no items match the filter.
56
+ * Allows the field to stretch and fill the entire width of its container.
64
57
  */
65
- this.emptyResult = 'No results found';
58
+ this.fluid = false;
59
+ /**
60
+ * Specifies the selected values of the multiselect field.
61
+ * This is the canonical value for the component and is used for form submission.
62
+ */
63
+ this.value = [];
66
64
  /**
67
65
  * Enables or disables the filtering feature for the multiselect items.
68
66
  */
69
67
  this.filterable = false;
68
+ /**
69
+ * The text to display when no items match the filter.
70
+ */
71
+ this.emptyResult = 'No results found';
70
72
  /**
71
73
  * Delay in milliseconds before the search is triggered when typing in the filter input.
72
74
  * @default 300
@@ -78,10 +80,6 @@ const NvFieldmultiselect = class {
78
80
  * element.
79
81
  */
80
82
  this.autofocus = false;
81
- /**
82
- * Allows the field to stretch and fill the entire width of its container.
83
- */
84
- this.fluid = false;
85
83
  /**
86
84
  * Text for the badge showing the number of selected items.
87
85
  */
@@ -90,6 +88,18 @@ const NvFieldmultiselect = class {
90
88
  * The text entered by the user for filtering multiselect items.
91
89
  */
92
90
  this.filterText = '';
91
+ /**
92
+ * Enables or disables the "Select All / Deselect All" toggle functionality.
93
+ */
94
+ this.enableSelectAll = false;
95
+ /**
96
+ * Text for the "Select All" button.
97
+ */
98
+ this.selectAllLabel = 'Select/deselect all';
99
+ /**
100
+ * Text for the "Deselect All" button.
101
+ */
102
+ this.deselectAllLabel = 'Select/deselect all';
93
103
  //#endregion PROPERTIES
94
104
  /****************************************************************************/
95
105
  //#region STATE
@@ -98,10 +108,22 @@ const NvFieldmultiselect = class {
98
108
  */
99
109
  this.sortedOptions = [];
100
110
  this.isHandlingEscape = false;
111
+ /**
112
+ * Indicates whether the current filter has visible results.
113
+ * Used to control the visibility of the "Select All" button.
114
+ */
115
+ this.hasFilterResults = true;
116
+ /**
117
+ * Controls the visibility of the select all section.
118
+ */
119
+ this.isSelectAllSectionVisible = true;
120
+ // Add the flag to the class
121
+ this.preventBlurClose = false;
101
122
  /**
102
123
  * Handle badge close for options mode.
103
124
  */
104
125
  this.handleBadgeCloseOptions = () => {
126
+ console.info('handleBadgeCloseOptions:', this.value);
105
127
  this.value = [];
106
128
  this.valueChanged.emit(this.value);
107
129
  // Uncheck all elements
@@ -119,6 +141,7 @@ const NvFieldmultiselect = class {
119
141
  * Handle badge close for slots mode.
120
142
  */
121
143
  this.handleBadgeCloseSlots = () => {
144
+ console.info('handleBadgeCloseSlots:', this.value);
122
145
  this.value = [];
123
146
  this.valueChanged.emit(this.value);
124
147
  // Uncheck all elements
@@ -127,8 +150,11 @@ const NvFieldmultiselect = class {
127
150
  item.checked = false;
128
151
  item.style.display = '';
129
152
  });
130
- // Reorder slot content
131
- this.reorderSlotContent();
153
+ // Force DOM update before reordering
154
+ requestAnimationFrame(() => {
155
+ // Reorder slot content
156
+ this.reorderSlotContent();
157
+ });
132
158
  };
133
159
  /**
134
160
  * Handle popover close
@@ -150,12 +176,17 @@ const NvFieldmultiselect = class {
150
176
  this.filterText = '';
151
177
  this.filterTextChanged.emit('');
152
178
  this.resetFilter();
179
+ this.hasFilterResults = true;
153
180
  };
154
181
  /**
155
182
  * Handle input blur for options mode.
156
183
  */
157
184
  this.handleInputBlurOptions = () => {
158
185
  setTimeout(() => {
186
+ if (this.preventBlurClose) {
187
+ this.preventBlurClose = false;
188
+ return; // Don't close the popover
189
+ }
159
190
  if (!this.el.contains(document.activeElement)) {
160
191
  // Close the popover without affecting the divider
161
192
  this.open = false;
@@ -302,6 +333,102 @@ const NvFieldmultiselect = class {
302
333
  }
303
334
  this.open = !this.open;
304
335
  };
336
+ /**
337
+ * Toggles the selection state of all non-disabled options in options mode.
338
+ * Respects filtering by only selecting/deselecting visible items.
339
+ * @param {boolean} selectAll - Whether to select all items (true) or deselect all (false)
340
+ */
341
+ this.toggleSelectAllOptions = (selectAll) => {
342
+ if (!this.options)
343
+ return;
344
+ // Get visible and enabled option values from DOM
345
+ const visibleOptionValues = this.getVisibleEnabledOptionItems();
346
+ console.info('[SelectAll][Options] toggleSelectAllOptions called. selectAll:', selectAll, 'visibleOptionValues:', visibleOptionValues, 'Current value:', this.value);
347
+ if (selectAll) {
348
+ // Select all visible options - merge with existing selections
349
+ this.value = [...new Set([...this.value, ...visibleOptionValues])];
350
+ }
351
+ else {
352
+ // Deselect only the visible options, keep others that might be filtered out
353
+ this.value = this.value.filter(val => !visibleOptionValues.includes(val));
354
+ }
355
+ console.info('[SelectAll][Options] New value after toggle:', this.value);
356
+ // Emit the change event
357
+ this.valueChanged.emit(this.value);
358
+ // Synchronize child components
359
+ this.syncChildComponents();
360
+ // Reorder content to move selected items to top
361
+ this.reorderOptionsContent();
362
+ };
363
+ /**
364
+ * Toggles the selection state of all non-disabled slot items.
365
+ * @param {boolean} selectAll - Whether to select all items (true) or deselect all (false)
366
+ */
367
+ this.toggleSelectAllSlots = (selectAll) => {
368
+ if (this.options)
369
+ return; // Only for slots mode
370
+ // Get visible and enabled items
371
+ const items = this.getVisibleEnabledSlotItems();
372
+ console.info('[SelectAll][Slots] toggleSelectAllSlots called. selectAll:', selectAll, 'visible slot items:', items.map(item => item.getAttribute('value') || item.getAttribute('label')), 'Current value:', this.value);
373
+ if (selectAll) {
374
+ // Select all visible items
375
+ const allActiveValues = items
376
+ .map(item => item.getAttribute('value') || item.getAttribute('label') || '')
377
+ .filter(value => value !== '');
378
+ this.value = [...new Set([...this.value, ...allActiveValues])];
379
+ }
380
+ else {
381
+ // Deselect only the visible items, keep others that might be filtered out
382
+ const visibleValues = items
383
+ .map(item => item.getAttribute('value') || item.getAttribute('label') || '')
384
+ .filter(value => value !== '');
385
+ this.value = this.value.filter(val => !visibleValues.includes(val));
386
+ }
387
+ console.info('[SelectAll][Slots] New value after toggle:', this.value);
388
+ // Emit the change event
389
+ this.valueChanged.emit(this.value);
390
+ // Force synchronization with a small delay to ensure DOM is updated
391
+ requestAnimationFrame(() => {
392
+ this.syncChildComponents();
393
+ this.reorderSlotContent();
394
+ });
395
+ };
396
+ /**
397
+ * Handle click on the select all checkbox in options mode.
398
+ * @param {Event} event - The click event.
399
+ */
400
+ this.handleSelectAllCheckboxOptionsClick = (event) => {
401
+ event.stopPropagation();
402
+ event.preventDefault();
403
+ console.info('[handleSelectAllCheckboxOptionsClick] event:', event);
404
+ const currentState = this.getSelectAllCheckboxStateOptions();
405
+ console.info('[SelectAll][Options] Checkbox clicked. Current state:', currentState, 'Current value:', this.value);
406
+ // Logic to handle the indeterminate state
407
+ // - unchecked → select all
408
+ // - indeterminate → select all (clicking on indeterminate will change to checked)
409
+ // - checked → deselect all
410
+ const shouldSelectAll = currentState === 'unchecked' || currentState === 'indeterminate';
411
+ console.info('[SelectAll][Options] shouldSelectAll:', shouldSelectAll);
412
+ this.toggleSelectAllOptions(shouldSelectAll);
413
+ };
414
+ /**
415
+ * Handle click on the select all checkbox in slots mode.
416
+ * @param {Event} event - The click event.
417
+ */
418
+ this.handleSelectAllCheckboxSlotsClick = (event) => {
419
+ event.stopPropagation();
420
+ event.preventDefault();
421
+ console.info('[handleSelectAllCheckboxSlotsClick] event:', event);
422
+ const currentState = this.getSelectAllCheckboxStateSlots();
423
+ console.info('[SelectAll][Slots] Checkbox clicked. Current state:', currentState, 'Current value:', this.value);
424
+ // Logic to handle the indeterminate state
425
+ // - unchecked → select all
426
+ // - indeterminate → select all (clicking on indeterminate will change to checked)
427
+ // - checked → deselect all
428
+ const shouldSelectAll = currentState === 'unchecked' || currentState === 'indeterminate';
429
+ console.info('[SelectAll][Slots] shouldSelectAll:', shouldSelectAll);
430
+ this.toggleSelectAllSlots(shouldSelectAll);
431
+ };
305
432
  //#endregion METHODS
306
433
  /****************************************************************************/
307
434
  //#region RENDER
@@ -310,35 +437,83 @@ const NvFieldmultiselect = class {
310
437
  * @returns {any} The JSX for options mode
311
438
  */
312
439
  this.renderOptionsMode = () => {
313
- return (index.h(index.Host, { "aria-label": this.label, "aria-expanded": this.open.toString() }, (this.label || this.el.querySelector('[slot="label"]')) && (index.h("label", { htmlFor: this.inputId }, index.h("slot", { name: "label" }, this.label))), index.h("nv-popover", { ref: el => (this.popoverElement = el), triggerMode: "controlled", placement: "bottom-start", open: this.open }, index.h("div", { class: "input-wrapper-multiselect", slot: "trigger" }, index.h("slot", { name: "before-input" }), index.h("div", { class: "input-container-multiselect" }, index.h("slot", { name: "leading-input" }), this.value.length > 0 && (index.h("nv-badge", { slot: "leading-input", "prevent-auto-close": true, color: "10", dismissible: this.value.length > 0, label: `${this.value.length} ${this.badgeLabel}`, "aria-label": `Clear all ${this.value.length} ${this.badgeLabel} items`, onCloseClicked: this.handleBadgeCloseOptions })), this.filterable || this.disabled || this.readonly ? (index.h("input", { type: "text", id: this.inputId, ref: e => (this.inputElement = e), autofocus: this.autofocus, autocomplete: this.autocomplete, placeholder: this.placeholder, name: this.name, value: this.filterText, required: this.required, disabled: this.disabled, readOnly: this.readonly, onInput: this.handleInputOptions, onFocus: this.handleInputFocusOptions, onBlur: this.handleInputBlurOptions, onKeyDown: this.handleKeyDown, "data-scope": "focusable" })) : (index.h("p", { id: this.inputId, class: "non-filterable-text", onClick: this.handleInputContainerClickOptions, tabIndex: 0, onKeyDown: this.handleKeyDown, onFocus: this.handleInputFocusOptions, role: "combobox", "aria-expanded": this.open, "data-scope": "focusable" }, index.h("span", null, this.placeholder))), this.error && (index.h("nv-icon", { name: "alert-circle", class: "validation", size: "md" })), this.filterable && this.filterText.length > 0 && (index.h("nv-iconbutton", { "data-scope": "clear-filter", name: "x", size: "md", emphasis: "lower", tabindex: "-1", onClick: this.clearFilterText, "aria-label": "Clear filter text" })), index.h("nv-iconbutton", { "data-scope": "toggle-dropdown", name: this.open ? 'chevron-top' : 'chevron-down', size: "md", emphasis: "lower", "aria-label": this.open ? 'Hide dropdown' : 'Show dropdown', "aria-pressed": this.open.toString(), onClick: this.togglePopoverOptions })), index.h("slot", { name: "after-input" })), index.h("div", { slot: "content", role: "listbox", "aria-multiselectable": "true", style: this.maxHeight ? { maxHeight: this.maxHeight } : {} }, index.h("ul", { role: "content" }, this.options.map(option => (index.h("nv-fielddropdownitemcheck", { label: option.label, description: option.description, value: option.value, checked: this.value.includes(option.value), disabled: option.disabled }))), index.h("hr", { class: "multiselect-divider", style: { display: 'none' } })))), this.renderDescriptions()));
440
+ return (index.h(index.Host, { "aria-label": this.label }, (this.label || this.el.querySelector('[slot="label"]')) && (index.h("label", { htmlFor: this.inputId }, index.h("slot", { name: "label" }, this.label))), index.h("nv-popover", { ref: el => (this.popoverElement = el), triggerMode: "controlled", placement: "bottom-start", open: this.open }, index.h("div", { class: "input-wrapper-multiselect", slot: "trigger" }, index.h("slot", { name: "before-input" }), index.h("div", { class: "input-container-multiselect" }, index.h("slot", { name: "leading-input" }), this.value.length > 0 && (index.h("nv-badge", { slot: "leading-input", "prevent-auto-close": true, color: "10", dismissible: this.value.length > 0, label: `${this.value.length} ${this.badgeLabel}`, "aria-label": `Clear all ${this.value.length} ${this.badgeLabel} items`, onCloseClicked: this.handleBadgeCloseOptions })), this.filterable || this.disabled || this.readonly ? (index.h("input", { type: "text", id: this.inputId, ref: e => (this.inputElement = e), autofocus: this.autofocus, autocomplete: this.autocomplete, placeholder: this.placeholder, name: this.name, value: this.filterText, required: this.required, disabled: this.disabled, readOnly: this.readonly, onInput: this.handleInputOptions, onFocus: this.handleInputFocusOptions, onBlur: this.handleInputBlurOptions, onKeyDown: this.handleKeyDown, "data-scope": "focusable", "aria-label": this.label, "aria-controls": `${this.inputId}-listbox` })) : (index.h(index.Fragment, null, index.h("input", { id: this.inputId, type: "text", style: {
441
+ position: 'absolute',
442
+ opacity: '0',
443
+ width: '0',
444
+ height: '0',
445
+ pointerEvents: 'none',
446
+ }, tabIndex: -1, "aria-hidden": "true", autoComplete: this.autocomplete, name: this.name, onFocus: this.handleInputFocusOptions }), index.h("p", { id: this.inputId, class: "non-filterable-text", onClick: this.handleInputContainerClickOptions, tabIndex: 0, onKeyDown: this.handleKeyDown, onFocus: this.handleInputFocusOptions, "aria-label": this.label, "aria-controls": `${this.inputId}-listbox`, "data-scope": "focusable", role: "button" }, index.h("span", null, this.placeholder)))), this.error && (index.h("nv-icon", { name: "alert-circle", class: "validation", size: "md" })), this.filterable && this.filterText.length > 0 && (index.h("nv-iconbutton", { "data-scope": "clear-filter", name: "x", size: "md", emphasis: "lower", "aria-label": "Clear filter text", tabindex: "-1", title: "Clear filter text", onMouseDown: () => {
447
+ this.preventBlurClose = true;
448
+ }, onClick: this.clearFilterText })), index.h("nv-iconbutton", { "data-scope": "toggle-dropdown", name: this.open ? 'chevron-top' : 'chevron-down', size: "md", emphasis: "lower", "aria-label": this.open ? 'Hide dropdown' : 'Show dropdown', title: this.open ? 'Hide dropdown' : 'Show dropdown', onMouseDown: () => {
449
+ this.preventBlurClose = true;
450
+ }, onClick: this.togglePopoverOptions })), index.h("slot", { name: "after-input" })), index.h("div", { id: `${this.inputId}-listbox`, slot: "content", style: this.maxHeight ? { maxHeight: this.maxHeight } : {} }, this.shouldShowToggleAllOptionsButton() && (index.h("div", { class: "select-all-container" }, index.h("div", { class: "select-all-header" }, this.isSelectAllSectionVisible && (index.h("nv-fieldcheckbox", { checked: this.getSelectAllCheckboxStateOptions() === 'checked', indeterminate: this.getSelectAllCheckboxStateOptions() ===
451
+ 'indeterminate', label: this.getSelectAllCheckboxStateOptions() === 'unchecked'
452
+ ? this.selectAllLabel
453
+ : this.deselectAllLabel, onMouseDown: () => {
454
+ this.preventBlurClose = true;
455
+ }, onClick: this.handleSelectAllCheckboxOptionsClick }))))), index.h("ul", { role: "listbox", "aria-multiselectable": "true" }, this.options.map(option => (index.h("nv-fielddropdownitemcheck", { role: "option", label: option.label, description: option.description, value: option.value, checked: this.value.includes(option.value), disabled: option.disabled })))))), this.renderDescriptions()));
314
456
  };
315
457
  /**
316
458
  * Renders the component in slots mode
317
459
  * @returns {any} The JSX for slots mode
318
460
  */
319
461
  this.renderSlotsMode = () => {
320
- return (index.h(index.Host, { "aria-label": this.label, "aria-expanded": this.open.toString() }, (this.label || this.el.querySelector('[slot="label"]')) && (index.h("label", { htmlFor: this.inputId }, index.h("slot", { name: "label" }, this.label))), index.h("nv-popover", { ref: el => (this.popoverElement = el), triggerMode: "controlled", placement: "bottom-start", open: this.open }, index.h("div", { class: "input-wrapper-multiselect", slot: "trigger" }, index.h("slot", { name: "before-input" }), index.h("div", { class: "input-container-multiselect", onClick: this.handleInputContainerClickSlots }, index.h("slot", { name: "leading-input" }), this.value.length > 0 && (index.h("nv-badge", { slot: "leading-input", "prevent-auto-close": true, color: "10", dismissible: this.value.length > 0, label: `${this.value.length} ${this.badgeLabel}`, "aria-label": `Clear all ${this.value.length} ${this.badgeLabel} items`, onCloseClicked: this.handleBadgeCloseSlots })), this.filterable || this.disabled || this.readonly ? (index.h("input", { id: this.inputId, ref: e => (this.inputElement = e), autocomplete: this.autocomplete, placeholder: this.placeholder, name: this.name, value: this.filterText, required: this.required, disabled: this.disabled, readOnly: this.readonly, onInput: this.handleInputSlots, onFocus: this.handleInputFocusSlots, onBlur: this.handleInputBlurSlots, onKeyDown: this.handleKeyDown, "data-scope": "focusable" })) : (index.h("p", { id: this.inputId, class: "non-filterable-text", onClick: this.handleInputContainerClickSlots, tabIndex: 0, onKeyDown: this.handleKeyDown, onFocus: this.handleInputFocusSlots, role: "combobox", "aria-expanded": this.open, "data-scope": "focusable" }, index.h("span", null, this.placeholder))), this.error && (index.h("nv-icon", { name: "alert-circle", class: "validation", size: "md" })), this.filterable && this.filterText.length > 0 && (index.h("nv-iconbutton", { name: "x", size: "md", emphasis: "lower", tabindex: "-1", onClick: this.clearFilterText, "aria-label": "Clear filter text" })), index.h("nv-iconbutton", { "data-scope": "toggle-dropdown", name: this.open ? 'chevron-top' : 'chevron-down', size: "md", emphasis: "lower", "aria-label": this.open ? 'Hide dropdown' : 'Show dropdown', "aria-pressed": this.open.toString(), onClick: this.togglePopoverSlots })), index.h("slot", { name: "after-input" })), index.h("div", { slot: "content", role: "listbox", "aria-multiselectable": "true", style: this.maxHeight ? { maxHeight: this.maxHeight } : {} }, index.h("slot", { name: "content" }))), this.renderDescriptions()));
462
+ return (index.h(index.Host, { "aria-label": this.label }, (this.label || this.el.querySelector('[slot="label"]')) && (index.h("label", { htmlFor: this.inputId }, index.h("slot", { name: "label" }, this.label))), index.h("nv-popover", { ref: el => (this.popoverElement = el), triggerMode: "controlled", placement: "bottom-start", open: this.open }, index.h("div", { class: "input-wrapper-multiselect", slot: "trigger" }, index.h("slot", { name: "before-input" }), index.h("div", { class: "input-container-multiselect", onClick: this.handleInputContainerClickSlots }, index.h("slot", { name: "leading-input" }), this.value.length > 0 && (index.h("nv-badge", { slot: "leading-input", "prevent-auto-close": true, color: "10", dismissible: this.value.length > 0, label: `${this.value.length} ${this.badgeLabel}`, "aria-label": `Clear all ${this.value.length} ${this.badgeLabel} items`, onCloseClicked: this.handleBadgeCloseSlots })), this.filterable || this.disabled || this.readonly ? (index.h("input", { id: this.inputId, ref: e => (this.inputElement = e), autocomplete: this.autocomplete, placeholder: this.placeholder, name: this.name, value: this.filterText, required: this.required, disabled: this.disabled, readOnly: this.readonly, onInput: this.handleInputSlots, onFocus: this.handleInputFocusSlots, onBlur: this.handleInputBlurSlots, onKeyDown: this.handleKeyDown, "data-scope": "focusable", "aria-label": this.label, "aria-controls": `${this.inputId}-listbox` })) : (index.h(index.Fragment, null, index.h("input", { id: this.inputId, type: "text", style: {
463
+ position: 'absolute',
464
+ opacity: '0',
465
+ width: '0',
466
+ height: '0',
467
+ pointerEvents: 'none',
468
+ }, tabIndex: -1, "aria-hidden": "true", autoComplete: this.autocomplete, name: this.name, onFocus: this.handleInputFocusSlots }), index.h("p", { id: this.inputId, class: "non-filterable-text", "aria-label": this.label, onClick: this.handleInputContainerClickSlots, tabIndex: 0, onKeyDown: this.handleKeyDown, onFocus: this.handleInputFocusSlots, "aria-controls": `${this.inputId}-listbox`, "data-scope": "focusable", role: "button" }, index.h("span", null, this.placeholder)))), this.error && (index.h("nv-icon", { name: "alert-circle", class: "validation", size: "md" })), this.filterable && this.filterText.length > 0 && (index.h("nv-iconbutton", { name: "x", size: "md", emphasis: "lower", tabindex: "-1", onMouseDown: () => {
469
+ this.preventBlurClose = true;
470
+ }, onClick: this.clearFilterText, "aria-label": "Clear filter text" })), index.h("nv-iconbutton", { "data-scope": "toggle-dropdown", name: this.open ? 'chevron-top' : 'chevron-down', size: "md", emphasis: "lower", "aria-label": this.open ? 'Hide dropdown' : 'Show dropdown', title: this.open ? 'Hide dropdown' : 'Show dropdown', onMouseDown: () => {
471
+ this.preventBlurClose = true;
472
+ }, onClick: this.togglePopoverSlots })), index.h("slot", { name: "after-input" })), index.h("div", { id: `${this.inputId}-listbox`, slot: "content", style: this.maxHeight ? { maxHeight: this.maxHeight } : {} }, this.shouldShowToggleAllSlotButton() && (index.h("div", { class: "select-all-container" }, index.h("div", { class: "select-all-header" }, this.isSelectAllSectionVisible && (index.h("nv-fieldcheckbox", { checked: this.getSelectAllCheckboxStateSlots() === 'checked', indeterminate: this.getSelectAllCheckboxStateSlots() ===
473
+ 'indeterminate', label: this.getSelectAllCheckboxStateSlots() === 'unchecked'
474
+ ? this.selectAllLabel
475
+ : this.deselectAllLabel, onMouseDown: () => {
476
+ this.preventBlurClose = true;
477
+ }, onClick: this.handleSelectAllCheckboxSlotsClick }))))), index.h("slot", { name: "content" }))), this.renderDescriptions()));
321
478
  };
322
479
  }
323
480
  //#endregion EVENTS
324
481
  /****************************************************************************/
325
482
  //#region WATCHERS
326
483
  handleOptionsChange(newValue) {
484
+ console.info('[Watch:options] newValue:', newValue);
485
+ console.info('[Watch:options] current value before update:', this.value);
327
486
  if (!newValue)
328
487
  return;
329
- this.value = newValue
330
- .filter(option => option.checked)
331
- .map(option => option.value);
488
+ // If the parent has set a value prop, use it. Otherwise, derive from checked options.
489
+ // (Assume: if value is undefined, it's not set by parent; if it's an array, it's set.)
490
+ if (this.value === undefined || this.value.length === 0) {
491
+ this.value = newValue
492
+ .filter(option => option.checked)
493
+ .map(option => option.value);
494
+ console.info('[Watch:options] updated value from checked options:', this.value);
495
+ }
496
+ else {
497
+ // If value is set, ensure checked states in options match value
498
+ newValue.forEach(option => {
499
+ option.checked = this.value.includes(option.value);
500
+ });
501
+ console.info('[Watch:options] options checked state synced to value:', newValue);
502
+ }
332
503
  this.reorderOptionsContent();
333
504
  }
334
- /**
335
- * Emitted when the value changes.
336
- */
337
505
  watchValueHandler() {
506
+ console.info('[Watch:value] Value changed:', this.value);
338
507
  // Synchronize child components when value changes programmatically
339
508
  if (this.el && this.el.isConnected) {
340
509
  this.syncChildComponents();
341
510
  }
511
+ // Also, update options checked state if options exist
512
+ if (this.options) {
513
+ this.options.forEach(option => {
514
+ option.checked = this.value.includes(option.value);
515
+ });
516
+ }
342
517
  }
343
518
  //#endregion WATCHERS
344
519
  /****************************************************************************/
@@ -377,6 +552,7 @@ const NvFieldmultiselect = class {
377
552
  return;
378
553
  }
379
554
  const { value, checked } = event.detail;
555
+ console.info('[Event:itemChecked] value:', value, 'checked:', checked, 'current value:', this.value);
380
556
  if (value !== undefined && value !== null) {
381
557
  const newValue = [...this.value];
382
558
  const valueIndex = newValue.indexOf(value);
@@ -386,6 +562,7 @@ const NvFieldmultiselect = class {
386
562
  else if (!checked && valueIndex > -1) {
387
563
  newValue.splice(valueIndex, 1);
388
564
  }
565
+ console.info('[Event:itemChecked] newValue after update:', newValue);
389
566
  // Always update the state and emit the event when an item is checked/unchecked
390
567
  this.value = newValue;
391
568
  this.valueChanged.emit(this.value);
@@ -398,7 +575,7 @@ const NvFieldmultiselect = class {
398
575
  }
399
576
  }
400
577
  else {
401
- console.warn('Received itemChecked event with undefined or null value'); // Warning log
578
+ console.warn('[Event:itemChecked] Received itemChecked event with undefined or null value'); // Warning log
402
579
  }
403
580
  }
404
581
  // Add a listener for the slot content
@@ -420,6 +597,7 @@ const NvFieldmultiselect = class {
420
597
  * Subscribe to click outside event.
421
598
  */
422
599
  connectedCallback() {
600
+ console.info('[Lifecycle] connectedCallback - value:', this.value);
423
601
  document.addEventListener('click', this.handleClickOutside.bind(this));
424
602
  }
425
603
  /**
@@ -427,12 +605,15 @@ const NvFieldmultiselect = class {
427
605
  */
428
606
  componentWillLoad() {
429
607
  var _a;
608
+ console.info('[Lifecycle] componentWillLoad - value:', this.value, 'options:', this.options);
430
609
  // Don't call handleOptionsChange if we are in slots mode
431
610
  if (this.options) {
432
611
  this.handleOptionsChange(this.options);
433
612
  }
434
613
  // Specific initialization for slots mode
435
614
  if (!this.options) {
615
+ // Initialize value from checked slotted children
616
+ this.initializeValueFromSlots();
436
617
  // Use a microtask to ensure DOM is ready
437
618
  Promise.resolve().then(() => {
438
619
  // Synchronize child components
@@ -451,21 +632,30 @@ const NvFieldmultiselect = class {
451
632
  if (!this.filterText) {
452
633
  this.resetFilter();
453
634
  }
635
+ // Initialize filter results state
636
+ this.hasFilterResults = true;
454
637
  }
455
638
  /**
456
639
  * Force reorder if options mode in componentDidLoad because of the initial render not trigger @watch
457
640
  */
458
641
  componentDidLoad() {
642
+ console.info('[Lifecycle] componentDidLoad - value:', this.value, 'options:', this.options);
459
643
  if (this.options) {
460
644
  this.handleOptionsChange(this.options);
461
645
  }
462
646
  // Final synchronization of child components after everything is loaded
463
647
  this.syncChildComponents();
648
+ // For slots mode, ensure value is initialized from checked children if not already
649
+ if (!this.options) {
650
+ this.initializeValueFromSlots();
651
+ this.syncChildComponents();
652
+ }
464
653
  }
465
654
  /**
466
655
  * Unsubscribe from click outside event.
467
656
  */
468
657
  disconnectedCallback() {
658
+ console.info('[Lifecycle] disconnectedCallback - value:', this.value);
469
659
  document.removeEventListener('click', this.handleClickOutside.bind(this));
470
660
  }
471
661
  //#endregion LIFECYCLE
@@ -500,14 +690,67 @@ const NvFieldmultiselect = class {
500
690
  this.manageDivider(ul, selectedItems, unselectedItems);
501
691
  }
502
692
  }
693
+ // Reset filter results state
694
+ this.hasFilterResults = true;
503
695
  }
504
696
  /**
505
697
  * Returns the list of selected values.
506
698
  * @returns {string[]} The selected values.
507
699
  */
508
700
  async getSelectedValues() {
701
+ console.info('getSelectedValues:', this.value);
509
702
  return this.value;
510
703
  }
704
+ /**
705
+ * Select all visible and enabled items.
706
+ * Works for both options and slots mode.
707
+ * @returns {Promise<void>}
708
+ */
709
+ async selectAll() {
710
+ if (this.disabled || this.readonly)
711
+ return;
712
+ if (this.options) {
713
+ this.toggleSelectAllOptions(true);
714
+ }
715
+ else {
716
+ this.toggleSelectAllSlots(true);
717
+ }
718
+ }
719
+ /**
720
+ * Deselect all visible and enabled items.
721
+ * Works for both options and slots mode.
722
+ * @returns {Promise<void>}
723
+ */
724
+ async deselectAll() {
725
+ if (this.disabled || this.readonly)
726
+ return;
727
+ if (this.options) {
728
+ this.toggleSelectAllOptions(false);
729
+ }
730
+ else {
731
+ this.toggleSelectAllSlots(false);
732
+ }
733
+ }
734
+ /**
735
+ * Toggle selection state of all visible and enabled items.
736
+ * If all items are selected, deselects all. Otherwise, selects all.
737
+ * Works for both options and slots mode.
738
+ * @returns {Promise<void>}
739
+ */
740
+ async toggleSelectAll() {
741
+ if (this.disabled || this.readonly)
742
+ return;
743
+ const currentState = this.options
744
+ ? this.getSelectAllCheckboxStateOptions()
745
+ : this.getSelectAllCheckboxStateSlots();
746
+ const shouldSelectAll = currentState === 'unchecked' || currentState === 'indeterminate';
747
+ if (this.options) {
748
+ this.toggleSelectAllOptions(shouldSelectAll);
749
+ }
750
+ else {
751
+ this.toggleSelectAllSlots(shouldSelectAll);
752
+ }
753
+ }
511
754
  /**
512
755
  * Reorder the content of the slot.
513
756
  */
@@ -551,7 +794,7 @@ const NvFieldmultiselect = class {
551
794
  * Reorder the content for options mode with async handling
552
795
  */
553
796
  reorderOptionsContent() {
554
- const ul = this.el.querySelector('ul[role="content"]');
797
+ const ul = this.el.querySelector('ul');
555
798
  if (!ul)
556
799
  return;
557
800
  const items = Array.from(ul.querySelectorAll('nv-fielddropdownitemcheck')).filter(item => item.style.display !== 'none');
@@ -659,6 +902,7 @@ const NvFieldmultiselect = class {
659
902
  this.removeEmptyMessageOption(ul);
660
903
  items.forEach(item => (item.style.display = ''));
661
904
  this.reorderOptionsContent(); // Reorder after reset
905
+ this.hasFilterResults = true; // Reset filter means we have results
662
906
  return;
663
907
  }
664
908
  // Filter the items
@@ -671,6 +915,8 @@ const NvFieldmultiselect = class {
671
915
  if (matchesFilter)
672
916
  hasVisibleItems = true;
673
917
  });
918
+ // Update the filter results state
919
+ this.hasFilterResults = hasVisibleItems;
674
920
  // Manage the divider with the visible items
675
921
  const visibleItems = items.filter(item => item.style.display !== 'none');
676
922
  const visibleSelected = visibleItems.filter(item => this.value.includes(item.getAttribute('value') || ''));
@@ -701,6 +947,7 @@ const NvFieldmultiselect = class {
701
947
  // If filter text is empty, reset all items visibility
702
948
  if (!this.filterText.trim()) {
703
949
  this.resetFilter();
950
+ this.hasFilterResults = true; // Reset filter means we have results
704
951
  return;
705
952
  }
706
953
  const normalizedFilter = this.normalizeText(this.filterText);
@@ -720,6 +967,8 @@ const NvFieldmultiselect = class {
720
967
  if (matchesFilter)
721
968
  hasVisibleItems = true;
722
969
  });
970
+ // Update the filter results state
971
+ this.hasFilterResults = hasVisibleItems;
723
972
  // Get visible items after filtering
724
973
  const visibleItems = items.filter(item => item.style.display !== 'none');
725
974
  const visibleSelectedItems = visibleItems.filter(item => this.value.includes(item.getAttribute('value') || ''));
@@ -930,10 +1179,13 @@ const NvFieldmultiselect = class {
930
1179
  return;
931
1180
  }
932
1181
  const items = Array.from(this.el.querySelectorAll('nv-fielddropdownitemcheck'));
1182
+ console.info('[syncChildComponents] value:', this.value);
933
1183
  items.forEach(item => {
934
1184
  // Get the effective value: use explicit value if present, otherwise use label
935
1185
  const itemValue = item.getAttribute('value') || item.getAttribute('label') || '';
936
- if (this.value.includes(itemValue)) {
1186
+ const shouldBeChecked = this.value.includes(itemValue);
1187
+ console.info('[syncChildComponents] itemValue:', itemValue, 'shouldBeChecked:', shouldBeChecked, 'item.checked(before):', item.checked);
1188
+ if (shouldBeChecked) {
937
1189
  item.setAttribute('checked', '');
938
1190
  item.checked = true;
939
1191
  }
@@ -941,8 +1193,106 @@ const NvFieldmultiselect = class {
941
1193
  item.removeAttribute('checked');
942
1194
  item.checked = false;
943
1195
  }
1196
+ console.info('[syncChildComponents] itemValue:', itemValue, 'item.checked(after):', item.checked);
1197
+ });
1198
+ }
1199
+ /**
1200
+ * Gets visible and enabled slot items using consistent logic.
1201
+ * @returns {Element[]} Array of visible and enabled items
1202
+ */
1203
+ getVisibleEnabledSlotItems() {
1204
+ const allItems = Array.from(this.el.querySelectorAll('nv-fielddropdownitemcheck'));
1205
+ return allItems.filter(item => {
1206
+ const isHidden = item.style.display === 'none';
1207
+ const isDisabled = item.hasAttribute('disabled');
1208
+ return !isHidden && !isDisabled;
944
1209
  });
945
1210
  }
1211
+ /**
1212
+ * Gets visible and enabled option items by checking DOM elements.
1213
+ * @returns {string[]} Array of visible and enabled option values
1214
+ */
1215
+ getVisibleEnabledOptionItems() {
1216
+ const allItems = Array.from(this.el.querySelectorAll('nv-fielddropdownitemcheck'));
1217
+ const visibleItems = allItems.filter(item => {
1218
+ const isHidden = item.style.display === 'none';
1219
+ const isDisabled = item.hasAttribute('disabled');
1220
+ return !isHidden && !isDisabled;
1221
+ });
1222
+ return visibleItems
1223
+ .map(item => item.getAttribute('value') || '')
1224
+ .filter(value => value !== '');
1225
+ }
1226
+ /**
1227
+ * Determines if the toggle all button should be shown in options mode.
1228
+ * @returns {boolean} True if there are visible items and no "No results found" message
1229
+ */
1230
+ shouldShowToggleAllOptionsButton() {
1231
+ if (!this.options)
1232
+ return false; // Only for options mode
1233
+ return this.enableSelectAll && this.hasFilterResults;
1234
+ }
1235
+ /**
1236
+ * Gets the checkbox state for the select all checkbox in options mode.
1237
+ * @returns {'checked' | 'unchecked' | 'indeterminate'} The checkbox state
1238
+ */
1239
+ getSelectAllCheckboxStateOptions() {
1240
+ if (!this.options)
1241
+ return 'unchecked';
1242
+ // Get visible and enabled option values from DOM
1243
+ const visibleOptionValues = this.getVisibleEnabledOptionItems();
1244
+ if (visibleOptionValues.length === 0)
1245
+ return 'unchecked';
1246
+ const selectedVisibleOptions = visibleOptionValues.filter(value => this.value.includes(value));
1247
+ if (selectedVisibleOptions.length === 0)
1248
+ return 'unchecked';
1249
+ if (selectedVisibleOptions.length === visibleOptionValues.length)
1250
+ return 'checked';
1251
+ return 'indeterminate';
1252
+ }
1253
+ /**
1254
+ * Gets the checkbox state for the select all checkbox in slots mode.
1255
+ * @returns {'checked' | 'unchecked' | 'indeterminate'} The checkbox state
1256
+ */
1257
+ getSelectAllCheckboxStateSlots() {
1258
+ if (this.options)
1259
+ return 'unchecked';
1260
+ // Get all visible and enabled items
1261
+ const items = this.getVisibleEnabledSlotItems();
1262
+ if (items.length === 0)
1263
+ return 'unchecked';
1264
+ const selectedItems = items.filter(item => {
1265
+ const itemValue = item.getAttribute('value') || item.getAttribute('label') || '';
1266
+ return itemValue !== '' && this.value.includes(itemValue);
1267
+ });
1268
+ if (selectedItems.length === 0)
1269
+ return 'unchecked';
1270
+ if (selectedItems.length === items.length)
1271
+ return 'checked';
1272
+ return 'indeterminate';
1273
+ }
1274
+ /**
1275
+ * Determines if the toggle all button should be shown in slots mode.
1276
+ * @returns {boolean} True if there are visible items and no "No results found" message
1277
+ */
1278
+ shouldShowToggleAllSlotButton() {
1279
+ if (this.options)
1280
+ return false; // Only for slots mode
1281
+ return this.enableSelectAll && this.hasFilterResults;
1282
+ }
1283
+ /**
1284
+ * Initializes the value array from checked slotted nv-fielddropdownitemcheck elements (slots mode only).
1285
+ */
1286
+ initializeValueFromSlots() {
1287
+ const items = Array.from(this.el.querySelectorAll('nv-fielddropdownitemcheck'));
1288
+ // Values from checked slot children
1289
+ const checkedValues = items
1290
+ .filter(item => item.hasAttribute('checked'))
1291
+ .map(item => item.getAttribute('value') || item.getAttribute('label') || '');
1292
+ // Combine with current this.value (set by code), ensuring uniqueness
1293
+ this.value = Array.from(new Set([...(this.value || []), ...checkedValues]));
1294
+ console.info('[initializeValueFromSlots] checkedValues:', checkedValues, 'combined value:', this.value);
1295
+ }
946
1296
  /**
947
1297
  * Renders description and error description sections
948
1298
  * @returns {any} The JSX for descriptions