UNPKG

2.57 kBJSXView Raw
1/* eslint-disable no-param-reassign, react/jsx-props-no-spreading, no-fallthrough */
2
3const React = require('react');
4const PropTypes = require('prop-types');
5const Lightbox = require('./Lightbox');
6
7class Image extends React.Component {
8 constructor(props) {
9 super(props);
10
11 this.state = {
12 lightbox: false,
13 };
14 this.lightbox = React.createRef();
15
16 this.toggle = this.toggle.bind(this);
17 this.handleKey = this.handleKey.bind(this);
18
19 this.isEmoji = props.className === 'emoji';
20 }
21
22 componentDidMount() {
23 this.lightboxSetup();
24 }
25
26 toggle(toState) {
27 if (this.props.className === 'emoji') return;
28
29 if (typeof toState === 'undefined') toState = !this.state.lightbox;
30
31 if (toState) this.lightboxSetup();
32
33 this.setState({ lightbox: toState });
34 }
35
36 lightboxSetup() {
37 const $el = this.lightbox.current;
38 setTimeout(() => {
39 $el.scrollTop = ($el.scrollHeight - $el.offsetHeight) / 2;
40 }, 0);
41 }
42
43 handleKey(e) {
44 let { key, metaKey: cmd } = e;
45
46 cmd = cmd ? 'cmd+' : '';
47 key = `${cmd}${key.toLowerCase()}`;
48
49 switch (key) {
50 case 'cmd+.':
51 case 'escape':
52 // CLOSE
53 this.toggle(false);
54 break;
55 case ' ':
56 case 'enter':
57 // OPEN
58 if (!this.state.open) this.toggle(true);
59 e.preventDefault();
60 default:
61 }
62 }
63
64 render() {
65 const { alt } = this.props;
66 if (this.isEmoji) {
67 return <img {...this.props} alt={alt} loading="lazy" />;
68 }
69 return (
70 <span className="img" onClick={() => this.toggle()} onKeyDown={this.handleKey} role={'button'} tabIndex={0}>
71 <img {...this.props} alt={alt} />
72 <Lightbox
73 ref={this.lightbox}
74 {...this.props}
75 onScroll={() => this.toggle(false)}
76 opened={this.state.lightbox}
77 />
78 </span>
79 );
80 }
81}
82
83Image.propTypes = {
84 align: PropTypes.string,
85 alt: PropTypes.string,
86 caption: PropTypes.oneOfType([PropTypes.string, PropTypes.bool]),
87 className: PropTypes.oneOfType([PropTypes.string, PropTypes.array]),
88 height: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
89 src: PropTypes.string.isRequired,
90 title: PropTypes.string,
91 width: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
92};
93
94Image.defaultProps = {
95 align: '',
96 alt: '',
97 caption: '',
98 height: 'auto',
99 src: '',
100 title: '',
101 width: 'auto',
102};
103
104module.exports = sanitizeSchema => {
105 sanitizeSchema.attributes.img = ['className', 'title', 'alt', 'width', 'height', 'align', 'src', 'longDesc'];
106 return Image;
107};