@instructure/ui-drilldown 11.0.1 → 11.0.2-snapshot-1
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/CHANGELOG.md +11 -0
- package/es/Drilldown/DrilldownGroup/props.js +1 -1
- package/es/Drilldown/index.js +106 -33
- package/lib/Drilldown/DrilldownGroup/props.js +1 -1
- package/lib/Drilldown/index.js +106 -33
- package/package.json +18 -18
- package/src/Drilldown/DrilldownGroup/props.ts +7 -0
- package/src/Drilldown/index.tsx +116 -34
- package/tsconfig.build.tsbuildinfo +1 -1
- package/types/Drilldown/DrilldownGroup/index.d.ts +1 -0
- package/types/Drilldown/DrilldownGroup/index.d.ts.map +1 -1
- package/types/Drilldown/DrilldownGroup/props.d.ts +5 -0
- package/types/Drilldown/DrilldownGroup/props.d.ts.map +1 -1
- package/types/Drilldown/index.d.ts +22 -2
- package/types/Drilldown/index.d.ts.map +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,17 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
## [11.0.2-snapshot-1](https://github.com/instructure/instructure-ui/compare/v11.0.1...v11.0.2-snapshot-1) (2025-10-17)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
### Features
|
|
10
|
+
|
|
11
|
+
* **ui-drilldown:** make Drilldown.Group controlled via selectedOptions prop. If provided, this prop fully drives the selection state instead of internal state ([3341639](https://github.com/instructure/instructure-ui/commit/33416395bf7d9a4d5649334d65cc9b599dbc2ec3))
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
6
17
|
## [11.0.1](https://github.com/instructure/instructure-ui/compare/v11.0.0...v11.0.1) (2025-10-13)
|
|
7
18
|
|
|
8
19
|
**Note:** Version bump only for package @instructure/ui-drilldown
|
|
@@ -22,5 +22,5 @@
|
|
|
22
22
|
* SOFTWARE.
|
|
23
23
|
*/
|
|
24
24
|
|
|
25
|
-
const allowedProps = ['id', 'children', 'renderGroupTitle', 'withoutSeparators', 'disabled', 'role', 'as', 'elementRef', 'selectableType', 'defaultSelected', 'onSelect'];
|
|
25
|
+
const allowedProps = ['id', 'children', 'renderGroupTitle', 'withoutSeparators', 'disabled', 'role', 'as', 'elementRef', 'selectableType', 'defaultSelected', 'selectedOptions', 'onSelect'];
|
|
26
26
|
export { allowedProps };
|
package/es/Drilldown/index.js
CHANGED
|
@@ -30,6 +30,7 @@ var _dec, _dec2, _class, _Drilldown, _IconArrowOpenEndSoli, _IconArrowOpenStartS
|
|
|
30
30
|
import { Children, Component } from 'react';
|
|
31
31
|
import { warn, error } from '@instructure/console';
|
|
32
32
|
import { contains, containsActiveElement } from '@instructure/ui-dom-utils';
|
|
33
|
+
import { deepEqual } from '@instructure/ui-utils';
|
|
33
34
|
import { callRenderProp, matchComponentTypes, omitProps, safeCloneElement, withDeterministicId } from '@instructure/ui-react-utils';
|
|
34
35
|
import { View } from '@instructure/ui-view';
|
|
35
36
|
import { Options } from '@instructure/ui-options';
|
|
@@ -79,7 +80,6 @@ let Drilldown = (_dec = withDeterministicId(), _dec2 = withStyle(generateStyle,
|
|
|
79
80
|
this._pageHistory = void 0;
|
|
80
81
|
// Map of the active options on the page (includes header options too)
|
|
81
82
|
this._activeOptionsMap = {};
|
|
82
|
-
// Map of the selected options in groups (grouped by group id)
|
|
83
83
|
this.ref = null;
|
|
84
84
|
this.handleRef = el => {
|
|
85
85
|
// ref and elementRef have to be set together for the same element
|
|
@@ -389,7 +389,7 @@ let Drilldown = (_dec = withDeterministicId(), _dec2 = withStyle(generateStyle,
|
|
|
389
389
|
activePageId: props.rootPageId,
|
|
390
390
|
highlightedOptionId: void 0,
|
|
391
391
|
lastSelectedId: void 0,
|
|
392
|
-
selectedGroupOptionsMap: this.
|
|
392
|
+
selectedGroupOptionsMap: this.getSelectedGroupOptionsMap()
|
|
393
393
|
};
|
|
394
394
|
this._pageHistory = [props.rootPageId];
|
|
395
395
|
this._id = props.id || props.deterministicId();
|
|
@@ -430,6 +430,47 @@ let Drilldown = (_dec = withDeterministicId(), _dec2 = withStyle(generateStyle,
|
|
|
430
430
|
highlightedOptionId: void 0
|
|
431
431
|
});
|
|
432
432
|
}
|
|
433
|
+
|
|
434
|
+
// This block syncs the internal state if the selectedOptions prop changes
|
|
435
|
+
// selectedOptions prop values always win over internal state.
|
|
436
|
+
let shouldUpdateState = false;
|
|
437
|
+
const nextSelectionMap = {
|
|
438
|
+
...this.state.selectedGroupOptionsMap
|
|
439
|
+
};
|
|
440
|
+
this.pages.forEach(page => {
|
|
441
|
+
this.getChildrenArray(page.props.children).forEach(child => {
|
|
442
|
+
if (matchComponentTypes(child, [DrilldownGroup])) {
|
|
443
|
+
var _this$getChildrenArra;
|
|
444
|
+
const _child$props = child.props,
|
|
445
|
+
groupId = _child$props.id,
|
|
446
|
+
selectableType = _child$props.selectableType,
|
|
447
|
+
selectedOptions = _child$props.selectedOptions,
|
|
448
|
+
groupChildren = _child$props.children;
|
|
449
|
+
if (!selectableType || !Array.isArray(selectedOptions)) return;
|
|
450
|
+
const newGroupMap = new Map();
|
|
451
|
+
(_this$getChildrenArra = this.getChildrenArray(groupChildren)) === null || _this$getChildrenArra === void 0 ? void 0 : _this$getChildrenArra.forEach(groupChild => {
|
|
452
|
+
if (matchComponentTypes(groupChild, [DrilldownOption])) {
|
|
453
|
+
const _groupChild$props = groupChild.props,
|
|
454
|
+
optionId = _groupChild$props.id,
|
|
455
|
+
optionValue = _groupChild$props.value;
|
|
456
|
+
if (selectedOptions.includes(optionValue)) {
|
|
457
|
+
newGroupMap.set(optionId, optionValue);
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
});
|
|
461
|
+
const currentGroupMapInState = this.state.selectedGroupOptionsMap[groupId] || new Map();
|
|
462
|
+
if (!deepEqual(this.getNormalizedMap(newGroupMap), this.getNormalizedMap(currentGroupMapInState))) {
|
|
463
|
+
nextSelectionMap[groupId] = newGroupMap;
|
|
464
|
+
shouldUpdateState = true;
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
});
|
|
468
|
+
});
|
|
469
|
+
if (shouldUpdateState) {
|
|
470
|
+
this.setState({
|
|
471
|
+
selectedGroupOptionsMap: nextSelectionMap
|
|
472
|
+
});
|
|
473
|
+
}
|
|
433
474
|
}
|
|
434
475
|
get makeStylesVariables() {
|
|
435
476
|
return {
|
|
@@ -521,43 +562,75 @@ let Drilldown = (_dec = withDeterministicId(), _dec2 = withStyle(generateStyle,
|
|
|
521
562
|
getPageChildById(id) {
|
|
522
563
|
return id ? this._activeOptionsMap[id] : void 0;
|
|
523
564
|
}
|
|
524
|
-
|
|
565
|
+
getNormalizedMap(map) {
|
|
566
|
+
return Array.from(map.entries());
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
/**
|
|
570
|
+
* Initializes the map of selected options for each group on initial render.
|
|
571
|
+
*
|
|
572
|
+
* This function establishes the selection state based on a clear precedence:
|
|
573
|
+
* 1. **Controlled Mode**: If a `Drilldown.Group` has the `selectedOptions` prop
|
|
574
|
+
* (as an array), it is treated as the absolute source of truth.
|
|
575
|
+
*
|
|
576
|
+
* 2. **Uncontrolled Mode**: If `selectedOptions` is not provided, the selection
|
|
577
|
+
* is determined by `defaultSelected` props, with the following priority:
|
|
578
|
+
* a. The `defaultSelected` boolean on an individual `Drilldown.Option`.
|
|
579
|
+
* b. The `defaultSelected` array of values on the `Drilldown.Group`.
|
|
580
|
+
*
|
|
581
|
+
* It also validates that 'single' selection groups do not mistakenly receive
|
|
582
|
+
* multiple selected or default values.
|
|
583
|
+
*
|
|
584
|
+
* @returns {SelectedGroupOptionsMap} An object where keys are group IDs and
|
|
585
|
+
* values are Maps of the selected { optionId: optionValue } pairs for that group.
|
|
586
|
+
*/
|
|
587
|
+
getSelectedGroupOptionsMap() {
|
|
525
588
|
const selectedGroupOptionsMap = {};
|
|
526
589
|
this.pages.forEach(page => {
|
|
527
590
|
const children = page.props.children;
|
|
528
591
|
this.getChildrenArray(children).forEach(child => {
|
|
529
592
|
if (matchComponentTypes(child, [DrilldownGroup])) {
|
|
530
|
-
var _this$
|
|
531
|
-
const _child$
|
|
532
|
-
groupId = _child$
|
|
533
|
-
selectableType = _child$
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
}
|
|
540
|
-
if (selectableType && !selectedGroupOptionsMap[groupId]) {
|
|
541
|
-
selectedGroupOptionsMap[groupId] = new Map();
|
|
542
|
-
}
|
|
543
|
-
if (selectableType === 'single' && groupDefaultSelected.length > 1) {
|
|
544
|
-
error(false, `Radio type selectable groups can have only one item selected! Group with id "${groupId}" cannot select multiple items: [${groupDefaultSelected.join(', ')}]!`);
|
|
545
|
-
return;
|
|
546
|
-
}
|
|
593
|
+
var _this$getChildrenArra2;
|
|
594
|
+
const _child$props2 = child.props,
|
|
595
|
+
groupId = _child$props2.id,
|
|
596
|
+
selectableType = _child$props2.selectableType,
|
|
597
|
+
selectedOptions = _child$props2.selectedOptions,
|
|
598
|
+
_child$props2$default = _child$props2.defaultSelected,
|
|
599
|
+
defaultSelected = _child$props2$default === void 0 ? [] : _child$props2$default,
|
|
600
|
+
groupChildren = _child$props2.children;
|
|
601
|
+
if (!selectableType) return;
|
|
547
602
|
selectedGroupOptionsMap[groupId] = new Map();
|
|
548
|
-
|
|
603
|
+
if (selectableType === 'single') {
|
|
604
|
+
if (Array.isArray(selectedOptions) && selectedOptions.length > 1) {
|
|
605
|
+
error(false, `Radio type selectable groups can have only one item selected! Group "${groupId}" has multiple values: [${selectedOptions.join(', ')}]!`);
|
|
606
|
+
return;
|
|
607
|
+
}
|
|
608
|
+
if (defaultSelected.length > 1) {
|
|
609
|
+
error(false, `Radio type selectable groups can have only one default item selected! Group "${groupId}" has multiple values: [${defaultSelected.join(', ')}]!`);
|
|
610
|
+
return;
|
|
611
|
+
}
|
|
612
|
+
}
|
|
613
|
+
(_this$getChildrenArra2 = this.getChildrenArray(groupChildren)) === null || _this$getChildrenArra2 === void 0 ? void 0 : _this$getChildrenArra2.forEach(groupChild => {
|
|
549
614
|
if (matchComponentTypes(groupChild, [DrilldownOption])) {
|
|
550
|
-
const _groupChild$
|
|
551
|
-
optionId = _groupChild$
|
|
552
|
-
optionValue = _groupChild$
|
|
553
|
-
optionDefaultSelected = _groupChild$
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
615
|
+
const _groupChild$props2 = groupChild.props,
|
|
616
|
+
optionId = _groupChild$props2.id,
|
|
617
|
+
optionValue = _groupChild$props2.value,
|
|
618
|
+
optionDefaultSelected = _groupChild$props2.defaultSelected;
|
|
619
|
+
if (optionValue == null) return;
|
|
620
|
+
let isSelected = false;
|
|
621
|
+
// If the group is controlled via the `selectedOptions` prop, it is the source of truth.
|
|
622
|
+
// `defaultSelected` values are ignored.
|
|
623
|
+
if (Array.isArray(selectedOptions)) {
|
|
624
|
+
isSelected = selectedOptions.includes(optionValue);
|
|
625
|
+
// Second strongest is the `defaultSelected` value on the option itself.
|
|
626
|
+
} else if (optionDefaultSelected === false) {
|
|
627
|
+
isSelected = false;
|
|
628
|
+
} else {
|
|
629
|
+
// Last is the `defaultSelected` array on the group.
|
|
630
|
+
const isGroupDefaultSelected = defaultSelected.includes(optionValue);
|
|
631
|
+
isSelected = optionDefaultSelected || isGroupDefaultSelected;
|
|
558
632
|
}
|
|
559
|
-
|
|
560
|
-
if (optionDefaultSelected || isGroupDefaultSelected) {
|
|
633
|
+
if (isSelected) {
|
|
561
634
|
selectedGroupOptionsMap[groupId].set(optionId, optionValue);
|
|
562
635
|
}
|
|
563
636
|
}
|
|
@@ -652,8 +725,8 @@ let Drilldown = (_dec = withDeterministicId(), _dec2 = withStyle(generateStyle,
|
|
|
652
725
|
let containsDuplicate = false;
|
|
653
726
|
const childMap = new Map();
|
|
654
727
|
for (const child of children) {
|
|
655
|
-
var _child$
|
|
656
|
-
if (child && typeof child === 'object' && (_child$
|
|
728
|
+
var _child$props3;
|
|
729
|
+
if (child && typeof child === 'object' && (_child$props3 = child.props) !== null && _child$props3 !== void 0 && _child$props3.id) {
|
|
657
730
|
if (!childMap.has(child.props.id)) {
|
|
658
731
|
childMap.set(child.props.id, true);
|
|
659
732
|
} else {
|
|
@@ -28,4 +28,4 @@ exports.allowedProps = void 0;
|
|
|
28
28
|
* SOFTWARE.
|
|
29
29
|
*/
|
|
30
30
|
|
|
31
|
-
const allowedProps = exports.allowedProps = ['id', 'children', 'renderGroupTitle', 'withoutSeparators', 'disabled', 'role', 'as', 'elementRef', 'selectableType', 'defaultSelected', 'onSelect'];
|
|
31
|
+
const allowedProps = exports.allowedProps = ['id', 'children', 'renderGroupTitle', 'withoutSeparators', 'disabled', 'role', 'as', 'elementRef', 'selectableType', 'defaultSelected', 'selectedOptions', 'onSelect'];
|
package/lib/Drilldown/index.js
CHANGED
|
@@ -10,6 +10,7 @@ var _react = require("react");
|
|
|
10
10
|
var _console = require("@instructure/console");
|
|
11
11
|
var _contains = require("@instructure/ui-dom-utils/lib/contains.js");
|
|
12
12
|
var _containsActiveElement = require("@instructure/ui-dom-utils/lib/containsActiveElement.js");
|
|
13
|
+
var _deepEqual = require("@instructure/ui-utils/lib/deepEqual.js");
|
|
13
14
|
var _callRenderProp = require("@instructure/ui-react-utils/lib/callRenderProp.js");
|
|
14
15
|
var _matchComponentTypes = require("@instructure/ui-react-utils/lib/matchComponentTypes.js");
|
|
15
16
|
var _omitProps = require("@instructure/ui-react-utils/lib/omitProps.js");
|
|
@@ -88,7 +89,6 @@ let Drilldown = exports.Drilldown = (_dec = (0, _withDeterministicId.withDetermi
|
|
|
88
89
|
this._pageHistory = void 0;
|
|
89
90
|
// Map of the active options on the page (includes header options too)
|
|
90
91
|
this._activeOptionsMap = {};
|
|
91
|
-
// Map of the selected options in groups (grouped by group id)
|
|
92
92
|
this.ref = null;
|
|
93
93
|
this.handleRef = el => {
|
|
94
94
|
// ref and elementRef have to be set together for the same element
|
|
@@ -398,7 +398,7 @@ let Drilldown = exports.Drilldown = (_dec = (0, _withDeterministicId.withDetermi
|
|
|
398
398
|
activePageId: props.rootPageId,
|
|
399
399
|
highlightedOptionId: void 0,
|
|
400
400
|
lastSelectedId: void 0,
|
|
401
|
-
selectedGroupOptionsMap: this.
|
|
401
|
+
selectedGroupOptionsMap: this.getSelectedGroupOptionsMap()
|
|
402
402
|
};
|
|
403
403
|
this._pageHistory = [props.rootPageId];
|
|
404
404
|
this._id = props.id || props.deterministicId();
|
|
@@ -439,6 +439,47 @@ let Drilldown = exports.Drilldown = (_dec = (0, _withDeterministicId.withDetermi
|
|
|
439
439
|
highlightedOptionId: void 0
|
|
440
440
|
});
|
|
441
441
|
}
|
|
442
|
+
|
|
443
|
+
// This block syncs the internal state if the selectedOptions prop changes
|
|
444
|
+
// selectedOptions prop values always win over internal state.
|
|
445
|
+
let shouldUpdateState = false;
|
|
446
|
+
const nextSelectionMap = {
|
|
447
|
+
...this.state.selectedGroupOptionsMap
|
|
448
|
+
};
|
|
449
|
+
this.pages.forEach(page => {
|
|
450
|
+
this.getChildrenArray(page.props.children).forEach(child => {
|
|
451
|
+
if ((0, _matchComponentTypes.matchComponentTypes)(child, [_DrilldownGroup.DrilldownGroup])) {
|
|
452
|
+
var _this$getChildrenArra;
|
|
453
|
+
const _child$props = child.props,
|
|
454
|
+
groupId = _child$props.id,
|
|
455
|
+
selectableType = _child$props.selectableType,
|
|
456
|
+
selectedOptions = _child$props.selectedOptions,
|
|
457
|
+
groupChildren = _child$props.children;
|
|
458
|
+
if (!selectableType || !Array.isArray(selectedOptions)) return;
|
|
459
|
+
const newGroupMap = new Map();
|
|
460
|
+
(_this$getChildrenArra = this.getChildrenArray(groupChildren)) === null || _this$getChildrenArra === void 0 ? void 0 : _this$getChildrenArra.forEach(groupChild => {
|
|
461
|
+
if ((0, _matchComponentTypes.matchComponentTypes)(groupChild, [_DrilldownOption.DrilldownOption])) {
|
|
462
|
+
const _groupChild$props = groupChild.props,
|
|
463
|
+
optionId = _groupChild$props.id,
|
|
464
|
+
optionValue = _groupChild$props.value;
|
|
465
|
+
if (selectedOptions.includes(optionValue)) {
|
|
466
|
+
newGroupMap.set(optionId, optionValue);
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
});
|
|
470
|
+
const currentGroupMapInState = this.state.selectedGroupOptionsMap[groupId] || new Map();
|
|
471
|
+
if (!(0, _deepEqual.deepEqual)(this.getNormalizedMap(newGroupMap), this.getNormalizedMap(currentGroupMapInState))) {
|
|
472
|
+
nextSelectionMap[groupId] = newGroupMap;
|
|
473
|
+
shouldUpdateState = true;
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
});
|
|
477
|
+
});
|
|
478
|
+
if (shouldUpdateState) {
|
|
479
|
+
this.setState({
|
|
480
|
+
selectedGroupOptionsMap: nextSelectionMap
|
|
481
|
+
});
|
|
482
|
+
}
|
|
442
483
|
}
|
|
443
484
|
get makeStylesVariables() {
|
|
444
485
|
return {
|
|
@@ -530,43 +571,75 @@ let Drilldown = exports.Drilldown = (_dec = (0, _withDeterministicId.withDetermi
|
|
|
530
571
|
getPageChildById(id) {
|
|
531
572
|
return id ? this._activeOptionsMap[id] : void 0;
|
|
532
573
|
}
|
|
533
|
-
|
|
574
|
+
getNormalizedMap(map) {
|
|
575
|
+
return Array.from(map.entries());
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
/**
|
|
579
|
+
* Initializes the map of selected options for each group on initial render.
|
|
580
|
+
*
|
|
581
|
+
* This function establishes the selection state based on a clear precedence:
|
|
582
|
+
* 1. **Controlled Mode**: If a `Drilldown.Group` has the `selectedOptions` prop
|
|
583
|
+
* (as an array), it is treated as the absolute source of truth.
|
|
584
|
+
*
|
|
585
|
+
* 2. **Uncontrolled Mode**: If `selectedOptions` is not provided, the selection
|
|
586
|
+
* is determined by `defaultSelected` props, with the following priority:
|
|
587
|
+
* a. The `defaultSelected` boolean on an individual `Drilldown.Option`.
|
|
588
|
+
* b. The `defaultSelected` array of values on the `Drilldown.Group`.
|
|
589
|
+
*
|
|
590
|
+
* It also validates that 'single' selection groups do not mistakenly receive
|
|
591
|
+
* multiple selected or default values.
|
|
592
|
+
*
|
|
593
|
+
* @returns {SelectedGroupOptionsMap} An object where keys are group IDs and
|
|
594
|
+
* values are Maps of the selected { optionId: optionValue } pairs for that group.
|
|
595
|
+
*/
|
|
596
|
+
getSelectedGroupOptionsMap() {
|
|
534
597
|
const selectedGroupOptionsMap = {};
|
|
535
598
|
this.pages.forEach(page => {
|
|
536
599
|
const children = page.props.children;
|
|
537
600
|
this.getChildrenArray(children).forEach(child => {
|
|
538
601
|
if ((0, _matchComponentTypes.matchComponentTypes)(child, [_DrilldownGroup.DrilldownGroup])) {
|
|
539
|
-
var _this$
|
|
540
|
-
const _child$
|
|
541
|
-
groupId = _child$
|
|
542
|
-
selectableType = _child$
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
}
|
|
549
|
-
if (selectableType && !selectedGroupOptionsMap[groupId]) {
|
|
550
|
-
selectedGroupOptionsMap[groupId] = new Map();
|
|
551
|
-
}
|
|
552
|
-
if (selectableType === 'single' && groupDefaultSelected.length > 1) {
|
|
553
|
-
(0, _console.error)(false, `Radio type selectable groups can have only one item selected! Group with id "${groupId}" cannot select multiple items: [${groupDefaultSelected.join(', ')}]!`);
|
|
554
|
-
return;
|
|
555
|
-
}
|
|
602
|
+
var _this$getChildrenArra2;
|
|
603
|
+
const _child$props2 = child.props,
|
|
604
|
+
groupId = _child$props2.id,
|
|
605
|
+
selectableType = _child$props2.selectableType,
|
|
606
|
+
selectedOptions = _child$props2.selectedOptions,
|
|
607
|
+
_child$props2$default = _child$props2.defaultSelected,
|
|
608
|
+
defaultSelected = _child$props2$default === void 0 ? [] : _child$props2$default,
|
|
609
|
+
groupChildren = _child$props2.children;
|
|
610
|
+
if (!selectableType) return;
|
|
556
611
|
selectedGroupOptionsMap[groupId] = new Map();
|
|
557
|
-
|
|
612
|
+
if (selectableType === 'single') {
|
|
613
|
+
if (Array.isArray(selectedOptions) && selectedOptions.length > 1) {
|
|
614
|
+
(0, _console.error)(false, `Radio type selectable groups can have only one item selected! Group "${groupId}" has multiple values: [${selectedOptions.join(', ')}]!`);
|
|
615
|
+
return;
|
|
616
|
+
}
|
|
617
|
+
if (defaultSelected.length > 1) {
|
|
618
|
+
(0, _console.error)(false, `Radio type selectable groups can have only one default item selected! Group "${groupId}" has multiple values: [${defaultSelected.join(', ')}]!`);
|
|
619
|
+
return;
|
|
620
|
+
}
|
|
621
|
+
}
|
|
622
|
+
(_this$getChildrenArra2 = this.getChildrenArray(groupChildren)) === null || _this$getChildrenArra2 === void 0 ? void 0 : _this$getChildrenArra2.forEach(groupChild => {
|
|
558
623
|
if ((0, _matchComponentTypes.matchComponentTypes)(groupChild, [_DrilldownOption.DrilldownOption])) {
|
|
559
|
-
const _groupChild$
|
|
560
|
-
optionId = _groupChild$
|
|
561
|
-
optionValue = _groupChild$
|
|
562
|
-
optionDefaultSelected = _groupChild$
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
624
|
+
const _groupChild$props2 = groupChild.props,
|
|
625
|
+
optionId = _groupChild$props2.id,
|
|
626
|
+
optionValue = _groupChild$props2.value,
|
|
627
|
+
optionDefaultSelected = _groupChild$props2.defaultSelected;
|
|
628
|
+
if (optionValue == null) return;
|
|
629
|
+
let isSelected = false;
|
|
630
|
+
// If the group is controlled via the `selectedOptions` prop, it is the source of truth.
|
|
631
|
+
// `defaultSelected` values are ignored.
|
|
632
|
+
if (Array.isArray(selectedOptions)) {
|
|
633
|
+
isSelected = selectedOptions.includes(optionValue);
|
|
634
|
+
// Second strongest is the `defaultSelected` value on the option itself.
|
|
635
|
+
} else if (optionDefaultSelected === false) {
|
|
636
|
+
isSelected = false;
|
|
637
|
+
} else {
|
|
638
|
+
// Last is the `defaultSelected` array on the group.
|
|
639
|
+
const isGroupDefaultSelected = defaultSelected.includes(optionValue);
|
|
640
|
+
isSelected = optionDefaultSelected || isGroupDefaultSelected;
|
|
567
641
|
}
|
|
568
|
-
|
|
569
|
-
if (optionDefaultSelected || isGroupDefaultSelected) {
|
|
642
|
+
if (isSelected) {
|
|
570
643
|
selectedGroupOptionsMap[groupId].set(optionId, optionValue);
|
|
571
644
|
}
|
|
572
645
|
}
|
|
@@ -661,8 +734,8 @@ let Drilldown = exports.Drilldown = (_dec = (0, _withDeterministicId.withDetermi
|
|
|
661
734
|
let containsDuplicate = false;
|
|
662
735
|
const childMap = new Map();
|
|
663
736
|
for (const child of children) {
|
|
664
|
-
var _child$
|
|
665
|
-
if (child && typeof child === 'object' && (_child$
|
|
737
|
+
var _child$props3;
|
|
738
|
+
if (child && typeof child === 'object' && (_child$props3 = child.props) !== null && _child$props3 !== void 0 && _child$props3.id) {
|
|
666
739
|
if (!childMap.has(child.props.id)) {
|
|
667
740
|
childMap.set(child.props.id, true);
|
|
668
741
|
} else {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@instructure/ui-drilldown",
|
|
3
|
-
"version": "11.0.1",
|
|
3
|
+
"version": "11.0.2-snapshot-1",
|
|
4
4
|
"description": "A drilldown menu component",
|
|
5
5
|
"author": "Instructure, Inc. Engineering and Product Design",
|
|
6
6
|
"module": "./es/index.js",
|
|
@@ -24,25 +24,25 @@
|
|
|
24
24
|
"license": "MIT",
|
|
25
25
|
"dependencies": {
|
|
26
26
|
"@babel/runtime": "^7.27.6",
|
|
27
|
-
"@instructure/console": "11.0.1",
|
|
28
|
-
"@instructure/emotion": "11.0.1",
|
|
29
|
-
"@instructure/shared-types": "11.0.1",
|
|
30
|
-
"@instructure/ui-dom-utils": "11.0.1",
|
|
31
|
-
"@instructure/ui-icons": "11.0.1",
|
|
32
|
-
"@instructure/ui-options": "11.0.1",
|
|
33
|
-
"@instructure/ui-popover": "11.0.1",
|
|
34
|
-
"@instructure/ui-position": "11.0.1",
|
|
35
|
-
"@instructure/ui-react-utils": "11.0.1",
|
|
36
|
-
"@instructure/ui-selectable": "11.0.1",
|
|
37
|
-
"@instructure/ui-utils": "11.0.1",
|
|
38
|
-
"@instructure/ui-view": "11.0.1"
|
|
27
|
+
"@instructure/console": "11.0.2-snapshot-1",
|
|
28
|
+
"@instructure/emotion": "11.0.2-snapshot-1",
|
|
29
|
+
"@instructure/shared-types": "11.0.2-snapshot-1",
|
|
30
|
+
"@instructure/ui-dom-utils": "11.0.2-snapshot-1",
|
|
31
|
+
"@instructure/ui-icons": "11.0.2-snapshot-1",
|
|
32
|
+
"@instructure/ui-options": "11.0.2-snapshot-1",
|
|
33
|
+
"@instructure/ui-popover": "11.0.2-snapshot-1",
|
|
34
|
+
"@instructure/ui-position": "11.0.2-snapshot-1",
|
|
35
|
+
"@instructure/ui-react-utils": "11.0.2-snapshot-1",
|
|
36
|
+
"@instructure/ui-selectable": "11.0.2-snapshot-1",
|
|
37
|
+
"@instructure/ui-utils": "11.0.2-snapshot-1",
|
|
38
|
+
"@instructure/ui-view": "11.0.2-snapshot-1"
|
|
39
39
|
},
|
|
40
40
|
"devDependencies": {
|
|
41
|
-
"@instructure/ui-axe-check": "11.0.1",
|
|
42
|
-
"@instructure/ui-babel-preset": "11.0.1",
|
|
43
|
-
"@instructure/ui-color-utils": "11.0.1",
|
|
44
|
-
"@instructure/ui-scripts": "11.0.1",
|
|
45
|
-
"@instructure/ui-themes": "11.0.1",
|
|
41
|
+
"@instructure/ui-axe-check": "11.0.2-snapshot-1",
|
|
42
|
+
"@instructure/ui-babel-preset": "11.0.2-snapshot-1",
|
|
43
|
+
"@instructure/ui-color-utils": "11.0.2-snapshot-1",
|
|
44
|
+
"@instructure/ui-scripts": "11.0.2-snapshot-1",
|
|
45
|
+
"@instructure/ui-themes": "11.0.2-snapshot-1",
|
|
46
46
|
"@testing-library/jest-dom": "^6.6.3",
|
|
47
47
|
"@testing-library/react": "15.0.7",
|
|
48
48
|
"@testing-library/user-event": "^14.6.1",
|
|
@@ -88,6 +88,12 @@ type DrilldownGroupOwnProps = {
|
|
|
88
88
|
*/
|
|
89
89
|
defaultSelected?: DrilldownOptionValue[]
|
|
90
90
|
|
|
91
|
+
/**
|
|
92
|
+
* An array of the values for the selected items. If defined, the component will act controlled and will not manage its own state. Works only with "selectableType" set.
|
|
93
|
+
* If "selectableType" is "single", the array has to have 1 item.
|
|
94
|
+
*/
|
|
95
|
+
selectedOptions?: DrilldownOptionValue[]
|
|
96
|
+
|
|
91
97
|
/**
|
|
92
98
|
* Callback fired when an option within the `<Drilldown.Group />` is selected
|
|
93
99
|
*/
|
|
@@ -120,6 +126,7 @@ const allowedProps: AllowedPropKeys = [
|
|
|
120
126
|
'elementRef',
|
|
121
127
|
'selectableType',
|
|
122
128
|
'defaultSelected',
|
|
129
|
+
'selectedOptions',
|
|
123
130
|
'onSelect'
|
|
124
131
|
]
|
|
125
132
|
|