Skip to content

Instantly share code, notes, and snippets.

@souporserious
Created February 15, 2018 22:38
Show Gist options
  • Save souporserious/d943dbc9e3a0ba4a5801a6c5ca9e0ccf to your computer and use it in GitHub Desktop.
Save souporserious/d943dbc9e3a0ba4a5801a6c5ca9e0ccf to your computer and use it in GitHub Desktop.
import React, { Component } from 'react'
import Collapse from './components/Collapse'
import OverflowMenu from './components/OverflowMenu'
import Popover from './components/Popover'
import Table from './components/Table'
import ResizeObserver from 'resize-observer-polyfill'
import createReactContext from 'create-react-context'
const { Provider, Consumer } = createReactContext()
class Observer extends Component {
nodes = {}
setRef = id => node => {
if (!this.nodes[id] && node) {
this.resizeObserver.observe(node)
this.nodes[id] = {
node,
unobserve: () => {
this.resizeObserver.unobserve(node)
delete this.nodes[id]
},
}
}
}
getRef = id => {
return this.nodes[id]
}
resizeObserver = new ResizeObserver(entries => {
console.log('resizeObserver called')
for (let entry of entries) {
console.log(entry)
}
})
value = {
setRef: this.setRef,
getRef: this.getRef,
}
render() {
return <Provider value={this.value}>{this.props.children}</Provider>
}
}
class ObserveChildInner extends Component {
componentWillUnmount() {
this.props.getRef(this.props.id).unobserve()
}
render() {
return this.props.children({
bind: {
ref: this.props.setRef(this.props.id),
},
})
}
}
function ObserveChild({ id, children }) {
return (
<Consumer>
{({ setRef, getRef }) => (
<ObserveChildInner id={id} setRef={setRef} getRef={getRef}>
{children}
</ObserveChildInner>
)}
</Consumer>
)
}
class InnerApp extends Component {
state = {
toggleOne: false,
toggleTwo: false,
toggleThree: true,
outsideUpdate: false,
}
render() {
const { toggleOne, toggleTwo, toggleThree } = this.state
return (
<div role="main">
{/* <Collapse /> */}
{/* <Popover /> */}
{/* <OverflowMenu /> */}
{/* <Table /> */}
{this.props.outsideUpdate && 'This is toggled'}
<Observer>
<button onClick={() => this.setState({ toggleOne: !toggleOne })}>
toggleOne
</button>
<button onClick={() => this.setState({ toggleTwo: !toggleTwo })}>
toggleTwo
</button>
<button onClick={() => this.setState({ toggleThree: !toggleThree })}>
toggleThree
</button>
Can have other stuff
<ObserveChild id="one">
{({ bind }) => (
<div {...bind} style={{ display: 'inline-block' }}>
{toggleOne ? 'One' : 'One has changed now as well'}
</div>
)}
</ObserveChild>
<ObserveChild id="two">
{({ bind }) => (
<span {...bind} style={{ display: 'inline-block' }}>
{toggleTwo ? 'Two' : 'Two changed'}
</span>
)}
</ObserveChild>
{toggleThree && (
<ObserveChild id="three">
{({ bind }) => (
<div {...bind} style={{ display: 'inline-block' }}>
Three
</div>
)}
</ObserveChild>
)}
<ObserveChild id="four">
{({ bind }) => (
<div {...bind} style={{ display: 'inline-block' }}>
{toggleTwo ? 'Four' : 'toggle four as well'}
</div>
)}
</ObserveChild>
Another string inside somewhere
<ObserveChild id="five">
{({ bind }) => (
<div {...bind} style={{ display: 'inline-block' }}>
Five is a really long string so we can see how it breaks down
</div>
)}
</ObserveChild>
</Observer>
</div>
)
}
}
class App extends Component {
state = {
outsideUpdate: false,
}
render() {
const { outsideUpdate } = this.state
return (
<div role="main">
<button
onClick={() => this.setState({ outsideUpdate: !outsideUpdate })}
>
toggle outsideUpdate
</button>
<InnerApp outsideUpdate={outsideUpdate} />
</div>
)
}
}
export default App
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment