mirror of
https://github.com/cinnyapp/cinny.git
synced 2025-09-13 22:32:26 +03:00
extract emoji board tabs component
This commit is contained in:
parent
6cfe9d19e3
commit
83abb8b4e3
6 changed files with 75 additions and 93 deletions
|
@ -44,10 +44,6 @@ export const Header = style({
|
||||||
paddingBottom: 0,
|
paddingBottom: 0,
|
||||||
});
|
});
|
||||||
|
|
||||||
export const EmojiBoardTab = style({
|
|
||||||
cursor: 'pointer',
|
|
||||||
});
|
|
||||||
|
|
||||||
export const Footer = style({
|
export const Footer = style({
|
||||||
padding: config.space.S200,
|
padding: config.space.S200,
|
||||||
margin: config.space.S300,
|
margin: config.space.S300,
|
||||||
|
|
|
@ -11,13 +11,10 @@ import React, {
|
||||||
useRef,
|
useRef,
|
||||||
} from 'react';
|
} from 'react';
|
||||||
import {
|
import {
|
||||||
Badge,
|
|
||||||
Box,
|
Box,
|
||||||
Chip,
|
|
||||||
Icon,
|
Icon,
|
||||||
IconButton,
|
IconButton,
|
||||||
Icons,
|
Icons,
|
||||||
Input,
|
|
||||||
Line,
|
Line,
|
||||||
Scroll,
|
Scroll,
|
||||||
Text,
|
Text,
|
||||||
|
@ -47,32 +44,15 @@ import { useAsyncSearch, UseAsyncSearchOptions } from '../../hooks/useAsyncSearc
|
||||||
import { useDebounce } from '../../hooks/useDebounce';
|
import { useDebounce } from '../../hooks/useDebounce';
|
||||||
import { useThrottle } from '../../hooks/useThrottle';
|
import { useThrottle } from '../../hooks/useThrottle';
|
||||||
import { addRecentEmoji } from '../../plugins/recent-emoji';
|
import { addRecentEmoji } from '../../plugins/recent-emoji';
|
||||||
import { mobileOrTablet } from '../../utils/user-agent';
|
|
||||||
import { useMediaAuthentication } from '../../hooks/useMediaAuthentication';
|
import { useMediaAuthentication } from '../../hooks/useMediaAuthentication';
|
||||||
import { ImagePack, ImageUsage, PackImageReader } from '../../plugins/custom-emoji';
|
import { ImagePack, ImageUsage, PackImageReader } from '../../plugins/custom-emoji';
|
||||||
import { getEmoticonSearchStr } from '../../plugins/utils';
|
import { getEmoticonSearchStr } from '../../plugins/utils';
|
||||||
|
import { SearchInput, EmojiBoardTabs } from './components';
|
||||||
|
import { EmojiBoardTab, EmojiItemInfo, EmojiType } from './types';
|
||||||
|
|
||||||
const RECENT_GROUP_ID = 'recent_group';
|
const RECENT_GROUP_ID = 'recent_group';
|
||||||
const SEARCH_GROUP_ID = 'search_group';
|
const SEARCH_GROUP_ID = 'search_group';
|
||||||
|
|
||||||
export enum EmojiBoardTab {
|
|
||||||
Emoji = 'Emoji',
|
|
||||||
Sticker = 'Sticker',
|
|
||||||
}
|
|
||||||
|
|
||||||
enum EmojiType {
|
|
||||||
Emoji = 'emoji',
|
|
||||||
CustomEmoji = 'customEmoji',
|
|
||||||
Sticker = 'sticker',
|
|
||||||
}
|
|
||||||
|
|
||||||
export type EmojiItemInfo = {
|
|
||||||
type: EmojiType;
|
|
||||||
data: string;
|
|
||||||
shortcode: string;
|
|
||||||
label: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
const getDOMGroupId = (id: string): string => `EmojiBoardGroup-${id}`;
|
const getDOMGroupId = (id: string): string => `EmojiBoardGroup-${id}`;
|
||||||
|
|
||||||
const getEmojiItemInfo = (element: Element): EmojiItemInfo | undefined => {
|
const getEmojiItemInfo = (element: Element): EmojiItemInfo | undefined => {
|
||||||
|
@ -167,43 +147,6 @@ const EmojiBoardLayout = as<
|
||||||
</Box>
|
</Box>
|
||||||
));
|
));
|
||||||
|
|
||||||
function EmojiBoardTabs({
|
|
||||||
tab,
|
|
||||||
onTabChange,
|
|
||||||
}: {
|
|
||||||
tab: EmojiBoardTab;
|
|
||||||
onTabChange: (tab: EmojiBoardTab) => void;
|
|
||||||
}) {
|
|
||||||
return (
|
|
||||||
<Box gap="100">
|
|
||||||
<Badge
|
|
||||||
className={css.EmojiBoardTab}
|
|
||||||
as="button"
|
|
||||||
variant="Secondary"
|
|
||||||
fill={tab === EmojiBoardTab.Sticker ? 'Solid' : 'None'}
|
|
||||||
size="500"
|
|
||||||
onClick={() => onTabChange(EmojiBoardTab.Sticker)}
|
|
||||||
>
|
|
||||||
<Text as="span" size="L400">
|
|
||||||
Sticker
|
|
||||||
</Text>
|
|
||||||
</Badge>
|
|
||||||
<Badge
|
|
||||||
className={css.EmojiBoardTab}
|
|
||||||
as="button"
|
|
||||||
variant="Secondary"
|
|
||||||
fill={tab === EmojiBoardTab.Emoji ? 'Solid' : 'None'}
|
|
||||||
size="500"
|
|
||||||
onClick={() => onTabChange(EmojiBoardTab.Emoji)}
|
|
||||||
>
|
|
||||||
<Text as="span" size="L400">
|
|
||||||
Emoji
|
|
||||||
</Text>
|
|
||||||
</Badge>
|
|
||||||
</Box>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function SidebarBtn<T extends string>({
|
export function SidebarBtn<T extends string>({
|
||||||
active,
|
active,
|
||||||
label,
|
label,
|
||||||
|
@ -753,6 +696,11 @@ export function EmojiBoard({
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleTextCustomEmojiSelect = (textEmoji: string) => {
|
||||||
|
onCustomEmojiSelect?.(textEmoji, textEmoji);
|
||||||
|
requestClose();
|
||||||
|
};
|
||||||
|
|
||||||
const handleEmojiPreview = useCallback(
|
const handleEmojiPreview = useCallback(
|
||||||
(element: HTMLButtonElement) => {
|
(element: HTMLButtonElement) => {
|
||||||
const emojiInfo = getEmojiItemInfo(element);
|
const emojiInfo = getEmojiItemInfo(element);
|
||||||
|
@ -819,37 +767,11 @@ export function EmojiBoard({
|
||||||
<Header>
|
<Header>
|
||||||
<Box direction="Column" gap="200">
|
<Box direction="Column" gap="200">
|
||||||
{onTabChange && <EmojiBoardTabs tab={tab} onTabChange={onTabChange} />}
|
{onTabChange && <EmojiBoardTabs tab={tab} onTabChange={onTabChange} />}
|
||||||
<Input
|
<SearchInput
|
||||||
data-emoji-board-search
|
query={result?.query}
|
||||||
variant="SurfaceVariant"
|
|
||||||
size="400"
|
|
||||||
placeholder={allowTextCustomEmoji ? 'Search or Text Reaction ' : 'Search'}
|
|
||||||
maxLength={50}
|
|
||||||
after={
|
|
||||||
allowTextCustomEmoji && result?.query ? (
|
|
||||||
<Chip
|
|
||||||
variant="Primary"
|
|
||||||
radii="Pill"
|
|
||||||
after={<Icon src={Icons.ArrowRight} size="50" />}
|
|
||||||
outlined
|
|
||||||
onClick={() => {
|
|
||||||
const searchInput = document.querySelector<HTMLInputElement>(
|
|
||||||
'[data-emoji-board-search="true"]'
|
|
||||||
);
|
|
||||||
const textReaction = searchInput?.value.trim();
|
|
||||||
if (!textReaction) return;
|
|
||||||
onCustomEmojiSelect?.(textReaction, textReaction);
|
|
||||||
requestClose();
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Text size="L400">React</Text>
|
|
||||||
</Chip>
|
|
||||||
) : (
|
|
||||||
<Icon src={Icons.Search} size="50" />
|
|
||||||
)
|
|
||||||
}
|
|
||||||
onChange={handleOnChange}
|
onChange={handleOnChange}
|
||||||
autoFocus={!mobileOrTablet()}
|
allowTextCustomEmoji={allowTextCustomEmoji}
|
||||||
|
onTextCustomEmojiSelect={handleTextCustomEmojiSelect}
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
</Header>
|
</Header>
|
||||||
|
|
44
src/app/components/emoji-board/components/Tabs.tsx
Normal file
44
src/app/components/emoji-board/components/Tabs.tsx
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
import React, { CSSProperties } from 'react';
|
||||||
|
import { Badge, Box, Text } from 'folds';
|
||||||
|
import { EmojiBoardTab } from '../types';
|
||||||
|
|
||||||
|
const styles: CSSProperties = {
|
||||||
|
cursor: 'pointer',
|
||||||
|
};
|
||||||
|
|
||||||
|
export function EmojiBoardTabs({
|
||||||
|
tab,
|
||||||
|
onTabChange,
|
||||||
|
}: {
|
||||||
|
tab: EmojiBoardTab;
|
||||||
|
onTabChange: (tab: EmojiBoardTab) => void;
|
||||||
|
}) {
|
||||||
|
return (
|
||||||
|
<Box gap="100">
|
||||||
|
<Badge
|
||||||
|
style={styles}
|
||||||
|
as="button"
|
||||||
|
variant="Secondary"
|
||||||
|
fill={tab === EmojiBoardTab.Sticker ? 'Solid' : 'None'}
|
||||||
|
size="500"
|
||||||
|
onClick={() => onTabChange(EmojiBoardTab.Sticker)}
|
||||||
|
>
|
||||||
|
<Text as="span" size="L400">
|
||||||
|
Sticker
|
||||||
|
</Text>
|
||||||
|
</Badge>
|
||||||
|
<Badge
|
||||||
|
style={styles}
|
||||||
|
as="button"
|
||||||
|
variant="Secondary"
|
||||||
|
fill={tab === EmojiBoardTab.Emoji ? 'Solid' : 'None'}
|
||||||
|
size="500"
|
||||||
|
onClick={() => onTabChange(EmojiBoardTab.Emoji)}
|
||||||
|
>
|
||||||
|
<Text as="span" size="L400">
|
||||||
|
Emoji
|
||||||
|
</Text>
|
||||||
|
</Badge>
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
}
|
2
src/app/components/emoji-board/components/index.tsx
Normal file
2
src/app/components/emoji-board/components/index.tsx
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
export * from './SearchInput';
|
||||||
|
export * from './Tabs';
|
|
@ -1 +1,2 @@
|
||||||
export * from './EmojiBoard';
|
export * from './EmojiBoard';
|
||||||
|
export * from './types';
|
||||||
|
|
17
src/app/components/emoji-board/types.ts
Normal file
17
src/app/components/emoji-board/types.ts
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
export enum EmojiBoardTab {
|
||||||
|
Emoji = 'Emoji',
|
||||||
|
Sticker = 'Sticker',
|
||||||
|
}
|
||||||
|
|
||||||
|
export enum EmojiType {
|
||||||
|
Emoji = 'emoji',
|
||||||
|
CustomEmoji = 'customEmoji',
|
||||||
|
Sticker = 'sticker',
|
||||||
|
}
|
||||||
|
|
||||||
|
export type EmojiItemInfo = {
|
||||||
|
type: EmojiType;
|
||||||
|
data: string;
|
||||||
|
shortcode: string;
|
||||||
|
label: string;
|
||||||
|
};
|
Loading…
Add table
Add a link
Reference in a new issue