Last active
August 17, 2017 08:05
-
-
Save jbmoelker/de436b83a6bc8c6c7efb8f69d02da0d6 to your computer and use it in GitHub Desktop.
Preact Details and Summary component
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { h } from 'preact'; | |
import { Details, Summary } from './DetailsSummary'; | |
const App = () => ( | |
<Details> | |
<Summary>This is a summary supporting <code>HTML</code></Summary> | |
<p>... with expandible details.</p> | |
<p>Based on <a href="http://html5doctor.com/summary-figcaption-element/">HTML5 details/summary elements</a>.</p> | |
<p>And added <a href="http://caniuse.com/#feat=details">support for browsers</a> lacking built-in support.</p> | |
</Details> | |
); | |
export default App; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* polyfill hidden behaviour */ | |
details:not([open]) > *:not(summary) { | |
display: none; | |
} | |
/* more styling tips: http://html5doctor.com/the-details-and-summary-elements/#styling */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { h, Component } from 'preact'; | |
import './DetailsSummary.css'; | |
export const Summary = ({ children }) => (<span>{ children }</span>); | |
Summary.displayName = 'Summary'; /* required as `nodeName.name` is minified during build */ | |
export class Details extends Component { | |
constructor(props) { | |
super(props); | |
this.state = { open: false }; | |
this.toggle = this.toggle.bind(this); | |
} | |
toggle(event) { | |
event.preventDefault(); | |
this.setState({ open: !this.state.open }) | |
} | |
render ({ children }, { open }) { | |
const summary = children.find(child => child.nodeName.displayName === 'Summary'); | |
const details = children.filter(child => child !== summary); | |
return ( | |
<details open={ open }> | |
<summary onClick={ this.toggle }>{ summary }</summary> | |
{ details } | |
</details> | |
); | |
} | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment