MM-61611 Fix layout of emoji picker in mobile view (#30747)
* Stop emoji picker header from overlapping tabs * Move emoji picker header above tabs There was also some stuff I could remove because the header will always be visible. * Don't scroll the emoji picker on hover * MM-61611 Fix emoji picker tabs being covered in mobile view * Improve layout of emoji picker and gif picker A lot of the emoji picker was explicitly sized before which made it difficult to make everything responsive in mobile view. Making the emoji picker layout into a flexbox fixed that, but due to the way that it's nested, that was a bit tricky, and it required a couple tricks: 1. The AutoSizer doesn't work if it's placed inside a flexbox container, but you can fix that by putting a div with position: relative in between it and the flexbox parent. That was already the case, but I accidentally removed it while trying to sort out the seemingly excessive nesting. 2. Children of flexbox elements will cause the parent to expand if they don't have min-height/min-width set. That's because the default value for those is 0 outside of flexbox, but it's auto inside of one. This breaks the layout and animation of the skin tone selector in the emoji picker, but that has issues on master as well, so it'll be addressed in the next commit. * Improve and fix opening animation for skin tone selector While this looked worse before in mobile view, it had some weirdness in desktop as well. I ended up rewriting the way that that animation worked so that I could position it correctly in both mobile (where it doesn't cover the input) and desktop (where it does). Notably, that change required: 1. Changing the skin tone selector to wait until its contents are hidden to unmount them so that the position and size could be calculated correctly. 2. Removed the flexbox from the search row and used a margin to make the skin tone button pretend to offset the input. That let us smoothy expand the selector over the input without having the input resize behind it. * Update CSS for positioning emojis and headings in emoji picker
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
291d5a2ba7
Коммит
80b61ad79b
@@ -3,155 +3,150 @@
|
|||||||
exports[`components/emoji_picker/EmojiPicker should match snapshot 1`] = `
|
exports[`components/emoji_picker/EmojiPicker should match snapshot 1`] = `
|
||||||
<DocumentFragment>
|
<DocumentFragment>
|
||||||
<div
|
<div
|
||||||
class="emoji-picker__inner"
|
aria-live="assertive"
|
||||||
role="application"
|
class="sr-only"
|
||||||
|
>
|
||||||
|
grinning emoji
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="emoji-picker__search-container"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
aria-live="assertive"
|
class="emoji-picker__text-container"
|
||||||
class="sr-only"
|
|
||||||
>
|
>
|
||||||
grinning emoji
|
<span
|
||||||
|
class="icon-magnify icon emoji-picker__search-icon"
|
||||||
|
/>
|
||||||
|
<input
|
||||||
|
aria-label="Search for an emoji"
|
||||||
|
autocomplete="off"
|
||||||
|
class="emoji-picker__search"
|
||||||
|
data-testid="emojiInputSearch"
|
||||||
|
id="emojiPickerSearch"
|
||||||
|
placeholder="Search emojis"
|
||||||
|
type="text"
|
||||||
|
value=""
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
<div />
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="emoji-picker__categories"
|
||||||
|
data-testid="emojiPickerCategories"
|
||||||
|
id="emojiPickerCategories"
|
||||||
|
>
|
||||||
|
<button
|
||||||
|
aria-label="Smileys & Emotion"
|
||||||
|
aria-pressed="true"
|
||||||
|
class="style--none emoji-picker__category emoji-picker__category--selected"
|
||||||
|
>
|
||||||
|
<i
|
||||||
|
class="icon-emoticon-happy-outline"
|
||||||
|
/>
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
aria-label="People & Body"
|
||||||
|
aria-pressed="false"
|
||||||
|
class="style--none emoji-picker__category"
|
||||||
|
>
|
||||||
|
<i
|
||||||
|
class="icon-account-outline"
|
||||||
|
/>
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
aria-label="Animals & Nature"
|
||||||
|
aria-pressed="false"
|
||||||
|
class="style--none emoji-picker__category"
|
||||||
|
>
|
||||||
|
<i
|
||||||
|
class="icon-leaf-outline"
|
||||||
|
/>
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
aria-label="Food & Drink"
|
||||||
|
aria-pressed="false"
|
||||||
|
class="style--none emoji-picker__category"
|
||||||
|
>
|
||||||
|
<i
|
||||||
|
class="icon-food-apple"
|
||||||
|
/>
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
aria-label="Travel & Places"
|
||||||
|
aria-pressed="false"
|
||||||
|
class="style--none emoji-picker__category"
|
||||||
|
>
|
||||||
|
<i
|
||||||
|
class="icon-airplane-variant"
|
||||||
|
/>
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
aria-label="Activities"
|
||||||
|
aria-pressed="false"
|
||||||
|
class="style--none emoji-picker__category"
|
||||||
|
>
|
||||||
|
<i
|
||||||
|
class="icon-basketball"
|
||||||
|
/>
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
aria-label="Objects"
|
||||||
|
aria-pressed="false"
|
||||||
|
class="style--none emoji-picker__category"
|
||||||
|
>
|
||||||
|
<i
|
||||||
|
class="icon-lightbulb-outline"
|
||||||
|
/>
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
aria-label="Symbols"
|
||||||
|
aria-pressed="false"
|
||||||
|
class="style--none emoji-picker__category"
|
||||||
|
>
|
||||||
|
<i
|
||||||
|
class="icon-heart-outline"
|
||||||
|
/>
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
aria-label="Flags"
|
||||||
|
aria-pressed="false"
|
||||||
|
class="style--none emoji-picker__category"
|
||||||
|
>
|
||||||
|
<i
|
||||||
|
class="icon-flag-outline"
|
||||||
|
/>
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
aria-label="Custom"
|
||||||
|
aria-pressed="false"
|
||||||
|
class="style--none emoji-picker__category"
|
||||||
|
>
|
||||||
|
<i
|
||||||
|
class="icon-emoticon-custom-outline"
|
||||||
|
/>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="emoji-picker__items"
|
||||||
|
style="height: 290px;"
|
||||||
|
>
|
||||||
<div
|
<div
|
||||||
class="emoji-picker__search-container"
|
aria-labelledby="emojiPickerSearch"
|
||||||
|
class="emoji-picker__container"
|
||||||
|
role="grid"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="emoji-picker__text-container"
|
style="overflow: visible; height: 0px; width: 0px;"
|
||||||
>
|
/>
|
||||||
<span
|
|
||||||
class="icon-magnify icon emoji-picker__search-icon"
|
|
||||||
/>
|
|
||||||
<input
|
|
||||||
aria-label="Search for an emoji"
|
|
||||||
autocomplete="off"
|
|
||||||
class="emoji-picker__search"
|
|
||||||
data-testid="emojiInputSearch"
|
|
||||||
id="emojiPickerSearch"
|
|
||||||
placeholder="Search emojis"
|
|
||||||
type="text"
|
|
||||||
value=""
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div />
|
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="emoji-picker__footer"
|
||||||
|
>
|
||||||
<div
|
<div
|
||||||
class="emoji-picker__categories"
|
class="emoji-picker__preview"
|
||||||
data-testid="emojiPickerCategories"
|
|
||||||
id="emojiPickerCategories"
|
|
||||||
>
|
>
|
||||||
<button
|
Preview for grinning emoji
|
||||||
aria-label="Smileys & Emotion"
|
|
||||||
aria-pressed="true"
|
|
||||||
class="style--none emoji-picker__category emoji-picker__category--selected"
|
|
||||||
>
|
|
||||||
<i
|
|
||||||
class="icon-emoticon-happy-outline"
|
|
||||||
/>
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
aria-label="People & Body"
|
|
||||||
aria-pressed="false"
|
|
||||||
class="style--none emoji-picker__category"
|
|
||||||
>
|
|
||||||
<i
|
|
||||||
class="icon-account-outline"
|
|
||||||
/>
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
aria-label="Animals & Nature"
|
|
||||||
aria-pressed="false"
|
|
||||||
class="style--none emoji-picker__category"
|
|
||||||
>
|
|
||||||
<i
|
|
||||||
class="icon-leaf-outline"
|
|
||||||
/>
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
aria-label="Food & Drink"
|
|
||||||
aria-pressed="false"
|
|
||||||
class="style--none emoji-picker__category"
|
|
||||||
>
|
|
||||||
<i
|
|
||||||
class="icon-food-apple"
|
|
||||||
/>
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
aria-label="Travel & Places"
|
|
||||||
aria-pressed="false"
|
|
||||||
class="style--none emoji-picker__category"
|
|
||||||
>
|
|
||||||
<i
|
|
||||||
class="icon-airplane-variant"
|
|
||||||
/>
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
aria-label="Activities"
|
|
||||||
aria-pressed="false"
|
|
||||||
class="style--none emoji-picker__category"
|
|
||||||
>
|
|
||||||
<i
|
|
||||||
class="icon-basketball"
|
|
||||||
/>
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
aria-label="Objects"
|
|
||||||
aria-pressed="false"
|
|
||||||
class="style--none emoji-picker__category"
|
|
||||||
>
|
|
||||||
<i
|
|
||||||
class="icon-lightbulb-outline"
|
|
||||||
/>
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
aria-label="Symbols"
|
|
||||||
aria-pressed="false"
|
|
||||||
class="style--none emoji-picker__category"
|
|
||||||
>
|
|
||||||
<i
|
|
||||||
class="icon-heart-outline"
|
|
||||||
/>
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
aria-label="Flags"
|
|
||||||
aria-pressed="false"
|
|
||||||
class="style--none emoji-picker__category"
|
|
||||||
>
|
|
||||||
<i
|
|
||||||
class="icon-flag-outline"
|
|
||||||
/>
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
aria-label="Custom"
|
|
||||||
aria-pressed="false"
|
|
||||||
class="style--none emoji-picker__category"
|
|
||||||
>
|
|
||||||
<i
|
|
||||||
class="icon-emoticon-custom-outline"
|
|
||||||
/>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
class="emoji-picker__items"
|
|
||||||
style="height: 290px;"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
aria-labelledby="emojiPickerSearch"
|
|
||||||
class="emoji-picker__container"
|
|
||||||
role="grid"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
style="overflow: visible; height: 0px; width: 0px;"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
class="emoji-picker__footer"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="emoji-picker__preview"
|
|
||||||
>
|
|
||||||
Preview for grinning emoji
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</DocumentFragment>
|
</DocumentFragment>
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
exports[`components/emoji_picker/components/EmojiPickerHeader handleEmojiPickerClose, should have called props.handleEmojiPickerClose 1`] = `
|
exports[`components/emoji_picker/components/EmojiPickerHeader handleEmojiPickerClose, should have called props.handleEmojiPickerClose 1`] = `
|
||||||
<div
|
<div
|
||||||
className="emoji-picker__header modal-header"
|
className="emoji-picker__header"
|
||||||
>
|
>
|
||||||
<button
|
<button
|
||||||
className="close emoji-picker__header-close-button"
|
className="close emoji-picker__header-close-button"
|
||||||
@@ -36,7 +36,7 @@ exports[`components/emoji_picker/components/EmojiPickerHeader handleEmojiPickerC
|
|||||||
|
|
||||||
exports[`components/emoji_picker/components/EmojiPickerHeader should match snapshot, 1`] = `
|
exports[`components/emoji_picker/components/EmojiPickerHeader should match snapshot, 1`] = `
|
||||||
<div
|
<div
|
||||||
className="emoji-picker__header modal-header"
|
className="emoji-picker__header"
|
||||||
>
|
>
|
||||||
<button
|
<button
|
||||||
className="close emoji-picker__header-close-button"
|
className="close emoji-picker__header-close-button"
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ interface Props {
|
|||||||
function EmojiPickerCategoryRow({categoryName, style}: Props) {
|
function EmojiPickerCategoryRow({categoryName, style}: Props) {
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className='emoji-picker-items__container'
|
className='emoji-picker__row'
|
||||||
style={style}
|
style={style}
|
||||||
role='row'
|
role='row'
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ type Props = {
|
|||||||
|
|
||||||
const EmojiPickerHeader = ({handleEmojiPickerClose}: Props) => {
|
const EmojiPickerHeader = ({handleEmojiPickerClose}: Props) => {
|
||||||
return (
|
return (
|
||||||
<div className='emoji-picker__header modal-header'>
|
<div className='emoji-picker__header'>
|
||||||
<button
|
<button
|
||||||
type='button'
|
type='button'
|
||||||
className='close emoji-picker__header-close-button'
|
className='close emoji-picker__header-close-button'
|
||||||
|
|||||||
@@ -80,6 +80,7 @@ export type Props = {
|
|||||||
|
|
||||||
type State = {
|
type State = {
|
||||||
pickerExtended: boolean;
|
pickerExtended: boolean;
|
||||||
|
pickerMounted: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class EmojiPickerSkin extends React.PureComponent<Props, State> {
|
export class EmojiPickerSkin extends React.PureComponent<Props, State> {
|
||||||
@@ -88,6 +89,7 @@ export class EmojiPickerSkin extends React.PureComponent<Props, State> {
|
|||||||
|
|
||||||
this.state = {
|
this.state = {
|
||||||
pickerExtended: false,
|
pickerExtended: false,
|
||||||
|
pickerMounted: false,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -109,7 +111,16 @@ export class EmojiPickerSkin extends React.PureComponent<Props, State> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
showSkinTonePicker = () => {
|
showSkinTonePicker = () => {
|
||||||
this.setState({pickerExtended: true});
|
this.setState({
|
||||||
|
pickerExtended: true,
|
||||||
|
pickerMounted: true,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
handleSkinToneHidden = () => {
|
||||||
|
this.setState({
|
||||||
|
pickerMounted: false,
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
skinTonePickerButton() {
|
skinTonePickerButton() {
|
||||||
@@ -194,16 +205,17 @@ export class EmojiPickerSkin extends React.PureComponent<Props, State> {
|
|||||||
return (
|
return (
|
||||||
<CSSTransition
|
<CSSTransition
|
||||||
in={this.state.pickerExtended}
|
in={this.state.pickerExtended}
|
||||||
|
onExited={this.handleSkinToneHidden}
|
||||||
classNames='skin-tones-animation'
|
classNames='skin-tones-animation'
|
||||||
timeout={200}
|
timeout={200}
|
||||||
>
|
>
|
||||||
<div className={classNames('skin-tones', {'skin-tones--active': this.state.pickerExtended})}>
|
<div className={classNames('skin-tones', {'skin-tones--active': this.state.pickerMounted})}>
|
||||||
<div
|
<div
|
||||||
className={classNames('skin-tones__content', {'skin-tones__content__single': !this.state.pickerExtended}, {'skin-tones__close': this.state.pickerExtended})}
|
className={classNames('skin-tones__content', {'skin-tones__content__single': !this.state.pickerMounted}, {'skin-tones__close': this.state.pickerMounted})}
|
||||||
aria-orientation='horizontal'
|
aria-orientation='horizontal'
|
||||||
>
|
>
|
||||||
{this.skinTonePickerButton()}
|
{this.skinTonePickerButton()}
|
||||||
{this.state.pickerExtended &&
|
{this.state.pickerMounted &&
|
||||||
<>
|
<>
|
||||||
<div className='skin-tones__close-text'>
|
<div className='skin-tones__close-text'>
|
||||||
<FormattedMessage
|
<FormattedMessage
|
||||||
|
|||||||
@@ -147,14 +147,6 @@ const EmojiPicker = ({
|
|||||||
infiniteLoaderRef?.current?._listRef?.scrollToItem(0, 'start');
|
infiniteLoaderRef?.current?._listRef?.scrollToItem(0, 'start');
|
||||||
}, [filter]);
|
}, [filter]);
|
||||||
|
|
||||||
// scroll as little as possible on cursor navigation
|
|
||||||
useEffect(() => {
|
|
||||||
if (cursor.emojiId) {
|
|
||||||
// eslint-disable-next-line no-underscore-dangle
|
|
||||||
infiniteLoaderRef?.current?._listRef?.scrollToItem(cursor.rowIndex, 'auto');
|
|
||||||
}
|
|
||||||
}, [cursor.rowIndex]);
|
|
||||||
|
|
||||||
const focusOnSearchInput = useCallback(() => {
|
const focusOnSearchInput = useCallback(() => {
|
||||||
searchInputRef.current?.focus();
|
searchInputRef.current?.focus();
|
||||||
}, []);
|
}, []);
|
||||||
@@ -209,6 +201,9 @@ const EmojiPicker = ({
|
|||||||
emojiId: '',
|
emojiId: '',
|
||||||
emoji: undefined,
|
emoji: undefined,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// eslint-disable-next-line no-underscore-dangle
|
||||||
|
infiniteLoaderRef.current?._listRef?.scrollTo(0);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const onAddCustomEmojiClickInner = useCallback(() => {
|
const onAddCustomEmojiClickInner = useCallback(() => {
|
||||||
@@ -348,6 +343,9 @@ const EmojiPicker = ({
|
|||||||
emojiId: newCursor.emojiId,
|
emojiId: newCursor.emojiId,
|
||||||
emoji: newCursorEmoji,
|
emoji: newCursorEmoji,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// eslint-disable-next-line no-underscore-dangle
|
||||||
|
infiniteLoaderRef?.current?._listRef?.scrollToItem(newCursor.rowIndex, 'auto');
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleEnterOnEmoji = useCallback(() => {
|
const handleEnterOnEmoji = useCallback(() => {
|
||||||
@@ -378,10 +376,7 @@ const EmojiPicker = ({
|
|||||||
const areSearchResultsEmpty = filter.length !== 0 && categoryOrEmojisRows.length === 1 && categoryOrEmojisRows?.[0]?.items?.[0]?.categoryName === SEARCH_RESULTS;
|
const areSearchResultsEmpty = filter.length !== 0 && categoryOrEmojisRows.length === 1 && categoryOrEmojisRows?.[0]?.items?.[0]?.categoryName === SEARCH_RESULTS;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<>
|
||||||
className='emoji-picker__inner'
|
|
||||||
role='application'
|
|
||||||
>
|
|
||||||
<div
|
<div
|
||||||
aria-live='assertive'
|
aria-live='assertive'
|
||||||
className='sr-only'
|
className='sr-only'
|
||||||
@@ -456,7 +451,7 @@ const EmojiPicker = ({
|
|||||||
onClick={onAddCustomEmojiClickInner}
|
onClick={onAddCustomEmojiClickInner}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ export default function EmojiPickerTabs(props: Props) {
|
|||||||
aria-label={activeKey === 1 ? intl.formatMessage({id: 'emoji_gif_picker.dialog.emojis', defaultMessage: 'Emoji Picker'}) : intl.formatMessage({id: 'emoji_gif_picker.dialog.gifs', defaultMessage: 'GIF Picker'})}
|
aria-label={activeKey === 1 ? intl.formatMessage({id: 'emoji_gif_picker.dialog.emojis', defaultMessage: 'Emoji Picker'}) : intl.formatMessage({id: 'emoji_gif_picker.dialog.gifs', defaultMessage: 'GIF Picker'})}
|
||||||
aria-modal='true'
|
aria-modal='true'
|
||||||
>
|
>
|
||||||
|
<EmojiPickerHeader handleEmojiPickerClose={props.onEmojiClose}/>
|
||||||
<Tabs
|
<Tabs
|
||||||
id='emoji-picker-tabs'
|
id='emoji-picker-tabs'
|
||||||
defaultActiveKey={1}
|
defaultActiveKey={1}
|
||||||
@@ -51,7 +52,6 @@ export default function EmojiPickerTabs(props: Props) {
|
|||||||
activeKey={activeKey}
|
activeKey={activeKey}
|
||||||
onSelect={(activeKey) => setActiveKey(activeKey)}
|
onSelect={(activeKey) => setActiveKey(activeKey)}
|
||||||
>
|
>
|
||||||
<EmojiPickerHeader handleEmojiPickerClose={props.onEmojiClose}/>
|
|
||||||
<Tab
|
<Tab
|
||||||
eventKey={1}
|
eventKey={1}
|
||||||
title={
|
title={
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ function GifPickerSearch(props: Props) {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='emoji-picker__search-container'>
|
<div className='emoji-picker__search-container'>
|
||||||
<div className='emoji-picker__text-container'>
|
<div className='emoji-picker__text-container gif-picker__text-container'>
|
||||||
<span className='icon-magnify icon emoji-picker__search-icon'/>
|
<span className='icon-magnify icon emoji-picker__search-icon'/>
|
||||||
<input
|
<input
|
||||||
id='emojiPickerSearch'
|
id='emojiPickerSearch'
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ const GifPicker = (props: Props) => {
|
|||||||
}, [props.getRootPickerNode]);
|
}, [props.getRootPickerNode]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<>
|
||||||
<GifPickerSearch
|
<GifPickerSearch
|
||||||
value={props.filter}
|
value={props.filter}
|
||||||
onChange={props.handleFilterChange}
|
onChange={props.handleFilterChange}
|
||||||
@@ -44,7 +44,7 @@ const GifPicker = (props: Props) => {
|
|||||||
filter={props.filter}
|
filter={props.filter}
|
||||||
onClick={handleItemClick}
|
onClick={handleItemClick}
|
||||||
/>
|
/>
|
||||||
</div>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -70,3 +70,35 @@
|
|||||||
.custom-emoji-tab__icon {
|
.custom-emoji-tab__icon {
|
||||||
margin-right: 7px;
|
margin-right: 7px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#emoji-picker-tabs {
|
||||||
|
display: flex;
|
||||||
|
|
||||||
|
// These prevent a flex element from overflowing its parent
|
||||||
|
min-width: 0;
|
||||||
|
min-height: 0;
|
||||||
|
|
||||||
|
flex: 1;
|
||||||
|
flex-direction: column;
|
||||||
|
|
||||||
|
.tab-content {
|
||||||
|
display: flex;
|
||||||
|
|
||||||
|
// These prevent a flex element from overflowing its parent
|
||||||
|
min-width: 0;
|
||||||
|
min-height: 0;
|
||||||
|
|
||||||
|
flex: 1;
|
||||||
|
|
||||||
|
.tab-pane {
|
||||||
|
display: flex;
|
||||||
|
|
||||||
|
// These prevent a flex element from overflowing its parent
|
||||||
|
min-width: 0;
|
||||||
|
min-height: 0;
|
||||||
|
|
||||||
|
flex: 1;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -100,16 +100,6 @@
|
|||||||
|
|
||||||
@include mixins.clearfix;
|
@include mixins.clearfix;
|
||||||
|
|
||||||
.emoji-picker__header {
|
|
||||||
background: var(--sidebar-header-bg);
|
|
||||||
}
|
|
||||||
|
|
||||||
&.emoji-picker--single {
|
|
||||||
.emoji-picker__header {
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.browser--ie & {
|
.browser--ie & {
|
||||||
width: 325px;
|
width: 325px;
|
||||||
}
|
}
|
||||||
@@ -135,11 +125,11 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
a {
|
a {
|
||||||
height: 40px;
|
|
||||||
padding: 7px 12px;
|
padding: 7px 12px;
|
||||||
border: none !important;
|
border: none !important;
|
||||||
border-bottom: 2px solid transparent !important;
|
border-bottom: 2px solid transparent !important;
|
||||||
margin-right: 5px;
|
margin-right: 5px;
|
||||||
|
margin-bottom: 0;
|
||||||
margin-left: 5px;
|
margin-left: 5px;
|
||||||
background: transparent;
|
background: transparent;
|
||||||
outline: none;
|
outline: none;
|
||||||
@@ -153,8 +143,6 @@
|
|||||||
|
|
||||||
&.active {
|
&.active {
|
||||||
a {
|
a {
|
||||||
height: 34px;
|
|
||||||
padding-top: 9px;
|
|
||||||
border-radius: 0;
|
border-radius: 0;
|
||||||
margin-right: 5px;
|
margin-right: 5px;
|
||||||
margin-left: 5px;
|
margin-left: 5px;
|
||||||
@@ -226,15 +214,12 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.emoji-picker__header,
|
.emoji-picker__header {
|
||||||
.modal-body .emoji-picker .emoji-picker__header {
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
top: 0;
|
||||||
display: none; // only visible < 480px width screen
|
display: none; // only visible < 480px width screen
|
||||||
width: 100%;
|
width: 100%;
|
||||||
padding: 13px 10px 13px 15px;
|
padding: 13px 10px 13px 15px;
|
||||||
border: 1px solid variables.$light-gray;
|
background: var(--sidebar-header-bg);
|
||||||
background: variables.$primary-color;
|
|
||||||
color: var(--sidebar-header-text-color);
|
color: var(--sidebar-header-text-color);
|
||||||
|
|
||||||
.emoji-picker__header-title {
|
.emoji-picker__header-title {
|
||||||
@@ -255,23 +240,16 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.modal-body .emoji-picker .emoji-picker__header {
|
|
||||||
.emoji-picker__header-title {
|
|
||||||
margin-top: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.emoji-picker__search-container {
|
.emoji-picker__search-container {
|
||||||
position: relative;
|
position: relative;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
border-color: transparent !important;
|
|
||||||
margin: 12px;
|
margin: 12px;
|
||||||
|
|
||||||
.skin-tones-animation {
|
.skin-tones-animation {
|
||||||
&-enter {
|
&-enter {
|
||||||
transform: translateX(100%);
|
transform: translateX(calc(100% - 32px));
|
||||||
}
|
}
|
||||||
|
|
||||||
&-enter-active {
|
&-enter-active {
|
||||||
@@ -279,30 +257,34 @@
|
|||||||
transition: transform 200ms ease-in-out;
|
transition: transform 200ms ease-in-out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&-enter-done {
|
||||||
|
transform: translateX(0%);
|
||||||
|
}
|
||||||
|
|
||||||
&-exit {
|
&-exit {
|
||||||
position: absolute;
|
|
||||||
width: 100%;
|
|
||||||
transform: translateX(0%);
|
transform: translateX(0%);
|
||||||
}
|
}
|
||||||
|
|
||||||
&-exit-active {
|
&-exit-active {
|
||||||
transform: translateX(90%);
|
transform: translateX(calc(100% - 32px));
|
||||||
transition: transform 200ms ease-in-out;
|
transition: transform 200ms ease-in-out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.skin-tones {
|
.skin-tones {
|
||||||
|
position: absolute;
|
||||||
z-index: 10;
|
z-index: 10;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
display: flex;
|
display: flex;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
background: var(--center-channel-bg);
|
background: var(--center-channel-bg);
|
||||||
margin-inline-start: 8px;
|
|
||||||
|
|
||||||
&--active {
|
&--active {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
width: 100%;
|
width: fit-content;
|
||||||
justify-content: space-around;
|
justify-content: flex-start;
|
||||||
|
|
||||||
.skin-tones__close,
|
.skin-tones__close,
|
||||||
.skin-tones__icons {
|
.skin-tones__icons {
|
||||||
@@ -351,13 +333,15 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.emoji-picker__text-container {
|
.emoji-picker__text-container {
|
||||||
position: relative;
|
|
||||||
z-index: 5;
|
|
||||||
width: 100%;
|
|
||||||
height: 32px;
|
height: 32px;
|
||||||
|
flex: 1;
|
||||||
border: 1px solid rgba(var(--center-channel-color-rgb), 0.24);
|
border: 1px solid rgba(var(--center-channel-color-rgb), 0.24);
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
|
|
||||||
|
&:not(.gif-picker__text-container) {
|
||||||
|
margin-right: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
&:focus-within {
|
&:focus-within {
|
||||||
border: 2px solid functions.v(button-bg);
|
border: 2px solid functions.v(button-bg);
|
||||||
|
|
||||||
@@ -459,8 +443,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.gif-attribution {
|
.gif-attribution {
|
||||||
padding: 5px 0 5px 5px;
|
|
||||||
margin-inline-start: 8px;
|
margin-inline-start: 8px;
|
||||||
|
padding-inline-start: 5px;
|
||||||
|
|
||||||
& > img {
|
& > img {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
@@ -476,14 +460,13 @@ $emoji-footer-height: $emoji-footer-border-width + $emoji-half-height + $emoji-
|
|||||||
|
|
||||||
.emoji-picker__items {
|
.emoji-picker__items {
|
||||||
position: relative;
|
position: relative;
|
||||||
width: 100%;
|
|
||||||
height: 270px;
|
|
||||||
padding: 4px 0 4px 12px;
|
|
||||||
border-top-width: 1px;
|
border-top-width: 1px;
|
||||||
border-top-style: solid;
|
border-top-style: solid;
|
||||||
-webkit-overflow-scrolling: touch;
|
-webkit-overflow-scrolling: touch;
|
||||||
overflow-x: hidden;
|
overflow-x: hidden;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
|
padding-block: 4px;
|
||||||
|
padding-inline: 0px;
|
||||||
|
|
||||||
&:has(.no-results__wrapper) {
|
&:has(.no-results__wrapper) {
|
||||||
display: flex;
|
display: flex;
|
||||||
@@ -507,11 +490,11 @@ $emoji-footer-height: $emoji-footer-border-width + $emoji-half-height + $emoji-
|
|||||||
|
|
||||||
.emoji-picker__category-header {
|
.emoji-picker__category-header {
|
||||||
position: relative;
|
position: relative;
|
||||||
padding-top: 3px;
|
align-content: center;
|
||||||
margin-top: 6px;
|
|
||||||
color: rgba(var(--center-channel-color-rgb), 0.48);
|
color: rgba(var(--center-channel-color-rgb), 0.48);
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
|
line-height: normal;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -531,6 +514,8 @@ $emoji-footer-height: $emoji-footer-border-width + $emoji-half-height + $emoji-
|
|||||||
.emoji-picker__row {
|
.emoji-picker__row {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: flex-start;
|
justify-content: flex-start;
|
||||||
|
padding-inline-end: 4px;
|
||||||
|
padding-inline-start: 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.emoji-picker__item {
|
.emoji-picker__item {
|
||||||
@@ -578,10 +563,6 @@ $emoji-footer-height: $emoji-footer-border-width + $emoji-half-height + $emoji-
|
|||||||
background-color: rgba(var(--center-channel-color-rgb), 0.32);
|
background-color: rgba(var(--center-channel-color-rgb), 0.32);
|
||||||
}
|
}
|
||||||
|
|
||||||
> div {
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
img {
|
img {
|
||||||
position: relative;
|
position: relative;
|
||||||
transition: transform 0.2s ease-in-out;
|
transition: transform 0.2s ease-in-out;
|
||||||
|
|||||||
@@ -378,41 +378,19 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.emoji-picker {
|
.emoji-picker {
|
||||||
// !important is used to overide inline styles
|
display: flex;
|
||||||
// used on larger screens
|
width: 100vw;
|
||||||
top: 0 !important;
|
height: 100vh;
|
||||||
right: auto !important;
|
flex-direction: column;
|
||||||
bottom: auto !important;
|
|
||||||
left: 0 !important;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
border-radius: 0;
|
border-radius: 0;
|
||||||
|
margin-right: 0;
|
||||||
>ul {
|
|
||||||
margin-top: 66px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.search-grid-container {
|
.search-grid-container {
|
||||||
height: calc(100vh - 170px);
|
height: calc(100vh - 170px);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.emoji-picker__inner {
|
.emoji-picker__header {
|
||||||
display: flex;
|
|
||||||
height: calc(100vh - 100px);
|
|
||||||
flex-direction: column;
|
|
||||||
|
|
||||||
.emoji-picker--single & {
|
|
||||||
height: calc(100vh - 55px);
|
|
||||||
}
|
|
||||||
|
|
||||||
>* {
|
|
||||||
flex-grow: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.emoji-picker__header,
|
|
||||||
.modal-body .emoji-picker .emoji-picker__header {
|
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -423,19 +401,10 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.emoji-picker__search-container {
|
|
||||||
height: 40px;
|
|
||||||
|
|
||||||
.emoji-picker__text-container {
|
|
||||||
width: 95%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.emoji-picker__items {
|
.emoji-picker__items {
|
||||||
flex-grow: 1;
|
flex: 1;
|
||||||
|
|
||||||
.emoji-picker__category-header {
|
.emoji-picker__category-header {
|
||||||
padding-top: 8px;
|
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -444,20 +413,7 @@
|
|||||||
width: calc(100% / 15);
|
width: calc(100% / 15);
|
||||||
height: auto;
|
height: auto;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
padding-top: calc(100% / 15);
|
margin-inline: calc(100% / 45);
|
||||||
margin: calc(100% / 45);
|
|
||||||
|
|
||||||
> div {
|
|
||||||
position: absolute;
|
|
||||||
top: 50%;
|
|
||||||
left: 50%;
|
|
||||||
display: flex;
|
|
||||||
width: 30px;
|
|
||||||
height: 30px;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
transform: translate(-50%, -50%);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.emoji-picker__preview {
|
.emoji-picker__preview {
|
||||||
@@ -1815,7 +1771,6 @@
|
|||||||
|
|
||||||
.emoji-picker__item {
|
.emoji-picker__item {
|
||||||
width: calc(100% / #{variables.$emoji-per-row});
|
width: calc(100% / #{variables.$emoji-per-row});
|
||||||
padding-top: calc(100% / #{variables.$emoji-per-row});
|
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ $announcement-bar-height: 40px;
|
|||||||
$backstage-bar-height: 43px;
|
$backstage-bar-height: 43px;
|
||||||
|
|
||||||
// Random variables
|
// Random variables
|
||||||
$emoji-per-row: 9; // needs to match variable `EMOJI_PER_ROW` in emoji_picker.jsx
|
$emoji-per-row: 9; // needs to match variable `EMOJI_PER_ROW` in components/emoji_picker/constants/index.ts
|
||||||
|
|
||||||
// Transition timing defaults
|
// Transition timing defaults
|
||||||
$transition-quick: 0.12s;
|
$transition-quick: 0.12s;
|
||||||
|
|||||||
@@ -323,7 +323,6 @@ export function applyTheme(theme: Theme) {
|
|||||||
changeCss('.app__body .channel-header .pinned-posts-button svg', 'fill:' + changeOpacity(theme.centerChannelColor, 0.75));
|
changeCss('.app__body .channel-header .pinned-posts-button svg', 'fill:' + changeOpacity(theme.centerChannelColor, 0.75));
|
||||||
changeCss('.app__body .channel-header .channel-header_plugin-dropdown svg', 'fill:' + changeOpacity(theme.centerChannelColor, 0.75));
|
changeCss('.app__body .channel-header .channel-header_plugin-dropdown svg', 'fill:' + changeOpacity(theme.centerChannelColor, 0.75));
|
||||||
changeCss('.app__body .file-preview, .app__body .post-image__details, .app__body .markdown__table th, .app__body .markdown__table td, .app__body .webhooks__container, .app__body .dropdown-menu', 'border-color:' + changeOpacity(theme.centerChannelColor, 0.2));
|
changeCss('.app__body .file-preview, .app__body .post-image__details, .app__body .markdown__table th, .app__body .markdown__table td, .app__body .webhooks__container, .app__body .dropdown-menu', 'border-color:' + changeOpacity(theme.centerChannelColor, 0.2));
|
||||||
changeCss('.emoji-picker .emoji-picker__header', 'border-color:' + changeOpacity(theme.centerChannelColor, 0.2));
|
|
||||||
changeCss('.app__body .popover.bottom>.arrow', 'border-bottom-color:' + changeOpacity(theme.centerChannelColor, 0.25));
|
changeCss('.app__body .popover.bottom>.arrow', 'border-bottom-color:' + changeOpacity(theme.centerChannelColor, 0.25));
|
||||||
changeCss('.app__body .btn.btn-transparent', 'color:' + changeOpacity(theme.centerChannelColor, 0.7));
|
changeCss('.app__body .btn.btn-transparent', 'color:' + changeOpacity(theme.centerChannelColor, 0.7));
|
||||||
changeCss('.app__body .popover.right>.arrow', 'border-right-color:' + changeOpacity(theme.centerChannelColor, 0.25));
|
changeCss('.app__body .popover.right>.arrow', 'border-right-color:' + changeOpacity(theme.centerChannelColor, 0.25));
|
||||||
@@ -366,7 +365,7 @@ export function applyTheme(theme: Theme) {
|
|||||||
changeCss('.app__body .emoji-picker', 'color:' + theme.centerChannelColor);
|
changeCss('.app__body .emoji-picker', 'color:' + theme.centerChannelColor);
|
||||||
changeCss('.app__body .emoji-picker', 'border-color:' + changeOpacity(theme.centerChannelColor, 0.2));
|
changeCss('.app__body .emoji-picker', 'border-color:' + changeOpacity(theme.centerChannelColor, 0.2));
|
||||||
changeCss('.app__body .emoji-picker__search-icon', 'color:' + changeOpacity(theme.centerChannelColor, 0.4));
|
changeCss('.app__body .emoji-picker__search-icon', 'color:' + changeOpacity(theme.centerChannelColor, 0.4));
|
||||||
changeCss('.app__body .emoji-picker__preview, .app__body .emoji-picker__items, .app__body .emoji-picker__search-container', 'border-color:' + changeOpacity(theme.centerChannelColor, 0.2));
|
changeCss('.app__body .emoji-picker__preview, .app__body .emoji-picker__items', 'border-color:' + changeOpacity(theme.centerChannelColor, 0.2));
|
||||||
changeCss('.emoji-picker__category .fa:hover', 'color:' + changeOpacity(theme.centerChannelColor, 0.8));
|
changeCss('.emoji-picker__category .fa:hover', 'color:' + changeOpacity(theme.centerChannelColor, 0.8));
|
||||||
changeCss('.app__body .emoji-picker__item-wrapper:hover', 'background-color:' + changeOpacity(theme.centerChannelColor, 0.8));
|
changeCss('.app__body .emoji-picker__item-wrapper:hover', 'background-color:' + changeOpacity(theme.centerChannelColor, 0.8));
|
||||||
changeCss('.app__body .icon__postcontent_picker:hover', 'color:' + changeOpacity(theme.centerChannelColor, 0.8));
|
changeCss('.app__body .icon__postcontent_picker:hover', 'color:' + changeOpacity(theme.centerChannelColor, 0.8));
|
||||||
|
|||||||
Ссылка в новой задаче
Block a user