Skip to content

Commit d6fd355

Browse files
authored
feat: Add new environment prop to handle tabs in iframes (#365)
1 parent 4949d07 commit d6fd355

File tree

3 files changed

+37
-13
lines changed

3 files changed

+37
-13
lines changed

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,10 @@ Provide a custom class name for disabled tabs.
120120
121121
Register a callback that will receive the underlying DOM node for every mount. It will also receive null on unmount.
122122
123+
#### environment: `Window`
124+
125+
If you're rendering `react-tabs` within a different `window` context than the default one; for example, an iframe.
126+
123127
#### forceRenderTabPanel: `boolean`
124128
125129
> default: `false`

src/components/Tabs.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ export default class Tabs extends Component {
1717
forceRenderTabPanel: false,
1818
selectedIndex: null,
1919
defaultIndex: null,
20+
environment: null,
2021
};
2122

2223
static propTypes = {
@@ -36,6 +37,7 @@ export default class Tabs extends Component {
3637
selectedIndex: selectedIndexPropType,
3738
selectedTabClassName: PropTypes.string,
3839
selectedTabPanelClassName: PropTypes.string,
40+
environment: PropTypes.object,
3941
};
4042

4143
constructor(props) {

src/components/UncontrolledTabs.js

Lines changed: 31 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -22,18 +22,24 @@ function isTabDisabled(node) {
2222
}
2323

2424
let canUseActiveElement;
25-
try {
26-
canUseActiveElement = !!(
27-
typeof window !== 'undefined' &&
28-
window.document &&
29-
window.document.activeElement
30-
);
31-
} catch (e) {
32-
// Work around for IE bug when accessing document.activeElement in an iframe
33-
// Refer to the following resources:
34-
// http://stackoverflow.com/a/10982960/369687
35-
// https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/12733599
36-
canUseActiveElement = false;
25+
26+
function determineCanUseActiveElement(environment) {
27+
const env =
28+
environment || (typeof window !== 'undefined' ? window : undefined);
29+
30+
try {
31+
canUseActiveElement = !!(
32+
typeof env !== 'undefined' &&
33+
env.document &&
34+
env.document.activeElement
35+
);
36+
} catch (e) {
37+
// Work around for IE bug when accessing document.activeElement in an iframe
38+
// Refer to the following resources:
39+
// http://stackoverflow.com/a/10982960/369687
40+
// https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/12733599
41+
canUseActiveElement = false;
42+
}
3743
}
3844
export default class UncontrolledTabs extends Component {
3945
static defaultProps = {
@@ -57,6 +63,7 @@ export default class UncontrolledTabs extends Component {
5763
selectedIndex: PropTypes.number.isRequired,
5864
selectedTabClassName: PropTypes.string,
5965
selectedTabPanelClassName: PropTypes.string,
66+
environment: PropTypes.object,
6067
};
6168

6269
tabNodes = [];
@@ -164,6 +171,7 @@ export default class UncontrolledTabs extends Component {
164171
selectedIndex,
165172
selectedTabClassName,
166173
selectedTabPanelClassName,
174+
environment,
167175
} = this.props;
168176

169177
this.tabIds = this.tabIds || [];
@@ -190,10 +198,19 @@ export default class UncontrolledTabs extends Component {
190198
// If it is we should keep the focus on the next selected tab
191199
let wasTabFocused = false;
192200

201+
if (canUseActiveElement == null) {
202+
determineCanUseActiveElement(environment);
203+
}
204+
193205
if (canUseActiveElement) {
194206
wasTabFocused = React.Children.toArray(child.props.children)
195207
.filter(isTab)
196-
.some((tab, i) => document.activeElement === this.getTab(i));
208+
.some((tab, i) => {
209+
const env =
210+
environment ||
211+
(typeof window !== 'undefined' ? window : undefined);
212+
return env && env.document.activeElement === this.getTab(i);
213+
});
197214
}
198215

199216
result = cloneElement(child, {
@@ -350,6 +367,7 @@ export default class UncontrolledTabs extends Component {
350367
selectedIndex, // unused
351368
selectedTabClassName, // unused
352369
selectedTabPanelClassName, // unused
370+
environment, // unused
353371
...attributes
354372
} = this.props;
355373

0 commit comments

Comments
 (0)