Browse Source

Merge branch 'master' into dynamic-theming

master
jmlee2k 4 years ago
parent
commit
79a5652d9e
  1. 2
      index.d.ts
  2. 5
      site/src/components/Sidebar.js
  3. 5
      site/src/examples/events/emoji.js
  4. 5
      site/src/examples/events/hidden.js
  5. 32
      site/src/pages/docs/api.js
  6. 108
      site/src/pages/docs/events.js
  7. 5
      src/emojiArea.ts
  8. 1
      src/events.ts
  9. 60
      src/index.ts

2
index.d.ts

@ -69,7 +69,7 @@ declare namespace EmojiButton {
export type EmojiTheme = 'dark' | 'light' | 'auto';
export type Event = 'emoji';
export type Event = 'emoji' | 'hidden';
export type Placement =
| 'auto'

5
site/src/components/Sidebar.js

@ -80,6 +80,11 @@ export default function Sidebar() {
API
</Link>
</li>
<li>
<Link activeClassName={styles.active} to="/docs/events">
Events
</Link>
</li>
</ul>
</nav>
);

5
site/src/examples/events/emoji.js

@ -0,0 +1,5 @@
const picker = new EmojiButton();
picker.on('emoji', selection => {
alert(`"emoji" event fired, emoji is ${selection.emoji}`);
});

5
site/src/examples/events/hidden.js

@ -0,0 +1,5 @@
const picker = new EmojiButton();
picker.on('hidden', () => {
alert('"hidden" event fired');
});

32
site/src/pages/docs/api.js

@ -479,15 +479,15 @@ export default function ApiDocs() {
</h3>
<p>
Removes the given listener for the given event. See{' '}
<a href="#events">Events</a> for a list of valid events.
<Link to="/docs/events">Events</Link> for a list of valid events.
</p>
<h3>
Method: <code>on(event, callback)</code>
</h3>
<p>
Adds a listener for the given event. See <a href="#events">Events</a>{' '}
for a list of valid events.
Adds a listener for the given event. See{' '}
<Link to="/docs/events">Events</Link> for a list of valid events.
</p>
<h3>
@ -515,32 +515,6 @@ export default function ApiDocs() {
<Link to="/docs/themes">Themes</Link> for more details.
</p>
<a name="events" />
<h2>Events</h2>
<h3>
<code>emoji</code>
</h3>
<p>
Fired when an emoji is selected. The callback will receive a single
object with one or more of the following properties:
</p>
<ul>
<li>
<code>custom</code>: This will be <code>true</code> for a custom
emoji.
</li>
<li>
<code>emoji</code>: The Unicode emoji character that was selected.
This will be included for native and Twemoji emojis, but not for
custom emojis.
</li>
<li>
<code>url</code>: The URL of the emoji image. This will be included
for Twemoji and custom emojis.
</li>
</ul>
<a name="categories" />
<h2>Category IDs</h2>
<p>The valid category IDs are as follows:</p>

108
site/src/pages/docs/events.js

@ -0,0 +1,108 @@
import React, { useRef, useState, useEffect } from 'react';
import { EmojiButton } from '@joeattardi/emoji-button';
import styles from '../../components/Example.module.css';
import DocLayout from '../../components/DocLayout';
import SourceFile from '../../components/SourceFile';
import emojiExample from '!!raw-loader!../../examples/events/emoji.js';
import hiddenExample from '!!raw-loader!../../examples/events/hidden.js';
function EventExample({
initialEmoji = '😎',
initialImageUrl,
options,
event,
eventCallback
}) {
const buttonRef = useRef();
const [picker, setPicker] = useState(null);
const [emoji, setEmoji] = useState(initialEmoji);
const [imageUrl, setImageUrl] = useState(initialImageUrl);
useEffect(() => {
const pickerObj = new EmojiButton(options);
pickerObj.on('emoji', selection => {
setEmoji(selection.emoji);
setImageUrl(selection.url);
});
pickerObj.on(event,eventCallback);
setPicker(pickerObj);
}, []);
function togglePicker() {
picker.togglePicker(buttonRef.current);
}
return (
<button
className={styles.emojiButton}
ref={buttonRef}
onClick={togglePicker}
>
{imageUrl ? <img alt={emoji} src={imageUrl} /> : <span>{emoji}</span>}
</button>
);
}
function onEmoji(selection)
{
alert(`"emoji" event fired, emoji is ${selection.emoji}`);
}
function onHidden()
{
alert('"hidden" event fired');
}
export default function Events() {
return (
<DocLayout>
<h1>Events</h1>
<p>
The <code>EmojiButton</code> class emits the following events:
</p>
<h2>
<code>emoji</code>
</h2>
<p>
Fired when an emoji is selected. The callback will receive a single
object with one or more of the following properties:
</p>
<ul>
<li>
<code>custom</code>: This will be <code>true</code> for a custom
emoji.
</li>
<li>
<code>emoji</code>: The Unicode emoji character that was selected.
This will be included for native and Twemoji emojis, but not for
custom emojis.
</li>
<li>
<code>url</code>: The URL of the emoji image. This will be included
for Twemoji and custom emojis.
</li>
</ul>
<EventExample event="emoji" eventCallback={onEmoji}/>
<SourceFile src={emojiExample} />
<h2>
<code>hidden</code>
</h2>
<p>
Fired when the picker is hidden.
</p>
<EventExample event="hidden" eventCallback={onHidden}/>
<SourceFile src={hiddenExample} />
</DocLayout>
);
}

5
src/emojiArea.ts

@ -328,6 +328,7 @@ export class EmojiArea {
) {
return;
}
let closestHeaderIndex = this.headerOffsets.findIndex(
offset => offset >= Math.round(this.emojis.scrollTop)
);
@ -345,6 +346,10 @@ export class EmojiArea {
closestHeaderIndex = this.headerOffsets.length;
}
if (this.headerOffsets[closestHeaderIndex] === this.emojis.scrollTop) {
closestHeaderIndex++;
}
this.currentCategory = closestHeaderIndex - 1;
if (this.options.showCategoryButtons) {
this.categoryButtons.setActiveButton(this.currentCategory);

1
src/events.ts

@ -5,3 +5,4 @@ export const SHOW_PREVIEW = 'showPreview';
export const HIDE_PREVIEW = 'hidePreview';
export const HIDE_VARIANT_POPUP = 'hideVariantPopup';
export const CATEGORY_CLICKED = 'categoryClicked';
export const PICKER_HIDDEN = 'hidden';

60
src/index.ts

@ -11,7 +11,8 @@ import {
EMOJI,
SHOW_SEARCH_RESULTS,
HIDE_SEARCH_RESULTS,
HIDE_VARIANT_POPUP
HIDE_VARIANT_POPUP,
PICKER_HIDDEN
} from './events';
import { EmojiPreview } from './preview';
import { Search } from './search';
@ -88,7 +89,7 @@ export class EmojiButton {
private emojiArea: EmojiArea;
private overlay: HTMLElement;
private overlay?: HTMLElement;
private popper: Popper;
@ -385,34 +386,47 @@ export class EmojiButton {
if (this.overlay) {
document.body.removeChild(this.overlay);
this.overlay = undefined;
}
// In some browsers, the delayed hide was triggering the scroll event handler
// and stealing the focus. Remove the scroll listener before doing the delayed hide.
this.emojiArea.emojis.removeEventListener(
'scroll',
this.emojiArea.highlightCategory
);
this.pickerEl.classList.add('hiding');
setTimeout(() => {
this.wrapper.style.display = 'none';
this.pickerEl.classList.remove('hiding');
setTimeout(
() => {
this.wrapper.style.display = 'none';
this.pickerEl.classList.remove('hiding');
if (this.pickerContent.firstChild !== this.emojiArea.container) {
empty(this.pickerContent);
this.pickerContent.appendChild(this.emojiArea.container);
}
if (this.pickerContent.firstChild !== this.emojiArea.container) {
empty(this.pickerContent);
this.pickerContent.appendChild(this.emojiArea.container);
}
const searchField = this.pickerEl.querySelector(
`.${CLASS_SEARCH_FIELD}`
) as HTMLInputElement;
if (searchField) {
searchField.value = '';
}
const searchField = this.pickerEl.querySelector(
`.${CLASS_SEARCH_FIELD}`
) as HTMLInputElement;
if (searchField) {
searchField.value = '';
}
const variantOverlay = this.pickerEl.querySelector(
`.${CLASS_VARIANT_OVERLAY}`
);
if (variantOverlay) {
this.events.emit(HIDE_VARIANT_POPUP);
}
const variantOverlay = this.pickerEl.querySelector(
`.${CLASS_VARIANT_OVERLAY}`
);
if (variantOverlay) {
this.events.emit(HIDE_VARIANT_POPUP);
}
this.hideInProgress = false;
this.hideInProgress = false;
}, 170);
this.publicEvents.emit(PICKER_HIDDEN);
},
this.options.showAnimation ? 170 : 0
);
setTimeout(() => {
document.removeEventListener('click', this.onDocumentClick);

Loading…
Cancel
Save