mirror of
https://github.com/Stremio/stremio-web.git
synced 2026-04-20 23:12:13 +00:00
Focusable component implemented
This commit is contained in:
parent
51854561b7
commit
5e43c94b59
5 changed files with 79 additions and 1 deletions
12
src/common/Focusable/Focusable.js
Normal file
12
src/common/Focusable/Focusable.js
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
import React from 'react';
|
||||
import FocusableContext from './FocusableContext';
|
||||
|
||||
const Focusable = ({ children }) => {
|
||||
return (
|
||||
<FocusableContext.Consumer>
|
||||
{focusable => React.cloneElement(React.Children.only(children), { tabIndex: focusable ? 0 : -1 })}
|
||||
</FocusableContext.Consumer>
|
||||
);
|
||||
};
|
||||
|
||||
export default Focusable;
|
||||
3
src/common/Focusable/FocusableContext.js
Normal file
3
src/common/Focusable/FocusableContext.js
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
import React from 'react';
|
||||
|
||||
export default React.createContext(false);
|
||||
53
src/common/Focusable/FocusableProvider.js
Normal file
53
src/common/Focusable/FocusableProvider.js
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
import React, { Component } from 'react';
|
||||
import FocusableContext from './FocusableContext';
|
||||
|
||||
class FocusableProvider extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.childElementRef = React.createRef();
|
||||
this.containerClildListObserver = new MutationObserver(this.containerClildListOnChange);
|
||||
this.state = {
|
||||
focusable: false
|
||||
};
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.containerClildListOnChange();
|
||||
this.containerClildListObserver.observe(this.childElementRef.current.parentElement, {
|
||||
childList: true
|
||||
});
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
this.containerClildListObserver.disconnect();
|
||||
}
|
||||
|
||||
shouldComponentUpdate(nextProps, nextState) {
|
||||
return nextProps.children !== this.props.children ||
|
||||
nextState.focusable !== this.state.focusable;
|
||||
}
|
||||
|
||||
containerClildListOnChange = () => {
|
||||
for (let i = this.childElementRef.current.parentElement.children.length - 1; i >= 0; i--) {
|
||||
const child = this.childElementRef.current.parentElement.children[i];
|
||||
const tagName = child.tagName.toLowerCase();
|
||||
if (tagName !== 'script' && tagName !== 'style') {
|
||||
this.setState({
|
||||
focusable: this.childElementRef.current === child
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<FocusableContext.Provider value={this.state.focusable}>
|
||||
{React.cloneElement(React.Children.only(this.props.children), { ref: this.childElementRef })}
|
||||
</FocusableContext.Provider>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default FocusableProvider;
|
||||
7
src/common/Focusable/index.js
Normal file
7
src/common/Focusable/index.js
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
import Focusable from './Focusable';
|
||||
import FocusableProvider from './FocusableProvider';
|
||||
|
||||
export {
|
||||
Focusable,
|
||||
FocusableProvider
|
||||
};
|
||||
|
|
@ -9,6 +9,7 @@ import MetaItem from './MetaItem';
|
|||
import ShareAddon from './ShareAddon';
|
||||
import UserPanel from './UserPanel';
|
||||
import Slider from './Slider';
|
||||
import { Focusable, FocusableProvider } from './Focusable';
|
||||
|
||||
export {
|
||||
Checkbox,
|
||||
|
|
@ -21,5 +22,7 @@ export {
|
|||
MetaItem,
|
||||
ShareAddon,
|
||||
UserPanel,
|
||||
Slider
|
||||
Slider,
|
||||
Focusable,
|
||||
FocusableProvider
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in a new issue