Skip to content

Commit 95339a3

Browse files
committed
fix!: partial option group should show the minus icon
1 parent 106dc0a commit 95339a3

3 files changed

Lines changed: 25 additions & 12 deletions

File tree

packages/multiple-select-vanilla/src/MultipleSelectInstance.ts

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -444,7 +444,7 @@ export class MultipleSelectInstance {
444444
const selectName = this.elm.getAttribute('name') || this.options.name || '';
445445
this.selectAllParentElm = createDomElement('div', { className: 'ms-select-all', dataset: { key: 'select_all' } });
446446
const saLabelElm = document.createElement('label');
447-
const saIconClass = this.isAllSelected ? 'ms-icon-check' : this.isPartiallyAllSelected ? 'ms-icon-minus' : 'ms-icon-uncheck';
447+
const saIconClass = this.isAllSelected ? 'ms-icon-check' : `ms-icon-${this.isPartiallyAllSelected ? 'partial-all' : 'uncheck'}`;
448448
const selectAllIconClass = `ms-icon ${saIconClass}`;
449449
const saIconContainerElm = createDomElement('div', { className: 'icon-checkbox-container' }, saLabelElm);
450450
createDomElement(
@@ -635,6 +635,12 @@ export class MultipleSelectInstance {
635635
if (isSingleWithoutRadioIcon) {
636636
itemOrGroupBlock = inputCheckboxStruct;
637637
} else {
638+
// determine if it's an optgroup and the group has a partial selection
639+
let hasPartialGroupSelected = true;
640+
if ('children' in dataRow && (dataRow as OptGroupRowData).children.some(child => child?.selected)) {
641+
hasPartialGroupSelected = true;
642+
}
643+
638644
itemOrGroupBlock = {
639645
tagName: 'div',
640646
props: {
@@ -645,7 +651,7 @@ export class MultipleSelectInstance {
645651
{
646652
tagName: 'div',
647653
props: {
648-
className: `ms-icon ${isChecked ? (type === 'radio' ? 'ms-icon-radio' : 'ms-icon-check') : 'ms-icon-uncheck'}`,
654+
className: `ms-icon ${isChecked ? (type === 'radio' ? 'ms-icon-radio' : 'ms-icon-check') : `ms-icon-${hasPartialGroupSelected ? 'partial-group' : 'uncheck'}`}`,
649655
},
650656
},
651657
],
@@ -1575,6 +1581,11 @@ export class MultipleSelectInstance {
15751581
const closestLiElm = inputElm.closest('li');
15761582
const iconDivElm = closestLiElm?.querySelector('.icon-checkbox-container div');
15771583
if (closestLiElm) {
1584+
// determine if it's an optgroup and the group has a partial selection
1585+
let hasPartialGroupSelected = false;
1586+
if ('children' in row && (row as OptGroupRowData).children.some(child => child?.selected)) {
1587+
hasPartialGroupSelected = true;
1588+
}
15781589
if (row.selected && !closestLiElm.classList.contains('selected')) {
15791590
closestLiElm.classList.add('selected');
15801591
closestLiElm.ariaSelected = 'true';
@@ -1585,7 +1596,7 @@ export class MultipleSelectInstance {
15851596
closestLiElm.classList.remove('selected');
15861597
closestLiElm.ariaSelected = 'false';
15871598
if (iconDivElm) {
1588-
iconDivElm.className = 'ms-icon ms-icon-uncheck';
1599+
iconDivElm.className = `ms-icon ms-icon-${hasPartialGroupSelected ? 'partial-group' : 'uncheck'}`;
15891600
}
15901601
}
15911602
}
@@ -1602,7 +1613,7 @@ export class MultipleSelectInstance {
16021613
if (this.isAllSelected) {
16031614
iconClass = 'ms-icon-check';
16041615
} else if (this.isPartiallyAllSelected) {
1605-
iconClass = 'ms-icon-minus';
1616+
iconClass = 'ms-icon-partial-all';
16061617
} else {
16071618
iconClass = 'ms-icon-uncheck';
16081619
}

packages/multiple-select-vanilla/src/styles/_variables.scss

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
@use 'sass:color';
77

8-
// this is the only variable without $ms prefix and exists so that user could use
8+
// this is the only variable without $ms prefix and exists so that user could use
99
// the same Bootstrap primary color without declaring $ms-primary-color variable (which also exists)
1010
$primary-color: #149085 !default;
1111
$ms-primary-color: $primary-color !default;
@@ -30,7 +30,8 @@ $ms-icon-caret-svg-path: "M7.41,8.58L12,13.17L16.59,8.58L18,10L12,16L6,10L7.41,8
3030
$ms-icon-close-svg-path: "M19,6.41L17.59,5L12,10.59L6.41,5L5,6.41L10.59,12L5,17.59L6.41,19L12,13.41L17.59,19L19,17.59L13.41,12L19,6.41Z" !default;
3131
$ms-icon-loading-svg-path: "M12,4V2A10,10 0 0,0 2,12H4A8,8 0 0,1 12,4Z" !default;
3232
$ms-icon-check-svg-path: "M9,20.42L2.79,14.21L5.62,11.38L9,14.77L18.88,4.88L21.71,7.71L9,20.42Z" !default;
33-
$ms-icon-minus-svg-path: "M20 14H4V10H20" !default;
33+
$ms-icon-partial-all-svg-path: "M20 14H4V10H20" !default;
34+
$ms-icon-partial-group-svg-path: "M19,13H5V11H19V13Z" !default;
3435
$ms-icon-radio-svg-path: "M12 3.7c4.6 0 8.3 3.7 8.3 8.3s-3.7 8.3-8.3 8.3-8.3-3.7-8.3-8.3S7.4 3.7 12 3.7z" !default;
3536
$ms-icon-color: #444 !default;
3637
$ms-icon-color-hover: #303030 !default;

packages/multiple-select-vanilla/src/styles/multiple-select.scss

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@
1414
@include m.createSvgClass("ms-icon-caret", v.$ms-icon-caret-svg-path);
1515
@include m.createSvgClass("ms-icon-close", v.$ms-icon-close-svg-path);
1616
@include m.createSvgClass("ms-icon-check", v.$ms-icon-check-svg-path);
17-
@include m.createSvgClass("ms-icon-minus", v.$ms-icon-minus-svg-path);
17+
@include m.createSvgClass("ms-icon-partial-all", v.$ms-icon-partial-all-svg-path);
18+
@include m.createSvgClass("ms-icon-partial-group", v.$ms-icon-partial-group-svg-path);
1819
@include m.createSvgClass("ms-icon-radio", v.$ms-icon-radio-svg-path);
1920
@include m.createSvgClass("ms-icon-loading", v.$ms-icon-loading-svg-path);
2021

@@ -56,14 +57,14 @@
5657
width: var(--ms-checkbox-icon-container-width, v.$ms-checkbox-icon-container-width);
5758
border: var(--ms-checkbox-icon-container-border, v.$ms-checkbox-icon-container-border);
5859
border-radius: var(--ms-checkbox-icon-container-border-radius, v.$ms-checkbox-icon-container-border-radius);
59-
60+
6061
div {
6162
font-size: 14px;
6263
color: var(--ms-checkbox-color, v.$ms-checkbox-color);
6364
&:hover {
6465
color: var(--ms-checkbox-hover-color, v.$ms-checkbox-hover-color);
6566
}
66-
// since we use the div container with a border, we don't actually need an icon for unchecked
67+
// since we use the div container with a border, we don't actually need an icon for unchecked
6768
// BUT since we want to keep the same size, we can simply hide the mask to keep the same size
6869
&.ms-icon-uncheck {
6970
visibility: hidden;
@@ -386,7 +387,7 @@
386387
margin-top: var(--ms-drop-input-margin-top, v.$ms-drop-input-margin-top);
387388
accent-color: var(--ms-checkbox-color, v.$ms-checkbox-color);
388389
}
389-
&:focus {
390+
&:focus {
390391
outline: var(--ms-input-focus-outline, v.$ms-input-focus-outline);
391392
}
392393
}
@@ -398,13 +399,13 @@
398399
.ms-loading {
399400
display: flex;
400401
align-items: center;
401-
gap: var(--ms-loading-gap, v.$ms-loading-gap);
402+
gap: var(--ms-loading-gap, v.$ms-loading-gap);
402403
padding: var(--ms-loading-padding, v.$ms-loading-padding);
403404
.ms-icon-loading {
404405
font-size: var(--ms-loading-icon-size, v.$ms-loading-icon-size);
405406
height: var(--ms-loading-icon-size, v.$ms-loading-icon-size);
406407
width: var(--ms-loading-icon-size, v.$ms-loading-icon-size);
407-
}
408+
}
408409
}
409410

410411
.ms-infinite-option {

0 commit comments

Comments
 (0)