@instructure/ui-drilldown 8.32.1 → 8.32.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 +16 -0
- package/es/Drilldown/DrilldownOption/props.js +2 -1
- package/es/Drilldown/index.js +83 -65
- package/lib/Drilldown/DrilldownOption/props.js +2 -1
- package/lib/Drilldown/index.js +83 -65
- package/package.json +20 -20
- package/src/Drilldown/DrilldownOption/props.ts +7 -0
- package/src/Drilldown/index.tsx +81 -71
- package/src/Drilldown/props.ts +7 -1
- package/tsconfig.build.tsbuildinfo +1 -1
- package/types/Drilldown/DrilldownOption/index.d.ts +2 -0
- package/types/Drilldown/DrilldownOption/index.d.ts.map +1 -1
- package/types/Drilldown/DrilldownOption/props.d.ts +4 -0
- package/types/Drilldown/DrilldownOption/props.d.ts.map +1 -1
- package/types/Drilldown/index.d.ts +4 -8
- package/types/Drilldown/index.d.ts.map +1 -1
- package/types/Drilldown/props.d.ts +5 -1
- package/types/Drilldown/props.d.ts.map +1 -1
package/src/Drilldown/index.tsx
CHANGED
|
@@ -57,7 +57,6 @@ import { withStyle, jsx } from '@instructure/emotion'
|
|
|
57
57
|
|
|
58
58
|
import { DrilldownSeparator } from './DrilldownSeparator'
|
|
59
59
|
import { DrilldownOption } from './DrilldownOption'
|
|
60
|
-
import type { DrilldownOptionValue } from './DrilldownOption/props'
|
|
61
60
|
import { DrilldownGroup } from './DrilldownGroup'
|
|
62
61
|
import type { DrilldownGroupProps, GroupChildren } from './DrilldownGroup/props'
|
|
63
62
|
import { DrilldownPage } from './DrilldownPage'
|
|
@@ -66,7 +65,7 @@ import type { DrilldownPageProps, PageChildren } from './DrilldownPage/props'
|
|
|
66
65
|
import generateStyle from './styles'
|
|
67
66
|
import generateComponentTheme from './theme'
|
|
68
67
|
|
|
69
|
-
import { propTypes, allowedProps } from './props'
|
|
68
|
+
import { propTypes, allowedProps, SelectedGroupOptionsMap } from './props'
|
|
70
69
|
|
|
71
70
|
import type {
|
|
72
71
|
DrilldownProps,
|
|
@@ -97,9 +96,6 @@ type MappedPage = DrilldownPageProps & {
|
|
|
97
96
|
// An object with the mapped Pages with their id as keys
|
|
98
97
|
type PageMap = Record<string, MappedPage>
|
|
99
98
|
|
|
100
|
-
// A Map width the selected options in a group, with the id as key and their value
|
|
101
|
-
type SelectedGroupOptionsMap = Map<string, DrilldownOptionValue>
|
|
102
|
-
|
|
103
99
|
/**
|
|
104
100
|
---
|
|
105
101
|
category: components
|
|
@@ -157,9 +153,6 @@ class Drilldown extends Component<DrilldownProps, DrilldownState> {
|
|
|
157
153
|
} = {}
|
|
158
154
|
|
|
159
155
|
// Map of the selected options in groups (grouped by group id)
|
|
160
|
-
_selectedGroupOptionsMap: {
|
|
161
|
-
[groupId: string]: SelectedGroupOptionsMap
|
|
162
|
-
} = {}
|
|
163
156
|
|
|
164
157
|
ref: HTMLDivElement | Element | null = null
|
|
165
158
|
|
|
@@ -197,13 +190,11 @@ class Drilldown extends Component<DrilldownProps, DrilldownState> {
|
|
|
197
190
|
isShowingPopover: props.trigger ? !!props.show : false,
|
|
198
191
|
activePageId: props.rootPageId,
|
|
199
192
|
highlightedOptionId: undefined,
|
|
200
|
-
lastSelectedId: undefined
|
|
193
|
+
lastSelectedId: undefined,
|
|
194
|
+
selectedGroupOptionsMap: this.setDefaultSelected()
|
|
201
195
|
}
|
|
202
|
-
|
|
203
196
|
this._pageHistory = [props.rootPageId]
|
|
204
197
|
|
|
205
|
-
this.setDefaultSelected()
|
|
206
|
-
|
|
207
198
|
this._id = props.id || props.deterministicId!()
|
|
208
199
|
this._triggerId = props.deterministicId!('Drilldown-Trigger')
|
|
209
200
|
this._headerBackId = props.deterministicId!('DrilldownHeader-Back')
|
|
@@ -358,6 +349,8 @@ class Drilldown extends Component<DrilldownProps, DrilldownState> {
|
|
|
358
349
|
}
|
|
359
350
|
|
|
360
351
|
setDefaultSelected() {
|
|
352
|
+
const selectedGroupOptionsMap: SelectedGroupOptionsMap = {}
|
|
353
|
+
|
|
361
354
|
this.pages.forEach((page) => {
|
|
362
355
|
const { children } = page.props
|
|
363
356
|
|
|
@@ -374,6 +367,10 @@ class Drilldown extends Component<DrilldownProps, DrilldownState> {
|
|
|
374
367
|
return
|
|
375
368
|
}
|
|
376
369
|
|
|
370
|
+
if (selectableType && !selectedGroupOptionsMap[groupId]) {
|
|
371
|
+
selectedGroupOptionsMap[groupId] = new Map()
|
|
372
|
+
}
|
|
373
|
+
|
|
377
374
|
if (selectableType === 'single' && groupDefaultSelected.length > 1) {
|
|
378
375
|
error(
|
|
379
376
|
false,
|
|
@@ -385,7 +382,7 @@ class Drilldown extends Component<DrilldownProps, DrilldownState> {
|
|
|
385
382
|
return
|
|
386
383
|
}
|
|
387
384
|
|
|
388
|
-
|
|
385
|
+
selectedGroupOptionsMap[groupId] = new Map()
|
|
389
386
|
|
|
390
387
|
this.getChildrenArray(groupChildren)?.forEach((groupChild) => {
|
|
391
388
|
if (
|
|
@@ -409,20 +406,18 @@ class Drilldown extends Component<DrilldownProps, DrilldownState> {
|
|
|
409
406
|
.includes(optionValue)
|
|
410
407
|
|
|
411
408
|
if (optionDefaultSelected || isGroupDefaultSelected) {
|
|
412
|
-
|
|
413
|
-
optionId,
|
|
414
|
-
optionValue
|
|
415
|
-
)
|
|
409
|
+
selectedGroupOptionsMap[groupId].set(optionId, optionValue)
|
|
416
410
|
}
|
|
417
411
|
}
|
|
418
412
|
})
|
|
419
413
|
}
|
|
420
414
|
})
|
|
421
415
|
})
|
|
416
|
+
return selectedGroupOptionsMap
|
|
422
417
|
}
|
|
423
418
|
|
|
424
419
|
get selectedGroupOptionIdsArray() {
|
|
425
|
-
return Object.values(this.
|
|
420
|
+
return Object.values(this.state.selectedGroupOptionsMap)
|
|
426
421
|
.map((groupIdMap) => Array.from(groupIdMap.keys()))
|
|
427
422
|
.flat()
|
|
428
423
|
}
|
|
@@ -718,54 +713,67 @@ class Drilldown extends Component<DrilldownProps, DrilldownState> {
|
|
|
718
713
|
event: React.SyntheticEvent,
|
|
719
714
|
selectedOption: MappedOption
|
|
720
715
|
) {
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
716
|
+
this.setState(
|
|
717
|
+
(oldState) => {
|
|
718
|
+
const { id: optionId, value } = selectedOption.props
|
|
719
|
+
const { id: groupId, selectableType } = selectedOption.groupProps!
|
|
720
|
+
|
|
721
|
+
let newState = new Map(oldState.selectedGroupOptionsMap[groupId])
|
|
722
|
+
|
|
723
|
+
if (
|
|
724
|
+
selectableType === 'multiple' &&
|
|
725
|
+
Boolean(oldState.selectedGroupOptionsMap[groupId]?.has(optionId))
|
|
726
|
+
) {
|
|
727
|
+
// toggle off, if already selected
|
|
728
|
+
newState.delete(optionId)
|
|
729
|
+
} else {
|
|
730
|
+
if (selectableType === 'multiple') {
|
|
731
|
+
// "checkbox"
|
|
732
|
+
newState.set(optionId, value)
|
|
733
|
+
} else if (selectableType === 'single') {
|
|
734
|
+
// "radio"
|
|
735
|
+
newState = new Map()
|
|
736
|
+
newState.set(optionId, value)
|
|
737
|
+
}
|
|
738
|
+
}
|
|
739
|
+
return {
|
|
740
|
+
...oldState,
|
|
741
|
+
selectedGroupOptionsMap: {
|
|
742
|
+
...oldState.selectedGroupOptionsMap,
|
|
743
|
+
[groupId]: newState
|
|
744
|
+
}
|
|
745
|
+
}
|
|
746
|
+
},
|
|
747
|
+
() => {
|
|
748
|
+
const { value } = selectedOption.props
|
|
749
|
+
const { id: groupId, onSelect: groupOnSelect } =
|
|
750
|
+
selectedOption.groupProps!
|
|
751
|
+
|
|
752
|
+
const { onSelect } = this.props
|
|
753
|
+
const { groupProps, ...option } = selectedOption
|
|
754
|
+
const selectedOptionValuesInGroup = [
|
|
755
|
+
...this.state.selectedGroupOptionsMap[groupId].values()
|
|
756
|
+
]
|
|
757
|
+
|
|
758
|
+
if (typeof groupOnSelect === 'function') {
|
|
759
|
+
groupOnSelect(event, {
|
|
760
|
+
value: selectedOptionValuesInGroup,
|
|
761
|
+
isSelected: selectedOptionValuesInGroup.includes(value),
|
|
762
|
+
selectedOption: option,
|
|
763
|
+
drilldown: this
|
|
764
|
+
})
|
|
765
|
+
}
|
|
729
766
|
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
// "radio"
|
|
739
|
-
this._selectedGroupOptionsMap[groupId] = new Map()
|
|
740
|
-
this._selectedGroupOptionsMap[groupId].set(optionId, value)
|
|
767
|
+
if (typeof onSelect === 'function') {
|
|
768
|
+
onSelect(event, {
|
|
769
|
+
value: selectedOptionValuesInGroup,
|
|
770
|
+
isSelected: selectedOptionValuesInGroup.includes(value),
|
|
771
|
+
selectedOption: option,
|
|
772
|
+
drilldown: this
|
|
773
|
+
})
|
|
774
|
+
}
|
|
741
775
|
}
|
|
742
|
-
}
|
|
743
|
-
|
|
744
|
-
// needed for rerender
|
|
745
|
-
this.setState({ lastSelectedId: optionId })
|
|
746
|
-
|
|
747
|
-
const { groupProps, ...option } = selectedOption
|
|
748
|
-
const selectedOptionValuesInGroup = Array.from(
|
|
749
|
-
this._selectedGroupOptionsMap[groupId].values()
|
|
750
776
|
)
|
|
751
|
-
|
|
752
|
-
if (typeof groupOnSelect === 'function') {
|
|
753
|
-
groupOnSelect(event, {
|
|
754
|
-
value: selectedOptionValuesInGroup,
|
|
755
|
-
isSelected: this._selectedGroupOptionsMap[groupId].has(optionId),
|
|
756
|
-
selectedOption: option,
|
|
757
|
-
drilldown: this
|
|
758
|
-
})
|
|
759
|
-
}
|
|
760
|
-
|
|
761
|
-
if (typeof onSelect === 'function') {
|
|
762
|
-
onSelect(event, {
|
|
763
|
-
value: selectedOptionValuesInGroup,
|
|
764
|
-
isSelected: this._selectedGroupOptionsMap[groupId].has(optionId),
|
|
765
|
-
selectedOption: option,
|
|
766
|
-
drilldown: this
|
|
767
|
-
})
|
|
768
|
-
}
|
|
769
777
|
}
|
|
770
778
|
|
|
771
779
|
handleOptionSelect = (
|
|
@@ -1092,8 +1100,15 @@ class Drilldown extends Component<DrilldownProps, DrilldownState> {
|
|
|
1092
1100
|
if (id === this._headerBackId) {
|
|
1093
1101
|
optionProps.renderBeforeLabel = <IconArrowOpenStartSolid />
|
|
1094
1102
|
}
|
|
1095
|
-
|
|
1096
|
-
|
|
1103
|
+
const isOptionControlled = typeof option.props.selected === 'boolean'
|
|
1104
|
+
if ((groupProps?.selectableType || isOptionControlled) && groupProps) {
|
|
1105
|
+
if (!isOptionControlled) {
|
|
1106
|
+
isSelected = Boolean(
|
|
1107
|
+
this.state.selectedGroupOptionsMap[groupProps.id]?.has(id)
|
|
1108
|
+
)
|
|
1109
|
+
} else {
|
|
1110
|
+
isSelected = Boolean(option.props.selected)
|
|
1111
|
+
}
|
|
1097
1112
|
optionProps['aria-checked'] = isSelected
|
|
1098
1113
|
|
|
1099
1114
|
optionProps.renderBeforeLabel = (
|
|
@@ -1103,6 +1118,7 @@ class Drilldown extends Component<DrilldownProps, DrilldownState> {
|
|
|
1103
1118
|
}}
|
|
1104
1119
|
/>
|
|
1105
1120
|
)
|
|
1121
|
+
|
|
1106
1122
|
warn(
|
|
1107
1123
|
!renderBeforeLabel,
|
|
1108
1124
|
`The prop "renderBeforeLabel" is reserved on item with id: "${id}". When this option is a selectable member of a Drilldown.Group, selection indicator will render before the label.`
|
|
@@ -1116,7 +1132,6 @@ class Drilldown extends Component<DrilldownProps, DrilldownState> {
|
|
|
1116
1132
|
optionProps.role = customRole || 'menuitemcheckbox'
|
|
1117
1133
|
}
|
|
1118
1134
|
}
|
|
1119
|
-
|
|
1120
1135
|
// display option as highlighted
|
|
1121
1136
|
if (id === this.state.highlightedOptionId) {
|
|
1122
1137
|
optionProps.variant = 'highlighted'
|
|
@@ -1243,7 +1258,6 @@ class Drilldown extends Component<DrilldownProps, DrilldownState> {
|
|
|
1243
1258
|
children,
|
|
1244
1259
|
renderGroupTitle,
|
|
1245
1260
|
themeOverride,
|
|
1246
|
-
selectableType,
|
|
1247
1261
|
role,
|
|
1248
1262
|
as,
|
|
1249
1263
|
elementRef
|
|
@@ -1263,10 +1277,6 @@ class Drilldown extends Component<DrilldownProps, DrilldownState> {
|
|
|
1263
1277
|
groupChildren.push(<Options.Separator />)
|
|
1264
1278
|
}
|
|
1265
1279
|
|
|
1266
|
-
if (selectableType && !this._selectedGroupOptionsMap[id]) {
|
|
1267
|
-
this._selectedGroupOptionsMap[id] = new Map()
|
|
1268
|
-
}
|
|
1269
|
-
|
|
1270
1280
|
// create a sublist as a group
|
|
1271
1281
|
// (a wrapping list item will be created by Options)
|
|
1272
1282
|
groupChildren.push(
|
package/src/Drilldown/props.ts
CHANGED
|
@@ -286,12 +286,17 @@ type DrilldownStyleProps = {
|
|
|
286
286
|
hasHighlightedOption: boolean
|
|
287
287
|
}
|
|
288
288
|
|
|
289
|
+
type SelectedGroupOptionsMap = {
|
|
290
|
+
[groupId: string]: Map<string, DrilldownOptionValue>
|
|
291
|
+
}
|
|
292
|
+
|
|
289
293
|
type DrilldownState = {
|
|
290
294
|
isShowingPopover: boolean
|
|
291
295
|
activePageId: string
|
|
292
296
|
highlightedOptionId?: string
|
|
293
297
|
// needed for rerender
|
|
294
298
|
lastSelectedId?: string
|
|
299
|
+
selectedGroupOptionsMap: SelectedGroupOptionsMap
|
|
295
300
|
}
|
|
296
301
|
|
|
297
302
|
const propTypes: PropValidators<PropKeys> = {
|
|
@@ -388,6 +393,7 @@ export type {
|
|
|
388
393
|
PageChild,
|
|
389
394
|
GroupChild,
|
|
390
395
|
OptionChild,
|
|
391
|
-
SeparatorChild
|
|
396
|
+
SeparatorChild,
|
|
397
|
+
SelectedGroupOptionsMap
|
|
392
398
|
}
|
|
393
399
|
export { propTypes, allowedProps }
|