@nova-design-system/nova-react 3.9.1 → 3.10.1-beta.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/{constants-4faa1fae-BzFAKCkR.js → constants-23aaef7b-Cj2b-su0.js} +12 -0
- package/dist/cjs/{index-BtjpbnUr.js → index-B-1F0q3j.js} +1458 -448
- package/dist/cjs/index.js +4 -1
- package/dist/cjs/{nv-accordion-item.entry-Dr_2iHhQ.js → nv-accordion-item.entry-BF6TIAqX.js} +2 -2
- package/dist/cjs/{nv-accordion.entry-CYVpcwuY.js → nv-accordion.entry-CaTzxCZe.js} +1 -1
- package/dist/cjs/{nv-alert.entry-C_H-R9wb.js → nv-alert.entry-EOVv8IiE.js} +8 -8
- package/dist/cjs/{nv-avatar.entry-BeSOqGvb.js → nv-avatar.entry-DyiNDtz4.js} +7 -7
- package/dist/cjs/nv-badge_2.entry-DTc3EkVi.js +212 -0
- package/dist/cjs/{nv-breadcrumb.entry-yQozUTFi.js → nv-breadcrumb.entry-DKmd0vLH.js} +2 -2
- package/dist/cjs/{nv-breadcrumbs.entry-Qar1fOI7.js → nv-breadcrumbs.entry-CQB0c_7Y.js} +1 -1
- package/dist/cjs/{nv-button.entry-M_c4r8PX.js → nv-button.entry-rPyTGZZw.js} +8 -8
- package/dist/cjs/nv-buttongroup.entry-BT9JC-IJ.js +195 -0
- package/dist/cjs/{nv-calendar.entry-DFE372aB.js → nv-calendar.entry-C4stLDAG.js} +120 -43
- package/dist/cjs/{nv-col.entry-Bi8pH33J.js → nv-col.entry-DY7HEDMv.js} +2 -2
- package/dist/cjs/{nv-datagrid.entry-B-blFDg-.js → nv-datagrid.entry-yzQVVpxg.js} +9 -9
- package/dist/cjs/{nv-datagridcolumn.entry-CAzB7NtB.js → nv-datagridcolumn.entry-AOVwen5Y.js} +2 -2
- package/dist/cjs/{nv-dialog.entry-Bdw3O22w.js → nv-dialog.entry-DztbR2hl.js} +3 -3
- package/dist/cjs/{nv-dialogfooter_2.entry-BTUrxVzn.js → nv-dialogfooter_2.entry-iPMNyDQF.js} +5 -5
- package/dist/cjs/{nv-fieldcheckbox.entry-DNzC8s-J.js → nv-fieldcheckbox.entry-WEzw8Y0l.js} +6 -6
- package/dist/cjs/{nv-fielddate.entry-BI8REINj.js → nv-fielddate.entry-B4B2QgCn.js} +7 -7
- package/dist/cjs/{nv-fielddaterange.entry-B7mtEV97.js → nv-fielddaterange.entry-BQ-J4HKx.js} +7 -7
- package/dist/cjs/{nv-fielddropdown.entry-Cz7yuHTj.js → nv-fielddropdown.entry-B2YBjdkI.js} +4 -4
- package/dist/cjs/{nv-fielddropdownitem.entry-CH_C4Dr-.js → nv-fielddropdownitem.entry-B0wCnSfT.js} +2 -2
- package/dist/cjs/{nv-fieldmultiselect.entry-BqEdEUR0.js → nv-fieldmultiselect.entry-DuPOvire.js} +433 -43
- package/dist/cjs/{nv-fieldnumber.entry-BhRb8v1L.js → nv-fieldnumber.entry-BJANMe4j.js} +4 -4
- package/dist/cjs/{nv-fieldpassword.entry-BL4T90zr.js → nv-fieldpassword.entry-DkkJHwkG.js} +4 -4
- package/dist/cjs/{nv-fieldradio.entry-D-x10Pri.js → nv-fieldradio.entry-8uDJz8PS.js} +5 -5
- package/dist/cjs/{nv-fieldselect.entry-B-kynHlw.js → nv-fieldselect.entry-DN6euwMc.js} +6 -6
- package/dist/cjs/{nv-fieldslider.entry-D6X0LJKJ.js → nv-fieldslider.entry-BI72B0_Z.js} +4 -4
- package/dist/cjs/{nv-fieldtext.entry-xR41AQcM.js → nv-fieldtext.entry-DzHqp5Lp.js} +4 -4
- package/dist/cjs/{nv-fieldtextarea.entry-4mqhSSHM.js → nv-fieldtextarea.entry-CFgoC_mT.js} +4 -4
- package/dist/cjs/{nv-fieldtime.entry-S3r7RYwN.js → nv-fieldtime.entry-nVAeh7Ot.js} +66 -66
- package/dist/cjs/{nv-icon.entry-C2t6pj-B.js → nv-icon.entry-C0-IQQji.js} +9 -9
- package/dist/cjs/{nv-iconbutton_2.entry-Cv1d6ktl.js → nv-iconbutton_2.entry-BnnDZjg4.js} +4 -4
- package/dist/cjs/{nv-menu.entry-J_Ytq1Kn.js → nv-menu.entry-BB2mjwHV.js} +2 -2
- package/dist/cjs/{nv-menuitem.entry-DpOO9tMo.js → nv-menuitem.entry-CgkJiqc_.js} +2 -2
- package/dist/cjs/{nv-popover.entry-BZJHJXSA.js → nv-popover.entry-_Iv8yq0t.js} +2 -2
- package/dist/cjs/{nv-row.entry-D4qBjtBv.js → nv-row.entry-BZ2prXQS.js} +2 -2
- package/dist/cjs/{nv-stack.entry-DOc6ZvMZ.js → nv-stack.entry-C69ZIFWU.js} +2 -2
- package/dist/cjs/{nv-table.entry-7-TxQSlH.js → nv-table.entry-CXqK-89M.js} +3 -3
- package/dist/cjs/{nv-tablecolumn.entry-Bd4xWDYD.js → nv-tablecolumn.entry-RMYxY100.js} +1 -1
- package/dist/cjs/{nv-toggle.entry-DJmXXavz.js → nv-toggle.entry-Bx7cG_fC.js} +4 -4
- package/dist/cjs/nv-togglebutton.entry-CeYlChll.js +55 -0
- package/dist/cjs/nv-togglebuttongroup.entry-ehe00MUL.js +169 -0
- package/dist/cjs/{nv-tooltip.entry-D9nl_ejz.js → nv-tooltip.entry-CCDVLdqi.js} +2 -2
- package/dist/generated/components.js +24 -0
- package/dist/generated/components.server.js +41 -4
- package/dist/types/generated/components.d.ts +16 -0
- package/dist/types/generated/components.server.d.ts +16 -0
- package/package.json +1 -1
- package/dist/cjs/nv-badge_2.entry-BGWUswPo.js +0 -206
package/dist/cjs/{nv-fieldmultiselect.entry-BqEdEUR0.js → nv-fieldmultiselect.entry-DuPOvire.js}
RENAMED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var index = require('./index-
|
|
3
|
+
var index = require('./index-B-1F0q3j.js');
|
|
4
4
|
var v4A79185f4 = require('./v4-a79185f4-2n0dOd_Y.js');
|
|
5
5
|
require('react');
|
|
6
6
|
|
|
7
|
-
const nvFieldmultiselectCss = "nv-fieldslider .slider-container .track-container:has(.thumb:hover) .track-range{background:var(--components-slider-track-filled-hover)}nv-fieldslider .slider-container .track-container:has(.thumb:hover) .thumb{border-color:var(--components-slider-track-filled-hover)}nv-fieldslider .slider-container .track-container:has(.thumb:focus) .track-range{background:var(--components-slider-track-filled-focus)}nv-fieldslider .slider-container .track-container:has(.thumb:focus) .thumb{border-color:var(--components-slider-track-filled-focus)}nv-fieldslider[error] .slider-container .track-container .track .track-range{background:var(--components-slider-track-filled-error)}nv-fieldslider[error] .slider-container .track-container .track .thumb{border-color:var(--components-slider-track-filled-error)}nv-fieldslider[error] .slider-container .track-container .track .thumb:hover{border-color:var(--components-slider-track-filled-error);outline:calc(var(--focus-outline-stroke) * 1) solid var(--components-slider-track-filled-error);outline-offset:calc(var(--focus-outline-offset) * 1);background-color:var(--components-slider-handler-background-error)}nv-fieldslider[error] .slider-container .track-container .track .thumb:focus{border-color:var(--components-slider-track-filled-error);outline:calc(var(--focus-outline-stroke) * 1) solid var(--components-slider-track-filled-error);outline-offset:calc(var(--focus-outline-offset) * 1);background-color:var(--components-slider-track-filled-error)}nv-fieldslider[error] .slider-container .track-container:has(.thumb:hover) .track-range{background:var(--components-slider-track-filled-error)}nv-fieldslider[error] .slider-container .track-container:has(.thumb:hover) .thumb{border-color:var(--components-slider-track-filled-error)}nv-fieldmultiselect{--nv-field-border-default:var(--components-form-field-border-default);--nv-field-border-hover:var(--components-form-field-border-hover);--nv-field-border-focus:var(--components-form-field-border-focus);--nv-field-border-disabled:var(--components-form-field-border-default);--nv-field-border-readonly:var(--components-form-field-border-default);--nv-field-focus-box-shadow:var(--color-focus-brand);--nv-field-background:var(--components-form-field-background-default);display:flex;flex-direction:column;align-items:flex-start;gap:var(--form-gap-y);box-sizing:border-box;max-width:480px}nv-fieldmultiselect[fluid]:not([fluid=false]){max-width:unset}nv-fieldmultiselect[readonly]:not([readonly=false]){--nv-field-border-default:var(--components-form-field-border-readonly);--nv-field-border-hover:var(--nv-field-border-default);--nv-field-border-focus:var(--components-form-field-border-focus);--nv-field-border-disabled:var(--nv-field-border-default);--nv-field-border-readonly:var(--nv-field-border-default);--nv-field-background:var(--components-form-field-background-readonly)}nv-fieldmultiselect[error]:not([error=false]){--nv-field-border-default:var(--components-form-field-border-error);--nv-field-border-hover:var(--nv-field-border-default);--nv-field-border-focus:var(--nv-field-border-default);--nv-field-border-disabled:var(--nv-field-border-default);--nv-field-border-readonly:var(--nv-field-border-default);--nv-field-focus-box-shadow:var(--color-focus-destructive-in-field)}nv-fieldmultiselect[required]:not([required=false])>label::after{content:\"*\";color:var(--components-form-text-required);font-weight:700}nv-fieldmultiselect label{display:flex;align-items:center;gap:var(--form-label-gap);align-self:stretch;color:var(--components-form-text-label-default);font-family:\"TT Norms Pro\", sans-serif;font-size:var(--form-label-font-size);font-style:normal;font-weight:500;line-height:var(--form-label-line-height)}nv-fieldmultiselect nv-popover{width:100%;display:block}nv-fieldmultiselect nv-popover [data-scope=popover]{width:100%;padding:var(--list-dropdown-padding);border-radius:var(--list-dropdown-radius);background-color:var(--components-list-dropdown-background);border:1px solid var(--components-list-dropdown-border)}nv-fieldmultiselect nv-popover [slot=content]{gap:var(--list-dropdown-gap-y);display:flex;flex-direction:column}nv-fieldmultiselect nv-popover hr{color:var(--components-list-dropdown-separator)}nv-fieldmultiselect nv-popover div[slot=content]{max-height:calc(90vh - var(--list-dropdown-padding) * 2);overflow-y:auto;position:relative}nv-fieldmultiselect nv-popover div[slot=content]::-webkit-scrollbar{width:6px;height:6px}nv-fieldmultiselect nv-popover div[slot=content]::-webkit-scrollbar-track{background-color:var(--color-level-10-background);border-radius:9999px}nv-fieldmultiselect nv-popover div[slot=content]::-webkit-scrollbar-thumb{background-color:var(--color-gray-200);border-radius:9999px}nv-fieldmultiselect .input-wrapper-multiselect{display:flex;flex-wrap:wrap;gap:var(--form-gap-x);align-items:stretch;align-self:stretch;width:100%}nv-fieldmultiselect .input-container-multiselect{display:flex;flex-grow:1;justify-content:center;align-items:center;align-self:stretch;border-radius:var(--form-field-radius);border-width:1px;border-style:solid;border-color:var(--nv-field-border-default);opacity:var(--components-form-opacity-default, 1);background:var(--nv-field-background);transition:all 150ms ease-out;position:relative;width:100%;min-height:40px;}nv-fieldmultiselect .input-container-multiselect:hover{border-color:var(--nv-field-border-hover)}nv-fieldmultiselect .input-container-multiselect:focus-within,nv-fieldmultiselect .input-container-multiselect:focus-within:hover,nv-fieldmultiselect .input-container-multiselect:focus,nv-fieldmultiselect .input-container-multiselect:focus:hover{border-color:var(--nv-field-border-focus);box-shadow:0px 0px 0px var(--focus-field-stroke) var(--nv-field-focus-box-shadow)}nv-fieldmultiselect .input-container-multiselect:has(input:read-only){opacity:0.5;background-color:var(--components-form-field-background-readonly);border-color:var(--nv-field-border-readonly)}nv-fieldmultiselect .input-container-multiselect:has(input:disabled){opacity:0.5;background-color:var(--components-form-field-background-disabled);border-color:var(--nv-field-border-disabled)}nv-fieldmultiselect .input-container-multiselect>nv-badge{margin-left:var(--form-field-padding-x)}nv-fieldmultiselect .input-container-multiselect input,nv-fieldmultiselect .input-container-multiselect p.non-filterable-text{display:flex;align-items:center;flex:1 0 0;overflow:hidden;background-color:transparent;color:var(--components-form-field-content-text);padding:var(--form-field-padding-y) var(--form-field-padding-x);font-size:var(--form-field-font-size);font-style:normal;font-weight:500;line-height:var(--form-field-line-height);width:100%;width:100%;flex-grow:1;margin:0;min-height:100%;box-sizing:border-box}nv-fieldmultiselect .input-container-multiselect input:focus,nv-fieldmultiselect .input-container-multiselect p.non-filterable-text:focus{outline:none}nv-fieldmultiselect .input-container-multiselect input::placeholder,nv-fieldmultiselect .input-container-multiselect p.non-filterable-text::placeholder{overflow:hidden;color:var(--components-form-field-content-placeholder);text-overflow:ellipsis;font-family:\"TT Norms Pro\", sans-serif;font-size:var(--form-field-font-size);font-style:normal;font-weight:400;line-height:var(--form-field-line-height)}nv-fieldmultiselect .input-container-multiselect input[type=password]::-ms-clear,nv-fieldmultiselect .input-container-multiselect input[type=password]::-ms-reveal,nv-fieldmultiselect .input-container-multiselect p.non-filterable-text[type=password]::-ms-clear,nv-fieldmultiselect .input-container-multiselect p.non-filterable-text[type=password]::-ms-reveal{display:none;width:0;height:0}nv-fieldmultiselect .input-container-multiselect>nv-iconbutton{border:0px;border-radius:0px}nv-fieldmultiselect .input-container-multiselect>nv-iconbutton:focus-visible{border-radius:var(--button-md-border-radius);outline-offset:-3px}nv-fieldmultiselect .input-container-multiselect nv-icon.validation{color:var(--nv-field-border-default)}nv-fieldmultiselect .non-filterable-text{display:block;border-radius:var(--form-field-radius);background-color:var(--nv-field-background);color:var(--components-form-field-content-text);font-size:var(--form-field-font-size);font-weight:500;line-height:var(--form-field-line-height);box-sizing:border-box;cursor:pointer;height:100%;min-height:40px}nv-fieldmultiselect .non-filterable-text span{display:inline-block;width:100%;overflow:hidden;text-overflow:ellipsis}nv-fieldmultiselect .description{display:flex;align-items:center;align-self:stretch;gap:var(--spacing-1);color:var(--components-form-text-description-default);font-family:\"TT Norms Pro\", sans-serif;font-size:var(--form-description-font-size);font-style:normal;line-height:var(--form-description-line-height)}nv-fieldmultiselect .error-description{display:flex;align-items:center;align-self:stretch;gap:var(--spacing-1);color:var(--components-form-text-description-default);font-family:\"TT Norms Pro\", sans-serif;font-size:var(--form-description-font-size);font-style:normal;line-height:var(--form-description-line-height);color:var(--components-form-text-description-error)}.no-results-message{text-align:center;padding:10px;color:var(--components-form-text-description-error)}.multiselect-divider{display:block;width:100%;height:1px;background-color:var(--components-list-dropdown-separator);margin:var(--list-dropdown-item-padding-y) 0;border:0}";
|
|
7
|
+
const nvFieldmultiselectCss = "nv-fieldslider .slider-container .track-container:has(.thumb:hover) .track-range{background:var(--components-slider-track-filled-hover)}nv-fieldslider .slider-container .track-container:has(.thumb:hover) .thumb{border-color:var(--components-slider-track-filled-hover)}nv-fieldslider .slider-container .track-container:has(.thumb:focus) .track-range{background:var(--components-slider-track-filled-focus)}nv-fieldslider .slider-container .track-container:has(.thumb:focus) .thumb{border-color:var(--components-slider-track-filled-focus)}nv-fieldslider[error] .slider-container .track-container .track .track-range{background:var(--components-slider-track-filled-error)}nv-fieldslider[error] .slider-container .track-container .track .thumb{border-color:var(--components-slider-track-filled-error)}nv-fieldslider[error] .slider-container .track-container .track .thumb:hover{border-color:var(--components-slider-track-filled-error);outline:calc(var(--focus-outline-stroke) * 1) solid var(--components-slider-track-filled-error);outline-offset:calc(var(--focus-outline-offset) * 1);background-color:var(--components-slider-handler-background-error)}nv-fieldslider[error] .slider-container .track-container .track .thumb:focus{border-color:var(--components-slider-track-filled-error);outline:calc(var(--focus-outline-stroke) * 1) solid var(--components-slider-track-filled-error);outline-offset:calc(var(--focus-outline-offset) * 1);background-color:var(--components-slider-track-filled-error)}nv-fieldslider[error] .slider-container .track-container:has(.thumb:hover) .track-range{background:var(--components-slider-track-filled-error)}nv-fieldslider[error] .slider-container .track-container:has(.thumb:hover) .thumb{border-color:var(--components-slider-track-filled-error)}nv-fieldslider .slider-container .track-container:has(.thumb:hover) .track-range{background:var(--components-slider-track-filled-hover)}nv-fieldslider .slider-container .track-container:has(.thumb:hover) .thumb{border-color:var(--components-slider-track-filled-hover)}nv-fieldslider .slider-container .track-container:has(.thumb:focus) .track-range{background:var(--components-slider-track-filled-focus)}nv-fieldslider .slider-container .track-container:has(.thumb:focus) .thumb{border-color:var(--components-slider-track-filled-focus)}nv-fieldslider[error] .slider-container .track-container .track .track-range{background:var(--components-slider-track-filled-error)}nv-fieldslider[error] .slider-container .track-container .track .thumb{border-color:var(--components-slider-track-filled-error)}nv-fieldslider[error] .slider-container .track-container .track .thumb:hover{border-color:var(--components-slider-track-filled-error);outline:calc(var(--focus-outline-stroke) * 1) solid var(--components-slider-track-filled-error);outline-offset:calc(var(--focus-outline-offset) * 1);background-color:var(--components-slider-handler-background-error)}nv-fieldslider[error] .slider-container .track-container .track .thumb:focus{border-color:var(--components-slider-track-filled-error);outline:calc(var(--focus-outline-stroke) * 1) solid var(--components-slider-track-filled-error);outline-offset:calc(var(--focus-outline-offset) * 1);background-color:var(--components-slider-track-filled-error)}nv-fieldslider[error] .slider-container .track-container:has(.thumb:hover) .track-range{background:var(--components-slider-track-filled-error)}nv-fieldslider[error] .slider-container .track-container:has(.thumb:hover) .thumb{border-color:var(--components-slider-track-filled-error)}nv-fieldmultiselect{--nv-field-border-default:var(--components-form-field-border-default);--nv-field-border-hover:var(--components-form-field-border-hover);--nv-field-border-focus:var(--components-form-field-border-focus);--nv-field-border-disabled:var(--components-form-field-border-default);--nv-field-border-readonly:var(--components-form-field-border-default);--nv-field-focus-box-shadow:var(--color-focus-brand);--nv-field-background:var(--components-form-field-background-default);display:flex;flex-direction:column;align-items:flex-start;gap:var(--form-gap-y);box-sizing:border-box;max-width:480px}nv-fieldmultiselect[fluid]:not([fluid=false]){max-width:unset}nv-fieldmultiselect[readonly]:not([readonly=false]){--nv-field-border-default:var(--components-form-field-border-readonly);--nv-field-border-hover:var(--nv-field-border-default);--nv-field-border-focus:var(--components-form-field-border-focus);--nv-field-border-disabled:var(--nv-field-border-default);--nv-field-border-readonly:var(--nv-field-border-default);--nv-field-background:var(--components-form-field-background-readonly)}nv-fieldmultiselect[error]:not([error=false]){--nv-field-border-default:var(--components-form-field-border-error);--nv-field-border-hover:var(--nv-field-border-default);--nv-field-border-focus:var(--nv-field-border-default);--nv-field-border-disabled:var(--nv-field-border-default);--nv-field-border-readonly:var(--nv-field-border-default);--nv-field-focus-box-shadow:var(--color-focus-destructive-in-field)}nv-fieldmultiselect[required]:not([required=false]) label::after{content:\"*\";color:var(--components-form-text-required);font-weight:700}nv-fieldmultiselect label{display:flex;align-items:center;gap:var(--form-label-gap);align-self:stretch;color:var(--components-form-text-label-default);font-family:\"TT Norms Pro\", sans-serif;font-size:var(--form-label-font-size);font-style:normal;font-weight:500;line-height:var(--form-label-line-height)}nv-fieldmultiselect nv-popover{width:100%;display:block}nv-fieldmultiselect nv-popover [data-scope=popover]{width:100%;padding:var(--list-dropdown-padding);border-radius:var(--list-dropdown-radius);background-color:var(--components-list-dropdown-background);border:1px solid var(--components-list-dropdown-border)}nv-fieldmultiselect nv-popover [slot=content]{gap:var(--list-dropdown-gap-y);display:flex;flex-direction:column}nv-fieldmultiselect nv-popover hr{color:var(--components-list-dropdown-separator)}nv-fieldmultiselect nv-popover div[slot=content]{max-height:calc(90vh - var(--list-dropdown-padding) * 2);overflow-y:auto;position:relative}nv-fieldmultiselect nv-popover div[slot=content]::-webkit-scrollbar{width:6px;height:6px}nv-fieldmultiselect nv-popover div[slot=content]::-webkit-scrollbar-track{background-color:var(--color-level-10-background);border-radius:9999px}nv-fieldmultiselect nv-popover div[slot=content]::-webkit-scrollbar-thumb{background-color:var(--color-gray-200);border-radius:9999px}nv-fieldmultiselect .input-wrapper-multiselect{display:flex;flex-wrap:wrap;gap:var(--form-gap-x);align-items:stretch;align-self:stretch;width:100%}nv-fieldmultiselect .input-container-multiselect{display:flex;flex-grow:1;justify-content:center;align-items:center;align-self:stretch;border-radius:var(--form-field-radius);border-width:1px;border-style:solid;border-color:var(--nv-field-border-default);opacity:var(--components-form-opacity-default, 1);background:var(--nv-field-background);transition:all 150ms ease-out;position:relative;width:100%;min-height:40px}nv-fieldmultiselect .input-container-multiselect:hover{border-color:var(--nv-field-border-hover)}nv-fieldmultiselect .input-container-multiselect:focus-within,nv-fieldmultiselect .input-container-multiselect:focus-within:hover,nv-fieldmultiselect .input-container-multiselect:focus,nv-fieldmultiselect .input-container-multiselect:focus:hover{border-color:var(--nv-field-border-focus);box-shadow:0px 0px 0px var(--focus-field-stroke) var(--nv-field-focus-box-shadow)}nv-fieldmultiselect .input-container-multiselect:has(input:read-only){opacity:0.5;background-color:var(--components-form-field-background-readonly);border-color:var(--nv-field-border-readonly)}nv-fieldmultiselect .input-container-multiselect:has(input:disabled){opacity:0.5;background-color:var(--components-form-field-background-disabled);border-color:var(--nv-field-border-disabled)}nv-fieldmultiselect .input-container-multiselect>nv-badge{margin-left:var(--form-field-padding-x)}nv-fieldmultiselect .input-container-multiselect input,nv-fieldmultiselect .input-container-multiselect p.non-filterable-text{display:flex;align-items:center;flex:1 0 0;overflow:hidden;background-color:transparent;color:var(--components-form-field-content-text);padding:var(--form-field-padding-y) var(--form-field-padding-x);font-size:var(--form-field-font-size);font-style:normal;font-weight:500;line-height:var(--form-field-line-height);width:100%;width:100%;flex-grow:1;margin:0;min-height:100%;box-sizing:border-box}nv-fieldmultiselect .input-container-multiselect input:focus,nv-fieldmultiselect .input-container-multiselect p.non-filterable-text:focus{outline:none}nv-fieldmultiselect .input-container-multiselect input::placeholder,nv-fieldmultiselect .input-container-multiselect p.non-filterable-text::placeholder{overflow:hidden;color:var(--components-form-field-content-placeholder);text-overflow:ellipsis;font-family:\"TT Norms Pro\", sans-serif;font-size:var(--form-field-font-size);font-style:normal;font-weight:400;line-height:var(--form-field-line-height)}nv-fieldmultiselect .input-container-multiselect input[type=password]::-ms-clear,nv-fieldmultiselect .input-container-multiselect input[type=password]::-ms-reveal,nv-fieldmultiselect .input-container-multiselect p.non-filterable-text[type=password]::-ms-clear,nv-fieldmultiselect .input-container-multiselect p.non-filterable-text[type=password]::-ms-reveal{display:none;width:0;height:0}nv-fieldmultiselect .input-container-multiselect>nv-iconbutton{border:0px;border-radius:0px}nv-fieldmultiselect .input-container-multiselect>nv-iconbutton:focus-visible{border-radius:var(--button-md-border-radius);outline-offset:-3px}nv-fieldmultiselect .input-container-multiselect nv-icon.validation{color:var(--nv-field-border-default)}nv-fieldmultiselect .non-filterable-text{display:block;border-radius:var(--form-field-radius);background-color:var(--nv-field-background);color:var(--components-form-field-content-text);font-size:var(--form-field-font-size);font-weight:500;line-height:var(--form-field-line-height);box-sizing:border-box;cursor:pointer;height:100%;min-height:40px}nv-fieldmultiselect .non-filterable-text span{display:inline-block;width:100%;overflow:hidden;text-overflow:ellipsis}nv-fieldmultiselect .description{display:flex;align-items:center;align-self:stretch;gap:var(--spacing-1);color:var(--components-form-text-description-default);font-family:\"TT Norms Pro\", sans-serif;font-size:var(--form-description-font-size);font-style:normal;line-height:var(--form-description-line-height)}nv-fieldmultiselect .error-description{display:flex;align-items:center;align-self:stretch;gap:var(--spacing-1);color:var(--components-form-text-description-default);font-family:\"TT Norms Pro\", sans-serif;font-size:var(--form-description-font-size);font-style:normal;line-height:var(--form-description-line-height);color:var(--components-form-text-description-error)}.no-results-message{cursor:not-allowed;background-color:unset;color:var(--components-menu-contextual-item-content-disabled);padding:var(--list-dropdown-item-padding-y) var(--list-dropdown-item-padding-x)}.multiselect-divider{display:block;width:100%;height:1px;background-color:var(--components-list-dropdown-separator);margin:var(--list-dropdown-item-padding-y) 0;border:0}.select-all-container{position:sticky;top:0;background-color:var(--components-list-dropdown-background);border-bottom:1px solid var(--components-list-dropdown-separator);padding:var(--list-dropdown-item-padding-y) var(--list-dropdown-item-padding-x);z-index:10;margin-bottom:0}.select-all-container .select-all-header{display:flex;align-items:center;gap:var(--form-field-gap)}.select-all-container .select-all-header nv-fieldcheckbox{flex:1;margin:0}.select-all-container .select-all-header nv-iconbutton,.select-all-container .select-all-header nv-button{flex-shrink:0;margin-left:auto}.select-all-container .select-all-header nv-button{justify-content:center}";
|
|
8
8
|
const NvFieldmultiselectStyle0 = nvFieldmultiselectCss;
|
|
9
9
|
|
|
10
10
|
const NvFieldmultiselect = class {
|
|
@@ -12,8 +12,7 @@ const NvFieldmultiselect = class {
|
|
|
12
12
|
index.registerInstance(this, hostRef);
|
|
13
13
|
this.valueChanged = index.createEvent(this, "valueChanged");
|
|
14
14
|
this.filterTextChanged = index.createEvent(this, "filterTextChanged");
|
|
15
|
-
|
|
16
|
-
//#region PROPERTIES
|
|
15
|
+
this.isBulkOperation = false;
|
|
17
16
|
/**
|
|
18
17
|
* Sets the ID for the input element and the for attribute of the associated
|
|
19
18
|
* label. If no ID is provided, a random one will be automatically generated
|
|
@@ -28,11 +27,6 @@ const NvFieldmultiselect = class {
|
|
|
28
27
|
* always type in fresh data.
|
|
29
28
|
*/
|
|
30
29
|
this.autocomplete = 'off';
|
|
31
|
-
/**
|
|
32
|
-
* Specifies the selected values of the multiselect field.
|
|
33
|
-
* This is the canonical value for the component and is used for form submission.
|
|
34
|
-
*/
|
|
35
|
-
this.value = [];
|
|
36
30
|
/**
|
|
37
31
|
* Marks the input field as required.
|
|
38
32
|
*/
|
|
@@ -60,13 +54,22 @@ const NvFieldmultiselect = class {
|
|
|
60
54
|
*/
|
|
61
55
|
this.open = false;
|
|
62
56
|
/**
|
|
63
|
-
*
|
|
57
|
+
* Allows the field to stretch and fill the entire width of its container.
|
|
64
58
|
*/
|
|
65
|
-
this.
|
|
59
|
+
this.fluid = false;
|
|
60
|
+
/**
|
|
61
|
+
* Specifies the selected values of the multiselect field.
|
|
62
|
+
* This is the canonical value for the component and is used for form submission.
|
|
63
|
+
*/
|
|
64
|
+
this.value = [];
|
|
66
65
|
/**
|
|
67
66
|
* Enables or disables the filtering feature for the multiselect items.
|
|
68
67
|
*/
|
|
69
68
|
this.filterable = false;
|
|
69
|
+
/**
|
|
70
|
+
* The text to display when no items match the filter.
|
|
71
|
+
*/
|
|
72
|
+
this.emptyResult = 'No results found';
|
|
70
73
|
/**
|
|
71
74
|
* Delay in milliseconds before the search is triggered when typing in the filter input.
|
|
72
75
|
* @default 300
|
|
@@ -78,10 +81,6 @@ const NvFieldmultiselect = class {
|
|
|
78
81
|
* element.
|
|
79
82
|
*/
|
|
80
83
|
this.autofocus = false;
|
|
81
|
-
/**
|
|
82
|
-
* Allows the field to stretch and fill the entire width of its container.
|
|
83
|
-
*/
|
|
84
|
-
this.fluid = false;
|
|
85
84
|
/**
|
|
86
85
|
* Text for the badge showing the number of selected items.
|
|
87
86
|
*/
|
|
@@ -90,6 +89,18 @@ const NvFieldmultiselect = class {
|
|
|
90
89
|
* The text entered by the user for filtering multiselect items.
|
|
91
90
|
*/
|
|
92
91
|
this.filterText = '';
|
|
92
|
+
/**
|
|
93
|
+
* Enables or disables the "Select All / Deselect All" toggle functionality.
|
|
94
|
+
*/
|
|
95
|
+
this.enableSelectAll = false;
|
|
96
|
+
/**
|
|
97
|
+
* Text for the "Select All" button.
|
|
98
|
+
*/
|
|
99
|
+
this.selectAllLabel = 'Select/deselect all';
|
|
100
|
+
/**
|
|
101
|
+
* Text for the "Deselect All" button.
|
|
102
|
+
*/
|
|
103
|
+
this.deselectAllLabel = 'Select/deselect all';
|
|
93
104
|
//#endregion PROPERTIES
|
|
94
105
|
/****************************************************************************/
|
|
95
106
|
//#region STATE
|
|
@@ -98,10 +109,25 @@ const NvFieldmultiselect = class {
|
|
|
98
109
|
*/
|
|
99
110
|
this.sortedOptions = [];
|
|
100
111
|
this.isHandlingEscape = false;
|
|
112
|
+
/**
|
|
113
|
+
* Indicates whether the current filter has visible results.
|
|
114
|
+
* Used to control the visibility of the "Select All" button.
|
|
115
|
+
*/
|
|
116
|
+
this.hasFilterResults = true;
|
|
117
|
+
/**
|
|
118
|
+
* Controls the visibility of the select all section.
|
|
119
|
+
*/
|
|
120
|
+
this.isSelectAllSectionVisible = true;
|
|
121
|
+
// Add the flag to the class
|
|
122
|
+
this.preventBlurClose = false;
|
|
123
|
+
this.handleMouseDownPreventBlur = () => {
|
|
124
|
+
this.preventBlurClose = true;
|
|
125
|
+
};
|
|
101
126
|
/**
|
|
102
127
|
* Handle badge close for options mode.
|
|
103
128
|
*/
|
|
104
129
|
this.handleBadgeCloseOptions = () => {
|
|
130
|
+
console.info('handleBadgeCloseOptions:', this.value);
|
|
105
131
|
this.value = [];
|
|
106
132
|
this.valueChanged.emit(this.value);
|
|
107
133
|
// Uncheck all elements
|
|
@@ -119,6 +145,7 @@ const NvFieldmultiselect = class {
|
|
|
119
145
|
* Handle badge close for slots mode.
|
|
120
146
|
*/
|
|
121
147
|
this.handleBadgeCloseSlots = () => {
|
|
148
|
+
console.info('handleBadgeCloseSlots:', this.value);
|
|
122
149
|
this.value = [];
|
|
123
150
|
this.valueChanged.emit(this.value);
|
|
124
151
|
// Uncheck all elements
|
|
@@ -127,8 +154,11 @@ const NvFieldmultiselect = class {
|
|
|
127
154
|
item.checked = false;
|
|
128
155
|
item.style.display = '';
|
|
129
156
|
});
|
|
130
|
-
//
|
|
131
|
-
|
|
157
|
+
// Force DOM update before reordering
|
|
158
|
+
requestAnimationFrame(() => {
|
|
159
|
+
// Reorder slot content
|
|
160
|
+
this.reorderSlotContent();
|
|
161
|
+
});
|
|
132
162
|
};
|
|
133
163
|
/**
|
|
134
164
|
* Handle popover close
|
|
@@ -150,12 +180,17 @@ const NvFieldmultiselect = class {
|
|
|
150
180
|
this.filterText = '';
|
|
151
181
|
this.filterTextChanged.emit('');
|
|
152
182
|
this.resetFilter();
|
|
183
|
+
this.hasFilterResults = true;
|
|
153
184
|
};
|
|
154
185
|
/**
|
|
155
186
|
* Handle input blur for options mode.
|
|
156
187
|
*/
|
|
157
188
|
this.handleInputBlurOptions = () => {
|
|
158
189
|
setTimeout(() => {
|
|
190
|
+
if (this.preventBlurClose) {
|
|
191
|
+
this.preventBlurClose = false;
|
|
192
|
+
return; // Don't close the popover
|
|
193
|
+
}
|
|
159
194
|
if (!this.el.contains(document.activeElement)) {
|
|
160
195
|
// Close the popover without affecting the divider
|
|
161
196
|
this.open = false;
|
|
@@ -274,6 +309,11 @@ const NvFieldmultiselect = class {
|
|
|
274
309
|
*/
|
|
275
310
|
this.handleInputBlurSlots = () => {
|
|
276
311
|
setTimeout(() => {
|
|
312
|
+
// Honor preventBlurClose to avoid closing when interacting inside the popover
|
|
313
|
+
if (this.preventBlurClose) {
|
|
314
|
+
this.preventBlurClose = false;
|
|
315
|
+
return; // Don't close the popover
|
|
316
|
+
}
|
|
277
317
|
if (!this.el.contains(document.activeElement)) {
|
|
278
318
|
// Close the popover without affecting the divider
|
|
279
319
|
this.open = false;
|
|
@@ -302,6 +342,120 @@ const NvFieldmultiselect = class {
|
|
|
302
342
|
}
|
|
303
343
|
this.open = !this.open;
|
|
304
344
|
};
|
|
345
|
+
/**
|
|
346
|
+
* Toggles the selection state of all non-disabled options in options mode.
|
|
347
|
+
* Respects filtering by only selecting/deselecting visible items.
|
|
348
|
+
* @param {boolean} selectAll - Whether to select all items (true) or deselect all (false)
|
|
349
|
+
*/
|
|
350
|
+
this.toggleSelectAllOptions = (selectAll) => {
|
|
351
|
+
if (!this.options)
|
|
352
|
+
return;
|
|
353
|
+
this.isBulkOperation = true; // Set flag to suppress individual emissions
|
|
354
|
+
try {
|
|
355
|
+
// Get visible and enabled option values from DOM
|
|
356
|
+
const visibleOptionValues = this.getVisibleEnabledOptionItems();
|
|
357
|
+
console.info('[SelectAll][Options] toggleSelectAllOptions called. selectAll:', selectAll, 'visibleOptionValues:', visibleOptionValues, 'Current value:', this.value);
|
|
358
|
+
if (selectAll) {
|
|
359
|
+
// Select all visible options - merge with existing selections
|
|
360
|
+
this.value = [...new Set([...this.value, ...visibleOptionValues])];
|
|
361
|
+
}
|
|
362
|
+
else {
|
|
363
|
+
// Deselect only the visible options, keep others that might be filtered out
|
|
364
|
+
this.value = this.value.filter(val => !visibleOptionValues.includes(val));
|
|
365
|
+
}
|
|
366
|
+
console.info('[SelectAll][Options] New value after toggle:', this.value);
|
|
367
|
+
// Emit the change event
|
|
368
|
+
this.valueChanged.emit(this.value);
|
|
369
|
+
// Synchronize child components
|
|
370
|
+
this.syncChildComponents();
|
|
371
|
+
// Reorder content to move selected items to top
|
|
372
|
+
this.reorderOptionsContent();
|
|
373
|
+
}
|
|
374
|
+
finally {
|
|
375
|
+
// Defer reset to next frame to ensure any async child emissions are ignored
|
|
376
|
+
requestAnimationFrame(() => {
|
|
377
|
+
this.isBulkOperation = false; // Reset flag
|
|
378
|
+
});
|
|
379
|
+
}
|
|
380
|
+
};
|
|
381
|
+
/**
|
|
382
|
+
* Toggles the selection state of all non-disabled slot items.
|
|
383
|
+
* @param {boolean} selectAll - Whether to select all items (true) or deselect all (false)
|
|
384
|
+
*/
|
|
385
|
+
this.toggleSelectAllSlots = (selectAll) => {
|
|
386
|
+
if (this.options)
|
|
387
|
+
return; // Only for slots mode
|
|
388
|
+
this.isBulkOperation = true; // Set flag to suppress individual emissions
|
|
389
|
+
try {
|
|
390
|
+
// Get visible and enabled items
|
|
391
|
+
const items = this.getVisibleEnabledSlotItems();
|
|
392
|
+
console.info('[SelectAll][Slots] toggleSelectAllSlots called. selectAll:', selectAll, 'visible slot items:', items.map(item => item.getAttribute('value') || item.getAttribute('label')), 'Current value:', this.value);
|
|
393
|
+
if (selectAll) {
|
|
394
|
+
// Select all visible items
|
|
395
|
+
const allActiveValues = items
|
|
396
|
+
.map(item => item.getAttribute('value') || item.getAttribute('label') || '')
|
|
397
|
+
.filter(value => value !== '');
|
|
398
|
+
this.value = [...new Set([...this.value, ...allActiveValues])];
|
|
399
|
+
}
|
|
400
|
+
else {
|
|
401
|
+
// Deselect only the visible items, keep others that might be filtered out
|
|
402
|
+
const visibleValues = items
|
|
403
|
+
.map(item => item.getAttribute('value') || item.getAttribute('label') || '')
|
|
404
|
+
.filter(value => value !== '');
|
|
405
|
+
this.value = this.value.filter(val => !visibleValues.includes(val));
|
|
406
|
+
}
|
|
407
|
+
console.info('[SelectAll][Slots] New value after toggle:', this.value);
|
|
408
|
+
// Emit the change event
|
|
409
|
+
this.valueChanged.emit(this.value);
|
|
410
|
+
// Force synchronization with a small delay to ensure DOM is updated
|
|
411
|
+
requestAnimationFrame(() => {
|
|
412
|
+
this.syncChildComponents();
|
|
413
|
+
this.reorderSlotContent();
|
|
414
|
+
});
|
|
415
|
+
}
|
|
416
|
+
finally {
|
|
417
|
+
// Defer reset to next frame to ensure any async child emissions are ignored
|
|
418
|
+
requestAnimationFrame(() => {
|
|
419
|
+
this.isBulkOperation = false; // Reset flag
|
|
420
|
+
});
|
|
421
|
+
}
|
|
422
|
+
};
|
|
423
|
+
/**
|
|
424
|
+
* Handle click on the select all checkbox in options mode.
|
|
425
|
+
* @param {Event} event - The click event.
|
|
426
|
+
*/
|
|
427
|
+
this.handleSelectAllCheckboxOptionsClick = (event) => {
|
|
428
|
+
event.stopPropagation();
|
|
429
|
+
event.preventDefault();
|
|
430
|
+
console.info('[handleSelectAllCheckboxOptionsClick] event:', event);
|
|
431
|
+
const currentState = this.getSelectAllCheckboxStateOptions();
|
|
432
|
+
console.info('[SelectAll][Options] Checkbox clicked. Current state:', currentState, 'Current value:', this.value);
|
|
433
|
+
// Logic to handle the indeterminate state
|
|
434
|
+
// - unchecked → select all
|
|
435
|
+
// - indeterminate → select all (clicking on indeterminate will change to checked)
|
|
436
|
+
// - checked → deselect all
|
|
437
|
+
const shouldSelectAll = currentState === 'unchecked' || currentState === 'indeterminate';
|
|
438
|
+
console.info('[SelectAll][Options] shouldSelectAll:', shouldSelectAll);
|
|
439
|
+
this.toggleSelectAllOptions(shouldSelectAll);
|
|
440
|
+
};
|
|
441
|
+
/**
|
|
442
|
+
* Handle click on the select all checkbox in slots mode.
|
|
443
|
+
* @param {Event} event - The click event.
|
|
444
|
+
*/
|
|
445
|
+
this.handleSelectAllCheckboxSlotsClick = (event) => {
|
|
446
|
+
event.stopPropagation();
|
|
447
|
+
event.preventDefault();
|
|
448
|
+
console.info('[handleSelectAllCheckboxSlotsClick] event:', event);
|
|
449
|
+
const currentState = this.getSelectAllCheckboxStateSlots();
|
|
450
|
+
console.info('[SelectAll][Slots] Checkbox clicked. Current state:', currentState, 'Current value:', this.value);
|
|
451
|
+
// Logic to handle the indeterminate state
|
|
452
|
+
// - unchecked → select all
|
|
453
|
+
// - indeterminate → select all (clicking on indeterminate will change to checked)
|
|
454
|
+
// - checked → deselect all
|
|
455
|
+
const shouldSelectAll = currentState === 'unchecked' || currentState === 'indeterminate';
|
|
456
|
+
console.info('[SelectAll][Slots] shouldSelectAll:', shouldSelectAll);
|
|
457
|
+
this.toggleSelectAllSlots(shouldSelectAll);
|
|
458
|
+
};
|
|
305
459
|
//#endregion METHODS
|
|
306
460
|
/****************************************************************************/
|
|
307
461
|
//#region RENDER
|
|
@@ -310,35 +464,76 @@ const NvFieldmultiselect = class {
|
|
|
310
464
|
* @returns {any} The JSX for options mode
|
|
311
465
|
*/
|
|
312
466
|
this.renderOptionsMode = () => {
|
|
313
|
-
return (index.h(index.Host, { "aria-label": this.label
|
|
467
|
+
return (index.h(index.Host, { "aria-label": this.label }, (this.label || this.el.querySelector('[slot="label"]')) && (index.h("label", { htmlFor: this.inputId }, index.h("slot", { name: "label" }, this.label))), index.h("nv-popover", { ref: el => (this.popoverElement = el), triggerMode: "controlled", placement: "bottom-start", open: this.open }, index.h("div", { class: "input-wrapper-multiselect", slot: "trigger" }, index.h("slot", { name: "before-input" }), index.h("div", { class: "input-container-multiselect" }, index.h("slot", { name: "leading-input" }), this.value.length > 0 && (index.h("nv-badge", { slot: "leading-input", "prevent-auto-close": true, color: "10", dismissible: this.value.length > 0, label: `${this.value.length} ${this.badgeLabel}`, "aria-label": `Clear all ${this.value.length} ${this.badgeLabel} items`, onCloseClicked: this.handleBadgeCloseOptions })), this.filterable || this.disabled || this.readonly ? (index.h("input", { type: "text", id: this.inputId, ref: e => (this.inputElement = e), autofocus: this.autofocus, autocomplete: this.autocomplete, placeholder: this.placeholder, name: this.name, value: this.filterText, required: this.required, disabled: this.disabled, readOnly: this.readonly, onInput: this.handleInputOptions, onFocus: this.handleInputFocusOptions, onBlur: this.handleInputBlurOptions, onKeyDown: this.handleKeyDown, "data-scope": "focusable", "aria-label": this.label, "aria-controls": `${this.inputId}-listbox` })) : (index.h(index.Fragment, null, index.h("input", { id: this.inputId, type: "text", style: {
|
|
468
|
+
position: 'absolute',
|
|
469
|
+
opacity: '0',
|
|
470
|
+
width: '0',
|
|
471
|
+
height: '0',
|
|
472
|
+
pointerEvents: 'none',
|
|
473
|
+
}, tabIndex: -1, "aria-hidden": "true", autoComplete: this.autocomplete, name: this.name, onFocus: this.handleInputFocusOptions }), index.h("p", { id: this.inputId, class: "non-filterable-text", onClick: this.handleInputContainerClickOptions, tabIndex: 0, onKeyDown: this.handleKeyDown, onFocus: this.handleInputFocusOptions, "aria-label": this.label, "aria-controls": `${this.inputId}-listbox`, "data-scope": "focusable", role: "button" }, index.h("span", null, this.placeholder)))), this.error && (index.h("nv-icon", { name: "alert-circle", class: "validation", size: "md" })), this.filterable && this.filterText.length > 0 && (index.h("nv-iconbutton", { "data-scope": "clear-filter", name: "x", size: "md", emphasis: "lower", "aria-label": "Clear filter text", tabindex: "-1", title: "Clear filter text", onMouseDown: this.handleMouseDownPreventBlur, onClick: this.clearFilterText })), index.h("nv-iconbutton", { "data-scope": "toggle-dropdown", name: this.open ? 'chevron-top' : 'chevron-down', size: "md", emphasis: "lower", "aria-label": this.open ? 'Hide dropdown' : 'Show dropdown', title: this.open ? 'Hide dropdown' : 'Show dropdown', onMouseDown: this.handleMouseDownPreventBlur, onClick: this.togglePopoverOptions })), index.h("slot", { name: "after-input" })), index.h("div", { id: `${this.inputId}-listbox`, slot: "content", style: this.maxHeight ? { maxHeight: this.maxHeight } : {}, onMouseDown: this.handleMouseDownPreventBlur }, this.shouldShowToggleAllOptionsButton() && (index.h("div", { class: "select-all-container" }, index.h("div", { class: "select-all-header" }, this.isSelectAllSectionVisible && (index.h("nv-fieldcheckbox", { checked: this.getSelectAllCheckboxStateOptions() === 'checked', indeterminate: this.getSelectAllCheckboxStateOptions() ===
|
|
474
|
+
'indeterminate', label: this.getSelectAllCheckboxStateOptions() === 'unchecked'
|
|
475
|
+
? this.selectAllLabel
|
|
476
|
+
: this.deselectAllLabel, onMouseDown: this.handleMouseDownPreventBlur, onClick: this.handleSelectAllCheckboxOptionsClick }))))), index.h("ul", { role: "listbox", "aria-multiselectable": "true" }, this.options.map(option => (index.h("nv-fielddropdownitemcheck", { role: "option", label: option.label, description: option.description, value: option.value, checked: this.value.includes(option.value), disabled: option.disabled })))))), this.renderDescriptions()));
|
|
314
477
|
};
|
|
315
478
|
/**
|
|
316
479
|
* Renders the component in slots mode
|
|
317
480
|
* @returns {any} The JSX for slots mode
|
|
318
481
|
*/
|
|
319
482
|
this.renderSlotsMode = () => {
|
|
320
|
-
return (index.h(index.Host, { "aria-label": this.label
|
|
483
|
+
return (index.h(index.Host, { "aria-label": this.label }, (this.label || this.el.querySelector('[slot="label"]')) && (index.h("label", { htmlFor: this.inputId }, index.h("slot", { name: "label" }, this.label))), index.h("nv-popover", { ref: el => (this.popoverElement = el), triggerMode: "controlled", placement: "bottom-start", open: this.open }, index.h("div", { class: "input-wrapper-multiselect", slot: "trigger" }, index.h("slot", { name: "before-input" }), index.h("div", { class: "input-container-multiselect", onClick: this.handleInputContainerClickSlots }, index.h("slot", { name: "leading-input" }), this.value.length > 0 && (index.h("nv-badge", { slot: "leading-input", "prevent-auto-close": true, color: "10", dismissible: this.value.length > 0, label: `${this.value.length} ${this.badgeLabel}`, "aria-label": `Clear all ${this.value.length} ${this.badgeLabel} items`, onCloseClicked: this.handleBadgeCloseSlots })), this.filterable || this.disabled || this.readonly ? (index.h("input", { id: this.inputId, ref: e => (this.inputElement = e), autocomplete: this.autocomplete, placeholder: this.placeholder, name: this.name, value: this.filterText, required: this.required, disabled: this.disabled, readOnly: this.readonly, onInput: this.handleInputSlots, onFocus: this.handleInputFocusSlots, onBlur: this.handleInputBlurSlots, onKeyDown: this.handleKeyDown, "data-scope": "focusable", "aria-label": this.label, "aria-controls": `${this.inputId}-listbox` })) : (index.h(index.Fragment, null, index.h("input", { id: this.inputId, type: "text", style: {
|
|
484
|
+
position: 'absolute',
|
|
485
|
+
opacity: '0',
|
|
486
|
+
width: '0',
|
|
487
|
+
height: '0',
|
|
488
|
+
pointerEvents: 'none',
|
|
489
|
+
}, tabIndex: -1, "aria-hidden": "true", autoComplete: this.autocomplete, name: this.name, onFocus: this.handleInputFocusSlots }), index.h("p", { id: this.inputId, class: "non-filterable-text", "aria-label": this.label, onClick: this.handleInputContainerClickSlots, tabIndex: 0, onKeyDown: this.handleKeyDown, onFocus: this.handleInputFocusSlots, "aria-controls": `${this.inputId}-listbox`, "data-scope": "focusable", role: "button" }, index.h("span", null, this.placeholder)))), this.error && (index.h("nv-icon", { name: "alert-circle", class: "validation", size: "md" })), this.filterable && this.filterText.length > 0 && (index.h("nv-iconbutton", { name: "x", size: "md", emphasis: "lower", tabindex: "-1", onMouseDown: this.handleMouseDownPreventBlur, onClick: this.clearFilterText, "aria-label": "Clear filter text" })), index.h("nv-iconbutton", { "data-scope": "toggle-dropdown", name: this.open ? 'chevron-top' : 'chevron-down', size: "md", emphasis: "lower", "aria-label": this.open ? 'Hide dropdown' : 'Show dropdown', title: this.open ? 'Hide dropdown' : 'Show dropdown', onMouseDown: this.handleMouseDownPreventBlur, onClick: this.togglePopoverSlots })), index.h("slot", { name: "after-input" })), index.h("div", { id: `${this.inputId}-listbox`, slot: "content", style: this.maxHeight ? { maxHeight: this.maxHeight } : {}, onMouseDown: this.handleMouseDownPreventBlur }, this.shouldShowToggleAllSlotButton() && (index.h("div", { class: "select-all-container" }, index.h("div", { class: "select-all-header" }, this.isSelectAllSectionVisible && (index.h("nv-fieldcheckbox", { checked: this.getSelectAllCheckboxStateSlots() === 'checked', indeterminate: this.getSelectAllCheckboxStateSlots() ===
|
|
490
|
+
'indeterminate', label: this.getSelectAllCheckboxStateSlots() === 'unchecked'
|
|
491
|
+
? this.selectAllLabel
|
|
492
|
+
: this.deselectAllLabel, onMouseDown: this.handleMouseDownPreventBlur, onClick: this.handleSelectAllCheckboxSlotsClick }))))), index.h("slot", { name: "content" }))), this.renderDescriptions()));
|
|
321
493
|
};
|
|
322
494
|
}
|
|
323
495
|
//#endregion EVENTS
|
|
324
496
|
/****************************************************************************/
|
|
325
497
|
//#region WATCHERS
|
|
326
498
|
handleOptionsChange(newValue) {
|
|
499
|
+
console.info('[Watch:options] newValue:', newValue);
|
|
500
|
+
console.info('[Watch:options] current value before update:', this.value);
|
|
327
501
|
if (!newValue)
|
|
328
502
|
return;
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
503
|
+
// If the parent has set a value prop, use it. Otherwise, derive from checked options.
|
|
504
|
+
// (Assume: if value is undefined, it's not set by parent; if it's an array, it's set.)
|
|
505
|
+
if (this.value === undefined || this.value.length === 0) {
|
|
506
|
+
this.value = newValue
|
|
507
|
+
.filter(option => option.checked)
|
|
508
|
+
.map(option => option.value);
|
|
509
|
+
console.info('[Watch:options] updated value from checked options:', this.value);
|
|
510
|
+
}
|
|
511
|
+
else {
|
|
512
|
+
// If value is set, ensure checked states in options match value
|
|
513
|
+
newValue.forEach(option => {
|
|
514
|
+
option.checked = this.value.includes(option.value);
|
|
515
|
+
});
|
|
516
|
+
console.info('[Watch:options] options checked state synced to value:', newValue);
|
|
517
|
+
}
|
|
332
518
|
this.reorderOptionsContent();
|
|
333
519
|
}
|
|
334
|
-
/**
|
|
335
|
-
* Emitted when the value changes.
|
|
336
|
-
*/
|
|
337
520
|
watchValueHandler() {
|
|
521
|
+
console.info('[Watch:value] Value changed:', this.value, 'isBulkOperation:', this.isBulkOperation);
|
|
522
|
+
// Skip processing during bulk operations
|
|
523
|
+
if (this.isBulkOperation) {
|
|
524
|
+
console.info('[Watch:value] Skipping syncChildComponents and options update due to bulk operation');
|
|
525
|
+
return;
|
|
526
|
+
}
|
|
338
527
|
// Synchronize child components when value changes programmatically
|
|
339
528
|
if (this.el && this.el.isConnected) {
|
|
340
529
|
this.syncChildComponents();
|
|
341
530
|
}
|
|
531
|
+
// Also, update options checked state if options exist
|
|
532
|
+
if (this.options) {
|
|
533
|
+
this.options.forEach(option => {
|
|
534
|
+
option.checked = this.value.includes(option.value);
|
|
535
|
+
});
|
|
536
|
+
}
|
|
342
537
|
}
|
|
343
538
|
//#endregion WATCHERS
|
|
344
539
|
/****************************************************************************/
|
|
@@ -373,32 +568,38 @@ const NvFieldmultiselect = class {
|
|
|
373
568
|
* @param {CustomEvent} event - The event object containing the selected value and its checked state.
|
|
374
569
|
*/
|
|
375
570
|
handleItemChecked(event) {
|
|
376
|
-
if (this.disabled || this.readonly) {
|
|
571
|
+
if (this.disabled || this.readonly || this.isBulkOperation) {
|
|
572
|
+
// Skip processing itemChecked events during bulk operations
|
|
573
|
+
console.info('[Event:itemChecked] Skipped due to bulk operation or disabled/readonly', event.detail);
|
|
377
574
|
return;
|
|
378
575
|
}
|
|
379
576
|
const { value, checked } = event.detail;
|
|
577
|
+
console.info('[Event:itemChecked] value:', value, 'checked:', checked, 'current value:', this.value);
|
|
380
578
|
if (value !== undefined && value !== null) {
|
|
381
579
|
const newValue = [...this.value];
|
|
382
580
|
const valueIndex = newValue.indexOf(value);
|
|
581
|
+
let hasChanged = false;
|
|
383
582
|
if (checked && valueIndex === -1) {
|
|
384
583
|
newValue.push(value);
|
|
584
|
+
hasChanged = true;
|
|
385
585
|
}
|
|
386
586
|
else if (!checked && valueIndex > -1) {
|
|
387
587
|
newValue.splice(valueIndex, 1);
|
|
588
|
+
hasChanged = true;
|
|
589
|
+
}
|
|
590
|
+
console.info('[Event:itemChecked] newValue after update:', newValue);
|
|
591
|
+
if (hasChanged) {
|
|
592
|
+
this.value = newValue;
|
|
593
|
+
this.valueChanged.emit(this.value);
|
|
594
|
+
this.syncChildComponents();
|
|
388
595
|
}
|
|
389
|
-
// Always update the state and emit the event when an item is checked/unchecked
|
|
390
|
-
this.value = newValue;
|
|
391
|
-
this.valueChanged.emit(this.value);
|
|
392
|
-
// Update the checked state of all items to ensure consistency
|
|
393
|
-
this.syncChildComponents();
|
|
394
596
|
// Preserve the filter text in the input
|
|
395
597
|
if (this.filterable && this.inputElement) {
|
|
396
|
-
// Keep the current filter text in the input
|
|
397
598
|
this.inputElement.value = this.filterText;
|
|
398
599
|
}
|
|
399
600
|
}
|
|
400
601
|
else {
|
|
401
|
-
console.warn('Received itemChecked event with undefined or null value'); // Warning log
|
|
602
|
+
console.warn('[Event:itemChecked] Received itemChecked event with undefined or null value'); // Warning log
|
|
402
603
|
}
|
|
403
604
|
}
|
|
404
605
|
// Add a listener for the slot content
|
|
@@ -420,19 +621,27 @@ const NvFieldmultiselect = class {
|
|
|
420
621
|
* Subscribe to click outside event.
|
|
421
622
|
*/
|
|
422
623
|
connectedCallback() {
|
|
423
|
-
|
|
624
|
+
console.info('[Lifecycle] connectedCallback - value:', this.value);
|
|
625
|
+
// Bind once and reuse the same reference for add/remove to avoid leaks
|
|
626
|
+
if (!this._boundHandleClickOutside) {
|
|
627
|
+
this._boundHandleClickOutside = this.handleClickOutside.bind(this);
|
|
628
|
+
}
|
|
629
|
+
document.addEventListener('click', this._boundHandleClickOutside);
|
|
424
630
|
}
|
|
425
631
|
/**
|
|
426
632
|
* Set the mode state and handle options change.
|
|
427
633
|
*/
|
|
428
634
|
componentWillLoad() {
|
|
429
635
|
var _a;
|
|
636
|
+
console.info('[Lifecycle] componentWillLoad - value:', this.value, 'options:', this.options);
|
|
430
637
|
// Don't call handleOptionsChange if we are in slots mode
|
|
431
638
|
if (this.options) {
|
|
432
639
|
this.handleOptionsChange(this.options);
|
|
433
640
|
}
|
|
434
641
|
// Specific initialization for slots mode
|
|
435
642
|
if (!this.options) {
|
|
643
|
+
// Initialize value from checked slotted children
|
|
644
|
+
this.initializeValueFromSlots();
|
|
436
645
|
// Use a microtask to ensure DOM is ready
|
|
437
646
|
Promise.resolve().then(() => {
|
|
438
647
|
// Synchronize child components
|
|
@@ -451,22 +660,33 @@ const NvFieldmultiselect = class {
|
|
|
451
660
|
if (!this.filterText) {
|
|
452
661
|
this.resetFilter();
|
|
453
662
|
}
|
|
663
|
+
// Initialize filter results state
|
|
664
|
+
this.hasFilterResults = true;
|
|
454
665
|
}
|
|
455
666
|
/**
|
|
456
667
|
* Force reorder if options mode in componentDidLoad because of the initial render not trigger @watch
|
|
457
668
|
*/
|
|
458
669
|
componentDidLoad() {
|
|
670
|
+
console.info('[Lifecycle] componentDidLoad - value:', this.value, 'options:', this.options);
|
|
459
671
|
if (this.options) {
|
|
460
672
|
this.handleOptionsChange(this.options);
|
|
461
673
|
}
|
|
462
674
|
// Final synchronization of child components after everything is loaded
|
|
463
675
|
this.syncChildComponents();
|
|
676
|
+
// For slots mode, ensure value is initialized from checked children if not already
|
|
677
|
+
if (!this.options) {
|
|
678
|
+
this.initializeValueFromSlots();
|
|
679
|
+
this.syncChildComponents();
|
|
680
|
+
}
|
|
464
681
|
}
|
|
465
682
|
/**
|
|
466
683
|
* Unsubscribe from click outside event.
|
|
467
684
|
*/
|
|
468
685
|
disconnectedCallback() {
|
|
469
|
-
|
|
686
|
+
console.info('[Lifecycle] disconnectedCallback - value:', this.value);
|
|
687
|
+
if (this._boundHandleClickOutside) {
|
|
688
|
+
document.removeEventListener('click', this._boundHandleClickOutside);
|
|
689
|
+
}
|
|
470
690
|
}
|
|
471
691
|
//#endregion LIFECYCLE
|
|
472
692
|
/****************************************************************************/
|
|
@@ -500,14 +720,67 @@ const NvFieldmultiselect = class {
|
|
|
500
720
|
this.manageDivider(ul, selectedItems, unselectedItems);
|
|
501
721
|
}
|
|
502
722
|
}
|
|
723
|
+
// Reset filter results state
|
|
724
|
+
this.hasFilterResults = true;
|
|
503
725
|
}
|
|
504
726
|
/**
|
|
505
727
|
* Returns the list of selected values.
|
|
506
728
|
* @returns {string[]} The selected values.
|
|
507
729
|
*/
|
|
508
730
|
async getSelectedValues() {
|
|
731
|
+
console.info('getSelectedValues:', this.value);
|
|
509
732
|
return this.value;
|
|
510
733
|
}
|
|
734
|
+
/**
|
|
735
|
+
* Select all visible and enabled items.
|
|
736
|
+
* Works for both options and slots mode.
|
|
737
|
+
* @returns {Promise<void>}
|
|
738
|
+
*/
|
|
739
|
+
async selectAll() {
|
|
740
|
+
if (this.disabled || this.readonly)
|
|
741
|
+
return;
|
|
742
|
+
if (this.options) {
|
|
743
|
+
this.toggleSelectAllOptions(true);
|
|
744
|
+
}
|
|
745
|
+
else {
|
|
746
|
+
this.toggleSelectAllSlots(true);
|
|
747
|
+
}
|
|
748
|
+
}
|
|
749
|
+
/**
|
|
750
|
+
* Deselect all visible and enabled items.
|
|
751
|
+
* Works for both options and slots mode.
|
|
752
|
+
* @returns {Promise<void>}
|
|
753
|
+
*/
|
|
754
|
+
async deselectAll() {
|
|
755
|
+
if (this.disabled || this.readonly)
|
|
756
|
+
return;
|
|
757
|
+
if (this.options) {
|
|
758
|
+
this.toggleSelectAllOptions(false);
|
|
759
|
+
}
|
|
760
|
+
else {
|
|
761
|
+
this.toggleSelectAllSlots(false);
|
|
762
|
+
}
|
|
763
|
+
}
|
|
764
|
+
/**
|
|
765
|
+
* Toggle selection state of all visible and enabled items.
|
|
766
|
+
* If all items are selected, deselects all. Otherwise, selects all.
|
|
767
|
+
* Works for both options and slots mode.
|
|
768
|
+
* @returns {Promise<void>}
|
|
769
|
+
*/
|
|
770
|
+
async toggleSelectAll() {
|
|
771
|
+
if (this.disabled || this.readonly)
|
|
772
|
+
return;
|
|
773
|
+
const currentState = this.options
|
|
774
|
+
? this.getSelectAllCheckboxStateOptions()
|
|
775
|
+
: this.getSelectAllCheckboxStateSlots();
|
|
776
|
+
const shouldSelectAll = currentState === 'unchecked' || currentState === 'indeterminate';
|
|
777
|
+
if (this.options) {
|
|
778
|
+
this.toggleSelectAllOptions(shouldSelectAll);
|
|
779
|
+
}
|
|
780
|
+
else {
|
|
781
|
+
this.toggleSelectAllSlots(shouldSelectAll);
|
|
782
|
+
}
|
|
783
|
+
}
|
|
511
784
|
/**
|
|
512
785
|
* Reorder the content of the slot.
|
|
513
786
|
*/
|
|
@@ -551,7 +824,7 @@ const NvFieldmultiselect = class {
|
|
|
551
824
|
* Reorder the content for options mode with async handling
|
|
552
825
|
*/
|
|
553
826
|
reorderOptionsContent() {
|
|
554
|
-
const ul = this.el.querySelector('ul
|
|
827
|
+
const ul = this.el.querySelector('ul');
|
|
555
828
|
if (!ul)
|
|
556
829
|
return;
|
|
557
830
|
const items = Array.from(ul.querySelectorAll('nv-fielddropdownitemcheck')).filter(item => item.style.display !== 'none');
|
|
@@ -659,6 +932,7 @@ const NvFieldmultiselect = class {
|
|
|
659
932
|
this.removeEmptyMessageOption(ul);
|
|
660
933
|
items.forEach(item => (item.style.display = ''));
|
|
661
934
|
this.reorderOptionsContent(); // Reorder after reset
|
|
935
|
+
this.hasFilterResults = true; // Reset filter means we have results
|
|
662
936
|
return;
|
|
663
937
|
}
|
|
664
938
|
// Filter the items
|
|
@@ -671,6 +945,8 @@ const NvFieldmultiselect = class {
|
|
|
671
945
|
if (matchesFilter)
|
|
672
946
|
hasVisibleItems = true;
|
|
673
947
|
});
|
|
948
|
+
// Update the filter results state
|
|
949
|
+
this.hasFilterResults = hasVisibleItems;
|
|
674
950
|
// Manage the divider with the visible items
|
|
675
951
|
const visibleItems = items.filter(item => item.style.display !== 'none');
|
|
676
952
|
const visibleSelected = visibleItems.filter(item => this.value.includes(item.getAttribute('value') || ''));
|
|
@@ -701,6 +977,7 @@ const NvFieldmultiselect = class {
|
|
|
701
977
|
// If filter text is empty, reset all items visibility
|
|
702
978
|
if (!this.filterText.trim()) {
|
|
703
979
|
this.resetFilter();
|
|
980
|
+
this.hasFilterResults = true; // Reset filter means we have results
|
|
704
981
|
return;
|
|
705
982
|
}
|
|
706
983
|
const normalizedFilter = this.normalizeText(this.filterText);
|
|
@@ -720,6 +997,8 @@ const NvFieldmultiselect = class {
|
|
|
720
997
|
if (matchesFilter)
|
|
721
998
|
hasVisibleItems = true;
|
|
722
999
|
});
|
|
1000
|
+
// Update the filter results state
|
|
1001
|
+
this.hasFilterResults = hasVisibleItems;
|
|
723
1002
|
// Get visible items after filtering
|
|
724
1003
|
const visibleItems = items.filter(item => item.style.display !== 'none');
|
|
725
1004
|
const visibleSelectedItems = visibleItems.filter(item => this.value.includes(item.getAttribute('value') || ''));
|
|
@@ -930,18 +1209,129 @@ const NvFieldmultiselect = class {
|
|
|
930
1209
|
return;
|
|
931
1210
|
}
|
|
932
1211
|
const items = Array.from(this.el.querySelectorAll('nv-fielddropdownitemcheck'));
|
|
1212
|
+
console.info('[syncChildComponents] value:', this.value);
|
|
933
1213
|
items.forEach(item => {
|
|
934
1214
|
// Get the effective value: use explicit value if present, otherwise use label
|
|
935
1215
|
const itemValue = item.getAttribute('value') || item.getAttribute('label') || '';
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
1216
|
+
const shouldBeChecked = this.value.includes(itemValue);
|
|
1217
|
+
console.info('[syncChildComponents] itemValue:', itemValue, 'shouldBeChecked:', shouldBeChecked, 'item.checked(before):', item.checked);
|
|
1218
|
+
// Only update if the checked state differs to avoid triggering unnecessary events
|
|
1219
|
+
if (item.checked !== shouldBeChecked) {
|
|
1220
|
+
// Set attribute and property, but avoid triggering itemChecked during bulk
|
|
1221
|
+
if (this.isBulkOperation) {
|
|
1222
|
+
// Directly update the DOM attribute to avoid triggering the setter
|
|
1223
|
+
if (shouldBeChecked) {
|
|
1224
|
+
item.setAttribute('checked', '');
|
|
1225
|
+
}
|
|
1226
|
+
else {
|
|
1227
|
+
item.removeAttribute('checked');
|
|
1228
|
+
}
|
|
1229
|
+
// Update internal state without emitting events (assumes nv-fielddropdownitemcheck respects this)
|
|
1230
|
+
item.checked = shouldBeChecked;
|
|
1231
|
+
}
|
|
1232
|
+
else {
|
|
1233
|
+
item.checked = shouldBeChecked;
|
|
1234
|
+
}
|
|
943
1235
|
}
|
|
1236
|
+
console.info('[syncChildComponents] itemValue:', itemValue, 'item.checked(after):', item.checked);
|
|
1237
|
+
});
|
|
1238
|
+
}
|
|
1239
|
+
/**
|
|
1240
|
+
* Gets visible and enabled slot items using consistent logic.
|
|
1241
|
+
* @returns {Element[]} Array of visible and enabled items
|
|
1242
|
+
*/
|
|
1243
|
+
getVisibleEnabledSlotItems() {
|
|
1244
|
+
const allItems = Array.from(this.el.querySelectorAll('nv-fielddropdownitemcheck'));
|
|
1245
|
+
return allItems.filter(item => {
|
|
1246
|
+
const isHidden = item.style.display === 'none';
|
|
1247
|
+
const isDisabled = item.hasAttribute('disabled');
|
|
1248
|
+
return !isHidden && !isDisabled;
|
|
1249
|
+
});
|
|
1250
|
+
}
|
|
1251
|
+
/**
|
|
1252
|
+
* Gets visible and enabled option items by checking DOM elements.
|
|
1253
|
+
* @returns {string[]} Array of visible and enabled option values
|
|
1254
|
+
*/
|
|
1255
|
+
getVisibleEnabledOptionItems() {
|
|
1256
|
+
const allItems = Array.from(this.el.querySelectorAll('nv-fielddropdownitemcheck'));
|
|
1257
|
+
const visibleItems = allItems.filter(item => {
|
|
1258
|
+
const isHidden = item.style.display === 'none';
|
|
1259
|
+
const isDisabled = item.hasAttribute('disabled');
|
|
1260
|
+
return !isHidden && !isDisabled;
|
|
1261
|
+
});
|
|
1262
|
+
return visibleItems
|
|
1263
|
+
.map(item => item.getAttribute('value') || '')
|
|
1264
|
+
.filter(value => value !== '');
|
|
1265
|
+
}
|
|
1266
|
+
/**
|
|
1267
|
+
* Determines if the toggle all button should be shown in options mode.
|
|
1268
|
+
* @returns {boolean} True if there are visible items and no "No results found" message
|
|
1269
|
+
*/
|
|
1270
|
+
shouldShowToggleAllOptionsButton() {
|
|
1271
|
+
if (!this.options)
|
|
1272
|
+
return false; // Only for options mode
|
|
1273
|
+
return this.enableSelectAll && this.hasFilterResults;
|
|
1274
|
+
}
|
|
1275
|
+
/**
|
|
1276
|
+
* Gets the checkbox state for the select all checkbox in options mode.
|
|
1277
|
+
* @returns {'checked' | 'unchecked' | 'indeterminate'} The checkbox state
|
|
1278
|
+
*/
|
|
1279
|
+
getSelectAllCheckboxStateOptions() {
|
|
1280
|
+
if (!this.options)
|
|
1281
|
+
return 'unchecked';
|
|
1282
|
+
// Get visible and enabled option values from DOM
|
|
1283
|
+
const visibleOptionValues = this.getVisibleEnabledOptionItems();
|
|
1284
|
+
if (visibleOptionValues.length === 0)
|
|
1285
|
+
return 'unchecked';
|
|
1286
|
+
const selectedVisibleOptions = visibleOptionValues.filter(value => this.value.includes(value));
|
|
1287
|
+
if (selectedVisibleOptions.length === 0)
|
|
1288
|
+
return 'unchecked';
|
|
1289
|
+
if (selectedVisibleOptions.length === visibleOptionValues.length)
|
|
1290
|
+
return 'checked';
|
|
1291
|
+
return 'indeterminate';
|
|
1292
|
+
}
|
|
1293
|
+
/**
|
|
1294
|
+
* Gets the checkbox state for the select all checkbox in slots mode.
|
|
1295
|
+
* @returns {'checked' | 'unchecked' | 'indeterminate'} The checkbox state
|
|
1296
|
+
*/
|
|
1297
|
+
getSelectAllCheckboxStateSlots() {
|
|
1298
|
+
if (this.options)
|
|
1299
|
+
return 'unchecked';
|
|
1300
|
+
// Get all visible and enabled items
|
|
1301
|
+
const items = this.getVisibleEnabledSlotItems();
|
|
1302
|
+
if (items.length === 0)
|
|
1303
|
+
return 'unchecked';
|
|
1304
|
+
const selectedItems = items.filter(item => {
|
|
1305
|
+
const itemValue = item.getAttribute('value') || item.getAttribute('label') || '';
|
|
1306
|
+
return itemValue !== '' && this.value.includes(itemValue);
|
|
944
1307
|
});
|
|
1308
|
+
if (selectedItems.length === 0)
|
|
1309
|
+
return 'unchecked';
|
|
1310
|
+
if (selectedItems.length === items.length)
|
|
1311
|
+
return 'checked';
|
|
1312
|
+
return 'indeterminate';
|
|
1313
|
+
}
|
|
1314
|
+
/**
|
|
1315
|
+
* Determines if the toggle all button should be shown in slots mode.
|
|
1316
|
+
* @returns {boolean} True if there are visible items and no "No results found" message
|
|
1317
|
+
*/
|
|
1318
|
+
shouldShowToggleAllSlotButton() {
|
|
1319
|
+
if (this.options)
|
|
1320
|
+
return false; // Only for slots mode
|
|
1321
|
+
return this.enableSelectAll && this.hasFilterResults;
|
|
1322
|
+
}
|
|
1323
|
+
/**
|
|
1324
|
+
* Initializes the value array from checked slotted nv-fielddropdownitemcheck elements (slots mode only).
|
|
1325
|
+
*/
|
|
1326
|
+
initializeValueFromSlots() {
|
|
1327
|
+
const items = Array.from(this.el.querySelectorAll('nv-fielddropdownitemcheck'));
|
|
1328
|
+
// Values from checked slot children
|
|
1329
|
+
const checkedValues = items
|
|
1330
|
+
.filter(item => item.hasAttribute('checked'))
|
|
1331
|
+
.map(item => item.getAttribute('value') || item.getAttribute('label') || '');
|
|
1332
|
+
// Combine with current this.value (set by code), ensuring uniqueness
|
|
1333
|
+
this.value = Array.from(new Set([...(this.value || []), ...checkedValues]));
|
|
1334
|
+
console.info('[initializeValueFromSlots] checkedValues:', checkedValues, 'combined value:', this.value);
|
|
945
1335
|
}
|
|
946
1336
|
/**
|
|
947
1337
|
* Renders description and error description sections
|