Update reaction picker visuals
This commit is contained in:
parent
1a3f87f7f6
commit
561bc0695f
10 changed files with 277 additions and 194 deletions
|
@ -3136,11 +3136,15 @@
|
||||||
"message": "Please set up Signal on your phone and desktop to use the Sticker Pack Creator",
|
"message": "Please set up Signal on your phone and desktop to use the Sticker Pack Creator",
|
||||||
"description": "The error message which appears when the user has not linked their account and attempts to use the Sticker Creator"
|
"description": "The error message which appears when the user has not linked their account and attempts to use the Sticker Creator"
|
||||||
},
|
},
|
||||||
|
"Reactions--remove": {
|
||||||
|
"message": "Remove reaction",
|
||||||
|
"describe": "Shown when you want to remove a reaction you've made"
|
||||||
|
},
|
||||||
"Reactions--error": {
|
"Reactions--error": {
|
||||||
"message": "Failed to send reaction. Please try again.",
|
"message": "Failed to send reaction. Please try again.",
|
||||||
"description": "Shown when a reaction fails to send"
|
"description": "Shown when a reaction fails to send"
|
||||||
},
|
},
|
||||||
"ReactionsViewer--more": {
|
"Reactions--more": {
|
||||||
"message": "More",
|
"message": "More",
|
||||||
"description": "Use in the reaction picker as the alt text for the 'more' button"
|
"description": "Use in the reaction picker as the alt text for the 'more' button"
|
||||||
},
|
},
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
<svg fill="none" height="32" viewBox="0 0 32 32" width="32" xmlns="http://www.w3.org/2000/svg"><circle cx="16" cy="16" fill="#4a4a4a" r="16"/><g fill="#e9e9e9"><circle cx="8" cy="16" r="2"/><circle cx="16" cy="16" r="2"/><circle cx="24" cy="16" r="2"/></g></svg>
|
|
Before Width: | Height: | Size: 262 B |
|
@ -1 +0,0 @@
|
||||||
<svg fill="none" height="32" viewBox="0 0 32 32" width="32" xmlns="http://www.w3.org/2000/svg"><circle cx="16" cy="16" fill="#2e2e2e" r="16"/><g fill="#e9e9e9"><circle cx="8" cy="16" r="2"/><circle cx="16" cy="16" r="2"/><circle cx="24" cy="16" r="2"/></g></svg>
|
|
Before Width: | Height: | Size: 262 B |
|
@ -1 +0,0 @@
|
||||||
<svg fill="none" height="32" viewBox="0 0 32 32" width="32" xmlns="http://www.w3.org/2000/svg"><path d="m16 32c8.8366 0 16-7.1634 16-16 0-8.83656-7.1634-16-16-16-8.83656 0-16 7.16344-16 16 0 8.8366 7.16344 16 16 16z" fill="#676767"/><g fill="#e9e9e9"><path d="m8 18c1.10457 0 2-.8954 2-2s-.89543-2-2-2-2 .8954-2 2 .89543 2 2 2z"/><path d="m16 18c1.1046 0 2-.8954 2-2s-.8954-2-2-2-2 .8954-2 2 .8954 2 2 2z"/><path d="m24 18c1.1046 0 2-.8954 2-2s-.8954-2-2-2-2 .8954-2 2 .8954 2 2 2z"/></g></svg>
|
|
Before Width: | Height: | Size: 494 B |
|
@ -1 +0,0 @@
|
||||||
<svg fill="none" height="32" viewBox="0 0 32 32" width="32" xmlns="http://www.w3.org/2000/svg"><path d="m16 32c8.8366 0 16-7.1634 16-16 0-8.83656-7.1634-16-16-16-8.83656 0-16 7.16344-16 16 0 8.8366 7.16344 16 16 16z" fill="#4a4a4a"/><g fill="#e9e9e9"><path d="m8 18c1.10457 0 2-.8954 2-2s-.89543-2-2-2-2 .8954-2 2 .89543 2 2 2z"/><path d="m16 18c1.1046 0 2-.8954 2-2s-.8954-2-2-2-2 .8954-2 2 .8954 2 2 2z"/><path d="m24 18c1.1046 0 2-.8954 2-2s-.8954-2-2-2-2 .8954-2 2 .8954 2 2 2z"/></g></svg>
|
|
Before Width: | Height: | Size: 494 B |
|
@ -4684,142 +4684,6 @@ button.module-image__border-overlay:focus {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Module: Reaction Picker
|
|
||||||
|
|
||||||
@keyframes module-reaction-picker__background-fade {
|
|
||||||
from {
|
|
||||||
background: transparent;
|
|
||||||
}
|
|
||||||
to {
|
|
||||||
// This color is the same in both light and dark themes
|
|
||||||
background: rgba($color-black, 0.8);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes module-reaction-picker__emoji-fade {
|
|
||||||
from {
|
|
||||||
transform: translate3d(0, 24px, 0);
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
to {
|
|
||||||
transform: translate3d(0, 0, 0);
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.module-reaction-picker {
|
|
||||||
width: 320px;
|
|
||||||
height: 56px;
|
|
||||||
border-radius: 30px;
|
|
||||||
position: relative;
|
|
||||||
z-index: 2;
|
|
||||||
|
|
||||||
animation: {
|
|
||||||
name: module-reaction-picker__background-fade;
|
|
||||||
duration: 400ms;
|
|
||||||
timing-function: $ease-out-expo;
|
|
||||||
fill-mode: forwards;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__emoji-btn {
|
|
||||||
@include button-reset;
|
|
||||||
display: flex;
|
|
||||||
min-width: 52px;
|
|
||||||
min-height: 52px;
|
|
||||||
border-radius: 52px;
|
|
||||||
|
|
||||||
position: absolute;
|
|
||||||
top: 2px;
|
|
||||||
|
|
||||||
@for $i from 0 through 6 {
|
|
||||||
&:nth-of-type(#{$i + 1}) {
|
|
||||||
left: 2px + ($i * 44px);
|
|
||||||
|
|
||||||
// Prevent animation jank
|
|
||||||
opacity: 0;
|
|
||||||
|
|
||||||
animation: {
|
|
||||||
name: module-reaction-picker__emoji-fade;
|
|
||||||
duration: 400ms;
|
|
||||||
timing-function: $ease-out-expo;
|
|
||||||
delay: #{$i * 10ms};
|
|
||||||
fill-mode: forwards;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
transition: background 400ms $ease-out-expo;
|
|
||||||
&--selected {
|
|
||||||
// This color is the same in both light and dark themes
|
|
||||||
background: rgba($color-white, 0.3);
|
|
||||||
}
|
|
||||||
&--more {
|
|
||||||
@include light-theme {
|
|
||||||
background: url('../images/any-emoji-32-light.svg') no-repeat center;
|
|
||||||
}
|
|
||||||
|
|
||||||
@include dark-theme {
|
|
||||||
background: url('../images/any-emoji-32-dark.svg') no-repeat center;
|
|
||||||
}
|
|
||||||
|
|
||||||
&::after {
|
|
||||||
content: '';
|
|
||||||
display: block;
|
|
||||||
width: 52px;
|
|
||||||
height: 52px;
|
|
||||||
opacity: 0;
|
|
||||||
transition: opacity 400ms $ease-out-expo;
|
|
||||||
|
|
||||||
@include light-theme {
|
|
||||||
background: url('../images/any-emoji-32-light-hover.svg') no-repeat
|
|
||||||
center;
|
|
||||||
}
|
|
||||||
|
|
||||||
@include dark-theme {
|
|
||||||
background: url('../images/any-emoji-32-dark-hover.svg') no-repeat
|
|
||||||
center;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&:hover::after {
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@include keyboard-mode {
|
|
||||||
&:focus:before {
|
|
||||||
content: '';
|
|
||||||
display: block;
|
|
||||||
width: 4px;
|
|
||||||
height: 4px;
|
|
||||||
background: $color-ultramarine;
|
|
||||||
border-radius: 2px;
|
|
||||||
position: absolute;
|
|
||||||
bottom: 4px;
|
|
||||||
left: calc(50% - 2px);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$emoji-btn: &;
|
|
||||||
|
|
||||||
&__emoji {
|
|
||||||
position: absolute;
|
|
||||||
left: 2px;
|
|
||||||
top: 2px;
|
|
||||||
transform-origin: center;
|
|
||||||
$scale: 32 / 48;
|
|
||||||
transform: scale3d($scale, $scale, $scale);
|
|
||||||
transition: transform 400ms $ease-out-expo;
|
|
||||||
|
|
||||||
#{$emoji-btn}:hover &,
|
|
||||||
.keyboard-mode #{$emoji-btn}:focus & {
|
|
||||||
transform: scale3d(1, 1, 1) translate3d(0, -24px, 0);
|
|
||||||
z-index: 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Module: Calling
|
// Module: Calling
|
||||||
.module-calling {
|
.module-calling {
|
||||||
&__container {
|
&__container {
|
||||||
|
|
182
stylesheets/components/ReactionPicker.scss
Normal file
182
stylesheets/components/ReactionPicker.scss
Normal file
|
@ -0,0 +1,182 @@
|
||||||
|
// Copyright 2021 Signal Messenger, LLC
|
||||||
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
|
.module-ReactionPicker {
|
||||||
|
$button-size: 40px;
|
||||||
|
$button-content-size: 28px;
|
||||||
|
$max-expected-buttons: 7;
|
||||||
|
|
||||||
|
$emoji-size-from-component: 48px;
|
||||||
|
$big-emoji-size: 42px;
|
||||||
|
|
||||||
|
@include rounded-corners;
|
||||||
|
align-items: center;
|
||||||
|
border-style: solid;
|
||||||
|
border-width: 1px;
|
||||||
|
box-shadow: 0 1px 4px $color-black-alpha-05, 0 10px 16px $color-black-alpha-20;
|
||||||
|
display: inline-flex;
|
||||||
|
flex-direction: row;
|
||||||
|
padding: 3px 7px;
|
||||||
|
position: relative;
|
||||||
|
user-select: none;
|
||||||
|
z-index: 2;
|
||||||
|
|
||||||
|
@media (prefers-reduced-motion: no-preference) {
|
||||||
|
animation: {
|
||||||
|
name: module-ReactionPicker__appear;
|
||||||
|
duration: 400ms;
|
||||||
|
timing-function: $ease-out-expo;
|
||||||
|
fill-mode: forwards;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@include light-theme {
|
||||||
|
background: $color-white;
|
||||||
|
border-color: $color-black-alpha-05;
|
||||||
|
}
|
||||||
|
|
||||||
|
@include dark-theme {
|
||||||
|
background: $color-gray-75;
|
||||||
|
border-color: $color-gray-80;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__button {
|
||||||
|
@include button-reset;
|
||||||
|
align-items: center;
|
||||||
|
border-radius: 100%;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
@media (prefers-reduced-motion: no-preference) {
|
||||||
|
// Prevent animation jank
|
||||||
|
opacity: 0;
|
||||||
|
|
||||||
|
animation: {
|
||||||
|
name: module-ReactionPicker__button-appear;
|
||||||
|
duration: 400ms;
|
||||||
|
timing-function: $ease-out-expo;
|
||||||
|
fill-mode: forwards;
|
||||||
|
// This delay is a fallback in case there are more than the expected number of
|
||||||
|
// buttons.
|
||||||
|
delay: #{$max-expected-buttons * 10ms};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@for $i from 0 through $max-expected-buttons {
|
||||||
|
&:nth-of-type(#{$i + 1}) {
|
||||||
|
animation-delay: #{$i * 10ms};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&--emoji {
|
||||||
|
$emoji-button-selector: &;
|
||||||
|
|
||||||
|
height: $button-size;
|
||||||
|
width: $button-size;
|
||||||
|
|
||||||
|
.module-emoji {
|
||||||
|
transform: scale($button-content-size / $emoji-size-from-component);
|
||||||
|
@media (prefers-reduced-motion: no-preference) {
|
||||||
|
transition: transform 400ms $ease-out-expo;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin focused-emoji {
|
||||||
|
@media (prefers-reduced-motion: no-preference) {
|
||||||
|
.module-emoji {
|
||||||
|
transform: scale($big-emoji-size / $emoji-size-from-component)
|
||||||
|
translateY(-16px);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
@include focused-emoji;
|
||||||
|
}
|
||||||
|
|
||||||
|
@include keyboard-mode {
|
||||||
|
&:focus {
|
||||||
|
@include focused-emoji;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&--more {
|
||||||
|
// The margin makes the button take up the same space as the other buttons, while
|
||||||
|
// not actually being as large.
|
||||||
|
height: $button-content-size;
|
||||||
|
margin: ($button-size - $button-content-size) / 2;
|
||||||
|
width: $button-content-size;
|
||||||
|
@media (prefers-reduced-motion: no-preference) {
|
||||||
|
transition: background 200ms $ease-out-expo;
|
||||||
|
}
|
||||||
|
|
||||||
|
@include light-theme {
|
||||||
|
background: $color-gray-02;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: $color-gray-05;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@include dark-theme {
|
||||||
|
background: $color-gray-60;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: $color-gray-45;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__dot {
|
||||||
|
border-radius: 100%;
|
||||||
|
height: 3px;
|
||||||
|
margin-right: 4px;
|
||||||
|
width: 3px;
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
margin-right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@include light-theme {
|
||||||
|
background: $color-gray-45;
|
||||||
|
}
|
||||||
|
|
||||||
|
@include dark-theme {
|
||||||
|
background: $color-gray-15;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&--selected {
|
||||||
|
@include light-theme {
|
||||||
|
background: $color-black-alpha-20;
|
||||||
|
}
|
||||||
|
|
||||||
|
@include dark-theme {
|
||||||
|
background: $color-white-alpha-20;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes module-ReactionPicker__appear {
|
||||||
|
from {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
to {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes module-ReactionPicker__button-appear {
|
||||||
|
from {
|
||||||
|
transform: translate3d(0, 24px, 0);
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
to {
|
||||||
|
transform: translate3d(0, 0, 0);
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
|
@ -27,8 +27,8 @@
|
||||||
|
|
||||||
// New style: components
|
// New style: components
|
||||||
@import './components/AddGroupMembersModal.scss';
|
@import './components/AddGroupMembersModal.scss';
|
||||||
@import './components/App.scss';
|
|
||||||
@import './components/AnnouncementsOnlyGroupBanner.scss';
|
@import './components/AnnouncementsOnlyGroupBanner.scss';
|
||||||
|
@import './components/App.scss';
|
||||||
@import './components/Avatar.scss';
|
@import './components/Avatar.scss';
|
||||||
@import './components/AvatarEditor.scss';
|
@import './components/AvatarEditor.scss';
|
||||||
@import './components/AvatarModalButtons.scss';
|
@import './components/AvatarModalButtons.scss';
|
||||||
|
@ -69,6 +69,7 @@
|
||||||
@import './components/Modal.scss';
|
@import './components/Modal.scss';
|
||||||
@import './components/Preferences.scss';
|
@import './components/Preferences.scss';
|
||||||
@import './components/ProfileEditor.scss';
|
@import './components/ProfileEditor.scss';
|
||||||
|
@import './components/ReactionPicker.scss';
|
||||||
@import './components/SafetyNumberChangeDialog.scss';
|
@import './components/SafetyNumberChangeDialog.scss';
|
||||||
@import './components/SafetyNumberViewer.scss';
|
@import './components/SafetyNumberViewer.scss';
|
||||||
@import './components/SearchInput.scss';
|
@import './components/SearchInput.scss';
|
||||||
|
|
|
@ -34,6 +34,34 @@ const DEFAULT_EMOJI_LIST = [
|
||||||
'cry',
|
'cry',
|
||||||
];
|
];
|
||||||
|
|
||||||
|
const EmojiButton = React.forwardRef<
|
||||||
|
HTMLButtonElement,
|
||||||
|
{
|
||||||
|
emoji: string;
|
||||||
|
onSelect: () => unknown;
|
||||||
|
selected: boolean;
|
||||||
|
title?: string;
|
||||||
|
}
|
||||||
|
>(({ emoji, onSelect, selected, title }, ref) => (
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
key={emoji}
|
||||||
|
ref={ref}
|
||||||
|
tabIndex={0}
|
||||||
|
className={classNames(
|
||||||
|
'module-ReactionPicker__button',
|
||||||
|
'module-ReactionPicker__button--emoji',
|
||||||
|
selected && 'module-ReactionPicker__button--selected'
|
||||||
|
)}
|
||||||
|
onClick={e => {
|
||||||
|
e.stopPropagation();
|
||||||
|
onSelect();
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Emoji size={48} emoji={emoji} title={title} />
|
||||||
|
</button>
|
||||||
|
));
|
||||||
|
|
||||||
export const ReactionPicker = React.forwardRef<HTMLDivElement, Props>(
|
export const ReactionPicker = React.forwardRef<HTMLDivElement, Props>(
|
||||||
(
|
(
|
||||||
{ i18n, selected, onClose, skinTone, onPick, renderEmojiPicker, style },
|
{ i18n, selected, onClose, skinTone, onPick, renderEmojiPicker, style },
|
||||||
|
@ -64,70 +92,69 @@ export const ReactionPicker = React.forwardRef<HTMLDivElement, Props>(
|
||||||
[onPick]
|
[onPick]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Focus first button and restore focus on unmount
|
||||||
|
const [focusRef] = useRestoreFocus();
|
||||||
|
|
||||||
|
if (pickingOther) {
|
||||||
|
return renderEmojiPicker({ onPickEmoji, onClose, style, ref });
|
||||||
|
}
|
||||||
|
|
||||||
const emojis = DEFAULT_EMOJI_LIST.map(shortName =>
|
const emojis = DEFAULT_EMOJI_LIST.map(shortName =>
|
||||||
convertShortName(shortName, skinTone)
|
convertShortName(shortName, skinTone)
|
||||||
);
|
);
|
||||||
|
|
||||||
// Focus first button and restore focus on unmount
|
|
||||||
const [focusRef] = useRestoreFocus();
|
|
||||||
|
|
||||||
const otherSelected = selected && !emojis.includes(selected);
|
const otherSelected = selected && !emojis.includes(selected);
|
||||||
|
|
||||||
return pickingOther ? (
|
let moreButton: React.ReactNode;
|
||||||
renderEmojiPicker({ onPickEmoji, onClose, style, ref })
|
if (otherSelected) {
|
||||||
) : (
|
moreButton = (
|
||||||
<div ref={ref} style={style} className="module-reaction-picker">
|
<EmojiButton
|
||||||
|
emoji={selected}
|
||||||
|
onSelect={() => {
|
||||||
|
onPick(selected);
|
||||||
|
}}
|
||||||
|
selected
|
||||||
|
title={i18n('Reactions--remove')}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
moreButton = (
|
||||||
|
<button
|
||||||
|
aria-label={i18n('ReactionsViewer--more')}
|
||||||
|
className="module-ReactionPicker__button module-ReactionPicker__button--more"
|
||||||
|
onClick={event => {
|
||||||
|
event.stopPropagation();
|
||||||
|
setPickingOther(true);
|
||||||
|
}}
|
||||||
|
tabIndex={0}
|
||||||
|
title={i18n('ReactionsViewer--more')}
|
||||||
|
type="button"
|
||||||
|
>
|
||||||
|
<div className="module-ReactionPicker__button--more__dot" />
|
||||||
|
<div className="module-ReactionPicker__button--more__dot" />
|
||||||
|
<div className="module-ReactionPicker__button--more__dot" />
|
||||||
|
</button>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div ref={ref} style={style} className="module-ReactionPicker">
|
||||||
{emojis.map((emoji, index) => {
|
{emojis.map((emoji, index) => {
|
||||||
const maybeFocusRef = index === 0 ? focusRef : undefined;
|
const maybeFocusRef = index === 0 ? focusRef : undefined;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<button
|
<EmojiButton
|
||||||
type="button"
|
emoji={emoji}
|
||||||
key={emoji}
|
key={emoji}
|
||||||
ref={maybeFocusRef}
|
onSelect={() => {
|
||||||
tabIndex={0}
|
|
||||||
className={classNames(
|
|
||||||
'module-reaction-picker__emoji-btn',
|
|
||||||
emoji === selected
|
|
||||||
? 'module-reaction-picker__emoji-btn--selected'
|
|
||||||
: null
|
|
||||||
)}
|
|
||||||
onClick={e => {
|
|
||||||
e.stopPropagation();
|
|
||||||
onPick(emoji);
|
onPick(emoji);
|
||||||
}}
|
}}
|
||||||
title={emoji}
|
ref={maybeFocusRef}
|
||||||
>
|
selected={emoji === selected}
|
||||||
<div className="module-reaction-picker__emoji-btn__emoji">
|
/>
|
||||||
<Emoji size={48} emoji={emoji} />
|
|
||||||
</div>
|
|
||||||
</button>
|
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
<button
|
{moreButton}
|
||||||
type="button"
|
|
||||||
className={classNames(
|
|
||||||
'module-reaction-picker__emoji-btn',
|
|
||||||
otherSelected
|
|
||||||
? 'module-reaction-picker__emoji-btn--selected'
|
|
||||||
: 'module-reaction-picker__emoji-btn--more'
|
|
||||||
)}
|
|
||||||
onClick={e => {
|
|
||||||
e.stopPropagation();
|
|
||||||
if (otherSelected && selected) {
|
|
||||||
onPick(selected);
|
|
||||||
} else {
|
|
||||||
setPickingOther(true);
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
title={i18n('ReactionsViewer--more')}
|
|
||||||
>
|
|
||||||
{otherSelected ? (
|
|
||||||
<div className="module-reaction-picker__emoji-btn__emoji">
|
|
||||||
<Emoji size={48} emoji={selected} />
|
|
||||||
</div>
|
|
||||||
) : null}
|
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,7 @@ export type OwnProps = {
|
||||||
skinTone?: SkinToneKey | number;
|
skinTone?: SkinToneKey | number;
|
||||||
size?: EmojiSizeType;
|
size?: EmojiSizeType;
|
||||||
children?: React.ReactNode;
|
children?: React.ReactNode;
|
||||||
|
title?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type Props = OwnProps &
|
export type Props = OwnProps &
|
||||||
|
@ -27,7 +28,15 @@ export type Props = OwnProps &
|
||||||
export const Emoji = React.memo(
|
export const Emoji = React.memo(
|
||||||
React.forwardRef<HTMLDivElement, Props>(
|
React.forwardRef<HTMLDivElement, Props>(
|
||||||
(
|
(
|
||||||
{ style = {}, size = 28, shortName, skinTone, emoji, className }: Props,
|
{
|
||||||
|
className,
|
||||||
|
emoji,
|
||||||
|
shortName,
|
||||||
|
size = 28,
|
||||||
|
skinTone,
|
||||||
|
style = {},
|
||||||
|
title,
|
||||||
|
}: Props,
|
||||||
ref
|
ref
|
||||||
) => {
|
) => {
|
||||||
let image = '';
|
let image = '';
|
||||||
|
@ -50,8 +59,8 @@ export const Emoji = React.memo(
|
||||||
<img
|
<img
|
||||||
className={`module-emoji__image--${size}px`}
|
className={`module-emoji__image--${size}px`}
|
||||||
src={image}
|
src={image}
|
||||||
aria-label={emoji}
|
aria-label={title ?? emoji}
|
||||||
title={emoji}
|
title={title ?? emoji}
|
||||||
/>
|
/>
|
||||||
</span>
|
</span>
|
||||||
);
|
);
|
||||||
|
|
Loading…
Reference in a new issue