Signal-Desktop/stylesheets/components/ReactionPickerPicker.scss

264 lines
5.8 KiB
SCSS

// Copyright 2021-2022 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
@use 'sass:math';
.module-ReactionPickerPicker {
$button-size: 40px;
$button-content-size: 28px;
$max-expected-buttons: 7;
$emoji-size-from-component: 48px;
$big-emoji-size: 42px;
$root-selector: &;
@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;
@media (prefers-reduced-motion: no-preference) {
animation: {
name: module-ReactionPickerPicker__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;
&--emoji {
$emoji-button-selector: &;
height: $button-size;
width: $button-size;
@media (prefers-reduced-motion: no-preference) {
transition: background 200ms $ease-out-expo;
}
.module-emoji {
transform: scale(
math.div($button-content-size, $emoji-size-from-component)
);
@media (prefers-reduced-motion: no-preference) {
transition: transform 400ms $ease-out-expo;
}
}
}
&--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: math.div($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 keyboard-mode {
&:focus {
background: $color-gray-05;
}
}
}
@include dark-theme {
background: $color-gray-60;
&:hover {
background: $color-gray-45;
}
@include dark-keyboard-mode {
&:focus {
background: $color-gray-45;
}
}
}
&__dot {
border-radius: 50%;
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;
}
@media (forced-colors: active) {
background-color: WindowText;
@include dark-theme {
background: WindowText;
}
}
}
}
}
&--picker-style {
z-index: $z-index-above-base;
#{$root-selector}__button {
@media (prefers-reduced-motion: no-preference) {
// Prevent animation jank
opacity: 0;
animation: {
name: module-ReactionPickerPicker__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 {
@mixin focus-or-hover-styles {
.module-emoji {
transform: scale(
math.div($big-emoji-size, $emoji-size-from-component)
)
translateY(-16px);
}
}
&:hover {
@include focus-or-hover-styles;
}
@include keyboard-mode {
&:focus {
@include focus-or-hover-styles;
}
}
}
&--selected {
@include light-theme {
background: $color-black-alpha-20;
}
@include dark-theme {
background: $color-white-alpha-20;
}
}
}
}
&--menu-style {
#{$root-selector}__button {
@include keyboard-mode {
&:focus {
background: $color-black-alpha-20;
}
}
@include dark-keyboard-mode {
&:focus {
background: $color-white-alpha-40;
}
}
&--selected {
opacity: 1;
.module-emoji {
transform: scale(
math.div($big-emoji-size, $emoji-size-from-component)
);
}
@media (prefers-reduced-motion: no-preference) {
animation: module-ReactionPickerPicker__button-selected 200ms
ease-in-out infinite alternate;
}
}
}
// These selectors are unpleasant, but we want to match "menu style" and "something is
// selected" classes on the same element.
@at-root #{&}#{$root-selector}--something-selected {
#{$root-selector}__button:not(#{$root-selector}__button--selected) {
opacity: 0.4;
transform: scale(0.9);
}
}
}
}
@keyframes module-ReactionPickerPicker__appear {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
@keyframes module-ReactionPickerPicker__button-appear {
from {
transform: translate3d(0, 24px, 0);
opacity: 0;
}
to {
transform: translate3d(0, 0, 0);
opacity: 1;
}
}
@keyframes module-ReactionPickerPicker__button-selected {
from {
transform: rotate(-8deg);
}
to {
transform: rotate(8deg);
}
}