@nova-design-system/nova-react 3.22.0 → 3.23.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.
- package/dist/cjs/_commonjsHelpers-B85MJLTf-CFO10eej.js +7 -0
- package/dist/cjs/{collapse.animation-6e0b08df-AHWzNGm_.js → collapse.animation-DZDm0vSK-C2TOIhIK.js} +3 -3
- package/dist/cjs/{fade.animation-9b939939-DV--bM4S.js → fade.animation-DcRL9lcm-DAZeHoKN.js} +75 -75
- package/dist/cjs/generated/components.server.js +245 -50
- package/dist/cjs/{grow.animation-24ad5cf8-LUp_ITEx.js → grow.animation-CvHGHBL4-DDIEYBK-.js} +5 -5
- package/dist/cjs/i18n.utils-DOZbXX2L-BizoXo6c.js +2498 -0
- package/dist/cjs/{index-WPRkQD3O.js → index-CtjeeUI-.js} +12063 -7049
- package/dist/cjs/index.js +12 -1
- package/dist/cjs/inputmask-CSo292ul-DlvupPk6.js +3758 -0
- package/dist/cjs/{nv-accordion-item.entry-BuTvA6w9.js → nv-accordion-item.entry-B_l0-ux0.js} +11 -10
- package/dist/cjs/{nv-accordion.entry-Dtsfw6He.js → nv-accordion.entry-BX8_YuZF.js} +8 -5
- package/dist/cjs/{nv-alert.entry-TIdfdU7Y.js → nv-alert.entry-DCWYR0OK.js} +22 -22
- package/dist/cjs/{nv-avatar.entry-CaxrhPuw.js → nv-avatar.entry-C_xZD3Lp.js} +11 -11
- package/dist/cjs/{nv-badge_2.entry-CfYvTZxX.js → nv-badge_2.entry-JjqANStV.js} +24 -24
- package/dist/cjs/{nv-breadcrumb.entry-BCZ4MmfD.js → nv-breadcrumb.entry-DQZDn6cm.js} +5 -5
- package/dist/cjs/{nv-breadcrumbs.entry-DwzCE7F6.js → nv-breadcrumbs.entry-Bz0GjhY_.js} +3 -3
- package/dist/cjs/{nv-button.entry-Cr_86bcZ.js → nv-button.entry-Br1DH9Vj.js} +9 -9
- package/dist/cjs/{nv-buttongroup.entry-CWjRoHY1.js → nv-buttongroup.entry-BZaTKN_n.js} +3 -3
- package/dist/cjs/{nv-calendar.entry-CXfwNt6G.js → nv-calendar.entry-D9ESuu7C.js} +105 -79
- package/dist/cjs/{nv-col.entry-CJLDS3LY.js → nv-col.entry-CfgPMMxS.js} +5 -5
- package/dist/cjs/{nv-datagrid.entry-Cns8XSud.js → nv-datagrid.entry-DcB5q2oC.js} +14 -14
- package/dist/cjs/{nv-datagridcolumn.entry-CFFAipHF.js → nv-datagridcolumn.entry-BhKOzXA6.js} +2 -1
- package/dist/cjs/{nv-dialog.entry-CDSK9pUH.js → nv-dialog.entry-O47Eol_7.js} +23 -23
- package/dist/cjs/{nv-dialogfooter_2.entry-To_dGUn4.js → nv-dialogfooter_2.entry-Dn16bI8a.js} +10 -11
- package/dist/cjs/nv-fieldcheckbox.entry-Bx6ArV_b.js +177 -0
- package/dist/cjs/{nv-fielddate.entry-C3pXtMHL.js → nv-fielddate.entry-B4P0U8QG.js} +86 -40
- package/dist/cjs/{nv-fielddaterange.entry-CjVVPEK_.js → nv-fielddaterange.entry-BORwYJ-k.js} +150 -101
- package/dist/cjs/nv-fielddropdown.entry-DzBAIynY.js +687 -0
- package/dist/cjs/{nv-fielddropdownitem.entry-Dah-PaE8.js → nv-fielddropdownitem.entry-C_17isWd.js} +6 -5
- package/dist/cjs/{nv-fieldmultiselect.entry-BMLjhqoJ.js → nv-fieldmultiselect.entry-DiqRreWh.js} +347 -232
- package/dist/cjs/nv-fieldnumber.entry-C9O4UPp3.js +187 -0
- package/dist/cjs/nv-fieldpassword.entry-BfVJNT0A.js +165 -0
- package/dist/cjs/{nv-fieldradio.entry-X_2VT1Dj.js → nv-fieldradio.entry-CG22oETM.js} +10 -10
- package/dist/cjs/{nv-fieldselect.entry-pSp-2rNn.js → nv-fieldselect.entry-BPQEtrv2.js} +52 -13
- package/dist/cjs/{nv-fieldslider.entry-pZf7zzLU.js → nv-fieldslider.entry-CozmnUfN.js} +16 -31
- package/dist/cjs/nv-fieldtext.entry-BD-z01ru.js +163 -0
- package/dist/cjs/{nv-fieldtextarea.entry-t3Ixxi23.js → nv-fieldtextarea.entry-7UrKWDHg.js} +51 -12
- package/dist/cjs/{nv-fieldtime.entry-DY7D5_6K.js → nv-fieldtime.entry-DakOlLiO.js} +109 -57
- package/dist/cjs/{nv-icon.entry-6oYPSf4c.js → nv-icon.entry-Db00kB2u.js} +11 -11
- package/dist/cjs/{nv-iconbutton_2.entry-ChULGovr.js → nv-iconbutton_2.entry-CaKCa8NT.js} +7 -8
- package/dist/cjs/{nv-menu.entry-sd0tatWq.js → nv-menu.entry-CK2HdmBt.js} +16 -29
- package/dist/cjs/{nv-menuitem.entry-CCOqR7UF.js → nv-menuitem.entry-mKMqCAdz.js} +6 -5
- package/dist/cjs/nv-notification-bullet.entry-DtbjtFxs.js +77 -0
- package/dist/cjs/{nv-notification.entry-Cc3zE3yY.js → nv-notification.entry-CLb0gNu3.js} +39 -39
- package/dist/cjs/{nv-notificationcontainer.entry-DV4D6oOH.js → nv-notificationcontainer.entry-Cijivlm6.js} +3 -3
- package/dist/cjs/{nv-popover.entry-DQSwI2jT.js → nv-popover.entry-mLdLSp6n.js} +49 -45
- package/dist/cjs/{nv-row.entry-UUuMSAY5.js → nv-row.entry-C2C94fcv.js} +3 -3
- package/dist/cjs/nv-sidebar.entry-inDVNJ4s.js +177 -0
- package/dist/cjs/nv-sidebarcontent.entry-DxoljE15.js +22 -0
- package/dist/cjs/nv-sidebardivider.entry-D_yern0R.js +22 -0
- package/dist/cjs/nv-sidebarfooter.entry-Rkkn9TB_.js +22 -0
- package/dist/cjs/nv-sidebargroup.entry-C1p9qqxr.js +23 -0
- package/dist/cjs/nv-sidebarheader.entry-CYpD_4pI.js +22 -0
- package/dist/cjs/nv-sidebarlogo.entry-BgK03M1v.js +32 -0
- package/dist/cjs/nv-sidebarnavitem.entry-DglvcCOD.js +297 -0
- package/dist/cjs/nv-sidebarnavsubitem.entry-Dt1jKmC-.js +35 -0
- package/dist/cjs/{nv-split.entry-CYP2bTTM.js → nv-split.entry-mzg2F66T.js} +6 -6
- package/dist/cjs/{nv-stack.entry-D35-75Vw.js → nv-stack.entry-nnvjTrBy.js} +5 -5
- package/dist/cjs/{nv-table.entry-DevWJBnL.js → nv-table.entry-DkbNgxtI.js} +4 -4
- package/dist/cjs/{nv-tableheader.entry-Hs7nUSOC.js → nv-tableheader.entry-CRVFTQA-.js} +6 -6
- package/dist/cjs/{nv-toggle.entry-Eje9d--6.js → nv-toggle.entry-oC9TVkr1.js} +9 -9
- package/dist/cjs/nv-togglebutton.entry-BTWCzbS9.js +67 -0
- package/dist/cjs/{nv-togglebuttongroup.entry-CWN_Ucry.js → nv-togglebuttongroup.entry-BYXX5ejg.js} +8 -5
- package/dist/cjs/{nv-tooltip.entry-BGkKDEFg.js → nv-tooltip.entry-OJGxfJEh.js} +5 -5
- package/dist/cjs/{style-value-types.es-f5d10b79-D0QCM8OB.js → style-value-types.es-xlgmw4x8-B1vLqX9m.js} +6 -3
- package/dist/cjs/{v4-a79185f4-2n0dOd_Y.js → v4-BdYh22OP-C1vaJ4yP.js} +1 -1
- package/dist/generated/components.js +80 -0
- package/dist/generated/components.server.js +216 -50
- package/dist/providers/NotificationProvider.js +3 -4
- package/dist/types/generated/components.d.ts +32 -0
- package/dist/types/generated/components.server.d.ts +32 -0
- package/package.json +2 -2
- package/dist/cjs/_commonjsHelpers-1789f0cf-BJu3ubxk.js +0 -10
- package/dist/cjs/inputmask-edcad3c1-B9Omti4z.js +0 -3749
- package/dist/cjs/nv-fieldcheckbox.entry-fdonR07Z.js +0 -138
- package/dist/cjs/nv-fielddropdown.entry-C9mXuNNj.js +0 -392
- package/dist/cjs/nv-fieldnumber.entry-DBdJviXu.js +0 -148
- package/dist/cjs/nv-fieldpassword.entry-Cim_usSM.js +0 -122
- package/dist/cjs/nv-fieldtext.entry-DlI_ExaV.js +0 -124
- package/dist/cjs/nv-togglebutton.entry-LGI7pIeK.js +0 -56
- /package/dist/cjs/{clsx-297c1ffe-BtxeOLZW.js → clsx-ChV9xqsO-BtxeOLZW.js} +0 -0
- /package/dist/cjs/{constants-69bafca2-DpB_ghPF.js → constants-BReL3Lsa-DpB_ghPF.js} +0 -0
- /package/dist/cjs/{timeline.animation-79215cd4-KteJaZPb.js → timeline.animation-CgHCo_Ho-KteJaZPb.js} +0 -0
package/dist/cjs/{nv-fieldmultiselect.entry-BMLjhqoJ.js → nv-fieldmultiselect.entry-DiqRreWh.js}
RENAMED
|
@@ -1,28 +1,37 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var index = require('./index-
|
|
4
|
-
var
|
|
3
|
+
var index = require('./index-CtjeeUI-.js');
|
|
4
|
+
var i18n_utilsDOZbXX2L = require('./i18n.utils-DOZbXX2L-BizoXo6c.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: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%}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 =
|
|
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.
|
|
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.
|
|
344
|
+
void this.filterItems();
|
|
280
345
|
}, this.debounceDelay);
|
|
281
346
|
};
|
|
282
347
|
/**
|
|
@@ -448,7 +513,12 @@ const NvFieldmultiselect = class {
|
|
|
448
513
|
*/
|
|
449
514
|
this.renderOptionsMode = () => {
|
|
450
515
|
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.
|
|
516
|
+
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" }), (((_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", Object.assign({ 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
|
|
517
|
+
? this.required
|
|
518
|
+
: undefined }, (this.getRequiredAttributes().ariaRequiredValue !==
|
|
519
|
+
undefined && {
|
|
520
|
+
'aria-required': String(this.getRequiredAttributes().ariaRequiredValue),
|
|
521
|
+
}), { 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
522
|
position: 'absolute',
|
|
453
523
|
opacity: '0',
|
|
454
524
|
width: '0',
|
|
@@ -465,7 +535,12 @@ const NvFieldmultiselect = class {
|
|
|
465
535
|
*/
|
|
466
536
|
this.renderSlotsMode = () => {
|
|
467
537
|
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.
|
|
538
|
+
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", Object.assign({ id: this.inputId, ref: e => (this.inputElement = e), autocomplete: this.autocomplete, placeholder: this.placeholder, name: this.name, value: this.filterText, required: this.getRequiredAttributes().useNativeRequired
|
|
539
|
+
? this.required
|
|
540
|
+
: undefined }, (this.getRequiredAttributes().ariaRequiredValue !==
|
|
541
|
+
undefined && {
|
|
542
|
+
'aria-required': String(this.getRequiredAttributes().ariaRequiredValue),
|
|
543
|
+
}), { 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
544
|
position: 'absolute',
|
|
470
545
|
opacity: '0',
|
|
471
546
|
width: '0',
|
|
@@ -531,46 +606,13 @@ const NvFieldmultiselect = class {
|
|
|
531
606
|
//#endregion WATCHERS
|
|
532
607
|
/****************************************************************************/
|
|
533
608
|
//#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
|
-
}
|
|
609
|
+
/* eslint-disable nova/native-event-listener */
|
|
569
610
|
/**
|
|
570
611
|
* Listen for the `itemChecked` event emitted by child items.
|
|
571
612
|
* @param {CustomEvent} event - The event object containing the selected value and its checked state.
|
|
572
613
|
*/
|
|
573
614
|
handleItemChecked(event) {
|
|
615
|
+
event.stopPropagation();
|
|
574
616
|
if (this.disabled || this.readonly || this.isBulkOperation) {
|
|
575
617
|
// Skip processing itemChecked events during bulk operations
|
|
576
618
|
return;
|
|
@@ -602,6 +644,7 @@ const NvFieldmultiselect = class {
|
|
|
602
644
|
console.warn('[Event:itemChecked] Received itemChecked event with undefined or null value'); // Warning log
|
|
603
645
|
}
|
|
604
646
|
}
|
|
647
|
+
/* eslint-enable nova/native-event-listener */
|
|
605
648
|
// Add a listener for the slot content
|
|
606
649
|
handleSlotChange(event) {
|
|
607
650
|
// Check: we only want to reorder if it's the "content" slot
|
|
@@ -759,14 +802,17 @@ const NvFieldmultiselect = class {
|
|
|
759
802
|
this.initializeValueFromSlots();
|
|
760
803
|
this.syncChildComponents();
|
|
761
804
|
}
|
|
805
|
+
// Build the search index on load
|
|
806
|
+
this.rebuildSearchIndex();
|
|
762
807
|
}
|
|
763
808
|
/**
|
|
764
|
-
* Unsubscribe from click outside event.
|
|
809
|
+
* Unsubscribe from click outside event and clean up worker.
|
|
765
810
|
*/
|
|
766
811
|
disconnectedCallback() {
|
|
767
812
|
if (this._boundHandleClickOutside) {
|
|
768
813
|
document.removeEventListener('click', this._boundHandleClickOutside);
|
|
769
814
|
}
|
|
815
|
+
this.terminateSearchWorker();
|
|
770
816
|
}
|
|
771
817
|
//#endregion LIFECYCLE
|
|
772
818
|
/****************************************************************************/
|
|
@@ -917,211 +963,224 @@ const NvFieldmultiselect = class {
|
|
|
917
963
|
}
|
|
918
964
|
/**
|
|
919
965
|
* Filter multiselect items based on the text entered by the user.
|
|
966
|
+
* Uses the search engine for optimized filtering with configurable modes.
|
|
920
967
|
*/
|
|
921
|
-
filterItems() {
|
|
968
|
+
async filterItems() {
|
|
969
|
+
var _a, _b;
|
|
922
970
|
const ul = this.el.querySelector('ul');
|
|
923
971
|
if (!ul)
|
|
924
972
|
return;
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
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
|
|
973
|
+
this.effectiveFilterMode = i18n_utilsDOZbXX2L.getEffectiveFilterMode(this.filterMode);
|
|
974
|
+
// Remove existing empty message and truncation message if any
|
|
975
|
+
(_a = ul.querySelector('[data-empty]')) === null || _a === void 0 ? void 0 : _a.remove();
|
|
976
|
+
(_b = ul.querySelector('[data-truncated]')) === null || _b === void 0 ? void 0 : _b.remove();
|
|
977
|
+
// Reset truncation state
|
|
978
|
+
this.resultsTruncated = false;
|
|
979
|
+
this.totalResults = 0;
|
|
980
|
+
if (!this.filterText.trim() ||
|
|
981
|
+
this.filterText.length < this.startFilterAt) {
|
|
982
|
+
// Reset display and apply maxResults limit
|
|
956
983
|
const items = Array.from(ul.querySelectorAll('nv-fielddropdownitemcheck'));
|
|
984
|
+
const effectiveMaxResults = i18n_utilsDOZbXX2L.clampMaxResults(this.maxResults);
|
|
985
|
+
let visibleCount = 0;
|
|
957
986
|
items.forEach(item => {
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
hasVisibleItems = true;
|
|
987
|
+
if (visibleCount < effectiveMaxResults) {
|
|
988
|
+
item.style.display = '';
|
|
989
|
+
visibleCount++;
|
|
990
|
+
}
|
|
991
|
+
else {
|
|
992
|
+
item.style.display = 'none';
|
|
965
993
|
}
|
|
966
994
|
});
|
|
967
|
-
//
|
|
995
|
+
// Track truncation
|
|
996
|
+
this.totalResults = items.length;
|
|
997
|
+
this.resultsTruncated = items.length > effectiveMaxResults;
|
|
998
|
+
this.hasFilterResults = visibleCount > 0;
|
|
999
|
+
// Reorder with divider
|
|
968
1000
|
const visibleItems = items.filter(item => item.style.display !== 'none');
|
|
969
|
-
const
|
|
970
|
-
const
|
|
971
|
-
this.manageDivider(ul,
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
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)
|
|
1001
|
+
const selectedItems = visibleItems.filter(item => (this.value || []).includes(item.getAttribute('value') || ''));
|
|
1002
|
+
const unselectedItems = visibleItems.filter(item => !(this.value || []).includes(item.getAttribute('value') || ''));
|
|
1003
|
+
this.manageDivider(ul, selectedItems, unselectedItems);
|
|
1004
|
+
if (this.resultsTruncated) {
|
|
1005
|
+
this.addTruncatedMessage(ul, effectiveMaxResults, items.length);
|
|
1006
|
+
}
|
|
1004
1007
|
return;
|
|
1005
|
-
|
|
1008
|
+
}
|
|
1009
|
+
// Use advanced search engine
|
|
1010
|
+
const result = await this.performAdvancedSearch();
|
|
1011
|
+
this.resultsTruncated = result.truncated;
|
|
1012
|
+
this.totalResults = result.total;
|
|
1013
|
+
// Create a Set of matching IDs for fast lookup
|
|
1014
|
+
const matchingIds = new Set(result.ids);
|
|
1006
1015
|
let hasVisibleItems = false;
|
|
1007
1016
|
const items = Array.from(ul.querySelectorAll('nv-fielddropdownitemcheck'));
|
|
1008
|
-
|
|
1009
|
-
|
|
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
|
|
1017
|
+
const effectiveMaxResults = i18n_utilsDOZbXX2L.clampMaxResults(this.maxResults);
|
|
1018
|
+
let visibleCount = 0;
|
|
1020
1019
|
items.forEach(item => {
|
|
1021
|
-
const
|
|
1022
|
-
if
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
item.style.display =
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
hasVisibleItems = true;
|
|
1020
|
+
const itemValue = item.getAttribute('value') || '';
|
|
1021
|
+
// Check if this item matches
|
|
1022
|
+
const isMatch = matchingIds.has(itemValue);
|
|
1023
|
+
if (isMatch && visibleCount < effectiveMaxResults) {
|
|
1024
|
+
item.style.display = '';
|
|
1025
|
+
hasVisibleItems = true;
|
|
1026
|
+
visibleCount++;
|
|
1029
1027
|
}
|
|
1030
1028
|
else {
|
|
1031
|
-
item.style.display = 'none';
|
|
1032
|
-
item.setAttribute('aria-hidden', 'true');
|
|
1029
|
+
item.style.display = 'none';
|
|
1033
1030
|
}
|
|
1034
1031
|
});
|
|
1035
|
-
// Update the filter results state
|
|
1036
|
-
this.hasFilterResults = hasVisibleItems;
|
|
1037
1032
|
// Manage the divider with the visible items
|
|
1038
1033
|
const visibleItems = items.filter(item => item.style.display !== 'none');
|
|
1039
1034
|
const visibleSelected = visibleItems.filter(item => (this.value || []).includes(item.getAttribute('value') || ''));
|
|
1040
1035
|
const visibleUnselected = visibleItems.filter(item => !(this.value || []).includes(item.getAttribute('value') || ''));
|
|
1041
1036
|
this.manageDivider(ul, visibleSelected, visibleUnselected);
|
|
1042
|
-
// Add
|
|
1037
|
+
// Add empty message if no items match the filter
|
|
1038
|
+
this.hasFilterResults = hasVisibleItems;
|
|
1043
1039
|
if (!hasVisibleItems) {
|
|
1044
|
-
|
|
1040
|
+
const emptyMessage = document.createElement('li');
|
|
1041
|
+
emptyMessage.setAttribute('data-empty', 'true');
|
|
1042
|
+
emptyMessage.textContent = this.emptyResult;
|
|
1043
|
+
emptyMessage.classList.add('no-results-message');
|
|
1044
|
+
ul.appendChild(emptyMessage);
|
|
1045
|
+
}
|
|
1046
|
+
else if (result.truncated) {
|
|
1047
|
+
this.addTruncatedMessage(ul, result.ids.length, result.total);
|
|
1048
|
+
}
|
|
1049
|
+
if (this.options) {
|
|
1050
|
+
this.reorderOptionsContent();
|
|
1045
1051
|
}
|
|
1046
1052
|
else {
|
|
1047
|
-
this.
|
|
1053
|
+
this.reorderSlotContent();
|
|
1048
1054
|
}
|
|
1049
1055
|
}
|
|
1050
1056
|
/**
|
|
1051
|
-
*
|
|
1057
|
+
* Rebuilds the search index from current items (options prop or slot items).
|
|
1052
1058
|
*/
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
if (
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1059
|
+
async rebuildSearchIndex() {
|
|
1060
|
+
var _a;
|
|
1061
|
+
// Build raw items array for indexing
|
|
1062
|
+
this.rawItems = [];
|
|
1063
|
+
if ((_a = this.options) === null || _a === void 0 ? void 0 : _a.length) {
|
|
1064
|
+
this.options.forEach((opt, index) => {
|
|
1065
|
+
if (!opt.isDivider) {
|
|
1066
|
+
this.rawItems.push({
|
|
1067
|
+
id: opt.value || `opt-${index}`,
|
|
1068
|
+
label: opt.label || opt.value || '',
|
|
1069
|
+
});
|
|
1070
|
+
}
|
|
1071
|
+
});
|
|
1063
1072
|
}
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
this.
|
|
1067
|
-
|
|
1073
|
+
else {
|
|
1074
|
+
// Use slot items
|
|
1075
|
+
const items = Array.from(this.el.querySelectorAll('nv-fielddropdownitemcheck'));
|
|
1076
|
+
items.forEach((item, index) => {
|
|
1077
|
+
var _a;
|
|
1078
|
+
this.rawItems.push({
|
|
1079
|
+
id: item.getAttribute('value') || `item-${index}`,
|
|
1080
|
+
label: item.getAttribute('label') || ((_a = item.textContent) === null || _a === void 0 ? void 0 : _a.trim()) || '',
|
|
1081
|
+
});
|
|
1082
|
+
});
|
|
1083
|
+
}
|
|
1084
|
+
// Build local index for main-thread search
|
|
1085
|
+
this.indexedItems = i18n_utilsDOZbXX2L.buildIndex(this.rawItems);
|
|
1086
|
+
// Determine effective filter mode
|
|
1087
|
+
this.effectiveFilterMode = i18n_utilsDOZbXX2L.getEffectiveFilterMode(this.filterMode);
|
|
1088
|
+
// Initialize worker if needed
|
|
1089
|
+
const itemCount = this.rawItems.length;
|
|
1090
|
+
const threshold = i18n_utilsDOZbXX2L.clampWorkerThreshold(this.workerThreshold);
|
|
1091
|
+
if (i18n_utilsDOZbXX2L.shouldUseWorker(itemCount, this.effectiveFilterMode, threshold)) {
|
|
1092
|
+
await this.initSearchWorker();
|
|
1093
|
+
}
|
|
1094
|
+
else {
|
|
1095
|
+
this.terminateSearchWorker();
|
|
1096
|
+
}
|
|
1097
|
+
}
|
|
1098
|
+
/**
|
|
1099
|
+
* Initializes the Web Worker for search operations.
|
|
1100
|
+
* Falls back to main thread if worker is not available.
|
|
1101
|
+
* Note: Fuzzy search now works on main thread with Fuse.js, so no mode change needed.
|
|
1102
|
+
*/
|
|
1103
|
+
async initSearchWorker() {
|
|
1104
|
+
if (!i18n_utilsDOZbXX2L.isWorkerSupported()) {
|
|
1105
|
+
// Workers not supported - will use main thread (fuzzy still works with Fuse.js)
|
|
1068
1106
|
return;
|
|
1069
1107
|
}
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
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);
|
|
1108
|
+
if (!this.workerClient) {
|
|
1109
|
+
this.workerClient = new i18n_utilsDOZbXX2L.SearchWorkerClient();
|
|
1110
|
+
// No fallback mode change needed - fuzzy works on main thread now
|
|
1100
1111
|
}
|
|
1112
|
+
// Init will silently handle fallback if worker can't be created
|
|
1113
|
+
await this.workerClient.init(this.rawItems);
|
|
1101
1114
|
}
|
|
1102
1115
|
/**
|
|
1103
|
-
*
|
|
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
|
|
1116
|
+
* Terminates the Web Worker and cleans up resources.
|
|
1118
1117
|
*/
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
.
|
|
1122
|
-
.
|
|
1123
|
-
|
|
1124
|
-
|
|
1118
|
+
terminateSearchWorker() {
|
|
1119
|
+
if (this.workerClient) {
|
|
1120
|
+
this.workerClient.terminate();
|
|
1121
|
+
this.workerClient = null;
|
|
1122
|
+
}
|
|
1123
|
+
}
|
|
1124
|
+
/**
|
|
1125
|
+
* Performs a search over the indexed items, using a Web Worker when available
|
|
1126
|
+
* and falling back to the main thread otherwise.
|
|
1127
|
+
* @returns {Promise<SearchResult>} Resolves with the search results.
|
|
1128
|
+
*/
|
|
1129
|
+
async performAdvancedSearch() {
|
|
1130
|
+
var _a;
|
|
1131
|
+
// Ensure index is built
|
|
1132
|
+
if (!this.indexedItems.length) {
|
|
1133
|
+
await this.rebuildSearchIndex();
|
|
1134
|
+
}
|
|
1135
|
+
const itemCount = this.rawItems.length;
|
|
1136
|
+
const threshold = i18n_utilsDOZbXX2L.clampWorkerThreshold(this.workerThreshold);
|
|
1137
|
+
const useWorker = i18n_utilsDOZbXX2L.shouldUseWorker(itemCount, this.effectiveFilterMode, threshold);
|
|
1138
|
+
if (useWorker && ((_a = this.workerClient) === null || _a === void 0 ? void 0 : _a.isReady)) {
|
|
1139
|
+
this.isSearching = true;
|
|
1140
|
+
try {
|
|
1141
|
+
return await this.workerClient.search(this.filterText, this.effectiveFilterMode, this.maxResults, this.fuzzyThreshold);
|
|
1142
|
+
}
|
|
1143
|
+
catch (error) {
|
|
1144
|
+
console.error('Worker search failed:', error);
|
|
1145
|
+
// Fall back to main thread (fuzzy now works with Fuse.js)
|
|
1146
|
+
return i18n_utilsDOZbXX2L.search(this.indexedItems, {
|
|
1147
|
+
query: this.filterText,
|
|
1148
|
+
filterMode: this.effectiveFilterMode,
|
|
1149
|
+
maxResults: this.maxResults,
|
|
1150
|
+
startFilterAt: this.startFilterAt,
|
|
1151
|
+
fuzzyThreshold: this.fuzzyThreshold,
|
|
1152
|
+
});
|
|
1153
|
+
}
|
|
1154
|
+
finally {
|
|
1155
|
+
this.isSearching = false;
|
|
1156
|
+
}
|
|
1157
|
+
}
|
|
1158
|
+
// Use main thread search (fuzzy now works with Fuse.js)
|
|
1159
|
+
return i18n_utilsDOZbXX2L.search(this.indexedItems, {
|
|
1160
|
+
query: this.filterText,
|
|
1161
|
+
filterMode: this.effectiveFilterMode,
|
|
1162
|
+
maxResults: this.maxResults,
|
|
1163
|
+
startFilterAt: this.startFilterAt,
|
|
1164
|
+
fuzzyThreshold: this.fuzzyThreshold,
|
|
1165
|
+
});
|
|
1166
|
+
}
|
|
1167
|
+
/**
|
|
1168
|
+
* Adds a non-selectable list item showing truncation information.
|
|
1169
|
+
* @param {HTMLElement} ul - The list element to which the truncation message will be appended.
|
|
1170
|
+
* @param {number} shown - The number of items currently shown.
|
|
1171
|
+
* @param {number} total - The total number of available items.
|
|
1172
|
+
*/
|
|
1173
|
+
addTruncatedMessage(ul, shown, total) {
|
|
1174
|
+
var _a;
|
|
1175
|
+
// Remove existing truncation message
|
|
1176
|
+
(_a = ul.querySelector('[data-truncated]')) === null || _a === void 0 ? void 0 : _a.remove();
|
|
1177
|
+
// Get the text template: use provided text or auto-detect from locale
|
|
1178
|
+
const textTemplate = this.truncatedResultsText || i18n_utilsDOZbXX2L.getTruncatedResultsText(this.locale);
|
|
1179
|
+
const truncatedItem = document.createElement('li');
|
|
1180
|
+
truncatedItem.setAttribute('data-truncated', 'true');
|
|
1181
|
+
truncatedItem.className = 'truncated-message no-results-message';
|
|
1182
|
+
truncatedItem.textContent = i18n_utilsDOZbXX2L.formatTruncatedResults(textTemplate, shown, total);
|
|
1183
|
+
ul.appendChild(truncatedItem);
|
|
1125
1184
|
}
|
|
1126
1185
|
handleClickOutside(event) {
|
|
1127
1186
|
if (this.el.contains(event.target) ||
|
|
@@ -1173,21 +1232,6 @@ const NvFieldmultiselect = class {
|
|
|
1173
1232
|
console.warn('No visible first item found to focus');
|
|
1174
1233
|
}
|
|
1175
1234
|
}
|
|
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
1235
|
manageDivider(ul, selectedItems, unselectedItems) {
|
|
1192
1236
|
let divider = ul.querySelector('hr.multiselect-divider');
|
|
1193
1237
|
if (!divider) {
|
|
@@ -1338,6 +1382,77 @@ const NvFieldmultiselect = class {
|
|
|
1338
1382
|
// Combine with current this.value (set by code), ensuring uniqueness
|
|
1339
1383
|
this.value = Array.from(new Set([...(this.value || []), ...checkedValues]));
|
|
1340
1384
|
}
|
|
1385
|
+
/**
|
|
1386
|
+
* Calculates aria-required and native required values based on props and attributes
|
|
1387
|
+
* @returns {object} Object with ariaRequiredValue and useNativeRequired
|
|
1388
|
+
*/
|
|
1389
|
+
getRequiredAttributes() {
|
|
1390
|
+
// Check aria-required from multiple sources:
|
|
1391
|
+
// 1. JavaScript prop (most reliable)
|
|
1392
|
+
// 2. HTML attribute 'aria-required' (direct HTML)
|
|
1393
|
+
// 3. HTML attribute 'aria-required-attr' (from JSX kebab-case conversion)
|
|
1394
|
+
// Check aria-required from multiple sources:
|
|
1395
|
+
// 1. HTML attribute 'aria-required' (direct HTML) - check if explicitly set
|
|
1396
|
+
// 2. JavaScript prop (when prop is explicitly set via JavaScript)
|
|
1397
|
+
// We use hasAttribute to determine if the attribute was explicitly set by the user,
|
|
1398
|
+
// since the prop now defaults to false (to maintain Blazor compatibility)
|
|
1399
|
+
const hasAriaRequiredAttr = this.el.hasAttribute('aria-required') ||
|
|
1400
|
+
this.el.hasAttribute('aria-required-attr');
|
|
1401
|
+
const ariaRequiredFromAttr = hasAriaRequiredAttr
|
|
1402
|
+
? this.el.getAttribute('aria-required') ||
|
|
1403
|
+
this.el.getAttribute('aria-required-attr')
|
|
1404
|
+
: null;
|
|
1405
|
+
// Use aria-required if the attribute was explicitly set
|
|
1406
|
+
// With reflect: true, setting the prop will also set the attribute
|
|
1407
|
+
const useAriaRequired = hasAriaRequiredAttr;
|
|
1408
|
+
// Determine the value: use attribute if it exists (prop reflects to attribute via reflect: true)
|
|
1409
|
+
// If attribute doesn't exist, the prop was never set and we don't use aria-required
|
|
1410
|
+
const ariaRequiredAttrValue = hasAriaRequiredAttr
|
|
1411
|
+
? ariaRequiredFromAttr
|
|
1412
|
+
: null;
|
|
1413
|
+
// Determine which attributes to use
|
|
1414
|
+
// If aria-required HTML attribute is present, use it (convert string to boolean)
|
|
1415
|
+
// If required is set and aria-required is not "false", use native required
|
|
1416
|
+
// If aria-required is "false", don't use native required even if required is set
|
|
1417
|
+
const ariaRequiredValue = useAriaRequired
|
|
1418
|
+
? ariaRequiredAttrValue === 'true' || ariaRequiredAttrValue === ''
|
|
1419
|
+
: undefined;
|
|
1420
|
+
const useNativeRequired = this.required && (!useAriaRequired || ariaRequiredValue === true);
|
|
1421
|
+
return {
|
|
1422
|
+
ariaRequiredValue,
|
|
1423
|
+
useNativeRequired,
|
|
1424
|
+
};
|
|
1425
|
+
}
|
|
1426
|
+
/**
|
|
1427
|
+
* Emitted when the input loses focus.
|
|
1428
|
+
* @param {CustomEvent<boolean>} event - The event object containing the focus state.
|
|
1429
|
+
*/
|
|
1430
|
+
handleOpenChanged(event) {
|
|
1431
|
+
// Only update if open state differs to avoid redundant actions
|
|
1432
|
+
if (this.open !== event.detail) {
|
|
1433
|
+
this.open = event.detail;
|
|
1434
|
+
if (this.open) {
|
|
1435
|
+
// Filter items only if there is filter text
|
|
1436
|
+
if (this.filterText) {
|
|
1437
|
+
this.filterItems();
|
|
1438
|
+
}
|
|
1439
|
+
}
|
|
1440
|
+
else {
|
|
1441
|
+
// Clear filter text on close if filterable
|
|
1442
|
+
if (this.filterable) {
|
|
1443
|
+
this.clearFilterText();
|
|
1444
|
+
}
|
|
1445
|
+
this.handlePopoverClose();
|
|
1446
|
+
}
|
|
1447
|
+
// Reorder content as needed
|
|
1448
|
+
if (this.options) {
|
|
1449
|
+
this.reorderOptionsContent();
|
|
1450
|
+
}
|
|
1451
|
+
else {
|
|
1452
|
+
this.reorderSlotContent();
|
|
1453
|
+
}
|
|
1454
|
+
}
|
|
1455
|
+
}
|
|
1341
1456
|
/**
|
|
1342
1457
|
* Renders description and error description sections
|
|
1343
1458
|
* @returns {any} The JSX for descriptions
|
|
@@ -1364,6 +1479,6 @@ const NvFieldmultiselect = class {
|
|
|
1364
1479
|
"open": ["handleOpenChange"]
|
|
1365
1480
|
}; }
|
|
1366
1481
|
};
|
|
1367
|
-
NvFieldmultiselect.style =
|
|
1482
|
+
NvFieldmultiselect.style = nvFieldmultiselectCss;
|
|
1368
1483
|
|
|
1369
1484
|
exports.nv_fieldmultiselect = NvFieldmultiselect;
|