function EmojiGroup({ name, emojis }) {
function getEmojiBoard() {
+ const emojiBoard = [];
const ROW_EMOJIS_COUNT = 7;
- const emojiRows = [];
const totalEmojis = emojis.length;
for (let r = 0; r < totalEmojis; r += ROW_EMOJIS_COUNT) {
const emojiRow = [];
for (let c = r; c < r + ROW_EMOJIS_COUNT; c += 1) {
- const emojiIndex = r + c;
+ const emojiIndex = c;
if (emojiIndex >= totalEmojis) break;
const emoji = emojis[emojiIndex];
emojiRow.push(
attributes: () => ({
unicode: emoji.unicode,
shortcodes: emoji.shortcodes?.toString(),
+ hexcode: emoji.hexcode,
}),
},
))
</span>,
);
}
- emojiRows.push(<div key={r} className="emoji-row">{emojiRow}</div>);
+ emojiBoard.push(<div key={r} className="emoji-row">{emojiRow}</div>);
}
- return emojiRows;
+ return emojiBoard;
}
return (
emojis: PropTypes.arrayOf(PropTypes.shape({
length: PropTypes.number,
unicode: PropTypes.string,
+ hexcode: PropTypes.string,
shortcodes: PropTypes.oneOfType([
PropTypes.string,
PropTypes.arrayOf(PropTypes.string),
function EmojiBoard({ onSelect }) {
const searchRef = useRef(null);
const scrollEmojisRef = useRef(null);
+ const emojiInfo = useRef(null);
function isTargetNotEmoji(target) {
return target.classList.contains('emoji') === false;
}
function getEmojiDataFromTarget(target) {
const unicode = target.getAttribute('unicode');
+ const hexcode = target.getAttribute('hexcode');
let shortcodes = target.getAttribute('shortcodes');
if (typeof shortcodes === 'undefined') shortcodes = undefined;
else shortcodes = shortcodes.split(',');
- return { unicode, shortcodes };
+ return { unicode, hexcode, shortcodes };
}
function selectEmoji(e) {
onSelect(getEmojiDataFromTarget(emoji));
}
+ function setEmojiInfo(emoji) {
+ const infoEmoji = emojiInfo.current.firstElementChild.firstElementChild;
+ const infoShortcode = emojiInfo.current.lastElementChild;
+
+ const emojiSrc = infoEmoji.src;
+ infoEmoji.src = `${emojiSrc.slice(0, emojiSrc.lastIndexOf('/') + 1)}${emoji.hexcode.toLowerCase()}.png`;
+ infoShortcode.textContent = `:${emoji.shortcode}:`;
+ }
+
function hoverEmoji(e) {
if (isTargetNotEmoji(e.target)) return;
const emoji = e.target;
- const { shortcodes } = getEmojiDataFromTarget(emoji);
+ const { shortcodes, hexcode } = getEmojiDataFromTarget(emoji);
if (typeof shortcodes === 'undefined') {
searchRef.current.placeholder = 'Search';
+ setEmojiInfo({ hexcode: '1f643', shortcode: 'slight_smile' });
return;
}
if (searchRef.current.placeholder === shortcodes[0]) return;
searchRef.current.setAttribute('placeholder', `:${shortcodes[0]}:`);
+ setEmojiInfo({ hexcode, shortcode: shortcodes[0] });
}
function handleSearchChange(e) {
return (
<div id="emoji-board" className="emoji-board">
<div className="emoji-board__content">
- <div className="emoji-board__emojis">
+ <div className="emoji-board__content__search">
+ <RawIcon size="small" src={SearchIC} />
+ <Input onChange={handleSearchChange} forwardRef={searchRef} placeholder="Search" />
+ </div>
+ <div className="emoji-board__content__emojis">
<ScrollView ref={scrollEmojisRef} autoHide>
<div onMouseMove={hoverEmoji} onClick={selectEmoji}>
<SearchedEmoji />
</div>
</ScrollView>
</div>
- <div className="emoji-board__search">
- <RawIcon size="small" src={SearchIC} />
- <Input onChange={handleSearchChange} forwardRef={searchRef} placeholder="Search" />
+ <div ref={emojiInfo} className="emoji-board__content__info">
+ <div>{ parse(twemoji.parse('🙂')) }</div>
+ <Text>:slight_smile:</Text>
</div>
</div>
<div className="emoji-board__nav">
.emoji-board {
display: flex;
-
&__content {
@extend .emoji-board-flexItem;
@extend .emoji-board-flexBoxV;
- height: 360px;
+ height: 400px;
+ width: 286px;
}
&__nav {
@extend .emoji-board-flexBoxV;
+ justify-content: center;
padding: 4px 6px;
background-color: var(--bg-surface-low);
& > .ic-btn-surface {
margin: calc(var(--sp-ultra-tight) / 2) 0;
+ opacity: 0.8;
}
}
}
-
-.emoji-board__emojis {
- @extend .emoji-board-flexItem;
-}
-.emoji-board__search {
- display: flex;
- align-items: center;
- padding: calc(var(--sp-ultra-tight) / 2) var(--sp-normal);
+.emoji-board__content__search {
+ padding: var(--sp-extra-tight);
+ position: relative;
+ & .ic-raw {
+ position: absolute;
+ left: var(--sp-normal);
+ top: var(--sp-normal);
+ transform: translateY(1px);
+ [dir=rtl] & {
+ left: unset;
+ right: var(--sp-normal);
+ }
+ }
+
& .input-container {
- @extend .emoji-board-flexItem;
& .input {
min-width: 100%;
width: 0;
- background-color: transparent;
- border: none !important;
- box-shadow: none !important;
+ padding: var(--sp-extra-tight) 36px;
+ border-radius: calc(var(--bo-radius) / 2);
}
}
}
+.emoji-board__content__emojis {
+ @extend .emoji-board-flexItem;
+ @extend .emoji-board-flexBoxV;
+}
+.emoji-board__content__info {
+ margin: 0 var(--sp-extra-tight);
+ padding: var(--sp-tight) var(--sp-extra-tight);
+ border-top: 1px solid var(--bg-surface-border);
+
+ display: flex;
+ align-items: center;
+
+ & > div:first-child {
+ line-height: 0;
+ .emoji {
+ width: 32px;
+ height: 32px;
+ }
+ }
+ & > p:last-child {
+ @extend .emoji-board-flexItem;
+ margin: 0 var(--sp-tight);
+ overflow: hidden;
+ white-space: nowrap;
+ text-overflow: ellipsis;
+ }
+}
.emoji-group {
--emoji-padding: 6px;
z-index: 99;
background-color: var(--bg-surface);
- padding: var(--sp-tight) var(--sp-normal);
+ margin-left: var(--sp-extra-tight);
+ padding: var(--sp-extra-tight) var(--sp-ultra-tight);
text-transform: uppercase;
font-weight: 600;
+ box-shadow: 0 -4px 0 0 var(--bg-surface);
+ border-bottom: 1px solid var(--bg-surface-border);
+ [dir=rtl] & {
+ margin-left: 0;
+ margin-right: var(--sp-extra-tight);
+ }
}
& .emoji-set {
- margin: 0 calc(var(--sp-normal) - var(--emoji-padding));
+ margin: var(--sp-extra-tight) calc(var(--sp-normal) - var(--emoji-padding));
margin-right: calc(var(--sp-extra-tight) - var(--emoji-padding));
[dir=rtl] & {
margin-right: calc(var(--sp-normal) - var(--emoji-padding));
}
& .emoji {
width: 38px;
+ height: 38px;
padding: var(--emoji-padding);
cursor: pointer;
&:hover {