Skip to content

Instantly share code, notes, and snippets.

@jbmoelker
Last active August 17, 2017 08:05
Show Gist options
  • Save jbmoelker/de436b83a6bc8c6c7efb8f69d02da0d6 to your computer and use it in GitHub Desktop.
Save jbmoelker/de436b83a6bc8c6c7efb8f69d02da0d6 to your computer and use it in GitHub Desktop.
Preact Details and Summary component
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;
/* polyfill hidden behaviour */
details:not([open]) > *:not(summary) {
display: none;
}
/* more styling tips: http://html5doctor.com/the-details-and-summary-elements/#styling */
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