@openedx/paragon 22.0.0-alpha.22 → 22.0.0-alpha.24
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/bin/paragon-scripts.js +12 -1
- package/dist/Button/index.js +2 -2
- package/dist/Button/index.js.map +1 -1
- package/dist/Button/index.scss +3 -3
- package/dist/ColorPicker/index.js +48 -18
- package/dist/ColorPicker/index.js.map +1 -1
- package/dist/Container/index.js +6 -2
- package/dist/Container/index.js.map +1 -1
- package/dist/DataTable/index.js +2 -1
- package/dist/DataTable/index.js.map +1 -1
- package/dist/DataTable/selection/BaseSelectionStatus.js +3 -2
- package/dist/DataTable/selection/BaseSelectionStatus.js.map +1 -1
- package/dist/Dropdown/index.js.map +1 -1
- package/dist/Dropzone/index.js +2 -3
- package/dist/Dropzone/index.js.map +1 -1
- package/dist/Form/FormAutosuggest.js +9 -4
- package/dist/Form/FormAutosuggest.js.map +1 -1
- package/dist/Form/FormSwitch.js +3 -0
- package/dist/Form/FormSwitch.js.map +1 -1
- package/dist/Hyperlink/index.js +7 -6
- package/dist/Hyperlink/index.js.map +1 -1
- package/dist/Icon/index.js +18 -11
- package/dist/Icon/index.js.map +1 -1
- package/dist/IconButton/index.js +1 -1
- package/dist/IconButton/index.js.map +1 -1
- package/dist/Layout/index.js.map +1 -1
- package/dist/Menu/MenuItem.js +2 -2
- package/dist/Menu/MenuItem.js.map +1 -1
- package/dist/Modal/ModalDialog.js +3 -0
- package/dist/Modal/ModalDialog.js.map +1 -1
- package/dist/Modal/_ModalDialog.scss +12 -20
- package/dist/Popover/index.js +8 -8
- package/dist/Popover/index.js.map +1 -1
- package/dist/ProductTour/Checkpoint.js +10 -8
- package/dist/ProductTour/Checkpoint.js.map +1 -1
- package/dist/ProductTour/messages.js +16 -0
- package/dist/SearchField/SearchFieldAdvanced.js +12 -7
- package/dist/SearchField/SearchFieldAdvanced.js.map +1 -1
- package/dist/SearchField/SearchFieldLabel.js +3 -3
- package/dist/SearchField/SearchFieldLabel.js.map +1 -1
- package/dist/SearchField/index.js +0 -1
- package/dist/SearchField/index.js.map +1 -1
- package/dist/SelectableBox/index.js +9 -5
- package/dist/SelectableBox/index.js.map +1 -1
- package/dist/Tabs/index.js +13 -13
- package/dist/Tabs/index.js.map +1 -1
- package/dist/core.css +17 -18
- package/dist/core.css.map +1 -1
- package/dist/core.min.css +1 -1
- package/dist/hooks/useIndexOfLastVisibleChild.js +33 -38
- package/dist/hooks/useIndexOfLastVisibleChild.js.map +1 -1
- package/dist/i18n/messages/ar.json +2 -1
- package/dist/i18n/messages/ca.json +2 -1
- package/dist/i18n/messages/es_419.json +2 -1
- package/dist/i18n/messages/es_AR.json +2 -1
- package/dist/i18n/messages/es_ES.json +2 -1
- package/dist/i18n/messages/fr.json +2 -1
- package/dist/i18n/messages/he.json +2 -1
- package/dist/i18n/messages/id.json +2 -1
- package/dist/i18n/messages/it_IT.json +2 -1
- package/dist/i18n/messages/ko_KR.json +2 -1
- package/dist/i18n/messages/pl.json +2 -1
- package/dist/i18n/messages/pt_BR.json +2 -1
- package/dist/i18n/messages/pt_PT.json +2 -1
- package/dist/i18n/messages/ru.json +2 -1
- package/dist/i18n/messages/th.json +2 -1
- package/dist/i18n/messages/tr_TR.json +2 -1
- package/dist/i18n/messages/uk.json +2 -1
- package/dist/i18n/messages/zh_CN.json +2 -1
- package/dist/light.css +11 -11
- package/dist/light.css.map +1 -1
- package/dist/light.min.css +1 -1
- package/icons/.svgrrc.js +1 -1
- package/icons/es5/Accessible.js +2 -1
- package/icons/es5/AccessibleForward.js +2 -1
- package/icons/es5/AssistWalker.js +2 -1
- package/icons/es5/Attribution.js +2 -1
- package/icons/es5/Bathtub.js +2 -1
- package/icons/es5/Biotech.js +2 -1
- package/icons/es5/Blind.js +2 -1
- package/icons/es5/BlurOff.js +16 -8
- package/icons/es5/Brightness1.js +2 -1
- package/icons/es5/BubbleChart.js +6 -3
- package/icons/es5/CameraAlt.js +2 -1
- package/icons/es5/Category.js +2 -1
- package/icons/es5/CheckCircleLightOutline.js +12 -17
- package/icons/es5/ChildCare.js +4 -2
- package/icons/es5/CoPresent.js +2 -1
- package/icons/es5/CoffeeMaker.js +2 -1
- package/icons/es5/CompassCalibration.js +2 -1
- package/icons/es5/ControlCamera.js +2 -1
- package/icons/es5/Deblur.js +24 -12
- package/icons/es5/Diversity1.js +4 -2
- package/icons/es5/EmojiPeople.js +2 -1
- package/icons/es5/EmojiSymbols.js +4 -2
- package/icons/es5/Face2.js +4 -2
- package/icons/es5/Face3.js +4 -2
- package/icons/es5/Face4.js +4 -2
- package/icons/es5/Face5.js +44 -22
- package/icons/es5/Face6.js +4 -2
- package/icons/es5/FaceRetouchingNatural.js +4 -2
- package/icons/es5/FaceRetouchingOff.js +2 -1
- package/icons/es5/FiberManualRecord.js +2 -1
- package/icons/es5/FiberSmartRecord.js +2 -1
- package/icons/es5/FireHydrantAlt.js +2 -1
- package/icons/es5/Garage.js +4 -2
- package/icons/es5/GolfCourse.js +2 -1
- package/icons/es5/HotTub.js +2 -1
- package/icons/es5/LinkedCamera.js +2 -1
- package/icons/es5/LocalSee.js +2 -1
- package/icons/es5/Man.js +2 -1
- package/icons/es5/Man2.js +2 -1
- package/icons/es5/Man4.js +2 -1
- package/icons/es5/ManageAccounts.js +2 -1
- package/icons/es5/MarkUnreadChatAlt.js +2 -1
- package/icons/es5/NoiseAware.js +2 -1
- package/icons/es5/NoiseControlOff.js +2 -1
- package/icons/es5/PeopleAlt.js +2 -1
- package/icons/es5/PersonSearch.js +2 -1
- package/icons/es5/Pets.js +8 -4
- package/icons/es5/Plagiarism.js +2 -1
- package/icons/es5/Policy.js +2 -1
- package/icons/es5/Pool.js +2 -1
- package/icons/es5/PriorityHigh.js +2 -1
- package/icons/es5/RecordVoiceOver.js +2 -1
- package/icons/es5/RememberMe.js +2 -1
- package/icons/es5/ReportGmailerrorred.js +2 -1
- package/icons/es5/RightSidebarFilled.js +15 -0
- package/icons/es5/RightSidebarOutlined.js +15 -0
- package/icons/es5/RssFeed.js +2 -1
- package/icons/es5/ScatterPlot.js +6 -3
- package/icons/es5/ScreenSearchDesktop.js +2 -1
- package/icons/es5/SelfImprovement.js +2 -1
- package/icons/es5/SentimentDissatisfied.js +4 -2
- package/icons/es5/SentimentSatisfied.js +4 -2
- package/icons/es5/SentimentSatisfiedAlt.js +4 -2
- package/icons/es5/SentimentSlightlyDissatisfied.js +4 -2
- package/icons/es5/SettingsApplications.js +2 -1
- package/icons/es5/Shower.js +12 -6
- package/icons/es5/SpatialAudio.js +2 -1
- package/icons/es5/SpatialAudioOff.js +2 -1
- package/icons/es5/SpatialTracking.js +2 -1
- package/icons/es5/SpeakerGroup.js +2 -1
- package/icons/es5/Sports.js +2 -1
- package/icons/es5/SportsCricket.js +2 -1
- package/icons/es5/SportsGolf.js +6 -3
- package/icons/es5/SportsKabaddi.js +2 -1
- package/icons/es5/SportsMartialArts.js +2 -1
- package/icons/es5/Stream.js +8 -4
- package/icons/es5/Streetview.js +2 -1
- package/icons/es5/Subway.js +4 -2
- package/icons/es5/SupportAgent.js +4 -2
- package/icons/es5/WindPower.js +2 -1
- package/icons/es5/Woman.js +2 -1
- package/icons/es5/Woman2.js +2 -1
- package/icons/es5/Yard.js +2 -1
- package/icons/es5/index.js +4 -2
- package/icons/jsx/Accessible.jsx +1 -1
- package/icons/jsx/AccessibleForward.jsx +1 -1
- package/icons/jsx/AssistWalker.jsx +1 -1
- package/icons/jsx/Attribution.jsx +1 -1
- package/icons/jsx/Bathtub.jsx +1 -1
- package/icons/jsx/Biotech.jsx +1 -1
- package/icons/jsx/Blind.jsx +1 -1
- package/icons/jsx/BlurOff.jsx +8 -8
- package/icons/jsx/Brightness1.jsx +1 -1
- package/icons/jsx/BubbleChart.jsx +3 -3
- package/icons/jsx/CameraAlt.jsx +1 -1
- package/icons/jsx/Category.jsx +1 -1
- package/icons/jsx/CheckCircleLightOutline.jsx +9 -16
- package/icons/jsx/ChildCare.jsx +2 -2
- package/icons/jsx/CoPresent.jsx +1 -1
- package/icons/jsx/CoffeeMaker.jsx +1 -1
- package/icons/jsx/CompassCalibration.jsx +1 -1
- package/icons/jsx/ControlCamera.jsx +1 -1
- package/icons/jsx/Deblur.jsx +12 -12
- package/icons/jsx/Diversity1.jsx +2 -2
- package/icons/jsx/EmojiPeople.jsx +1 -1
- package/icons/jsx/EmojiSymbols.jsx +2 -2
- package/icons/jsx/Face2.jsx +2 -2
- package/icons/jsx/Face3.jsx +2 -2
- package/icons/jsx/Face4.jsx +2 -2
- package/icons/jsx/Face5.jsx +22 -22
- package/icons/jsx/Face6.jsx +2 -2
- package/icons/jsx/FaceRetouchingNatural.jsx +2 -2
- package/icons/jsx/FaceRetouchingOff.jsx +1 -1
- package/icons/jsx/FiberManualRecord.jsx +1 -1
- package/icons/jsx/FiberSmartRecord.jsx +1 -1
- package/icons/jsx/FireHydrantAlt.jsx +1 -1
- package/icons/jsx/Garage.jsx +2 -2
- package/icons/jsx/GolfCourse.jsx +1 -1
- package/icons/jsx/HotTub.jsx +1 -1
- package/icons/jsx/LinkedCamera.jsx +1 -1
- package/icons/jsx/LocalSee.jsx +1 -1
- package/icons/jsx/Man.jsx +1 -1
- package/icons/jsx/Man2.jsx +1 -1
- package/icons/jsx/Man4.jsx +1 -1
- package/icons/jsx/ManageAccounts.jsx +1 -1
- package/icons/jsx/MarkUnreadChatAlt.jsx +1 -1
- package/icons/jsx/NoiseAware.jsx +1 -1
- package/icons/jsx/NoiseControlOff.jsx +1 -1
- package/icons/jsx/PeopleAlt.jsx +1 -1
- package/icons/jsx/PersonSearch.jsx +1 -1
- package/icons/jsx/Pets.jsx +4 -4
- package/icons/jsx/Plagiarism.jsx +1 -1
- package/icons/jsx/Policy.jsx +1 -1
- package/icons/jsx/Pool.jsx +1 -1
- package/icons/jsx/PriorityHigh.jsx +1 -1
- package/icons/jsx/RecordVoiceOver.jsx +1 -1
- package/icons/jsx/RememberMe.jsx +1 -1
- package/icons/jsx/ReportGmailerrorred.jsx +1 -1
- package/icons/jsx/RightSidebarFilled.jsx +19 -0
- package/icons/jsx/RightSidebarOutlined.jsx +19 -0
- package/icons/jsx/RssFeed.jsx +1 -1
- package/icons/jsx/ScatterPlot.jsx +3 -3
- package/icons/jsx/ScreenSearchDesktop.jsx +1 -1
- package/icons/jsx/SelfImprovement.jsx +1 -1
- package/icons/jsx/SentimentDissatisfied.jsx +2 -2
- package/icons/jsx/SentimentSatisfied.jsx +2 -2
- package/icons/jsx/SentimentSatisfiedAlt.jsx +2 -2
- package/icons/jsx/SentimentSlightlyDissatisfied.jsx +2 -2
- package/icons/jsx/SettingsApplications.jsx +1 -1
- package/icons/jsx/Shower.jsx +6 -6
- package/icons/jsx/SpatialAudio.jsx +1 -1
- package/icons/jsx/SpatialAudioOff.jsx +1 -1
- package/icons/jsx/SpatialTracking.jsx +1 -1
- package/icons/jsx/SpeakerGroup.jsx +1 -1
- package/icons/jsx/Sports.jsx +1 -1
- package/icons/jsx/SportsCricket.jsx +1 -1
- package/icons/jsx/SportsGolf.jsx +3 -3
- package/icons/jsx/SportsKabaddi.jsx +1 -1
- package/icons/jsx/SportsMartialArts.jsx +1 -1
- package/icons/jsx/Stream.jsx +4 -4
- package/icons/jsx/Streetview.jsx +1 -1
- package/icons/jsx/Subway.jsx +2 -2
- package/icons/jsx/SupportAgent.jsx +2 -2
- package/icons/jsx/WindPower.jsx +1 -1
- package/icons/jsx/Woman.jsx +1 -1
- package/icons/jsx/Woman2.jsx +1 -1
- package/icons/jsx/Yard.jsx +1 -1
- package/icons/jsx/index.jsx +2 -0
- package/icons/svg/check_circle_light_outline.svg +13 -0
- package/icons/svg/right_sidebar_filled.svg +3 -0
- package/icons/svg/right_sidebar_outlined.svg +3 -0
- package/lib/version.js +9 -0
- package/package.json +3 -3
- package/src/Button/README.md +99 -92
- package/src/Button/index.jsx +2 -2
- package/src/Button/index.scss +3 -3
- package/src/ColorPicker/ColorPicker.test.jsx +24 -2
- package/src/ColorPicker/index.jsx +56 -16
- package/src/Container/index.jsx +4 -0
- package/src/DataTable/README.md +4 -4
- package/src/DataTable/index.jsx +2 -1
- package/src/DataTable/selection/BaseSelectionStatus.jsx +2 -2
- package/src/DataTable/tablefilters.mdx +3 -3
- package/src/DataTable/tests/DataTable.test.jsx +31 -0
- package/src/Dropdown/index.jsx +4 -0
- package/src/Dropzone/index.jsx +2 -3
- package/src/Form/FormAutosuggest.jsx +11 -5
- package/src/Form/FormSwitch.jsx +3 -0
- package/src/Form/form-autosuggest.mdx +80 -72
- package/src/Form/tests/FormAutosuggest.test.jsx +21 -0
- package/src/Hyperlink/index.jsx +7 -6
- package/src/Icon/index.jsx +18 -11
- package/src/IconButton/index.jsx +1 -1
- package/src/Layout/index.jsx +1 -4
- package/src/Menu/MenuItem.jsx +2 -2
- package/src/Modal/ModalDialog.jsx +3 -0
- package/src/Modal/_ModalDialog.scss +12 -20
- package/src/Overlay/README.md +1 -1
- package/src/Popover/README.md +0 -1
- package/src/Popover/index.jsx +11 -11
- package/src/ProductTour/Checkpoint.jsx +9 -6
- package/src/ProductTour/messages.js +16 -0
- package/src/SearchField/SearchFieldAdvanced.jsx +12 -7
- package/src/SearchField/SearchFieldLabel.jsx +3 -3
- package/src/SearchField/index.jsx +0 -1
- package/src/SelectableBox/README.md +103 -71
- package/src/SelectableBox/index.jsx +5 -1
- package/src/SelectableBox/tests/SelectableBox.test.jsx +7 -0
- package/src/SelectableBox/tests/SelectableBoxSet.test.jsx +1 -1
- package/src/Tabs/README.md +76 -0
- package/src/Tabs/index.jsx +19 -13
- package/src/hooks/tests/useIndexOfLastVisibleChild.test.jsx +3 -3
- package/src/hooks/useIndexOfLastVisibleChild.jsx +36 -38
- package/src/hooks/useIndexOfLastVisibleChild.mdx +3 -3
- package/src/i18n/messages/ar.json +2 -1
- package/src/i18n/messages/ca.json +2 -1
- package/src/i18n/messages/es_419.json +2 -1
- package/src/i18n/messages/es_AR.json +2 -1
- package/src/i18n/messages/es_ES.json +2 -1
- package/src/i18n/messages/fr.json +2 -1
- package/src/i18n/messages/he.json +2 -1
- package/src/i18n/messages/id.json +2 -1
- package/src/i18n/messages/it_IT.json +2 -1
- package/src/i18n/messages/ko_KR.json +2 -1
- package/src/i18n/messages/pl.json +2 -1
- package/src/i18n/messages/pt_BR.json +2 -1
- package/src/i18n/messages/pt_PT.json +2 -1
- package/src/i18n/messages/ru.json +2 -1
- package/src/i18n/messages/th.json +2 -1
- package/src/i18n/messages/tr_TR.json +2 -1
- package/src/i18n/messages/uk.json +2 -1
- package/src/i18n/messages/zh_CN.json +2 -1
- package/styles/css/core/variables.css +5 -3
- package/styles/css/themes/light/variables.css +11 -11
- package/tokens/src/core/components/Button/core.json +8 -4
- package/tokens/src/themes/light/alias/color.json +10 -10
|
@@ -10,6 +10,7 @@ import CheckpointActionRow from './CheckpointActionRow';
|
|
|
10
10
|
import CheckpointBody from './CheckpointBody';
|
|
11
11
|
import CheckpointBreadcrumbs from './CheckpointBreadcrumbs';
|
|
12
12
|
import CheckpointTitle from './CheckpointTitle';
|
|
13
|
+
import messages from './messages';
|
|
13
14
|
|
|
14
15
|
const Checkpoint = React.forwardRef(({
|
|
15
16
|
body,
|
|
@@ -99,10 +100,8 @@ const Checkpoint = React.forwardRef(({
|
|
|
99
100
|
>
|
|
100
101
|
<span className="sr-only">
|
|
101
102
|
<FormattedMessage
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
value={{ step: index + 1 }}
|
|
105
|
-
description="Screen-reader message to indicate the user's position in a sequence of checkpoints."
|
|
103
|
+
{...messages.topPositionText}
|
|
104
|
+
values={{ step: index + 1 }}
|
|
106
105
|
/>
|
|
107
106
|
</span>
|
|
108
107
|
{(title || !isOnlyCheckpoint) && (
|
|
@@ -118,8 +117,12 @@ const Checkpoint = React.forwardRef(({
|
|
|
118
117
|
{...props}
|
|
119
118
|
/>
|
|
120
119
|
<div id="pgn__checkpoint-arrow" data-popper-arrow />
|
|
121
|
-
|
|
122
|
-
|
|
120
|
+
<span className="sr-only">
|
|
121
|
+
<FormattedMessage
|
|
122
|
+
{...messages.bottomPositionText}
|
|
123
|
+
values={{ step: index + 1 }}
|
|
124
|
+
/>
|
|
125
|
+
</span>
|
|
123
126
|
</div>
|
|
124
127
|
);
|
|
125
128
|
});
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { defineMessages } from 'react-intl';
|
|
2
|
+
|
|
3
|
+
const messages = defineMessages({
|
|
4
|
+
topPositionText: {
|
|
5
|
+
id: 'pgn.ProductTour.Checkpoint.top-position-text',
|
|
6
|
+
defaultMessage: 'Top of step {step}',
|
|
7
|
+
description: 'Screen-reader message to notify user that they are located at the bottom of the product tour step.',
|
|
8
|
+
},
|
|
9
|
+
bottomPositionText: {
|
|
10
|
+
id: 'pgn.ProductTour.Checkpoint.bottom-position-text',
|
|
11
|
+
defaultMessage: 'Bottom of step {step}',
|
|
12
|
+
description: 'Screen-reader message to notify user that they are located at the bottom of the product tour step.',
|
|
13
|
+
},
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
export default messages;
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
/* eslint-disable max-len */
|
|
2
1
|
import React, {
|
|
3
2
|
useRef, createContext, useState, useEffect,
|
|
4
3
|
} from 'react';
|
|
@@ -138,27 +137,32 @@ SearchFieldAdvanced.propTypes = {
|
|
|
138
137
|
onSubmit: PropTypes.func.isRequired,
|
|
139
138
|
/** specifies a custom class name. */
|
|
140
139
|
className: PropTypes.string,
|
|
141
|
-
/** specifies a callback function for when the user loses focus in the `SearchField` component.
|
|
140
|
+
/** specifies a callback function for when the user loses focus in the `SearchField` component.
|
|
141
|
+
* The default is an empty function. For example:
|
|
142
142
|
```jsx
|
|
143
143
|
<SearchField onBlur={event => console.log(event)} />
|
|
144
144
|
``` */
|
|
145
145
|
onBlur: PropTypes.func,
|
|
146
|
-
/** specifies a callback function for when the value in `SearchField` is changed by the user.
|
|
146
|
+
/** specifies a callback function for when the value in `SearchField` is changed by the user.
|
|
147
|
+
* The default is an empty function. For example:
|
|
147
148
|
```jsx
|
|
148
149
|
<SearchField onChange={value => console.log(value)} />
|
|
149
150
|
``` */
|
|
150
151
|
onChange: PropTypes.func,
|
|
151
|
-
/** specifies a callback function for when the value in `SearchField` is cleared by the user.
|
|
152
|
+
/** specifies a callback function for when the value in `SearchField` is cleared by the user.
|
|
153
|
+
* The default is an empty function. For example:
|
|
152
154
|
```jsx
|
|
153
155
|
<SearchField onClear={() => console.log('search cleared')} />
|
|
154
156
|
``` */
|
|
155
157
|
onClear: PropTypes.func,
|
|
156
|
-
/** specifies a callback function for when the user focuses in the `SearchField` component.
|
|
158
|
+
/** specifies a callback function for when the user focuses in the `SearchField` component.
|
|
159
|
+
* The default is an empty function. For example:
|
|
157
160
|
```jsx
|
|
158
161
|
<SearchField onFocus={event => console.log(event)} />
|
|
159
162
|
``` */
|
|
160
163
|
onFocus: PropTypes.func,
|
|
161
|
-
/** specifies the screenreader text for both the clear and submit buttons (e.g., for i18n translations).
|
|
164
|
+
/** specifies the screenreader text for both the clear and submit buttons (e.g., for i18n translations).
|
|
165
|
+
* The default is `{ label: 'search', clearButton: 'clear search', searchButton: 'submit search' }`. */
|
|
162
166
|
screenReaderText: PropTypes.shape({
|
|
163
167
|
label: PropTypes.oneOfType([PropTypes.string, PropTypes.element]).isRequired,
|
|
164
168
|
submitButton: PropTypes.oneOfType([PropTypes.string, PropTypes.element]).isRequired,
|
|
@@ -171,7 +175,8 @@ SearchFieldAdvanced.propTypes = {
|
|
|
171
175
|
submit: PropTypes.element.isRequired,
|
|
172
176
|
clear: PropTypes.element,
|
|
173
177
|
}),
|
|
174
|
-
/** specifies the aria-label attribute on the form element. This is useful if you use the `SearchField` component
|
|
178
|
+
/** specifies the aria-label attribute on the form element. This is useful if you use the `SearchField` component
|
|
179
|
+
* more than once on a page. */
|
|
175
180
|
formAriaLabel: PropTypes.string,
|
|
176
181
|
/** Specifies whether the `SearchField` is disabled. */
|
|
177
182
|
disabled: PropTypes.bool,
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
/* eslint-disable max-len */
|
|
2
1
|
import React, { useContext } from 'react';
|
|
3
2
|
import PropTypes from 'prop-types';
|
|
4
3
|
import classNames from 'classnames';
|
|
@@ -21,8 +20,9 @@ function SearchFieldLabel({ children, ...props }) {
|
|
|
21
20
|
|
|
22
21
|
SearchFieldLabel.propTypes = {
|
|
23
22
|
/**
|
|
24
|
-
* specifies the label to use for the input field (e.g., for i18n translations).
|
|
25
|
-
* a screenreader-only label will be used in
|
|
23
|
+
* specifies the label to use for the input field (e.g., for i18n translations).
|
|
24
|
+
* Note: if `children` is not provided, a screenreader-only label will be used in
|
|
25
|
+
* its placed based on the `screenReaderText.label` prop for `SearchField.Advanced`.
|
|
26
26
|
*/
|
|
27
27
|
children: PropTypes.oneOfType([PropTypes.string, PropTypes.element]),
|
|
28
28
|
};
|
|
@@ -6,9 +6,9 @@ components:
|
|
|
6
6
|
- SelectableBoxSet
|
|
7
7
|
categories:
|
|
8
8
|
- Forms
|
|
9
|
-
status: '
|
|
9
|
+
status: 'Stable'
|
|
10
10
|
designStatus: 'Done'
|
|
11
|
-
devStatus: '
|
|
11
|
+
devStatus: 'Done'
|
|
12
12
|
notes: |
|
|
13
13
|
---
|
|
14
14
|
|
|
@@ -26,7 +26,7 @@ As ``Checkbox``
|
|
|
26
26
|
const allCheeseOptions = ['swiss', 'cheddar', 'pepperjack'];
|
|
27
27
|
const [checkedCheeses, { add, remove, set, clear }] = useCheckboxSetValues(['swiss']);
|
|
28
28
|
|
|
29
|
-
const handleChange = e => {
|
|
29
|
+
const handleChange = (e) => {
|
|
30
30
|
e.target.checked ? add(e.target.value) : remove(e.target.value);
|
|
31
31
|
};
|
|
32
32
|
|
|
@@ -34,35 +34,32 @@ As ``Checkbox``
|
|
|
34
34
|
const isExtraSmall = useMediaQuery({ maxWidth: breakpoints.extraSmall.maxWidth });
|
|
35
35
|
|
|
36
36
|
return (
|
|
37
|
-
<
|
|
38
|
-
|
|
39
|
-
|
|
37
|
+
<SelectableBox.Set
|
|
38
|
+
className="bg-light-200 p-3"
|
|
39
|
+
value={checkedCheeses}
|
|
40
|
+
type={type}
|
|
41
|
+
onChange={handleChange}
|
|
42
|
+
name="cheeses"
|
|
43
|
+
columns={isExtraSmall ? 1 : 2}
|
|
44
|
+
ariaLabel="cheese selection"
|
|
45
|
+
>
|
|
46
|
+
<SelectableBox value="swiss" type={type} aria-label="swiss checkbox">
|
|
47
|
+
<h3>It is my first SelectableBox</h3>
|
|
48
|
+
<p>Swiss</p>
|
|
49
|
+
</SelectableBox>
|
|
50
|
+
<SelectableBox value="cheddar" inputHidden={false} type={type} aria-label="cheddar checkbox">
|
|
51
|
+
<h3>Cheddar</h3>
|
|
52
|
+
</SelectableBox>
|
|
53
|
+
<SelectableBox
|
|
54
|
+
value="pepperjack"
|
|
55
|
+
inputHidden={false}
|
|
40
56
|
type={type}
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
columns={isExtraSmall ? 1 : 2}
|
|
44
|
-
ariaLabel="cheese selection"
|
|
57
|
+
isInvalid={isInvalid()}
|
|
58
|
+
aria-label="pepperjack checkbox"
|
|
45
59
|
>
|
|
46
|
-
<
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
<p>Swiss</p>
|
|
50
|
-
</div>
|
|
51
|
-
</SelectableBox>
|
|
52
|
-
<SelectableBox value="cheddar" inputHidden={false} type={type} aria-label="cheddar checkbox">
|
|
53
|
-
Cheddar
|
|
54
|
-
</SelectableBox>
|
|
55
|
-
<SelectableBox
|
|
56
|
-
value="pepperjack"
|
|
57
|
-
inputHidden={false}
|
|
58
|
-
type={type}
|
|
59
|
-
isInvalid={isInvalid()}
|
|
60
|
-
aria-label="pepperjack checkbox"
|
|
61
|
-
>
|
|
62
|
-
<h3>Pepperjack</h3>
|
|
63
|
-
</SelectableBox>
|
|
64
|
-
</SelectableBox.Set>
|
|
65
|
-
</div>
|
|
60
|
+
<h3>Pepperjack</h3>
|
|
61
|
+
</SelectableBox>
|
|
62
|
+
</SelectableBox.Set>
|
|
66
63
|
);
|
|
67
64
|
}
|
|
68
65
|
```
|
|
@@ -71,31 +68,27 @@ As ``Checkbox``
|
|
|
71
68
|
|
|
72
69
|
```jsx live
|
|
73
70
|
() => {
|
|
74
|
-
const type = 'radio';
|
|
75
71
|
const [value, setValue] = useState('green');
|
|
76
|
-
const handleChange = e => setValue(e.target.value);
|
|
72
|
+
const handleChange = (e) => setValue(e.target.value);
|
|
77
73
|
const isExtraSmall = useMediaQuery({ maxWidth: breakpoints.extraSmall.maxWidth });
|
|
78
74
|
|
|
79
75
|
return (
|
|
80
76
|
<SelectableBox.Set
|
|
81
|
-
type={type}
|
|
82
77
|
value={value}
|
|
83
78
|
onChange={handleChange}
|
|
84
79
|
name="colors"
|
|
85
80
|
columns={isExtraSmall ? 1 : 3}
|
|
86
81
|
ariaLabel="color selection"
|
|
87
82
|
>
|
|
88
|
-
<SelectableBox value="red"
|
|
89
|
-
<
|
|
90
|
-
|
|
91
|
-
<p>Select me</p>
|
|
92
|
-
</div>
|
|
83
|
+
<SelectableBox value="red" aria-label="red checkbox">
|
|
84
|
+
<h3>It is Red color</h3>
|
|
85
|
+
<p>Select me</p>
|
|
93
86
|
</SelectableBox>
|
|
94
|
-
<SelectableBox value="green" inputHidden={false}
|
|
87
|
+
<SelectableBox value="green" inputHidden={false} aria-label="green radio-button">
|
|
95
88
|
<h3>Green</h3>
|
|
96
89
|
<p>Leaves and grass</p>
|
|
97
90
|
</SelectableBox>
|
|
98
|
-
<SelectableBox value="blue" inputHidden={false}
|
|
91
|
+
<SelectableBox value="blue" inputHidden={false} aria-label="blue radio-button">
|
|
99
92
|
<h3>Blue</h3>
|
|
100
93
|
<p>The sky</p>
|
|
101
94
|
</SelectableBox>
|
|
@@ -103,6 +96,7 @@ As ``Checkbox``
|
|
|
103
96
|
);
|
|
104
97
|
}
|
|
105
98
|
```
|
|
99
|
+
|
|
106
100
|
## As Checkbox
|
|
107
101
|
As ``Checkbox`` with ``isIndeterminate``
|
|
108
102
|
|
|
@@ -117,7 +111,7 @@ As ``Checkbox`` with ``isIndeterminate``
|
|
|
117
111
|
const isIndeterminate = someChecked && !allChecked;
|
|
118
112
|
const isExtraSmall = useMediaQuery({ maxWidth: breakpoints.small.maxWidth });
|
|
119
113
|
|
|
120
|
-
const handleChange = e => {
|
|
114
|
+
const handleChange = (e) => {
|
|
121
115
|
e.target.checked ? add(e.target.value) : remove(e.target.value);
|
|
122
116
|
};
|
|
123
117
|
|
|
@@ -127,18 +121,17 @@ As ``Checkbox`` with ``isIndeterminate``
|
|
|
127
121
|
|
|
128
122
|
return (
|
|
129
123
|
<>
|
|
130
|
-
<
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
</div>
|
|
124
|
+
<SelectableBox
|
|
125
|
+
className="mb-3"
|
|
126
|
+
checked={allChecked}
|
|
127
|
+
isIndeterminate={isIndeterminate}
|
|
128
|
+
onClick={handleCheckAllChange}
|
|
129
|
+
inputHidden={false}
|
|
130
|
+
type={type}
|
|
131
|
+
aria-label="all options checkbox"
|
|
132
|
+
>
|
|
133
|
+
All the cheese
|
|
134
|
+
</SelectableBox>
|
|
142
135
|
<SelectableBox.Set
|
|
143
136
|
value={checkedCheeses}
|
|
144
137
|
type={type}
|
|
@@ -148,13 +141,11 @@ As ``Checkbox`` with ``isIndeterminate``
|
|
|
148
141
|
ariaLabel="cheese selection"
|
|
149
142
|
>
|
|
150
143
|
<SelectableBox value="swiss" type={type} aria-label="swiss checkbox">
|
|
151
|
-
<
|
|
152
|
-
|
|
153
|
-
<p>Swiss</p>
|
|
154
|
-
</div>
|
|
144
|
+
<h3>It is my first SelectableBox</h3>
|
|
145
|
+
<p>Swiss</p>
|
|
155
146
|
</SelectableBox>
|
|
156
147
|
<SelectableBox value="cheddar" inputHidden={false} type={type} aria-label="cheddar checkbox">
|
|
157
|
-
Cheddar
|
|
148
|
+
<h3>Cheddar</h3>
|
|
158
149
|
</SelectableBox>
|
|
159
150
|
<SelectableBox value="pepperjack" inputHidden={false} type={type} aria-label="pepperjack checkbox">
|
|
160
151
|
<h3>Pepperjack</h3>
|
|
@@ -173,16 +164,16 @@ As ``Checkbox`` with ``ariaLabelledby``
|
|
|
173
164
|
const allCheeseOptions = ['swiss', 'cheddar', 'pepperjack'];
|
|
174
165
|
const [checkedCheeses, { add, remove, set, clear }] = useCheckboxSetValues(['swiss']);
|
|
175
166
|
|
|
176
|
-
const handleChange = e => {
|
|
167
|
+
const handleChange = (e) => {
|
|
177
168
|
e.target.checked ? add(e.target.value) : remove(e.target.value);
|
|
178
169
|
};
|
|
179
170
|
|
|
180
171
|
const isExtraSmall = useMediaQuery({ maxWidth: breakpoints.extraSmall.maxWidth });
|
|
181
172
|
|
|
182
173
|
return (
|
|
183
|
-
<
|
|
174
|
+
<Stack className="bg-light-200 p-3">
|
|
184
175
|
<h3 id="cheese selection" className="mb-4">
|
|
185
|
-
Select your favorite cheese
|
|
176
|
+
Select your favorite cheese:
|
|
186
177
|
</h3>
|
|
187
178
|
<SelectableBox.Set
|
|
188
179
|
value={checkedCheeses}
|
|
@@ -193,22 +184,63 @@ As ``Checkbox`` with ``ariaLabelledby``
|
|
|
193
184
|
ariaLabelledby="cheese selection"
|
|
194
185
|
>
|
|
195
186
|
<SelectableBox value="swiss" inputHidden={false} type={type} aria-label="swiss checkbox">
|
|
196
|
-
<h3>
|
|
197
|
-
Swiss
|
|
198
|
-
</h3>
|
|
187
|
+
<h3>Swiss</h3>
|
|
199
188
|
</SelectableBox>
|
|
200
189
|
<SelectableBox value="cheddar" inputHidden={false} type={type} aria-label="cheddar checkbox">
|
|
201
|
-
<h3>
|
|
202
|
-
Cheddar
|
|
203
|
-
</h3>
|
|
190
|
+
<h3>Cheddar</h3>
|
|
204
191
|
</SelectableBox>
|
|
205
192
|
<SelectableBox value="pepperjack" inputHidden={false} type={type} aria-label="pepperjack checkbox">
|
|
206
|
-
<h3>
|
|
207
|
-
Pepperjack
|
|
208
|
-
</h3>
|
|
193
|
+
<h3>Pepperjack</h3>
|
|
209
194
|
</SelectableBox>
|
|
210
195
|
</SelectableBox.Set>
|
|
211
|
-
</
|
|
196
|
+
</Stack>
|
|
197
|
+
);
|
|
198
|
+
}
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
## Without active outline
|
|
202
|
+
The `showActiveBoxState` property only affects `SelectableBox` that have `inputHidden` set to `false`.
|
|
203
|
+
If a component has no input, the border is always rendered in an active state.
|
|
204
|
+
|
|
205
|
+
```jsx live
|
|
206
|
+
() => {
|
|
207
|
+
const [value, setValue] = useState('apples');
|
|
208
|
+
const handleChange = (e) => setValue(e.target.value);
|
|
209
|
+
const isExtraSmall = useMediaQuery({ maxWidth: breakpoints.extraSmall.maxWidth });
|
|
210
|
+
|
|
211
|
+
return (
|
|
212
|
+
<SelectableBox.Set
|
|
213
|
+
value={value}
|
|
214
|
+
onChange={handleChange}
|
|
215
|
+
name="fruits"
|
|
216
|
+
columns={isExtraSmall ? 1 : 3}
|
|
217
|
+
ariaLabel="fruits selection"
|
|
218
|
+
>
|
|
219
|
+
<SelectableBox
|
|
220
|
+
value="apples"
|
|
221
|
+
inputHidden={false}
|
|
222
|
+
showActiveBoxState={false}
|
|
223
|
+
aria-label="apple radio-button"
|
|
224
|
+
>
|
|
225
|
+
<h3>Apples</h3>
|
|
226
|
+
</SelectableBox>
|
|
227
|
+
<SelectableBox
|
|
228
|
+
value="oranges"
|
|
229
|
+
inputHidden={false}
|
|
230
|
+
showActiveBoxState={false}
|
|
231
|
+
aria-label="orange radio-button"
|
|
232
|
+
>
|
|
233
|
+
<h3>Oranges</h3>
|
|
234
|
+
</SelectableBox>
|
|
235
|
+
<SelectableBox
|
|
236
|
+
value="bananas"
|
|
237
|
+
inputHidden={false}
|
|
238
|
+
showActiveBoxState={false}
|
|
239
|
+
aria-label="banana radio-button"
|
|
240
|
+
>
|
|
241
|
+
<h3>Bananas</h3>
|
|
242
|
+
</SelectableBox>
|
|
243
|
+
</SelectableBox.Set>
|
|
212
244
|
);
|
|
213
245
|
}
|
|
214
246
|
```
|
|
@@ -22,6 +22,7 @@ const SelectableBox = React.forwardRef(({
|
|
|
22
22
|
onFocus,
|
|
23
23
|
inputHidden,
|
|
24
24
|
className,
|
|
25
|
+
showActiveBoxState,
|
|
25
26
|
...props
|
|
26
27
|
}, ref) => {
|
|
27
28
|
const inputType = getInputType('SelectableBox', type);
|
|
@@ -63,7 +64,7 @@ const SelectableBox = React.forwardRef(({
|
|
|
63
64
|
onClick={() => inputRef.current.click()}
|
|
64
65
|
onFocus={onFocus}
|
|
65
66
|
className={classNames('pgn__selectable_box', className, {
|
|
66
|
-
'pgn__selectable_box-active': isChecked() || checked,
|
|
67
|
+
'pgn__selectable_box-active': (!inputHidden && !showActiveBoxState) ? false : isChecked() || checked,
|
|
67
68
|
'pgn__selectable_box-invalid': isInvalid,
|
|
68
69
|
})}
|
|
69
70
|
tabIndex={0}
|
|
@@ -97,6 +98,8 @@ SelectableBox.propTypes = {
|
|
|
97
98
|
isInvalid: PropTypes.bool,
|
|
98
99
|
/** A class that is appended to the base element. */
|
|
99
100
|
className: PropTypes.string,
|
|
101
|
+
/** Controls the visibility of the active state for the `SelectableBox`. */
|
|
102
|
+
showActiveBoxState: PropTypes.bool,
|
|
100
103
|
};
|
|
101
104
|
|
|
102
105
|
SelectableBox.defaultProps = {
|
|
@@ -109,6 +112,7 @@ SelectableBox.defaultProps = {
|
|
|
109
112
|
isIndeterminate: false,
|
|
110
113
|
isInvalid: false,
|
|
111
114
|
className: undefined,
|
|
115
|
+
showActiveBoxState: true,
|
|
112
116
|
};
|
|
113
117
|
|
|
114
118
|
SelectableBox.Set = SelectableBoxSet;
|
|
@@ -100,6 +100,13 @@ describe('<SelectableBox />', () => {
|
|
|
100
100
|
rerender(<SelectableCheckbox inputHidden={false} />);
|
|
101
101
|
expect(inputElement.getAttribute('hidden')).toBeNull();
|
|
102
102
|
});
|
|
103
|
+
it('renders with active state and updates to inactive when showActiveBoxState is false', async () => {
|
|
104
|
+
const { rerender } = render(<SelectableCheckbox inputHidden={false} checked />);
|
|
105
|
+
const selectableBox = screen.getByRole('button');
|
|
106
|
+
expect(selectableBox.classList.contains('pgn__selectable_box-active')).toEqual(true);
|
|
107
|
+
rerender(<SelectableCheckbox inputHidden={false} showActiveBoxState={false} checked />);
|
|
108
|
+
expect(selectableBox.classList.contains('pgn__selectable_box-active')).toEqual(false);
|
|
109
|
+
});
|
|
103
110
|
});
|
|
104
111
|
describe('correct interactions', () => {
|
|
105
112
|
it('correct checkbox state change when checked is changed', () => {
|
package/src/Tabs/README.md
CHANGED
|
@@ -223,3 +223,79 @@ devStatus: 'Done'
|
|
|
223
223
|
</Tab>
|
|
224
224
|
</Tabs>
|
|
225
225
|
```
|
|
226
|
+
|
|
227
|
+
## Conditional rendering
|
|
228
|
+
|
|
229
|
+
```jsx live
|
|
230
|
+
() => {
|
|
231
|
+
const librariesEnabled = true;
|
|
232
|
+
const visibleTabs = useMemo(() => {
|
|
233
|
+
const tabs = [];
|
|
234
|
+
|
|
235
|
+
tabs.push(
|
|
236
|
+
<Tab
|
|
237
|
+
key="courses"
|
|
238
|
+
eventKey="courses"
|
|
239
|
+
title="Courses"
|
|
240
|
+
>
|
|
241
|
+
Hello I am the courses panel.
|
|
242
|
+
</Tab>
|
|
243
|
+
);
|
|
244
|
+
|
|
245
|
+
tabs.push(
|
|
246
|
+
<Tab
|
|
247
|
+
key="programs"
|
|
248
|
+
eventKey="programs"
|
|
249
|
+
title="Programs"
|
|
250
|
+
>
|
|
251
|
+
Hello I am the programs panel.
|
|
252
|
+
</Tab>
|
|
253
|
+
);
|
|
254
|
+
|
|
255
|
+
if (librariesEnabled) {
|
|
256
|
+
tabs.push(
|
|
257
|
+
<Tab
|
|
258
|
+
key="libraries"
|
|
259
|
+
eventKey="libraries"
|
|
260
|
+
title="Libraries"
|
|
261
|
+
>
|
|
262
|
+
Hello I am the libraries panel.
|
|
263
|
+
</Tab>
|
|
264
|
+
);
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
return tabs;
|
|
268
|
+
}, [librariesEnabled]);
|
|
269
|
+
|
|
270
|
+
return (
|
|
271
|
+
<Tabs
|
|
272
|
+
id="tabs"
|
|
273
|
+
defaultActiveKey="courses"
|
|
274
|
+
>
|
|
275
|
+
{visibleTabs}
|
|
276
|
+
</Tabs>
|
|
277
|
+
);
|
|
278
|
+
}
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
***
|
|
282
|
+
|
|
283
|
+
## Tabs.Deprecated
|
|
284
|
+
|
|
285
|
+
<br/>
|
|
286
|
+
|
|
287
|
+
### (Deprecated) basic usage
|
|
288
|
+
|
|
289
|
+
```jsx live
|
|
290
|
+
<Tabs.Deprecated
|
|
291
|
+
labels={[
|
|
292
|
+
'Panel 1',
|
|
293
|
+
'Panel 2',
|
|
294
|
+
'Panel 3'
|
|
295
|
+
]}
|
|
296
|
+
>
|
|
297
|
+
<div>Hello I am the first panel</div>
|
|
298
|
+
<div>Hello I am the second panel</div>
|
|
299
|
+
<div>Hello I am the third panel</div>
|
|
300
|
+
</Tabs.Deprecated>
|
|
301
|
+
```
|
package/src/Tabs/index.jsx
CHANGED
|
@@ -1,4 +1,10 @@
|
|
|
1
|
-
import React, {
|
|
1
|
+
import React, {
|
|
2
|
+
useEffect,
|
|
3
|
+
useMemo,
|
|
4
|
+
useRef,
|
|
5
|
+
useState,
|
|
6
|
+
useCallback,
|
|
7
|
+
} from 'react';
|
|
2
8
|
import classNames from 'classnames';
|
|
3
9
|
import PropTypes from 'prop-types';
|
|
4
10
|
import BaseTabs from 'react-bootstrap/Tabs';
|
|
@@ -17,15 +23,15 @@ function Tabs({
|
|
|
17
23
|
activeKey,
|
|
18
24
|
...props
|
|
19
25
|
}) {
|
|
20
|
-
const containerElementRef =
|
|
26
|
+
const [containerElementRef, setContainerElementRef] = useState(null);
|
|
21
27
|
const overflowElementRef = useRef(null);
|
|
22
28
|
const indexOfLastVisibleChild = useIndexOfLastVisibleChild(
|
|
23
|
-
containerElementRef
|
|
29
|
+
containerElementRef?.firstChild,
|
|
24
30
|
overflowElementRef.current?.parentNode,
|
|
25
31
|
);
|
|
26
32
|
|
|
27
33
|
useEffect(() => {
|
|
28
|
-
if (containerElementRef
|
|
34
|
+
if (containerElementRef) {
|
|
29
35
|
const observer = new MutationObserver((mutations => {
|
|
30
36
|
mutations.forEach(mutation => {
|
|
31
37
|
// React-Bootstrap attribute 'data-rb-event-key' is responsible for the tab identification
|
|
@@ -34,8 +40,8 @@ function Tabs({
|
|
|
34
40
|
const isActive = mutation.target.getAttribute('aria-selected') === 'true';
|
|
35
41
|
// datakey attribute is added manually to the dropdown
|
|
36
42
|
// elements so that they correspond to the native tabs' eventKey
|
|
37
|
-
const element = containerElementRef.
|
|
38
|
-
const moreTab = containerElementRef.
|
|
43
|
+
const element = containerElementRef.querySelector(`[datakey='${eventKey}']`);
|
|
44
|
+
const moreTab = containerElementRef.querySelector('.pgn__tab_more');
|
|
39
45
|
if (isActive) {
|
|
40
46
|
element?.classList.add('active');
|
|
41
47
|
// Here we add active class to the 'More Tab' if element exists in the dropdown
|
|
@@ -49,13 +55,13 @@ function Tabs({
|
|
|
49
55
|
}
|
|
50
56
|
});
|
|
51
57
|
}));
|
|
52
|
-
observer.observe(containerElementRef
|
|
58
|
+
observer.observe(containerElementRef, {
|
|
53
59
|
attributes: true, subtree: true, attributeFilter: ['aria-selected'],
|
|
54
60
|
});
|
|
55
61
|
return () => observer.disconnect();
|
|
56
62
|
}
|
|
57
63
|
return undefined;
|
|
58
|
-
}, []);
|
|
64
|
+
}, [containerElementRef]);
|
|
59
65
|
|
|
60
66
|
useEffect(() => {
|
|
61
67
|
if (overflowElementRef.current?.parentNode) {
|
|
@@ -63,10 +69,10 @@ function Tabs({
|
|
|
63
69
|
}
|
|
64
70
|
}, [overflowElementRef.current?.parentNode]);
|
|
65
71
|
|
|
66
|
-
const handleDropdownTabClick = (eventKey) => {
|
|
67
|
-
const hiddenTab = containerElementRef.
|
|
72
|
+
const handleDropdownTabClick = useCallback((eventKey) => {
|
|
73
|
+
const hiddenTab = containerElementRef.querySelector(`[data-rb-event-key='${eventKey}']`);
|
|
68
74
|
hiddenTab.click();
|
|
69
|
-
};
|
|
75
|
+
}, [containerElementRef]);
|
|
70
76
|
|
|
71
77
|
const tabsChildren = useMemo(() => {
|
|
72
78
|
const indexOfOverflowStart = indexOfLastVisibleChild + 1;
|
|
@@ -164,10 +170,10 @@ function Tabs({
|
|
|
164
170
|
/>
|
|
165
171
|
));
|
|
166
172
|
return childrenList;
|
|
167
|
-
}, [activeKey, children, defaultActiveKey, indexOfLastVisibleChild, moreTabText]);
|
|
173
|
+
}, [activeKey, children, defaultActiveKey, indexOfLastVisibleChild, moreTabText, handleDropdownTabClick]);
|
|
168
174
|
|
|
169
175
|
return (
|
|
170
|
-
<div ref={
|
|
176
|
+
<div ref={setContainerElementRef}>
|
|
171
177
|
<BaseTabs
|
|
172
178
|
defaultActiveKey={defaultActiveKey}
|
|
173
179
|
activeKey={activeKey}
|
|
@@ -12,12 +12,12 @@ window.ResizeObserver = window.ResizeObserver
|
|
|
12
12
|
}));
|
|
13
13
|
|
|
14
14
|
function TestComponent() {
|
|
15
|
-
const containerElementRef = React.
|
|
15
|
+
const [containerElementRef, setContainerElementRef] = React.useState(null);
|
|
16
16
|
const overflowElementRef = React.useRef(null);
|
|
17
|
-
const indexOfLastVisibleChild = useIndexOfLastVisibleChild(containerElementRef
|
|
17
|
+
const indexOfLastVisibleChild = useIndexOfLastVisibleChild(containerElementRef, overflowElementRef.current);
|
|
18
18
|
|
|
19
19
|
return (
|
|
20
|
-
<div ref={
|
|
20
|
+
<div ref={setContainerElementRef} style={{ display: 'flex' }}>
|
|
21
21
|
<div style={{ width: '250px' }} className="element">Element 1</div>
|
|
22
22
|
<div style={{ width: '250px' }} className="element">Element 2</div>
|
|
23
23
|
<div style={{ width: '250px' }} className="element">Element 3</div>
|