UNPKG

boundless-popover

Version:

A non-blocking container positioned to a specific anchor element.

139 lines (126 loc) 5.21 kB
import { createElement, PureComponent } from 'react'; import ArrowKeyNavigation from '../../boundless-arrow-key-navigation/index'; import Button from '../../boundless-button/index'; import Popover from '../'; export default class PopoverDemo extends PureComponent { state = { words: [ { word: 'transcendental', syllabicRepresentation: 'tran·scen·den·tal', type: 'adjective', primaryDefinition: '', secondaryDefinitions: [ 'of or relating to a spiritual or nonphysical realm', '(of a number, e.g., e or π) real but not a root of an algebraic equation with rational roots', ], }, { word: 'obstetrics', syllabicRepresentation: 'ob·stet·rics', type: 'noun', preset: Popover.preset.N, primaryDefinition: 'the branch of medicine and surgery concerned with childbirth and the care of women giving birth', secondaryDefinitions: [], }, { word: 'olio', syllabicRepresentation: 'o·li·o', type: 'noun', preset: Popover.preset.E, primaryDefinition: [ <span key='1'>another term for </span>, <a key='2' href='https://www.google.com/search?safe=active&espv=2&biw=1440&bih=74&q=define+olla+podrida&sa=X&ved=0CB8QgCswAGoVChMIlbiutZmDxwIVQx0-Ch1f-g9t'>olla podrida</a>, ], secondaryDefinitions: [ 'a miscellaneous collection of things', 'a variety act or show', ], }, { word: 'anastrophe', syllabicRepresentation: 'a·nas·tro·phe', type: 'noun', preset: Popover.preset.W, primaryDefinition: 'the inversion of the usual order of words or clauses', secondaryDefinitions: [], }, { word: 'octothorp', syllabicRepresentation: 'oc·to·thorp', type: 'noun', preset: Popover.preset.WNW, primaryDefinition: 'another term for the pound sign (#)', secondaryDefinitions: [], } ], } handleKeyDown(index, event) { if (event.key === 'Enter') { this[this.state['showPopover' + index] ? 'showPopover' : 'hidePopover'](index, event); } } openPopover(index) { this.setState({ ['showPopover' + index]: true }); } closePopover(index) { this.setState({ ['showPopover' + index]: false }); } renderSecondaryDefinitions(definitions = []) { return definitions.length ? ( <ArrowKeyNavigation component='ol'> {definitions.map((definition, index) => <li key={index}>{definition}</li>)} </ArrowKeyNavigation> ) : null; } renderPrimaryDefinition(definition) { return definition ? (<p>{definition}</p>) : null; } renderBody(definition) { return ( <div> <strong>{definition.syllabicRepresentation}</strong> <br /> <em>{definition.type}</em> {this.renderPrimaryDefinition(definition.primaryDefinition)} {this.renderSecondaryDefinitions(definition.secondaryDefinitions)} </div> ); } renderPopovers() { return this.state.words.map((definition, index) => { return this.state['showPopover' + index] ? ( <Popover key={definition.word} anchor={this.refs[`$word${index}`]} caretAnchor={this.refs[`$word-caret-anchor${index}`]} className='demo-popover' closeOnOutsideFocus={true} preset={definition.preset} onClose={() => this.closePopover(index)}> {this.renderBody(definition)} </Popover> ) : undefined; }); } render() { return ( <div> <p> Words of the day for {(new Date()).toLocaleDateString()}:<br /> <sub>Note that the words with ⓘ symbols have their caret anchored to the symbol, rather than the center of the button.</sub> </p> <div className='spread'> {this.state.words.map((definition, index) => { return ( <Button key={definition.word} ref={`$word${index}`} className='show-help-popover' onPressed={() => this.openPopover(index)} pressed={this.state[`showPopover${index}`]} tabIndex='0'> {definition.word} {index % 2 === 0 ? <span ref={`$word-caret-anchor${index}`}></span> : null} </Button> ); })} </div> {this.renderPopovers()} </div> ); } }