@instructure/ui-drilldown 8.32.1 → 8.32.2-snapshot-2

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 CHANGED
@@ -3,6 +3,22 @@
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
+ ## [8.32.2-snapshot-2](https://github.com/instructure/instructure-ui/compare/v8.32.1...v8.32.2-snapshot-2) (2023-01-02)
7
+
8
+
9
+ ### Bug Fixes
10
+
11
+ * **ui-drilldown:** selectableType=single works like radio buttons ([3a20ddb](https://github.com/instructure/instructure-ui/commit/3a20ddb132bf5efd15f719df1236cd98933f1219))
12
+
13
+
14
+ ### Features
15
+
16
+ * **ui-drilldown:** add `selected` prop to Drilldown.Option which allows controlled behavior ([5776937](https://github.com/instructure/instructure-ui/commit/57769376930e8f6201ce603b9e9e832564db2dd6))
17
+
18
+
19
+
20
+
21
+
6
22
  ## [8.32.1](https://github.com/instructure/instructure-ui/compare/v8.30.0...v8.32.1) (2022-12-01)
7
23
 
8
24
  **Note:** Version bump only for package @instructure/ui-drilldown
@@ -27,6 +27,7 @@ const propTypes = {
27
27
  children: PropTypes.oneOfType([PropTypes.node, PropTypes.func]),
28
28
  subPageId: PropTypes.string,
29
29
  disabled: PropTypes.bool,
30
+ selected: PropTypes.bool,
30
31
  value: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
31
32
  href: PropTypes.string,
32
33
  as: PropTypes.elementType,
@@ -42,5 +43,5 @@ const propTypes = {
42
43
  defaultSelected: PropTypes.bool,
43
44
  elementRef: PropTypes.func
44
45
  };
45
- const allowedProps = ['id', 'children', 'subPageId', 'disabled', 'value', 'href', 'as', 'role', 'renderLabelInfo', 'renderBeforeLabel', 'renderAfterLabel', 'beforeLabelContentVAlign', 'afterLabelContentVAlign', 'description', 'descriptionRole', 'onOptionClick', 'defaultSelected', 'elementRef'];
46
+ const allowedProps = ['id', 'children', 'subPageId', 'disabled', 'selected', 'value', 'href', 'as', 'role', 'renderLabelInfo', 'renderBeforeLabel', 'renderAfterLabel', 'beforeLabelContentVAlign', 'afterLabelContentVAlign', 'description', 'descriptionRole', 'onOptionClick', 'defaultSelected', 'elementRef'];
46
47
  export { propTypes, allowedProps };
@@ -75,7 +75,6 @@ let Drilldown = (_dec = withDeterministicId(), _dec2 = withStyle(generateStyle,
75
75
  this._headerActionId = void 0;
76
76
  this._pageHistory = void 0;
77
77
  this._activeOptionsMap = {};
78
- this._selectedGroupOptionsMap = {};
79
78
  this.ref = null;
80
79
 
81
80
  this.handleRef = el => {
@@ -370,10 +369,10 @@ let Drilldown = (_dec = withDeterministicId(), _dec2 = withStyle(generateStyle,
370
369
  isShowingPopover: props.trigger ? !!props.show : false,
371
370
  activePageId: props.rootPageId,
372
371
  highlightedOptionId: void 0,
373
- lastSelectedId: void 0
372
+ lastSelectedId: void 0,
373
+ selectedGroupOptionsMap: this.setDefaultSelected()
374
374
  };
375
375
  this._pageHistory = [props.rootPageId];
376
- this.setDefaultSelected();
377
376
  this._id = props.id || props.deterministicId();
378
377
  this._triggerId = props.deterministicId('Drilldown-Trigger');
379
378
  this._headerBackId = props.deterministicId('DrilldownHeader-Back');
@@ -523,6 +522,7 @@ let Drilldown = (_dec = withDeterministicId(), _dec2 = withStyle(generateStyle,
523
522
  }
524
523
 
525
524
  setDefaultSelected() {
525
+ const selectedGroupOptionsMap = {};
526
526
  this.pages.forEach(page => {
527
527
  const children = page.props.children;
528
528
  this.getChildrenArray(children).forEach(child => {
@@ -540,12 +540,16 @@ let Drilldown = (_dec = withDeterministicId(), _dec2 = withStyle(generateStyle,
540
540
  return;
541
541
  }
542
542
 
543
+ if (selectableType && !selectedGroupOptionsMap[groupId]) {
544
+ selectedGroupOptionsMap[groupId] = new Map();
545
+ }
546
+
543
547
  if (selectableType === 'single' && groupDefaultSelected.length > 1) {
544
548
  error(false, `Radio type selectable groups can have only one item selected! Group with id "${groupId}" cannot select multiple items: [${groupDefaultSelected.join(', ')}]!`);
545
549
  return;
546
550
  }
547
551
 
548
- this._selectedGroupOptionsMap[groupId] = new Map();
552
+ selectedGroupOptionsMap[groupId] = new Map();
549
553
  (_this$getChildrenArra = this.getChildrenArray(groupChildren)) === null || _this$getChildrenArra === void 0 ? void 0 : _this$getChildrenArra.forEach(groupChild => {
550
554
  if (matchComponentTypes(groupChild, [DrilldownOption])) {
551
555
  const _groupChild$props = groupChild.props,
@@ -560,17 +564,18 @@ let Drilldown = (_dec = withDeterministicId(), _dec2 = withStyle(generateStyle,
560
564
  const isGroupDefaultSelected = typeof optionValue !== 'undefined' && groupDefaultSelected.filter(value => typeof value !== 'undefined').includes(optionValue);
561
565
 
562
566
  if (optionDefaultSelected || isGroupDefaultSelected) {
563
- this._selectedGroupOptionsMap[groupId].set(optionId, optionValue);
567
+ selectedGroupOptionsMap[groupId].set(optionId, optionValue);
564
568
  }
565
569
  }
566
570
  });
567
571
  }
568
572
  });
569
573
  });
574
+ return selectedGroupOptionsMap;
570
575
  }
571
576
 
572
577
  get selectedGroupOptionIdsArray() {
573
- return Object.values(this._selectedGroupOptionsMap).map(groupIdMap => Array.from(groupIdMap.keys())).flat();
578
+ return Object.values(this.state.selectedGroupOptionsMap).map(groupIdMap => Array.from(groupIdMap.keys())).flat();
574
579
  }
575
580
 
576
581
  get headerChildren() {
@@ -705,57 +710,66 @@ let Drilldown = (_dec = withDeterministicId(), _dec2 = withStyle(generateStyle,
705
710
  }
706
711
 
707
712
  handleGroupOptionSelected(event, selectedOption) {
708
- const _selectedOption$props = selectedOption.props,
709
- optionId = _selectedOption$props.id,
710
- value = _selectedOption$props.value;
711
- const _ref6 = selectedOption.groupProps,
712
- groupId = _ref6.id,
713
- selectableType = _ref6.selectableType,
714
- groupOnSelect = _ref6.onSelect;
715
- const onSelect = this.props.onSelect;
716
-
717
- if (this._selectedGroupOptionsMap[groupId].has(optionId)) {
718
- // toggle off, if already selected
719
- this._selectedGroupOptionsMap[groupId].delete(optionId);
720
- } else {
721
- if (selectableType === 'multiple') {
722
- // "checkbox"
723
- this._selectedGroupOptionsMap[groupId].set(optionId, value);
724
- } else if (selectableType === 'single') {
725
- // "radio"
726
- this._selectedGroupOptionsMap[groupId] = new Map();
727
-
728
- this._selectedGroupOptionsMap[groupId].set(optionId, value);
713
+ this.setState(oldState => {
714
+ var _oldState$selectedGro;
715
+
716
+ const _selectedOption$props = selectedOption.props,
717
+ optionId = _selectedOption$props.id,
718
+ value = _selectedOption$props.value;
719
+ const _ref6 = selectedOption.groupProps,
720
+ groupId = _ref6.id,
721
+ selectableType = _ref6.selectableType;
722
+ let newState = new Map(oldState.selectedGroupOptionsMap[groupId]);
723
+
724
+ if (selectableType === 'multiple' && Boolean((_oldState$selectedGro = oldState.selectedGroupOptionsMap[groupId]) === null || _oldState$selectedGro === void 0 ? void 0 : _oldState$selectedGro.has(optionId))) {
725
+ // toggle off, if already selected
726
+ newState.delete(optionId);
727
+ } else {
728
+ if (selectableType === 'multiple') {
729
+ // "checkbox"
730
+ newState.set(optionId, value);
731
+ } else if (selectableType === 'single') {
732
+ // "radio"
733
+ newState = new Map();
734
+ newState.set(optionId, value);
735
+ }
729
736
  }
730
- } // needed for rerender
731
-
732
737
 
733
- this.setState({
734
- lastSelectedId: optionId
735
- });
738
+ return { ...oldState,
739
+ selectedGroupOptionsMap: { ...oldState.selectedGroupOptionsMap,
740
+ [groupId]: newState
741
+ }
742
+ };
743
+ }, () => {
744
+ const value = selectedOption.props.value;
745
+ const _ref7 = selectedOption.groupProps,
746
+ groupId = _ref7.id,
747
+ groupOnSelect = _ref7.onSelect;
748
+ const onSelect = this.props.onSelect;
736
749
 
737
- const groupProps = selectedOption.groupProps,
738
- option = _objectWithoutProperties(selectedOption, _excluded2);
750
+ const groupProps = selectedOption.groupProps,
751
+ option = _objectWithoutProperties(selectedOption, _excluded2);
739
752
 
740
- const selectedOptionValuesInGroup = Array.from(this._selectedGroupOptionsMap[groupId].values());
753
+ const selectedOptionValuesInGroup = [...this.state.selectedGroupOptionsMap[groupId].values()];
741
754
 
742
- if (typeof groupOnSelect === 'function') {
743
- groupOnSelect(event, {
744
- value: selectedOptionValuesInGroup,
745
- isSelected: this._selectedGroupOptionsMap[groupId].has(optionId),
746
- selectedOption: option,
747
- drilldown: this
748
- });
749
- }
755
+ if (typeof groupOnSelect === 'function') {
756
+ groupOnSelect(event, {
757
+ value: selectedOptionValuesInGroup,
758
+ isSelected: selectedOptionValuesInGroup.includes(value),
759
+ selectedOption: option,
760
+ drilldown: this
761
+ });
762
+ }
750
763
 
751
- if (typeof onSelect === 'function') {
752
- onSelect(event, {
753
- value: selectedOptionValuesInGroup,
754
- isSelected: this._selectedGroupOptionsMap[groupId].has(optionId),
755
- selectedOption: option,
756
- drilldown: this
757
- });
758
- }
764
+ if (typeof onSelect === 'function') {
765
+ onSelect(event, {
766
+ value: selectedOptionValuesInGroup,
767
+ isSelected: selectedOptionValuesInGroup.includes(value),
768
+ selectedOption: option,
769
+ drilldown: this
770
+ });
771
+ }
772
+ });
759
773
  }
760
774
 
761
775
  renderList(getOptionProps, getDisabledOptionProps) {
@@ -911,8 +925,17 @@ let Drilldown = (_dec = withDeterministicId(), _dec2 = withStyle(generateStyle,
911
925
  optionProps.renderBeforeLabel = _IconArrowOpenStartSo || (_IconArrowOpenStartSo = jsx(IconArrowOpenStartSolid, null));
912
926
  }
913
927
 
914
- if (groupProps !== null && groupProps !== void 0 && groupProps.selectableType) {
915
- isSelected = this._selectedGroupOptionsMap[groupProps.id].has(id);
928
+ const isOptionControlled = typeof option.props.selected === 'boolean';
929
+
930
+ if ((groupProps !== null && groupProps !== void 0 && groupProps.selectableType || isOptionControlled) && groupProps) {
931
+ if (!isOptionControlled) {
932
+ var _this$state$selectedG;
933
+
934
+ isSelected = Boolean((_this$state$selectedG = this.state.selectedGroupOptionsMap[groupProps.id]) === null || _this$state$selectedG === void 0 ? void 0 : _this$state$selectedG.has(id));
935
+ } else {
936
+ isSelected = Boolean(option.props.selected);
937
+ }
938
+
916
939
  optionProps['aria-checked'] = isSelected;
917
940
  optionProps.renderBeforeLabel = jsx(IconCheckSolid, {
918
941
  style: {
@@ -1014,7 +1037,6 @@ let Drilldown = (_dec = withDeterministicId(), _dec2 = withStyle(generateStyle,
1014
1037
  children = _group$props.children,
1015
1038
  renderGroupTitle = _group$props.renderGroupTitle,
1016
1039
  themeOverride = _group$props.themeOverride,
1017
- selectableType = _group$props.selectableType,
1018
1040
  role = _group$props.role,
1019
1041
  as = _group$props.as,
1020
1042
  elementRef = _group$props.elementRef;
@@ -1027,10 +1049,6 @@ let Drilldown = (_dec = withDeterministicId(), _dec2 = withStyle(generateStyle,
1027
1049
 
1028
1050
  if (needsFirstSeparator) {
1029
1051
  groupChildren.push(_Options$Separator || (_Options$Separator = jsx(Options.Separator, null)));
1030
- }
1031
-
1032
- if (selectableType && !this._selectedGroupOptionsMap[id]) {
1033
- this._selectedGroupOptionsMap[id] = new Map();
1034
1052
  } // create a sublist as a group
1035
1053
  // (a wrapping list item will be created by Options)
1036
1054
 
@@ -1100,11 +1118,11 @@ let Drilldown = (_dec = withDeterministicId(), _dec2 = withStyle(generateStyle,
1100
1118
  id: lastOptionId
1101
1119
  });
1102
1120
  }
1103
- }, _ref7 => {
1104
- let getTriggerProps = _ref7.getTriggerProps,
1105
- getListProps = _ref7.getListProps,
1106
- getOptionProps = _ref7.getOptionProps,
1107
- getDisabledOptionProps = _ref7.getDisabledOptionProps;
1121
+ }, _ref8 => {
1122
+ let getTriggerProps = _ref8.getTriggerProps,
1123
+ getListProps = _ref8.getListProps,
1124
+ getOptionProps = _ref8.getOptionProps,
1125
+ getDisabledOptionProps = _ref8.getDisabledOptionProps;
1108
1126
  return jsx(View, Object.assign({
1109
1127
  as: "div",
1110
1128
  elementRef: this.handleDrilldownRef,
@@ -1190,8 +1208,8 @@ let Drilldown = (_dec = withDeterministicId(), _dec2 = withStyle(generateStyle,
1190
1208
  isShowingContent: show,
1191
1209
  defaultIsShowingContent: defaultShow,
1192
1210
  shouldCloseOnDocumentClick: true,
1193
- onHideContent: (event, _ref8) => {
1194
- let documentClick = _ref8.documentClick;
1211
+ onHideContent: (event, _ref9) => {
1212
+ let documentClick = _ref9.documentClick;
1195
1213
 
1196
1214
  if (typeof onDismiss === 'function') {
1197
1215
  onDismiss(event, documentClick);
@@ -37,6 +37,7 @@ const propTypes = {
37
37
  children: _propTypes.default.oneOfType([_propTypes.default.node, _propTypes.default.func]),
38
38
  subPageId: _propTypes.default.string,
39
39
  disabled: _propTypes.default.bool,
40
+ selected: _propTypes.default.bool,
40
41
  value: _propTypes.default.oneOfType([_propTypes.default.number, _propTypes.default.string]),
41
42
  href: _propTypes.default.string,
42
43
  as: _propTypes.default.elementType,
@@ -53,5 +54,5 @@ const propTypes = {
53
54
  elementRef: _propTypes.default.func
54
55
  };
55
56
  exports.propTypes = propTypes;
56
- const allowedProps = ['id', 'children', 'subPageId', 'disabled', 'value', 'href', 'as', 'role', 'renderLabelInfo', 'renderBeforeLabel', 'renderAfterLabel', 'beforeLabelContentVAlign', 'afterLabelContentVAlign', 'description', 'descriptionRole', 'onOptionClick', 'defaultSelected', 'elementRef'];
57
+ const allowedProps = ['id', 'children', 'subPageId', 'disabled', 'selected', 'value', 'href', 'as', 'role', 'renderLabelInfo', 'renderBeforeLabel', 'renderAfterLabel', 'beforeLabelContentVAlign', 'afterLabelContentVAlign', 'description', 'descriptionRole', 'onOptionClick', 'defaultSelected', 'elementRef'];
57
58
  exports.allowedProps = allowedProps;
@@ -91,7 +91,6 @@ let Drilldown = (_dec = (0, _withDeterministicId.withDeterministicId)(), _dec2 =
91
91
  this._headerActionId = void 0;
92
92
  this._pageHistory = void 0;
93
93
  this._activeOptionsMap = {};
94
- this._selectedGroupOptionsMap = {};
95
94
  this.ref = null;
96
95
 
97
96
  this.handleRef = el => {
@@ -384,10 +383,10 @@ let Drilldown = (_dec = (0, _withDeterministicId.withDeterministicId)(), _dec2 =
384
383
  isShowingPopover: props.trigger ? !!props.show : false,
385
384
  activePageId: props.rootPageId,
386
385
  highlightedOptionId: void 0,
387
- lastSelectedId: void 0
386
+ lastSelectedId: void 0,
387
+ selectedGroupOptionsMap: this.setDefaultSelected()
388
388
  };
389
389
  this._pageHistory = [props.rootPageId];
390
- this.setDefaultSelected();
391
390
  this._id = props.id || props.deterministicId();
392
391
  this._triggerId = props.deterministicId('Drilldown-Trigger');
393
392
  this._headerBackId = props.deterministicId('DrilldownHeader-Back');
@@ -537,6 +536,7 @@ let Drilldown = (_dec = (0, _withDeterministicId.withDeterministicId)(), _dec2 =
537
536
  }
538
537
 
539
538
  setDefaultSelected() {
539
+ const selectedGroupOptionsMap = {};
540
540
  this.pages.forEach(page => {
541
541
  const children = page.props.children;
542
542
  this.getChildrenArray(children).forEach(child => {
@@ -554,12 +554,16 @@ let Drilldown = (_dec = (0, _withDeterministicId.withDeterministicId)(), _dec2 =
554
554
  return;
555
555
  }
556
556
 
557
+ if (selectableType && !selectedGroupOptionsMap[groupId]) {
558
+ selectedGroupOptionsMap[groupId] = new Map();
559
+ }
560
+
557
561
  if (selectableType === 'single' && groupDefaultSelected.length > 1) {
558
562
  (0, _console.error)(false, `Radio type selectable groups can have only one item selected! Group with id "${groupId}" cannot select multiple items: [${groupDefaultSelected.join(', ')}]!`);
559
563
  return;
560
564
  }
561
565
 
562
- this._selectedGroupOptionsMap[groupId] = new Map();
566
+ selectedGroupOptionsMap[groupId] = new Map();
563
567
  (_this$getChildrenArra = this.getChildrenArray(groupChildren)) === null || _this$getChildrenArra === void 0 ? void 0 : _this$getChildrenArra.forEach(groupChild => {
564
568
  if ((0, _matchComponentTypes.matchComponentTypes)(groupChild, [_DrilldownOption.DrilldownOption])) {
565
569
  const _groupChild$props = groupChild.props,
@@ -574,17 +578,18 @@ let Drilldown = (_dec = (0, _withDeterministicId.withDeterministicId)(), _dec2 =
574
578
  const isGroupDefaultSelected = typeof optionValue !== 'undefined' && groupDefaultSelected.filter(value => typeof value !== 'undefined').includes(optionValue);
575
579
 
576
580
  if (optionDefaultSelected || isGroupDefaultSelected) {
577
- this._selectedGroupOptionsMap[groupId].set(optionId, optionValue);
581
+ selectedGroupOptionsMap[groupId].set(optionId, optionValue);
578
582
  }
579
583
  }
580
584
  });
581
585
  }
582
586
  });
583
587
  });
588
+ return selectedGroupOptionsMap;
584
589
  }
585
590
 
586
591
  get selectedGroupOptionIdsArray() {
587
- return Object.values(this._selectedGroupOptionsMap).map(groupIdMap => Array.from(groupIdMap.keys())).flat();
592
+ return Object.values(this.state.selectedGroupOptionsMap).map(groupIdMap => Array.from(groupIdMap.keys())).flat();
588
593
  }
589
594
 
590
595
  get headerChildren() {
@@ -719,55 +724,64 @@ let Drilldown = (_dec = (0, _withDeterministicId.withDeterministicId)(), _dec2 =
719
724
  }
720
725
 
721
726
  handleGroupOptionSelected(event, selectedOption) {
722
- const _selectedOption$props = selectedOption.props,
723
- optionId = _selectedOption$props.id,
724
- value = _selectedOption$props.value;
725
- const _ref6 = selectedOption.groupProps,
726
- groupId = _ref6.id,
727
- selectableType = _ref6.selectableType,
728
- groupOnSelect = _ref6.onSelect;
729
- const onSelect = this.props.onSelect;
730
-
731
- if (this._selectedGroupOptionsMap[groupId].has(optionId)) {
732
- // toggle off, if already selected
733
- this._selectedGroupOptionsMap[groupId].delete(optionId);
734
- } else {
735
- if (selectableType === 'multiple') {
736
- // "checkbox"
737
- this._selectedGroupOptionsMap[groupId].set(optionId, value);
738
- } else if (selectableType === 'single') {
739
- // "radio"
740
- this._selectedGroupOptionsMap[groupId] = new Map();
741
-
742
- this._selectedGroupOptionsMap[groupId].set(optionId, value);
727
+ this.setState(oldState => {
728
+ var _oldState$selectedGro;
729
+
730
+ const _selectedOption$props = selectedOption.props,
731
+ optionId = _selectedOption$props.id,
732
+ value = _selectedOption$props.value;
733
+ const _ref6 = selectedOption.groupProps,
734
+ groupId = _ref6.id,
735
+ selectableType = _ref6.selectableType;
736
+ let newState = new Map(oldState.selectedGroupOptionsMap[groupId]);
737
+
738
+ if (selectableType === 'multiple' && Boolean((_oldState$selectedGro = oldState.selectedGroupOptionsMap[groupId]) === null || _oldState$selectedGro === void 0 ? void 0 : _oldState$selectedGro.has(optionId))) {
739
+ // toggle off, if already selected
740
+ newState.delete(optionId);
741
+ } else {
742
+ if (selectableType === 'multiple') {
743
+ // "checkbox"
744
+ newState.set(optionId, value);
745
+ } else if (selectableType === 'single') {
746
+ // "radio"
747
+ newState = new Map();
748
+ newState.set(optionId, value);
749
+ }
743
750
  }
744
- } // needed for rerender
745
751
 
752
+ return { ...oldState,
753
+ selectedGroupOptionsMap: { ...oldState.selectedGroupOptionsMap,
754
+ [groupId]: newState
755
+ }
756
+ };
757
+ }, () => {
758
+ const value = selectedOption.props.value;
759
+ const _ref7 = selectedOption.groupProps,
760
+ groupId = _ref7.id,
761
+ groupOnSelect = _ref7.onSelect;
762
+ const onSelect = this.props.onSelect;
763
+ const groupProps = selectedOption.groupProps,
764
+ option = (0, _objectWithoutProperties2.default)(selectedOption, _excluded2);
765
+ const selectedOptionValuesInGroup = [...this.state.selectedGroupOptionsMap[groupId].values()];
766
+
767
+ if (typeof groupOnSelect === 'function') {
768
+ groupOnSelect(event, {
769
+ value: selectedOptionValuesInGroup,
770
+ isSelected: selectedOptionValuesInGroup.includes(value),
771
+ selectedOption: option,
772
+ drilldown: this
773
+ });
774
+ }
746
775
 
747
- this.setState({
748
- lastSelectedId: optionId
776
+ if (typeof onSelect === 'function') {
777
+ onSelect(event, {
778
+ value: selectedOptionValuesInGroup,
779
+ isSelected: selectedOptionValuesInGroup.includes(value),
780
+ selectedOption: option,
781
+ drilldown: this
782
+ });
783
+ }
749
784
  });
750
- const groupProps = selectedOption.groupProps,
751
- option = (0, _objectWithoutProperties2.default)(selectedOption, _excluded2);
752
- const selectedOptionValuesInGroup = Array.from(this._selectedGroupOptionsMap[groupId].values());
753
-
754
- if (typeof groupOnSelect === 'function') {
755
- groupOnSelect(event, {
756
- value: selectedOptionValuesInGroup,
757
- isSelected: this._selectedGroupOptionsMap[groupId].has(optionId),
758
- selectedOption: option,
759
- drilldown: this
760
- });
761
- }
762
-
763
- if (typeof onSelect === 'function') {
764
- onSelect(event, {
765
- value: selectedOptionValuesInGroup,
766
- isSelected: this._selectedGroupOptionsMap[groupId].has(optionId),
767
- selectedOption: option,
768
- drilldown: this
769
- });
770
- }
771
785
  }
772
786
 
773
787
  renderList(getOptionProps, getDisabledOptionProps) {
@@ -922,8 +936,17 @@ let Drilldown = (_dec = (0, _withDeterministicId.withDeterministicId)(), _dec2 =
922
936
  optionProps.renderBeforeLabel = _IconArrowOpenStartSo || (_IconArrowOpenStartSo = (0, _emotion.jsx)(_IconArrowOpenStartSolid.IconArrowOpenStartSolid, null));
923
937
  }
924
938
 
925
- if (groupProps !== null && groupProps !== void 0 && groupProps.selectableType) {
926
- isSelected = this._selectedGroupOptionsMap[groupProps.id].has(id);
939
+ const isOptionControlled = typeof option.props.selected === 'boolean';
940
+
941
+ if ((groupProps !== null && groupProps !== void 0 && groupProps.selectableType || isOptionControlled) && groupProps) {
942
+ if (!isOptionControlled) {
943
+ var _this$state$selectedG;
944
+
945
+ isSelected = Boolean((_this$state$selectedG = this.state.selectedGroupOptionsMap[groupProps.id]) === null || _this$state$selectedG === void 0 ? void 0 : _this$state$selectedG.has(id));
946
+ } else {
947
+ isSelected = Boolean(option.props.selected);
948
+ }
949
+
927
950
  optionProps['aria-checked'] = isSelected;
928
951
  optionProps.renderBeforeLabel = (0, _emotion.jsx)(_IconCheckSolid.IconCheckSolid, {
929
952
  style: {
@@ -1025,7 +1048,6 @@ let Drilldown = (_dec = (0, _withDeterministicId.withDeterministicId)(), _dec2 =
1025
1048
  children = _group$props.children,
1026
1049
  renderGroupTitle = _group$props.renderGroupTitle,
1027
1050
  themeOverride = _group$props.themeOverride,
1028
- selectableType = _group$props.selectableType,
1029
1051
  role = _group$props.role,
1030
1052
  as = _group$props.as,
1031
1053
  elementRef = _group$props.elementRef;
@@ -1038,10 +1060,6 @@ let Drilldown = (_dec = (0, _withDeterministicId.withDeterministicId)(), _dec2 =
1038
1060
 
1039
1061
  if (needsFirstSeparator) {
1040
1062
  groupChildren.push(_Options$Separator || (_Options$Separator = (0, _emotion.jsx)(_Options.Options.Separator, null)));
1041
- }
1042
-
1043
- if (selectableType && !this._selectedGroupOptionsMap[id]) {
1044
- this._selectedGroupOptionsMap[id] = new Map();
1045
1063
  } // create a sublist as a group
1046
1064
  // (a wrapping list item will be created by Options)
1047
1065
 
@@ -1111,11 +1129,11 @@ let Drilldown = (_dec = (0, _withDeterministicId.withDeterministicId)(), _dec2 =
1111
1129
  id: lastOptionId
1112
1130
  });
1113
1131
  }
1114
- }, _ref7 => {
1115
- let getTriggerProps = _ref7.getTriggerProps,
1116
- getListProps = _ref7.getListProps,
1117
- getOptionProps = _ref7.getOptionProps,
1118
- getDisabledOptionProps = _ref7.getDisabledOptionProps;
1132
+ }, _ref8 => {
1133
+ let getTriggerProps = _ref8.getTriggerProps,
1134
+ getListProps = _ref8.getListProps,
1135
+ getOptionProps = _ref8.getOptionProps,
1136
+ getDisabledOptionProps = _ref8.getDisabledOptionProps;
1119
1137
  return (0, _emotion.jsx)(_View.View, Object.assign({
1120
1138
  as: "div",
1121
1139
  elementRef: this.handleDrilldownRef,
@@ -1201,8 +1219,8 @@ let Drilldown = (_dec = (0, _withDeterministicId.withDeterministicId)(), _dec2 =
1201
1219
  isShowingContent: show,
1202
1220
  defaultIsShowingContent: defaultShow,
1203
1221
  shouldCloseOnDocumentClick: true,
1204
- onHideContent: (event, _ref8) => {
1205
- let documentClick = _ref8.documentClick;
1222
+ onHideContent: (event, _ref9) => {
1223
+ let documentClick = _ref9.documentClick;
1206
1224
 
1207
1225
  if (typeof onDismiss === 'function') {
1208
1226
  onDismiss(event, documentClick);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@instructure/ui-drilldown",
3
- "version": "8.32.1",
3
+ "version": "8.32.2-snapshot-2",
4
4
  "description": "A drilldown menu component",
5
5
  "author": "Instructure, Inc. Engineering and Product Design",
6
6
  "module": "./es/index.js",
@@ -24,28 +24,28 @@
24
24
  "license": "MIT",
25
25
  "dependencies": {
26
26
  "@babel/runtime": "^7.13.10",
27
- "@instructure/console": "8.32.1",
28
- "@instructure/emotion": "8.32.1",
29
- "@instructure/shared-types": "8.32.1",
30
- "@instructure/ui-dom-utils": "8.32.1",
31
- "@instructure/ui-icons": "8.32.1",
32
- "@instructure/ui-options": "8.32.1",
33
- "@instructure/ui-popover": "8.32.1",
34
- "@instructure/ui-position": "8.32.1",
35
- "@instructure/ui-prop-types": "8.32.1",
36
- "@instructure/ui-react-utils": "8.32.1",
37
- "@instructure/ui-selectable": "8.32.1",
38
- "@instructure/ui-testable": "8.32.1",
39
- "@instructure/ui-utils": "8.32.1",
40
- "@instructure/ui-view": "8.32.1",
27
+ "@instructure/console": "8.32.2-snapshot-2",
28
+ "@instructure/emotion": "8.32.2-snapshot-2",
29
+ "@instructure/shared-types": "8.32.2-snapshot-2",
30
+ "@instructure/ui-dom-utils": "8.32.2-snapshot-2",
31
+ "@instructure/ui-icons": "8.32.2-snapshot-2",
32
+ "@instructure/ui-options": "8.32.2-snapshot-2",
33
+ "@instructure/ui-popover": "8.32.2-snapshot-2",
34
+ "@instructure/ui-position": "8.32.2-snapshot-2",
35
+ "@instructure/ui-prop-types": "8.32.2-snapshot-2",
36
+ "@instructure/ui-react-utils": "8.32.2-snapshot-2",
37
+ "@instructure/ui-selectable": "8.32.2-snapshot-2",
38
+ "@instructure/ui-testable": "8.32.2-snapshot-2",
39
+ "@instructure/ui-utils": "8.32.2-snapshot-2",
40
+ "@instructure/ui-view": "8.32.2-snapshot-2",
41
41
  "prop-types": "^15"
42
42
  },
43
43
  "devDependencies": {
44
- "@instructure/ui-babel-preset": "8.32.1",
45
- "@instructure/ui-color-utils": "8.32.1",
46
- "@instructure/ui-test-locator": "8.32.1",
47
- "@instructure/ui-test-utils": "8.32.1",
48
- "@instructure/ui-themes": "8.32.1"
44
+ "@instructure/ui-babel-preset": "8.32.2-snapshot-2",
45
+ "@instructure/ui-color-utils": "8.32.2-snapshot-2",
46
+ "@instructure/ui-test-locator": "8.32.2-snapshot-2",
47
+ "@instructure/ui-test-utils": "8.32.2-snapshot-2",
48
+ "@instructure/ui-themes": "8.32.2-snapshot-2"
49
49
  },
50
50
  "peerDependencies": {
51
51
  "react": ">=16.8 <=18"
@@ -78,6 +78,11 @@ type DrilldownOptionOwnProps = {
78
78
  */
79
79
  disabled?: boolean
80
80
 
81
+ /**
82
+ * Whether the option is selected or not. (Setting this property assumes controlled behaviour)
83
+ */
84
+ selected?: boolean
85
+
81
86
  /**
82
87
  * The value of the option. Should be set for options in selectable groups.
83
88
  */
@@ -181,6 +186,7 @@ const propTypes: PropValidators<PropKeys> = {
181
186
  children: PropTypes.oneOfType([PropTypes.node, PropTypes.func]),
182
187
  subPageId: PropTypes.string,
183
188
  disabled: PropTypes.bool,
189
+ selected: PropTypes.bool,
184
190
  value: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
185
191
  href: PropTypes.string,
186
192
  as: PropTypes.elementType,
@@ -202,6 +208,7 @@ const allowedProps: AllowedPropKeys = [
202
208
  'children',
203
209
  'subPageId',
204
210
  'disabled',
211
+ 'selected',
205
212
  'value',
206
213
  'href',
207
214
  'as',