@nova-design-system/nova-react 3.22.0 → 3.24.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 (91) hide show
  1. package/dist/cjs/_commonjsHelpers-B85MJLTf-CFO10eej.js +7 -0
  2. package/dist/cjs/{collapse.animation-6e0b08df-AHWzNGm_.js → collapse.animation-DZDm0vSK-C2TOIhIK.js} +3 -3
  3. package/dist/cjs/events.utils-B6GgGra--01N__3wY.js +23 -0
  4. package/dist/cjs/{fade.animation-9b939939-DV--bM4S.js → fade.animation-DcRL9lcm-DAZeHoKN.js} +75 -75
  5. package/dist/cjs/generated/components.server.js +292 -50
  6. package/dist/cjs/{grow.animation-24ad5cf8-LUp_ITEx.js → grow.animation-D7ep_aVl-BuXEDSK-.js} +5 -26
  7. package/dist/cjs/i18n.utils-IlwlcG9l-ku0bScip.js +2494 -0
  8. package/dist/cjs/{index-WPRkQD3O.js → index-kU2nW5aN.js} +12692 -7009
  9. package/dist/cjs/{nv-dialog.entry-CDSK9pUH.js → index.esm-D3eWMME9-CG1TVKfu.js} +1 -296
  10. package/dist/cjs/index.js +15 -1
  11. package/dist/cjs/inputmask-CSo292ul-DlvupPk6.js +3758 -0
  12. package/dist/cjs/{nv-accordion-item.entry-BuTvA6w9.js → nv-accordion-item.entry-Bu1tAcCq.js} +11 -10
  13. package/dist/cjs/{nv-accordion.entry-Dtsfw6He.js → nv-accordion.entry-jWjLdX8w.js} +9 -11
  14. package/dist/cjs/{nv-alert.entry-TIdfdU7Y.js → nv-alert.entry-E9ZJay_K.js} +22 -23
  15. package/dist/cjs/{nv-avatar.entry-CaxrhPuw.js → nv-avatar.entry-CUX7u0kR.js} +11 -11
  16. package/dist/cjs/{nv-badge_2.entry-CfYvTZxX.js → nv-badge_2.entry-bxpV5gxE.js} +24 -24
  17. package/dist/cjs/{nv-breadcrumb.entry-BCZ4MmfD.js → nv-breadcrumb.entry-Cbbb9Qeh.js} +5 -5
  18. package/dist/cjs/{nv-breadcrumbs.entry-DwzCE7F6.js → nv-breadcrumbs.entry-BTqnp9zO.js} +3 -3
  19. package/dist/cjs/{nv-button.entry-Cr_86bcZ.js → nv-button.entry-upWH19y6.js} +12 -14
  20. package/dist/cjs/{nv-buttongroup.entry-CWjRoHY1.js → nv-buttongroup.entry-CuZCRsnV.js} +3 -3
  21. package/dist/cjs/{nv-calendar.entry-CXfwNt6G.js → nv-calendar.entry-CT3mASW6.js} +113 -97
  22. package/dist/cjs/{nv-col.entry-CJLDS3LY.js → nv-col.entry--pCxkaTh.js} +5 -5
  23. package/dist/cjs/{nv-datagrid.entry-Cns8XSud.js → nv-datagrid.entry-CGCEhO8C.js} +80 -85
  24. package/dist/cjs/{nv-datagridcolumn.entry-CFFAipHF.js → nv-datagridcolumn.entry-Fsqc7CT_.js} +2 -1
  25. package/dist/cjs/nv-dialog.entry-B6OYcZxQ.js +300 -0
  26. package/dist/cjs/{nv-dialogfooter_2.entry-To_dGUn4.js → nv-dialogfooter_2.entry-C4fP_n2-.js} +10 -11
  27. package/dist/cjs/nv-drawer.entry-C5O4KvHU.js +445 -0
  28. package/dist/cjs/nv-drawerfooter_2.entry-C-reYJXG.js +146 -0
  29. package/dist/cjs/nv-fieldcheckbox.entry-bk7UNQny.js +177 -0
  30. package/dist/cjs/{nv-fielddate.entry-C3pXtMHL.js → nv-fielddate.entry-dqZDBVmm.js} +89 -46
  31. package/dist/cjs/{nv-fielddaterange.entry-CjVVPEK_.js → nv-fielddaterange.entry-wNRasXky.js} +151 -103
  32. package/dist/cjs/nv-fielddropdown.entry-BA15piWa.js +678 -0
  33. package/dist/cjs/{nv-fielddropdownitem.entry-Dah-PaE8.js → nv-fielddropdownitem.entry-DEWaf9dC.js} +7 -7
  34. package/dist/cjs/{nv-fieldmultiselect.entry-BMLjhqoJ.js → nv-fieldmultiselect.entry-BWY5xOAd.js} +343 -236
  35. package/dist/cjs/nv-fieldnumber.entry-DoYORd0d.js +187 -0
  36. package/dist/cjs/nv-fieldpassword.entry-CPaLj9aD.js +165 -0
  37. package/dist/cjs/{nv-fieldradio.entry-X_2VT1Dj.js → nv-fieldradio.entry-CvUmEaCa.js} +11 -11
  38. package/dist/cjs/{nv-fieldselect.entry-pSp-2rNn.js → nv-fieldselect.entry-uUIZ6hmN.js} +52 -13
  39. package/dist/cjs/{nv-fieldslider.entry-pZf7zzLU.js → nv-fieldslider.entry-DnvmxxYY.js} +16 -31
  40. package/dist/cjs/nv-fieldtext.entry-BYAJp3n_.js +163 -0
  41. package/dist/cjs/{nv-fieldtextarea.entry-t3Ixxi23.js → nv-fieldtextarea.entry-DU2bWYeg.js} +52 -14
  42. package/dist/cjs/{nv-fieldtime.entry-DY7D5_6K.js → nv-fieldtime.entry-DlMNDTht.js} +128 -84
  43. package/dist/cjs/{nv-icon.entry-6oYPSf4c.js → nv-icon.entry-CnUkRzaA.js} +12 -12
  44. package/dist/cjs/{nv-iconbutton_2.entry-ChULGovr.js → nv-iconbutton_2.entry-hqp4AcRq.js} +10 -12
  45. package/dist/cjs/{nv-menu.entry-sd0tatWq.js → nv-menu.entry-Dc_FvIx7.js} +18 -32
  46. package/dist/cjs/{nv-menuitem.entry-CCOqR7UF.js → nv-menuitem.entry-DzMhx6c_.js} +6 -5
  47. package/dist/cjs/nv-notification-bullet.entry-BwhHCMQF.js +76 -0
  48. package/dist/cjs/{nv-notification.entry-Cc3zE3yY.js → nv-notification.entry-C3m5p5BL.js} +42 -128
  49. package/dist/cjs/{nv-notificationcontainer.entry-DV4D6oOH.js → nv-notificationcontainer.entry-DTRNn7VE.js} +4 -4
  50. package/dist/cjs/{nv-popover.entry-DQSwI2jT.js → nv-popover.entry-B0c-2rO4.js} +51 -47
  51. package/dist/cjs/{nv-row.entry-UUuMSAY5.js → nv-row.entry-CdcjVGZv.js} +4 -4
  52. package/dist/cjs/nv-sidebar.entry-CiN813gQ.js +177 -0
  53. package/dist/cjs/nv-sidebarcontent.entry-D9hpAhK8.js +22 -0
  54. package/dist/cjs/nv-sidebardivider.entry-B4EMyca5.js +22 -0
  55. package/dist/cjs/nv-sidebarfooter.entry-CHi4qOFe.js +22 -0
  56. package/dist/cjs/nv-sidebargroup.entry-RVqrsyIU.js +23 -0
  57. package/dist/cjs/nv-sidebarheader.entry-_7ch0O3G.js +22 -0
  58. package/dist/cjs/nv-sidebarlogo.entry-Ch9F-JnT.js +32 -0
  59. package/dist/cjs/nv-sidebarnavitem.entry-DVrafSMr.js +296 -0
  60. package/dist/cjs/nv-sidebarnavsubitem.entry-C0XDAzma.js +35 -0
  61. package/dist/cjs/{nv-split.entry-CYP2bTTM.js → nv-split.entry-0HTslRAX.js} +47 -45
  62. package/dist/cjs/{nv-stack.entry-D35-75Vw.js → nv-stack.entry-CqO7uTQf.js} +5 -5
  63. package/dist/cjs/{nv-table.entry-DevWJBnL.js → nv-table.entry-DH85n8Mc.js} +9 -11
  64. package/dist/cjs/{nv-tableheader.entry-Hs7nUSOC.js → nv-tableheader.entry-CKfocdxD.js} +7 -7
  65. package/dist/cjs/{nv-toggle.entry-Eje9d--6.js → nv-toggle.entry-BHUl76Im.js} +9 -9
  66. package/dist/cjs/nv-togglebutton.entry-D_9COjY-.js +67 -0
  67. package/dist/cjs/{nv-togglebuttongroup.entry-CWN_Ucry.js → nv-togglebuttongroup.entry-C0NLbsq7.js} +10 -8
  68. package/dist/cjs/{nv-tooltip.entry-BGkKDEFg.js → nv-tooltip.entry-BfViGE_U.js} +5 -5
  69. package/dist/cjs/slide.animation-CmH5d1of-BZuw607U.js +90 -0
  70. package/dist/cjs/{style-value-types.es-f5d10b79-D0QCM8OB.js → style-value-types.es-xlgmw4x8-B1vLqX9m.js} +6 -3
  71. package/dist/cjs/{v4-a79185f4-2n0dOd_Y.js → v4-BdYh22OP-C1vaJ4yP.js} +1 -1
  72. package/dist/components/NvDatatable/NvDatatable.js +40 -24
  73. package/dist/generated/components.js +107 -0
  74. package/dist/generated/components.server.js +260 -50
  75. package/dist/providers/NotificationProvider.js +3 -4
  76. package/dist/types/components/NvDatatable/NvDatatable.d.ts +1 -1
  77. package/dist/types/components/NvDatatable/types.d.ts +8 -3
  78. package/dist/types/generated/components.d.ts +46 -0
  79. package/dist/types/generated/components.server.d.ts +46 -0
  80. package/package.json +2 -2
  81. package/dist/cjs/_commonjsHelpers-1789f0cf-BJu3ubxk.js +0 -10
  82. package/dist/cjs/inputmask-edcad3c1-B9Omti4z.js +0 -3749
  83. package/dist/cjs/nv-fieldcheckbox.entry-fdonR07Z.js +0 -138
  84. package/dist/cjs/nv-fielddropdown.entry-C9mXuNNj.js +0 -392
  85. package/dist/cjs/nv-fieldnumber.entry-DBdJviXu.js +0 -148
  86. package/dist/cjs/nv-fieldpassword.entry-Cim_usSM.js +0 -122
  87. package/dist/cjs/nv-fieldtext.entry-DlI_ExaV.js +0 -124
  88. package/dist/cjs/nv-togglebutton.entry-LGI7pIeK.js +0 -56
  89. /package/dist/cjs/{clsx-297c1ffe-BtxeOLZW.js → clsx-ChV9xqsO-BtxeOLZW.js} +0 -0
  90. /package/dist/cjs/{constants-69bafca2-DpB_ghPF.js → constants-BReL3Lsa-DpB_ghPF.js} +0 -0
  91. /package/dist/cjs/{timeline.animation-79215cd4-KteJaZPb.js → timeline.animation-CgHCo_Ho-KteJaZPb.js} +0 -0
@@ -1,28 +1,37 @@
1
1
  'use strict';
2
2
 
3
- var index = require('./index-WPRkQD3O.js');
4
- var v4A79185f4 = require('./v4-a79185f4-2n0dOd_Y.js');
3
+ var index = require('./index-kU2nW5aN.js');
4
+ var i18n_utilsIlwlcG9l = require('./i18n.utils-IlwlcG9l-ku0bScip.js');
5
+ var v4BdYh22OP = require('./v4-BdYh22OP-C1vaJ4yP.js');
6
+ require('@stencil/react-output-target/runtime');
5
7
  require('react');
6
8
  require('react-dom');
7
9
 
8
- 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:var(--font-weight-high-emphasis)}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:var(--font-family-default), var(--font-family-fallback), sans-serif;font-size:var(--form-label-font-size);font-style:normal;font-weight:var(--font-weight-medium-emphasis);line-height:var(--form-label-line-height)}nv-fieldmultiselect nv-popover{width:100%;display:block}nv-fieldmultiselect nv-popover [data-scope=popover]{min-width:100%;width:max-content;max-width:400px;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:var(--font-weight-medium-emphasis);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:var(--font-family-default), var(--font-family-fallback), sans-serif;font-size:var(--form-field-font-size);font-style:normal;font-weight:var(--font-weight-low-emphasis);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-iconbutton:last-of-type{border-top-right-radius:var(--form-field-radius);border-bottom-right-radius:var(--form-field-radius)}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:var(--font-weight-medium-emphasis);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:var(--font-family-default), var(--font-family-fallback), 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:var(--font-family-default), var(--font-family-fallback), 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}";
9
- const NvFieldmultiselectStyle0 = nvFieldmultiselectCss;
10
+ 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,nv-fieldmultiselect[aria-required=true] label::after{content:\"*\";color:var(--components-form-text-required);font-weight:var(--font-weight-high-emphasis)}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:var(--font-family-default), var(--font-family-fallback), sans-serif;font-size:var(--form-label-font-size);font-style:normal;font-weight:var(--font-weight-medium-emphasis);line-height:var(--form-label-line-height)}nv-fieldmultiselect nv-popover{width:100%;display:block}nv-fieldmultiselect nv-popover [data-scope=popover]{min-width:100%;width:max-content;max-width:400px;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]::-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 nv-popover div[slot=content]{max-height:calc(90vh - var(--list-dropdown-padding) * 2);overflow-y:auto;position:relative}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}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){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{position:relative;width:100%;min-height:40px}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:calc(var(--form-field-padding-y) - 1px) var(--form-field-padding-x);font-size:var(--form-field-font-size);font-style:normal;font-weight:var(--font-weight-medium-emphasis);line-height:var(--form-field-line-height);width:100%}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:var(--font-family-default), var(--font-family-fallback), sans-serif;font-size:var(--form-field-font-size);font-style:normal;font-weight:var(--font-weight-low-emphasis);line-height:var(--form-field-line-height)}nv-fieldmultiselect .input-container-multiselect input,nv-fieldmultiselect .input-container-multiselect p.non-filterable-text{}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 input,nv-fieldmultiselect .input-container-multiselect p.non-filterable-text{width:100%;flex-grow:1;margin:0;min-height:100%;box-sizing:border-box}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-iconbutton:last-of-type{border-top-right-radius:var(--form-field-radius);border-bottom-right-radius:var(--form-field-radius)}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:var(--font-weight-medium-emphasis);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:var(--font-family-default), var(--font-family-fallback), 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:var(--font-family-default), var(--font-family-fallback), 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}";
10
11
 
11
12
  const NvFieldmultiselect = class {
12
13
  constructor(hostRef) {
13
14
  index.registerInstance(this, hostRef);
14
- this.valueChanged = index.createEvent(this, "valueChanged");
15
- this.filterTextChanged = index.createEvent(this, "filterTextChanged");
15
+ this.valueChanged = index.createEvent(this, "valueChanged", 3);
16
+ this.filterTextChanged = index.createEvent(this, "filterTextChanged", 3);
16
17
  this.isBulkOperation = false;
17
18
  // Add the flag to the class
18
19
  this.preventBlurClose = false;
20
+ /** Pre-computed search index for efficient filtering */
21
+ this.indexedItems = [];
22
+ /** Raw items for worker initialization */
23
+ this.rawItems = [];
24
+ /** Web Worker client for async search operations */
25
+ this.workerClient = null;
26
+ /** Effective filter mode (may differ from prop if fuzzy falls back to smart) */
27
+ this.effectiveFilterMode = 'strict';
19
28
  /**
20
29
  * Sets the ID for the input element and the for attribute of the associated
21
30
  * label. If no ID is provided, a random one will be automatically generated
22
31
  * to ensure unique identification, facilitating proper label association and
23
32
  * accessibility.
24
33
  */
25
- this.inputId = v4A79185f4.v4();
34
+ this.inputId = v4BdYh22OP.v4();
26
35
  /**
27
36
  * The autocomplete prop helps users fill out the input field faster by
28
37
  * suggesting entries they've used before, like their email or address.
@@ -32,8 +41,18 @@ const NvFieldmultiselect = class {
32
41
  this.autocomplete = 'off';
33
42
  /**
34
43
  * Marks the input field as required.
44
+ * @note This uses the native HTML `required` attribute, which triggers browser validation.
35
45
  */
36
46
  this.required = false;
47
+ /**
48
+ * Marks the input field as required for accessibility purposes without triggering
49
+ * native HTML validation. Use this when implementing custom validation logic.
50
+ * @note When set, this uses `aria-required` instead of the native `required` attribute.
51
+ * This allows developers to implement custom validation while maintaining accessibility.
52
+ * @note If this prop is not explicitly set, the component will check for the HTML attribute
53
+ * 'aria-required' directly to determine if it should be applied.
54
+ */
55
+ this.ariaRequiredAttr = false;
37
56
  /**
38
57
  * Display the input field's content without allowing users to change it.
39
58
  */
@@ -104,6 +123,39 @@ const NvFieldmultiselect = class {
104
123
  * Text for the "Deselect All" button.
105
124
  */
106
125
  this.deselectAllLabel = 'Select/deselect all';
126
+ /**
127
+ * Filter mode for multiselect search:
128
+ * - 'strict': Simple substring matching (normalized includes)
129
+ * - 'smart': Token-based matching (all query tokens must exist, order ignored)
130
+ * - 'fuzzy': Typo-tolerant matching using Fuse.js (runs in Web Worker)
131
+ * @default 'strict'
132
+ */
133
+ this.filterMode = 'strict';
134
+ /**
135
+ * Maximum number of results to display. Protects UI performance on large datasets.
136
+ * Values are clamped between 10 and 500 (hard cap).
137
+ * @default 25
138
+ */
139
+ this.maxResults = 25;
140
+ /**
141
+ * Minimum number of characters required before filtering starts.
142
+ * Useful for preventing overwhelming results on very large datasets.
143
+ * @default 0
144
+ */
145
+ this.startFilterAt = 0;
146
+ /**
147
+ * Number of items above which filtering is offloaded to a Web Worker.
148
+ * This keeps the main thread responsive for large datasets.
149
+ * @default 2000
150
+ */
151
+ this.workerThreshold = 2000;
152
+ /**
153
+ * Threshold for fuzzy matching (0-1). Lower values are stricter.
154
+ * Only applies when filterMode is 'fuzzy'.
155
+ * @default 0.3
156
+ * @see {@link https://fusejs.io/api/options.html#threshold} Fuse.js threshold documentation
157
+ */
158
+ this.fuzzyThreshold = 0.3;
107
159
  //#endregion PROPERTIES
108
160
  /****************************************************************************/
109
161
  //#region STATE
@@ -121,6 +173,19 @@ const NvFieldmultiselect = class {
121
173
  * Controls the visibility of the select all section.
122
174
  */
123
175
  this.isSelectAllSectionVisible = true;
176
+ /**
177
+ * Whether search results were truncated due to maxResults limit.
178
+ */
179
+ this.resultsTruncated = false;
180
+ /**
181
+ * Total number of matches before truncation.
182
+ */
183
+ this.totalResults = 0;
184
+ /**
185
+ * Whether a worker search is in progress.
186
+ */
187
+ this.isSearching = false;
188
+ // (filterItems handles both options and slots mode)
124
189
  /**
125
190
  * Handle badge close for options mode.
126
191
  */
@@ -255,7 +320,7 @@ const NvFieldmultiselect = class {
255
320
  }
256
321
  // Set a new timer for filtering
257
322
  this.debounceTimer = window.setTimeout(() => {
258
- this.filterItemsOption();
323
+ void this.filterItems();
259
324
  }, this.debounceDelay);
260
325
  };
261
326
  /**
@@ -276,7 +341,7 @@ const NvFieldmultiselect = class {
276
341
  }
277
342
  // Set a new timer for filtering
278
343
  this.debounceTimer = window.setTimeout(() => {
279
- this.filterSlotsItems();
344
+ void this.filterItems();
280
345
  }, this.debounceDelay);
281
346
  };
282
347
  /**
@@ -447,8 +512,12 @@ const NvFieldmultiselect = class {
447
512
  * @returns {any} The JSX for options mode
448
513
  */
449
514
  this.renderOptionsMode = () => {
450
- var _a, _b, _c, _d;
451
- 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" }), (((_a = this.value) === null || _a === void 0 ? void 0 : _a.length) || 0) > 0 && (index.h("nv-badge", { slot: "leading-input", "prevent-auto-close": true, color: "10", dismissible: (((_b = this.value) === null || _b === void 0 ? void 0 : _b.length) || 0) > 0, label: `${((_c = this.value) === null || _c === void 0 ? void 0 : _c.length) || 0} ${this.badgeLabel}`, "aria-label": `Clear all ${((_d = this.value) === null || _d === void 0 ? void 0 : _d.length) || 0} ${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: {
515
+ 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, onOpenChanged: this.handleOpenChanged }, 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) > 0 && (index.h("nv-badge", { slot: "leading-input", "prevent-auto-close": true, color: "10", dismissible: (this.value?.length || 0) > 0, label: `${this.value?.length || 0} ${this.badgeLabel}`, "aria-label": `Clear all ${this.value?.length || 0} ${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.getRequiredAttributes().useNativeRequired
516
+ ? this.required
517
+ : undefined, ...(this.getRequiredAttributes().ariaRequiredValue !==
518
+ undefined && {
519
+ 'aria-required': String(this.getRequiredAttributes().ariaRequiredValue),
520
+ }), 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: {
452
521
  position: 'absolute',
453
522
  opacity: '0',
454
523
  width: '0',
@@ -464,8 +533,12 @@ const NvFieldmultiselect = class {
464
533
  * @returns {any} The JSX for slots mode
465
534
  */
466
535
  this.renderSlotsMode = () => {
467
- var _a, _b, _c, _d;
468
- 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" }), (((_a = this.value) === null || _a === void 0 ? void 0 : _a.length) || 0) > 0 && (index.h("nv-badge", { slot: "leading-input", "prevent-auto-close": true, color: "10", dismissible: (((_b = this.value) === null || _b === void 0 ? void 0 : _b.length) || 0) > 0, label: `${((_c = this.value) === null || _c === void 0 ? void 0 : _c.length) || 0} ${this.badgeLabel}`, "aria-label": `Clear all ${((_d = this.value) === null || _d === void 0 ? void 0 : _d.length) || 0} ${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: {
536
+ 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) > 0 && (index.h("nv-badge", { slot: "leading-input", "prevent-auto-close": true, color: "10", dismissible: (this.value?.length || 0) > 0, label: `${this.value?.length || 0} ${this.badgeLabel}`, "aria-label": `Clear all ${this.value?.length || 0} ${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.getRequiredAttributes().useNativeRequired
537
+ ? this.required
538
+ : undefined, ...(this.getRequiredAttributes().ariaRequiredValue !==
539
+ undefined && {
540
+ 'aria-required': String(this.getRequiredAttributes().ariaRequiredValue),
541
+ }), 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: {
469
542
  position: 'absolute',
470
543
  opacity: '0',
471
544
  width: '0',
@@ -531,46 +604,13 @@ const NvFieldmultiselect = class {
531
604
  //#endregion WATCHERS
532
605
  /****************************************************************************/
533
606
  //#region LISTENERS
534
- /**
535
- * Emitted when the input loses focus.
536
- * @param {CustomEvent<boolean>} event - The event object containing the focus state.
537
- */
538
- handleOpenChanged(event) {
539
- // Stop propagation to prevent the event from affecting parent components like dialogs
540
- event.stopPropagation();
541
- // Only update if the event comes from our popover
542
- if (event.target === this.popoverElement) {
543
- // Only update if open state differs to avoid redundant actions
544
- if (this.open !== event.detail) {
545
- this.open = event.detail;
546
- if (this.open) {
547
- // Filter items only if there is filter text
548
- if (this.filterText) {
549
- this.filterItems();
550
- }
551
- }
552
- else {
553
- // Clear filter text on close if filterable
554
- if (this.filterable) {
555
- this.clearFilterText();
556
- }
557
- this.handlePopoverClose();
558
- }
559
- // Reorder content as needed
560
- if (this.options) {
561
- this.reorderOptionsContent();
562
- }
563
- else {
564
- this.reorderSlotContent();
565
- }
566
- }
567
- }
568
- }
607
+ /* eslint-disable nova/native-event-listener */
569
608
  /**
570
609
  * Listen for the `itemChecked` event emitted by child items.
571
610
  * @param {CustomEvent} event - The event object containing the selected value and its checked state.
572
611
  */
573
612
  handleItemChecked(event) {
613
+ event.stopPropagation();
574
614
  if (this.disabled || this.readonly || this.isBulkOperation) {
575
615
  // Skip processing itemChecked events during bulk operations
576
616
  return;
@@ -602,6 +642,7 @@ const NvFieldmultiselect = class {
602
642
  console.warn('[Event:itemChecked] Received itemChecked event with undefined or null value'); // Warning log
603
643
  }
604
644
  }
645
+ /* eslint-enable nova/native-event-listener */
605
646
  // Add a listener for the slot content
606
647
  handleSlotChange(event) {
607
648
  // Check: we only want to reorder if it's the "content" slot
@@ -715,7 +756,6 @@ const NvFieldmultiselect = class {
715
756
  * Set the mode state and handle options change.
716
757
  */
717
758
  componentWillLoad() {
718
- var _a;
719
759
  // Don't call handleOptionsChange if we are in slots mode
720
760
  if (this.options) {
721
761
  this.handleOptionsChange(this.options);
@@ -736,7 +776,7 @@ const NvFieldmultiselect = class {
736
776
  }
737
777
  // Initialize the sorted options array with the parsed options for initial rendering
738
778
  if (this.options) {
739
- this.sortedOptions = [...((_a = this.options) !== null && _a !== void 0 ? _a : [])];
779
+ this.sortedOptions = [...(this.options ?? [])];
740
780
  }
741
781
  // Reset filter if needed
742
782
  if (!this.filterText) {
@@ -759,14 +799,17 @@ const NvFieldmultiselect = class {
759
799
  this.initializeValueFromSlots();
760
800
  this.syncChildComponents();
761
801
  }
802
+ // Build the search index on load
803
+ this.rebuildSearchIndex();
762
804
  }
763
805
  /**
764
- * Unsubscribe from click outside event.
806
+ * Unsubscribe from click outside event and clean up worker.
765
807
  */
766
808
  disconnectedCallback() {
767
809
  if (this._boundHandleClickOutside) {
768
810
  document.removeEventListener('click', this._boundHandleClickOutside);
769
811
  }
812
+ this.terminateSearchWorker();
770
813
  }
771
814
  //#endregion LIFECYCLE
772
815
  /****************************************************************************/
@@ -917,211 +960,219 @@ const NvFieldmultiselect = class {
917
960
  }
918
961
  /**
919
962
  * Filter multiselect items based on the text entered by the user.
963
+ * Uses the search engine for optimized filtering with configurable modes.
920
964
  */
921
- filterItems() {
965
+ async filterItems() {
922
966
  const ul = this.el.querySelector('ul');
923
967
  if (!ul)
924
968
  return;
925
- // Remove existing empty message if any
926
- const existingEmptyMessage = ul.querySelector('[data-empty]');
927
- if (existingEmptyMessage) {
928
- existingEmptyMessage.remove();
929
- }
930
- if (!this.filterText.trim()) {
931
- if (this.options && this.options.length > 0) {
932
- // Reset options display
933
- const items = Array.from(ul.querySelectorAll('nv-fielddropdownitemcheck'));
934
- items.forEach(item => {
935
- item.style.display = '';
936
- });
937
- }
938
- else {
939
- // Reset slot items display
940
- const items = Array.from(this.el.querySelectorAll('nv-fielddropdownitemcheck'));
941
- items.forEach(item => {
942
- item.style.display = '';
943
- });
944
- }
945
- // Reorder with divider
946
- const items = Array.from(ul.querySelectorAll('nv-fielddropdownitemcheck'));
947
- const selectedItems = items.filter(item => (this.value || []).includes(item.getAttribute('value') || ''));
948
- const unselectedItems = items.filter(item => !(this.value || []).includes(item.getAttribute('value') || ''));
949
- this.manageDivider(ul, selectedItems, unselectedItems);
950
- return;
951
- }
952
- const normalizedFilter = this.normalizeText(this.filterText);
953
- let hasVisibleItems = false;
954
- if (this.options && this.options.length > 0) {
955
- // Filter options mode
969
+ this.effectiveFilterMode = i18n_utilsIlwlcG9l.getEffectiveFilterMode(this.filterMode);
970
+ // Remove existing empty message and truncation message if any
971
+ ul.querySelector('[data-empty]')?.remove();
972
+ ul.querySelector('[data-truncated]')?.remove();
973
+ // Reset truncation state
974
+ this.resultsTruncated = false;
975
+ this.totalResults = 0;
976
+ if (!this.filterText.trim() ||
977
+ this.filterText.length < this.startFilterAt) {
978
+ // Reset display and apply maxResults limit
956
979
  const items = Array.from(ul.querySelectorAll('nv-fielddropdownitemcheck'));
980
+ const effectiveMaxResults = i18n_utilsIlwlcG9l.clampMaxResults(this.maxResults);
981
+ let visibleCount = 0;
957
982
  items.forEach(item => {
958
- const option = this.options.find(opt => opt.value === item.getAttribute('value'));
959
- if (option && !option.isDivider) {
960
- const matchesFilter = this.normalizeText(option.label).includes(normalizedFilter) ||
961
- this.normalizeText(option.value).includes(normalizedFilter);
962
- item.style.display = matchesFilter ? '' : 'none';
963
- if (matchesFilter)
964
- hasVisibleItems = true;
983
+ if (visibleCount < effectiveMaxResults) {
984
+ item.style.display = '';
985
+ visibleCount++;
986
+ }
987
+ else {
988
+ item.style.display = 'none';
965
989
  }
966
990
  });
967
- // Manage the divider with the visible items
991
+ // Track truncation
992
+ this.totalResults = items.length;
993
+ this.resultsTruncated = items.length > effectiveMaxResults;
994
+ this.hasFilterResults = visibleCount > 0;
995
+ // Reorder with divider
968
996
  const visibleItems = items.filter(item => item.style.display !== 'none');
969
- const visibleSelected = visibleItems.filter(item => (this.value || []).includes(item.getAttribute('value') || ''));
970
- const visibleUnselected = visibleItems.filter(item => !(this.value || []).includes(item.getAttribute('value') || ''));
971
- this.manageDivider(ul, visibleSelected, visibleUnselected);
972
- }
973
- else {
974
- // Filter slot items mode
975
- const items = Array.from(this.el.querySelectorAll('nv-fielddropdownitemcheck'));
976
- items.forEach(item => {
977
- const label = item.getAttribute('label') || '';
978
- const value = item.getAttribute('value') || '';
979
- const textContent = item.textContent || '';
980
- const matchesFilter = this.normalizeText(label).includes(normalizedFilter) ||
981
- this.normalizeText(value).includes(normalizedFilter) ||
982
- this.normalizeText(textContent).includes(normalizedFilter);
983
- item.style.display = matchesFilter ? '' : 'none';
984
- if (matchesFilter)
985
- hasVisibleItems = true;
986
- });
987
- }
988
- // Add empty message if no items match the filter
989
- if (!hasVisibleItems) {
990
- const emptyMessage = document.createElement('li');
991
- emptyMessage.setAttribute('data-empty', 'true');
992
- emptyMessage.textContent = this.emptyResult;
993
- emptyMessage.classList.add('no-results-message');
994
- ul.appendChild(emptyMessage);
995
- }
996
- this.reorderSlotContent();
997
- }
998
- /**
999
- * Filter multiselect items in options mode.
1000
- */
1001
- filterItemsOption() {
1002
- const ul = this.el.querySelector('ul');
1003
- if (!ul)
997
+ const selectedItems = visibleItems.filter(item => (this.value || []).includes(item.getAttribute('value') || ''));
998
+ const unselectedItems = visibleItems.filter(item => !(this.value || []).includes(item.getAttribute('value') || ''));
999
+ this.manageDivider(ul, selectedItems, unselectedItems);
1000
+ if (this.resultsTruncated) {
1001
+ this.addTruncatedMessage(ul, effectiveMaxResults, items.length);
1002
+ }
1004
1003
  return;
1005
- const normalizedFilter = this.normalizeText(this.filterText);
1004
+ }
1005
+ // Use advanced search engine
1006
+ const result = await this.performAdvancedSearch();
1007
+ this.resultsTruncated = result.truncated;
1008
+ this.totalResults = result.total;
1009
+ // Create a Set of matching IDs for fast lookup
1010
+ const matchingIds = new Set(result.ids);
1006
1011
  let hasVisibleItems = false;
1007
1012
  const items = Array.from(ul.querySelectorAll('nv-fielddropdownitemcheck'));
1008
- // Reset items if the filter text is empty
1009
- if (!this.filterText.trim()) {
1010
- this.removeEmptyMessageOption(ul);
1011
- items.forEach(item => {
1012
- item.style.display = '';
1013
- item.removeAttribute('aria-hidden'); // Ensure accessibility
1014
- });
1015
- this.reorderOptionsContent();
1016
- this.hasFilterResults = true;
1017
- return;
1018
- }
1019
- // Filter the items
1013
+ const effectiveMaxResults = i18n_utilsIlwlcG9l.clampMaxResults(this.maxResults);
1014
+ let visibleCount = 0;
1020
1015
  items.forEach(item => {
1021
- const option = this.options.find(opt => opt.value === item.getAttribute('value'));
1022
- if (option && !option.isDivider) {
1023
- const matchesFilter = this.normalizeText(option.label).includes(normalizedFilter) ||
1024
- this.normalizeText(option.value).includes(normalizedFilter);
1025
- item.style.display = matchesFilter ? '' : 'none';
1026
- item.setAttribute('aria-hidden', matchesFilter ? 'false' : 'true'); // Update accessibility
1027
- if (matchesFilter)
1028
- hasVisibleItems = true;
1016
+ const itemValue = item.getAttribute('value') || '';
1017
+ // Check if this item matches
1018
+ const isMatch = matchingIds.has(itemValue);
1019
+ if (isMatch && visibleCount < effectiveMaxResults) {
1020
+ item.style.display = '';
1021
+ hasVisibleItems = true;
1022
+ visibleCount++;
1029
1023
  }
1030
1024
  else {
1031
- item.style.display = 'none'; // Hide dividers during filtering
1032
- item.setAttribute('aria-hidden', 'true');
1025
+ item.style.display = 'none';
1033
1026
  }
1034
1027
  });
1035
- // Update the filter results state
1036
- this.hasFilterResults = hasVisibleItems;
1037
1028
  // Manage the divider with the visible items
1038
1029
  const visibleItems = items.filter(item => item.style.display !== 'none');
1039
1030
  const visibleSelected = visibleItems.filter(item => (this.value || []).includes(item.getAttribute('value') || ''));
1040
1031
  const visibleUnselected = visibleItems.filter(item => !(this.value || []).includes(item.getAttribute('value') || ''));
1041
1032
  this.manageDivider(ul, visibleSelected, visibleUnselected);
1042
- // Add or remove the empty message
1033
+ // Add empty message if no items match the filter
1034
+ this.hasFilterResults = hasVisibleItems;
1043
1035
  if (!hasVisibleItems) {
1044
- this.addEmptyMessageOption(ul);
1036
+ const emptyMessage = document.createElement('li');
1037
+ emptyMessage.setAttribute('data-empty', 'true');
1038
+ emptyMessage.textContent = this.emptyResult;
1039
+ emptyMessage.classList.add('no-results-message');
1040
+ ul.appendChild(emptyMessage);
1041
+ }
1042
+ else if (result.truncated) {
1043
+ this.addTruncatedMessage(ul, result.ids.length, result.total);
1044
+ }
1045
+ if (this.options) {
1046
+ this.reorderOptionsContent();
1045
1047
  }
1046
1048
  else {
1047
- this.removeEmptyMessageOption(ul);
1049
+ this.reorderSlotContent();
1048
1050
  }
1049
1051
  }
1050
1052
  /**
1051
- * Filter multiselect items in slots mode
1053
+ * Rebuilds the search index from current items (options prop or slot items).
1052
1054
  */
1053
- filterSlotsItems() {
1054
- if (this.options)
1055
- return;
1056
- const ul = this.el.querySelector('ul');
1057
- if (!ul)
1058
- return;
1059
- // Remove existing empty message if any
1060
- const existingEmptyMessage = ul.querySelector('[data-empty]');
1061
- if (existingEmptyMessage) {
1062
- existingEmptyMessage.remove();
1055
+ async rebuildSearchIndex() {
1056
+ // Build raw items array for indexing
1057
+ this.rawItems = [];
1058
+ if (this.options?.length) {
1059
+ this.options.forEach((opt, index) => {
1060
+ if (!opt.isDivider) {
1061
+ this.rawItems.push({
1062
+ id: opt.value || `opt-${index}`,
1063
+ label: opt.label || opt.value || '',
1064
+ });
1065
+ }
1066
+ });
1063
1067
  }
1064
- // If filter text is empty, reset all items visibility
1065
- if (!this.filterText.trim()) {
1066
- this.resetFilter();
1067
- this.hasFilterResults = true; // Reset filter means we have results
1068
+ else {
1069
+ // Use slot items
1070
+ const items = Array.from(this.el.querySelectorAll('nv-fielddropdownitemcheck'));
1071
+ items.forEach((item, index) => {
1072
+ this.rawItems.push({
1073
+ id: item.getAttribute('value') || `item-${index}`,
1074
+ label: item.getAttribute('label') || item.textContent?.trim() || '',
1075
+ });
1076
+ });
1077
+ }
1078
+ // Build local index for main-thread search
1079
+ this.indexedItems = i18n_utilsIlwlcG9l.buildIndex(this.rawItems);
1080
+ // Determine effective filter mode
1081
+ this.effectiveFilterMode = i18n_utilsIlwlcG9l.getEffectiveFilterMode(this.filterMode);
1082
+ // Initialize worker if needed
1083
+ const itemCount = this.rawItems.length;
1084
+ const threshold = i18n_utilsIlwlcG9l.clampWorkerThreshold(this.workerThreshold);
1085
+ if (i18n_utilsIlwlcG9l.shouldUseWorker(itemCount, this.effectiveFilterMode, threshold)) {
1086
+ await this.initSearchWorker();
1087
+ }
1088
+ else {
1089
+ this.terminateSearchWorker();
1090
+ }
1091
+ }
1092
+ /**
1093
+ * Initializes the Web Worker for search operations.
1094
+ * Falls back to main thread if worker is not available.
1095
+ * Note: Fuzzy search now works on main thread with Fuse.js, so no mode change needed.
1096
+ */
1097
+ async initSearchWorker() {
1098
+ if (!i18n_utilsIlwlcG9l.isWorkerSupported()) {
1099
+ // Workers not supported - will use main thread (fuzzy still works with Fuse.js)
1068
1100
  return;
1069
1101
  }
1070
- const normalizedFilter = this.normalizeText(this.filterText);
1071
- let hasVisibleItems = false;
1072
- // Get all items and preserve them in the DOM
1073
- const items = Array.from(this.el.querySelectorAll('nv-fielddropdownitemcheck'));
1074
- // Instead of removing/reordering, just hide/show items
1075
- items.forEach(item => {
1076
- var _a;
1077
- const label = item.getAttribute('label') || '';
1078
- const value = item.getAttribute('value') || '';
1079
- const textContent = ((_a = item.textContent) === null || _a === void 0 ? void 0 : _a.trim()) || '';
1080
- const matchesFilter = this.normalizeText(label).includes(normalizedFilter) ||
1081
- this.normalizeText(value).includes(normalizedFilter) ||
1082
- this.normalizeText(textContent).includes(normalizedFilter);
1083
- item.style.display = matchesFilter ? '' : 'none';
1084
- if (matchesFilter)
1085
- hasVisibleItems = true;
1086
- });
1087
- // Update the filter results state
1088
- this.hasFilterResults = hasVisibleItems;
1089
- // Get visible items after filtering
1090
- const visibleItems = items.filter(item => item.style.display !== 'none');
1091
- const visibleSelectedItems = visibleItems.filter(item => (this.value || []).includes(item.getAttribute('value') || ''));
1092
- this.manageDivider(ul, visibleSelectedItems, visibleItems.filter(item => !(this.value || []).includes(item.getAttribute('value') || '')));
1093
- // Add empty message if no items match the filter
1094
- if (!hasVisibleItems) {
1095
- const emptyMessage = document.createElement('li');
1096
- emptyMessage.setAttribute('data-empty', 'true');
1097
- emptyMessage.textContent = this.emptyResult;
1098
- emptyMessage.classList.add('no-results-message');
1099
- ul.appendChild(emptyMessage);
1102
+ if (!this.workerClient) {
1103
+ this.workerClient = new i18n_utilsIlwlcG9l.SearchWorkerClient();
1104
+ // No fallback mode change needed - fuzzy works on main thread now
1100
1105
  }
1106
+ // Init will silently handle fallback if worker can't be created
1107
+ await this.workerClient.init(this.rawItems);
1101
1108
  }
1102
1109
  /**
1103
- * Normalizes text by removing accents and converting to lowercase
1104
- * @param {string} text - The text to normalize
1105
- * @returns {string} The normalized text
1106
- *
1107
- * @example
1108
- * normalizeText("Café Latte") => "cafe latte"
1109
- *
1110
- * @description
1111
- * This function performs text normalization in three steps:
1112
- * 1. Decomposes characters into their base form and combining characters (NFD)
1113
- * 2. Removes all diacritical marks (accents, umlauts, etc.)
1114
- * 3. Converts to lowercase and trims whitespace
1115
- *
1116
- * @see {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/normalize} - MDN documentation on String.normalize()
1117
- * @see {@link https://en.wikipedia.org/wiki/Unicode_equivalence#Normal_forms} - More info about Unicode normalization forms
1110
+ * Terminates the Web Worker and cleans up resources.
1118
1111
  */
1119
- normalizeText(text) {
1120
- return text
1121
- .normalize('NFD') // Decompose characters into base + combining characters (e.g., é => e + ´)
1122
- .replace(/[\u0300-\u036f]/g, '') // Remove all diacritical marks (Unicode range for combining characters)
1123
- .toLowerCase() // Convert to lowercase
1124
- .trim(); // Remove leading and trailing whitespace
1112
+ terminateSearchWorker() {
1113
+ if (this.workerClient) {
1114
+ this.workerClient.terminate();
1115
+ this.workerClient = null;
1116
+ }
1117
+ }
1118
+ /**
1119
+ * Performs a search over the indexed items, using a Web Worker when available
1120
+ * and falling back to the main thread otherwise.
1121
+ * @returns {Promise<SearchResult>} Resolves with the search results.
1122
+ */
1123
+ async performAdvancedSearch() {
1124
+ // Ensure index is built
1125
+ if (!this.indexedItems.length) {
1126
+ await this.rebuildSearchIndex();
1127
+ }
1128
+ const itemCount = this.rawItems.length;
1129
+ const threshold = i18n_utilsIlwlcG9l.clampWorkerThreshold(this.workerThreshold);
1130
+ const useWorker = i18n_utilsIlwlcG9l.shouldUseWorker(itemCount, this.effectiveFilterMode, threshold);
1131
+ if (useWorker && this.workerClient?.isReady) {
1132
+ this.isSearching = true;
1133
+ try {
1134
+ return await this.workerClient.search(this.filterText, this.effectiveFilterMode, this.maxResults, this.fuzzyThreshold);
1135
+ }
1136
+ catch (error) {
1137
+ console.error('Worker search failed:', error);
1138
+ // Fall back to main thread (fuzzy now works with Fuse.js)
1139
+ return i18n_utilsIlwlcG9l.search(this.indexedItems, {
1140
+ query: this.filterText,
1141
+ filterMode: this.effectiveFilterMode,
1142
+ maxResults: this.maxResults,
1143
+ startFilterAt: this.startFilterAt,
1144
+ fuzzyThreshold: this.fuzzyThreshold,
1145
+ });
1146
+ }
1147
+ finally {
1148
+ this.isSearching = false;
1149
+ }
1150
+ }
1151
+ // Use main thread search (fuzzy now works with Fuse.js)
1152
+ return i18n_utilsIlwlcG9l.search(this.indexedItems, {
1153
+ query: this.filterText,
1154
+ filterMode: this.effectiveFilterMode,
1155
+ maxResults: this.maxResults,
1156
+ startFilterAt: this.startFilterAt,
1157
+ fuzzyThreshold: this.fuzzyThreshold,
1158
+ });
1159
+ }
1160
+ /**
1161
+ * Adds a non-selectable list item showing truncation information.
1162
+ * @param {HTMLElement} ul - The list element to which the truncation message will be appended.
1163
+ * @param {number} shown - The number of items currently shown.
1164
+ * @param {number} total - The total number of available items.
1165
+ */
1166
+ addTruncatedMessage(ul, shown, total) {
1167
+ // Remove existing truncation message
1168
+ ul.querySelector('[data-truncated]')?.remove();
1169
+ // Get the text template: use provided text or auto-detect from locale
1170
+ const textTemplate = this.truncatedResultsText || i18n_utilsIlwlcG9l.getTruncatedResultsText(this.locale);
1171
+ const truncatedItem = document.createElement('li');
1172
+ truncatedItem.setAttribute('data-truncated', 'true');
1173
+ truncatedItem.className = 'truncated-message no-results-message';
1174
+ truncatedItem.textContent = i18n_utilsIlwlcG9l.formatTruncatedResults(textTemplate, shown, total);
1175
+ ul.appendChild(truncatedItem);
1125
1176
  }
1126
1177
  handleClickOutside(event) {
1127
1178
  if (this.el.contains(event.target) ||
@@ -1173,21 +1224,6 @@ const NvFieldmultiselect = class {
1173
1224
  console.warn('No visible first item found to focus');
1174
1225
  }
1175
1226
  }
1176
- addEmptyMessageOption(ul) {
1177
- const existingMessage = ul.querySelector('[data-empty]');
1178
- if (existingMessage)
1179
- return;
1180
- const emptyMessage = document.createElement('li');
1181
- emptyMessage.setAttribute('data-empty', 'true');
1182
- emptyMessage.textContent = this.emptyResult;
1183
- emptyMessage.classList.add('no-results-message');
1184
- ul.appendChild(emptyMessage);
1185
- }
1186
- removeEmptyMessageOption(ul) {
1187
- const existingMessage = ul.querySelector('[data-empty]');
1188
- if (existingMessage)
1189
- existingMessage.remove();
1190
- }
1191
1227
  manageDivider(ul, selectedItems, unselectedItems) {
1192
1228
  let divider = ul.querySelector('hr.multiselect-divider');
1193
1229
  if (!divider) {
@@ -1338,6 +1374,77 @@ const NvFieldmultiselect = class {
1338
1374
  // Combine with current this.value (set by code), ensuring uniqueness
1339
1375
  this.value = Array.from(new Set([...(this.value || []), ...checkedValues]));
1340
1376
  }
1377
+ /**
1378
+ * Calculates aria-required and native required values based on props and attributes
1379
+ * @returns {object} Object with ariaRequiredValue and useNativeRequired
1380
+ */
1381
+ getRequiredAttributes() {
1382
+ // Check aria-required from multiple sources:
1383
+ // 1. JavaScript prop (most reliable)
1384
+ // 2. HTML attribute 'aria-required' (direct HTML)
1385
+ // 3. HTML attribute 'aria-required-attr' (from JSX kebab-case conversion)
1386
+ // Check aria-required from multiple sources:
1387
+ // 1. HTML attribute 'aria-required' (direct HTML) - check if explicitly set
1388
+ // 2. JavaScript prop (when prop is explicitly set via JavaScript)
1389
+ // We use hasAttribute to determine if the attribute was explicitly set by the user,
1390
+ // since the prop now defaults to false (to maintain Blazor compatibility)
1391
+ const hasAriaRequiredAttr = this.el.hasAttribute('aria-required') ||
1392
+ this.el.hasAttribute('aria-required-attr');
1393
+ const ariaRequiredFromAttr = hasAriaRequiredAttr
1394
+ ? this.el.getAttribute('aria-required') ||
1395
+ this.el.getAttribute('aria-required-attr')
1396
+ : null;
1397
+ // Use aria-required if the attribute was explicitly set
1398
+ // With reflect: true, setting the prop will also set the attribute
1399
+ const useAriaRequired = hasAriaRequiredAttr;
1400
+ // Determine the value: use attribute if it exists (prop reflects to attribute via reflect: true)
1401
+ // If attribute doesn't exist, the prop was never set and we don't use aria-required
1402
+ const ariaRequiredAttrValue = hasAriaRequiredAttr
1403
+ ? ariaRequiredFromAttr
1404
+ : null;
1405
+ // Determine which attributes to use
1406
+ // If aria-required HTML attribute is present, use it (convert string to boolean)
1407
+ // If required is set and aria-required is not "false", use native required
1408
+ // If aria-required is "false", don't use native required even if required is set
1409
+ const ariaRequiredValue = useAriaRequired
1410
+ ? ariaRequiredAttrValue === 'true' || ariaRequiredAttrValue === ''
1411
+ : undefined;
1412
+ const useNativeRequired = this.required && (!useAriaRequired || ariaRequiredValue === true);
1413
+ return {
1414
+ ariaRequiredValue,
1415
+ useNativeRequired,
1416
+ };
1417
+ }
1418
+ /**
1419
+ * Emitted when the input loses focus.
1420
+ * @param {CustomEvent<boolean>} event - The event object containing the focus state.
1421
+ */
1422
+ handleOpenChanged(event) {
1423
+ // Only update if open state differs to avoid redundant actions
1424
+ if (this.open !== event.detail) {
1425
+ this.open = event.detail;
1426
+ if (this.open) {
1427
+ // Filter items only if there is filter text
1428
+ if (this.filterText) {
1429
+ this.filterItems();
1430
+ }
1431
+ }
1432
+ else {
1433
+ // Clear filter text on close if filterable
1434
+ if (this.filterable) {
1435
+ this.clearFilterText();
1436
+ }
1437
+ this.handlePopoverClose();
1438
+ }
1439
+ // Reorder content as needed
1440
+ if (this.options) {
1441
+ this.reorderOptionsContent();
1442
+ }
1443
+ else {
1444
+ this.reorderSlotContent();
1445
+ }
1446
+ }
1447
+ }
1341
1448
  /**
1342
1449
  * Renders description and error description sections
1343
1450
  * @returns {any} The JSX for descriptions
@@ -1364,6 +1471,6 @@ const NvFieldmultiselect = class {
1364
1471
  "open": ["handleOpenChange"]
1365
1472
  }; }
1366
1473
  };
1367
- NvFieldmultiselect.style = NvFieldmultiselectStyle0;
1474
+ NvFieldmultiselect.style = nvFieldmultiselectCss;
1368
1475
 
1369
1476
  exports.nv_fieldmultiselect = NvFieldmultiselect;