Add ESC btn to toolbar to quickly exit formatting (#1283)
* Add ESC btn to toolbar to quickly exit formatting * add horizontal scroll to toolbar item * make editor toolbar usable in touch device * fix editor hotkeys not working in window * remove unused import
This commit is contained in:
parent
2883b4c35b
commit
bc5e7445d9
7 changed files with 210 additions and 108 deletions
|
@ -43,6 +43,7 @@ export const EditorPlaceholder = style([
|
||||||
{
|
{
|
||||||
position: 'absolute',
|
position: 'absolute',
|
||||||
zIndex: 1,
|
zIndex: 1,
|
||||||
|
width: '100%',
|
||||||
opacity: config.opacity.Placeholder,
|
opacity: config.opacity.Placeholder,
|
||||||
pointerEvents: 'none',
|
pointerEvents: 'none',
|
||||||
userSelect: 'none',
|
userSelect: 'none',
|
||||||
|
@ -55,9 +56,10 @@ export const EditorPlaceholder = style([
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
|
|
||||||
export const EditorToolbar = style([
|
export const EditorToolbarBase = style({
|
||||||
DefaultReset,
|
padding: `0 ${config.borderWidth.B300}`,
|
||||||
{
|
});
|
||||||
padding: config.space.S100,
|
|
||||||
},
|
export const EditorToolbar = style({
|
||||||
]);
|
padding: config.space.S100,
|
||||||
|
});
|
||||||
|
|
|
@ -104,7 +104,13 @@ export const CustomEditor = forwardRef<HTMLDivElement, CustomEditorProps>(
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
const { style, ...props } = attributes;
|
const { style, ...props } = attributes;
|
||||||
return (
|
return (
|
||||||
<Text as="span" {...props} className={css.EditorPlaceholder} contentEditable={false}>
|
<Text
|
||||||
|
as="span"
|
||||||
|
{...props}
|
||||||
|
className={css.EditorPlaceholder}
|
||||||
|
contentEditable={false}
|
||||||
|
truncate
|
||||||
|
>
|
||||||
{children}
|
{children}
|
||||||
</Text>
|
</Text>
|
||||||
);
|
);
|
||||||
|
|
|
@ -10,6 +10,7 @@ import {
|
||||||
Line,
|
Line,
|
||||||
Menu,
|
Menu,
|
||||||
PopOut,
|
PopOut,
|
||||||
|
Scroll,
|
||||||
Text,
|
Text,
|
||||||
Tooltip,
|
Tooltip,
|
||||||
TooltipProvider,
|
TooltipProvider,
|
||||||
|
@ -17,7 +18,14 @@ import {
|
||||||
} from 'folds';
|
} from 'folds';
|
||||||
import React, { ReactNode, useState } from 'react';
|
import React, { ReactNode, useState } from 'react';
|
||||||
import { ReactEditor, useSlate } from 'slate-react';
|
import { ReactEditor, useSlate } from 'slate-react';
|
||||||
import { isBlockActive, isMarkActive, toggleBlock, toggleMark } from './common';
|
import {
|
||||||
|
isAnyMarkActive,
|
||||||
|
isBlockActive,
|
||||||
|
isMarkActive,
|
||||||
|
removeAllMark,
|
||||||
|
toggleBlock,
|
||||||
|
toggleMark,
|
||||||
|
} from './common';
|
||||||
import * as css from './Editor.css';
|
import * as css from './Editor.css';
|
||||||
import { BlockType, MarkType } from './Elements';
|
import { BlockType, MarkType } from './Elements';
|
||||||
import { HeadingLevel } from './slate';
|
import { HeadingLevel } from './slate';
|
||||||
|
@ -44,6 +52,11 @@ function BtnTooltip({ text, shortCode }: { text: string; shortCode?: string }) {
|
||||||
type MarkButtonProps = { format: MarkType; icon: IconSrc; tooltip: ReactNode };
|
type MarkButtonProps = { format: MarkType; icon: IconSrc; tooltip: ReactNode };
|
||||||
export function MarkButton({ format, icon, tooltip }: MarkButtonProps) {
|
export function MarkButton({ format, icon, tooltip }: MarkButtonProps) {
|
||||||
const editor = useSlate();
|
const editor = useSlate();
|
||||||
|
const disableInline = isBlockActive(editor, BlockType.CodeBlock);
|
||||||
|
|
||||||
|
if (disableInline) {
|
||||||
|
removeAllMark(editor);
|
||||||
|
}
|
||||||
|
|
||||||
const handleClick = () => {
|
const handleClick = () => {
|
||||||
toggleMark(editor, format);
|
toggleMark(editor, format);
|
||||||
|
@ -58,10 +71,11 @@ export function MarkButton({ format, icon, tooltip }: MarkButtonProps) {
|
||||||
variant="SurfaceVariant"
|
variant="SurfaceVariant"
|
||||||
onClick={handleClick}
|
onClick={handleClick}
|
||||||
aria-pressed={isMarkActive(editor, format)}
|
aria-pressed={isMarkActive(editor, format)}
|
||||||
size="300"
|
size="400"
|
||||||
radii="300"
|
radii="300"
|
||||||
|
disabled={disableInline}
|
||||||
>
|
>
|
||||||
<Icon size="50" src={icon} />
|
<Icon size="200" src={icon} />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
)}
|
)}
|
||||||
</TooltipProvider>
|
</TooltipProvider>
|
||||||
|
@ -89,10 +103,10 @@ export function BlockButton({ format, icon, tooltip }: BlockButtonProps) {
|
||||||
variant="SurfaceVariant"
|
variant="SurfaceVariant"
|
||||||
onClick={handleClick}
|
onClick={handleClick}
|
||||||
aria-pressed={isBlockActive(editor, format)}
|
aria-pressed={isBlockActive(editor, format)}
|
||||||
size="300"
|
size="400"
|
||||||
radii="300"
|
radii="300"
|
||||||
>
|
>
|
||||||
<Icon size="50" src={icon} />
|
<Icon size="200" src={icon} />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
)}
|
)}
|
||||||
</TooltipProvider>
|
</TooltipProvider>
|
||||||
|
@ -115,6 +129,7 @@ export function HeadingBlockButton() {
|
||||||
return (
|
return (
|
||||||
<PopOut
|
<PopOut
|
||||||
open={open}
|
open={open}
|
||||||
|
offset={5}
|
||||||
align="Start"
|
align="Start"
|
||||||
position="Top"
|
position="Top"
|
||||||
content={
|
content={
|
||||||
|
@ -130,14 +145,14 @@ export function HeadingBlockButton() {
|
||||||
>
|
>
|
||||||
<Menu style={{ padding: config.space.S100 }}>
|
<Menu style={{ padding: config.space.S100 }}>
|
||||||
<Box gap="100">
|
<Box gap="100">
|
||||||
<IconButton onClick={() => handleMenuSelect(1)} size="300" radii="300">
|
<IconButton onClick={() => handleMenuSelect(1)} size="400" radii="300">
|
||||||
<Icon size="100" src={Icons.Heading1} />
|
<Icon size="200" src={Icons.Heading1} />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
<IconButton onClick={() => handleMenuSelect(2)} size="300" radii="300">
|
<IconButton onClick={() => handleMenuSelect(2)} size="400" radii="300">
|
||||||
<Icon size="100" src={Icons.Heading2} />
|
<Icon size="200" src={Icons.Heading2} />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
<IconButton onClick={() => handleMenuSelect(3)} size="300" radii="300">
|
<IconButton onClick={() => handleMenuSelect(3)} size="400" radii="300">
|
||||||
<Icon size="100" src={Icons.Heading3} />
|
<Icon size="200" src={Icons.Heading3} />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
</Box>
|
</Box>
|
||||||
</Menu>
|
</Menu>
|
||||||
|
@ -151,97 +166,143 @@ export function HeadingBlockButton() {
|
||||||
variant="SurfaceVariant"
|
variant="SurfaceVariant"
|
||||||
onClick={() => (isActive ? toggleBlock(editor, BlockType.Heading) : setOpen(!open))}
|
onClick={() => (isActive ? toggleBlock(editor, BlockType.Heading) : setOpen(!open))}
|
||||||
aria-pressed={isActive}
|
aria-pressed={isActive}
|
||||||
size="300"
|
size="400"
|
||||||
radii="300"
|
radii="300"
|
||||||
>
|
>
|
||||||
<Icon size="50" src={Icons[`Heading${level}`]} />
|
<Icon size="200" src={Icons[`Heading${level}`]} />
|
||||||
<Icon size="50" src={isActive ? Icons.Cross : Icons.ChevronBottom} />
|
<Icon size="200" src={isActive ? Icons.Cross : Icons.ChevronBottom} />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
)}
|
)}
|
||||||
</PopOut>
|
</PopOut>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function Toolbar() {
|
type ExitFormattingProps = { tooltip: ReactNode };
|
||||||
|
export function ExitFormatting({ tooltip }: ExitFormattingProps) {
|
||||||
const editor = useSlate();
|
const editor = useSlate();
|
||||||
const allowInline = !isBlockActive(editor, BlockType.CodeBlock);
|
|
||||||
const modKey = isMacOS() ? KeySymbol.Command : 'Ctrl';
|
const handleClick = () => {
|
||||||
|
if (isAnyMarkActive(editor)) {
|
||||||
|
removeAllMark(editor);
|
||||||
|
} else if (!isBlockActive(editor, BlockType.Paragraph)) {
|
||||||
|
toggleBlock(editor, BlockType.Paragraph);
|
||||||
|
}
|
||||||
|
ReactEditor.focus(editor);
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box className={css.EditorToolbar} alignItems="Center" gap="300">
|
<TooltipProvider tooltip={tooltip} delay={500}>
|
||||||
<Box gap="100">
|
{(triggerRef) => (
|
||||||
<HeadingBlockButton />
|
<IconButton
|
||||||
<BlockButton
|
ref={triggerRef}
|
||||||
format={BlockType.OrderedList}
|
variant="SurfaceVariant"
|
||||||
icon={Icons.OrderList}
|
onClick={handleClick}
|
||||||
tooltip={
|
size="400"
|
||||||
<BtnTooltip text="Ordered List" shortCode={`${modKey} + ${KeySymbol.Shift} + 0`} />
|
radii="300"
|
||||||
}
|
>
|
||||||
/>
|
<Text size="B400">{`Exit ${KeySymbol.Hyper}`}</Text>
|
||||||
<BlockButton
|
</IconButton>
|
||||||
format={BlockType.UnorderedList}
|
)}
|
||||||
icon={Icons.UnorderList}
|
</TooltipProvider>
|
||||||
tooltip={
|
);
|
||||||
<BtnTooltip text="Unordered List" shortCode={`${modKey} + ${KeySymbol.Shift} + 8`} />
|
}
|
||||||
}
|
|
||||||
/>
|
export function Toolbar() {
|
||||||
<BlockButton
|
const editor = useSlate();
|
||||||
format={BlockType.BlockQuote}
|
const modKey = isMacOS() ? KeySymbol.Command : 'Ctrl';
|
||||||
icon={Icons.BlockQuote}
|
|
||||||
tooltip={
|
const canEscape = isAnyMarkActive(editor) || !isBlockActive(editor, BlockType.Paragraph);
|
||||||
<BtnTooltip text="Block Quote" shortCode={`${modKey} + ${KeySymbol.Shift} + '`} />
|
|
||||||
}
|
return (
|
||||||
/>
|
<Box className={css.EditorToolbarBase}>
|
||||||
<BlockButton
|
<Scroll direction="Horizontal" size="0">
|
||||||
format={BlockType.CodeBlock}
|
<Box className={css.EditorToolbar} alignItems="Center" gap="300">
|
||||||
icon={Icons.BlockCode}
|
<>
|
||||||
tooltip={
|
<Box shrink="No" gap="100">
|
||||||
<BtnTooltip text="Block Code" shortCode={`${modKey} + ${KeySymbol.Shift} + ;`} />
|
<MarkButton
|
||||||
}
|
format={MarkType.Bold}
|
||||||
/>
|
icon={Icons.Bold}
|
||||||
</Box>
|
tooltip={<BtnTooltip text="Bold" shortCode={`${modKey} + B`} />}
|
||||||
{allowInline && (
|
/>
|
||||||
<>
|
<MarkButton
|
||||||
<Line variant="SurfaceVariant" direction="Vertical" style={{ height: toRem(12) }} />
|
format={MarkType.Italic}
|
||||||
<Box gap="100">
|
icon={Icons.Italic}
|
||||||
<MarkButton
|
tooltip={<BtnTooltip text="Italic" shortCode={`${modKey} + I`} />}
|
||||||
format={MarkType.Bold}
|
/>
|
||||||
icon={Icons.Bold}
|
<MarkButton
|
||||||
tooltip={<BtnTooltip text="Bold" shortCode={`${modKey} + B`} />}
|
format={MarkType.Underline}
|
||||||
|
icon={Icons.Underline}
|
||||||
|
tooltip={<BtnTooltip text="Underline" shortCode={`${modKey} + U`} />}
|
||||||
|
/>
|
||||||
|
<MarkButton
|
||||||
|
format={MarkType.StrikeThrough}
|
||||||
|
icon={Icons.Strike}
|
||||||
|
tooltip={
|
||||||
|
<BtnTooltip
|
||||||
|
text="Strike Through"
|
||||||
|
shortCode={`${modKey} + ${KeySymbol.Shift} + U`}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<MarkButton
|
||||||
|
format={MarkType.Code}
|
||||||
|
icon={Icons.Code}
|
||||||
|
tooltip={<BtnTooltip text="Inline Code" shortCode={`${modKey} + [`} />}
|
||||||
|
/>
|
||||||
|
<MarkButton
|
||||||
|
format={MarkType.Spoiler}
|
||||||
|
icon={Icons.EyeBlind}
|
||||||
|
tooltip={<BtnTooltip text="Spoiler" shortCode={`${modKey} + H`} />}
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
<Line variant="SurfaceVariant" direction="Vertical" style={{ height: toRem(12) }} />
|
||||||
|
</>
|
||||||
|
<Box shrink="No" gap="100">
|
||||||
|
<BlockButton
|
||||||
|
format={BlockType.BlockQuote}
|
||||||
|
icon={Icons.BlockQuote}
|
||||||
|
tooltip={
|
||||||
|
<BtnTooltip text="Block Quote" shortCode={`${modKey} + ${KeySymbol.Shift} + '`} />
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
<MarkButton
|
<BlockButton
|
||||||
format={MarkType.Italic}
|
format={BlockType.CodeBlock}
|
||||||
icon={Icons.Italic}
|
icon={Icons.BlockCode}
|
||||||
tooltip={<BtnTooltip text="Italic" shortCode={`${modKey} + I`} />}
|
tooltip={
|
||||||
|
<BtnTooltip text="Block Code" shortCode={`${modKey} + ${KeySymbol.Shift} + ;`} />
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
<MarkButton
|
<BlockButton
|
||||||
format={MarkType.Underline}
|
format={BlockType.OrderedList}
|
||||||
icon={Icons.Underline}
|
icon={Icons.OrderList}
|
||||||
tooltip={<BtnTooltip text="Underline" shortCode={`${modKey} + U`} />}
|
tooltip={
|
||||||
|
<BtnTooltip text="Ordered List" shortCode={`${modKey} + ${KeySymbol.Shift} + 7`} />
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
<MarkButton
|
<BlockButton
|
||||||
format={MarkType.StrikeThrough}
|
format={BlockType.UnorderedList}
|
||||||
icon={Icons.Strike}
|
icon={Icons.UnorderList}
|
||||||
tooltip={
|
tooltip={
|
||||||
<BtnTooltip
|
<BtnTooltip
|
||||||
text="Strike Through"
|
text="Unordered List"
|
||||||
shortCode={`${modKey} + ${KeySymbol.Shift} + U`}
|
shortCode={`${modKey} + ${KeySymbol.Shift} + 8`}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
<MarkButton
|
<HeadingBlockButton />
|
||||||
format={MarkType.Code}
|
|
||||||
icon={Icons.Code}
|
|
||||||
tooltip={<BtnTooltip text="Inline Code" shortCode={`${modKey} + [`} />}
|
|
||||||
/>
|
|
||||||
<MarkButton
|
|
||||||
format={MarkType.Spoiler}
|
|
||||||
icon={Icons.EyeBlind}
|
|
||||||
tooltip={<BtnTooltip text="Spoiler" shortCode={`${modKey} + H`} />}
|
|
||||||
/>
|
|
||||||
</Box>
|
</Box>
|
||||||
</>
|
{canEscape && (
|
||||||
)}
|
<>
|
||||||
|
<Line variant="SurfaceVariant" direction="Vertical" style={{ height: toRem(12) }} />
|
||||||
|
<Box shrink="No" gap="100">
|
||||||
|
<ExitFormatting
|
||||||
|
tooltip={<BtnTooltip text="Exit Formatting" shortCode={`${modKey} + E`} />}
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</Box>
|
||||||
|
</Scroll>
|
||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,7 +32,9 @@ export const toggleMark = (editor: Editor, format: MarkType) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
export const removeAllMark = (editor: Editor) => {
|
export const removeAllMark = (editor: Editor) => {
|
||||||
ALL_MARK_TYPE.forEach((mark) => Editor.removeMark(editor, mark));
|
ALL_MARK_TYPE.forEach((mark) => {
|
||||||
|
if (isMarkActive(editor, mark)) Editor.removeMark(editor, mark);
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
export const isBlockActive = (editor: Editor, format: BlockType) => {
|
export const isBlockActive = (editor: Editor, format: BlockType) => {
|
||||||
|
|
|
@ -15,7 +15,7 @@ export const INLINE_HOTKEYS: Record<string, MarkType> = {
|
||||||
const INLINE_KEYS = Object.keys(INLINE_HOTKEYS);
|
const INLINE_KEYS = Object.keys(INLINE_HOTKEYS);
|
||||||
|
|
||||||
export const BLOCK_HOTKEYS: Record<string, BlockType> = {
|
export const BLOCK_HOTKEYS: Record<string, BlockType> = {
|
||||||
'mod+shift+0': BlockType.OrderedList,
|
'mod+shift+7': BlockType.OrderedList,
|
||||||
'mod+shift+8': BlockType.UnorderedList,
|
'mod+shift+8': BlockType.UnorderedList,
|
||||||
"mod+shift+'": BlockType.BlockQuote,
|
"mod+shift+'": BlockType.BlockQuote,
|
||||||
'mod+shift+;': BlockType.CodeBlock,
|
'mod+shift+;': BlockType.CodeBlock,
|
||||||
|
@ -26,12 +26,12 @@ const BLOCK_KEYS = Object.keys(BLOCK_HOTKEYS);
|
||||||
* @return boolean true if shortcut is toggled.
|
* @return boolean true if shortcut is toggled.
|
||||||
*/
|
*/
|
||||||
export const toggleKeyboardShortcut = (editor: Editor, event: KeyboardEvent<Element>): boolean => {
|
export const toggleKeyboardShortcut = (editor: Editor, event: KeyboardEvent<Element>): boolean => {
|
||||||
if (isHotkey('escape', event)) {
|
if (isHotkey('mod+e', event)) {
|
||||||
if (isAnyMarkActive(editor)) {
|
if (isAnyMarkActive(editor)) {
|
||||||
removeAllMark(editor);
|
removeAllMark(editor);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
console.log(isBlockActive(editor, BlockType.Paragraph));
|
|
||||||
if (!isBlockActive(editor, BlockType.Paragraph)) {
|
if (!isBlockActive(editor, BlockType.Paragraph)) {
|
||||||
toggleBlock(editor, BlockType.Paragraph);
|
toggleBlock(editor, BlockType.Paragraph);
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -19,6 +19,7 @@ import {
|
||||||
Icon,
|
Icon,
|
||||||
IconButton,
|
IconButton,
|
||||||
Icons,
|
Icons,
|
||||||
|
Line,
|
||||||
Overlay,
|
Overlay,
|
||||||
OverlayBackdrop,
|
OverlayBackdrop,
|
||||||
OverlayCenter,
|
OverlayCenter,
|
||||||
|
@ -95,6 +96,7 @@ import { MessageReply } from '../../molecules/message/Message';
|
||||||
import colorMXID from '../../../util/colorMXID';
|
import colorMXID from '../../../util/colorMXID';
|
||||||
import { parseReplyBody, parseReplyFormattedBody } from '../../utils/room';
|
import { parseReplyBody, parseReplyFormattedBody } from '../../utils/room';
|
||||||
import { sanitizeText } from '../../utils/sanitize';
|
import { sanitizeText } from '../../utils/sanitize';
|
||||||
|
import { getResizeObserverEntry, useResizeObserver } from '../../hooks/useResizeObserver';
|
||||||
|
|
||||||
interface RoomInputProps {
|
interface RoomInputProps {
|
||||||
roomViewRef: RefObject<HTMLElement>;
|
roomViewRef: RefObject<HTMLElement>;
|
||||||
|
@ -158,6 +160,16 @@ export const RoomInput = forwardRef<HTMLDivElement, RoomInputProps>(
|
||||||
const handlePaste = useFilePasteHandler(handleFiles);
|
const handlePaste = useFilePasteHandler(handleFiles);
|
||||||
const dropZoneVisible = useFileDropZone(roomViewRef, handleFiles);
|
const dropZoneVisible = useFileDropZone(roomViewRef, handleFiles);
|
||||||
|
|
||||||
|
const [mobile, setMobile] = useState(document.body.clientWidth < 500);
|
||||||
|
useResizeObserver(
|
||||||
|
document.body,
|
||||||
|
useCallback((entries) => {
|
||||||
|
const bodyEntry = getResizeObserverEntry(document.body, entries);
|
||||||
|
if (bodyEntry && bodyEntry.contentRect.width < 500) setMobile(true);
|
||||||
|
else setMobile(false);
|
||||||
|
}, [])
|
||||||
|
);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
Transforms.insertFragment(editor, msgDraft);
|
Transforms.insertFragment(editor, msgDraft);
|
||||||
}, [editor, msgDraft]);
|
}, [editor, msgDraft]);
|
||||||
|
@ -500,27 +512,36 @@ export const RoomInput = forwardRef<HTMLDivElement, RoomInputProps>(
|
||||||
>
|
>
|
||||||
{(anchorRef) => (
|
{(anchorRef) => (
|
||||||
<>
|
<>
|
||||||
<IconButton
|
{!mobile && (
|
||||||
aria-pressed={emojiBoardTab === EmojiBoardTab.Sticker}
|
<IconButton
|
||||||
onClick={() => setEmojiBoardTab(EmojiBoardTab.Sticker)}
|
aria-pressed={emojiBoardTab === EmojiBoardTab.Sticker}
|
||||||
variant="SurfaceVariant"
|
onClick={() => setEmojiBoardTab(EmojiBoardTab.Sticker)}
|
||||||
size="300"
|
variant="SurfaceVariant"
|
||||||
radii="300"
|
size="300"
|
||||||
>
|
radii="300"
|
||||||
<Icon
|
>
|
||||||
src={Icons.Sticker}
|
<Icon
|
||||||
filled={emojiBoardTab === EmojiBoardTab.Sticker}
|
src={Icons.Sticker}
|
||||||
/>
|
filled={emojiBoardTab === EmojiBoardTab.Sticker}
|
||||||
</IconButton>
|
/>
|
||||||
|
</IconButton>
|
||||||
|
)}
|
||||||
<IconButton
|
<IconButton
|
||||||
ref={anchorRef}
|
ref={anchorRef}
|
||||||
aria-pressed={emojiBoardTab === EmojiBoardTab.Emoji}
|
aria-pressed={
|
||||||
|
mobile ? !!emojiBoardTab : emojiBoardTab === EmojiBoardTab.Emoji
|
||||||
|
}
|
||||||
onClick={() => setEmojiBoardTab(EmojiBoardTab.Emoji)}
|
onClick={() => setEmojiBoardTab(EmojiBoardTab.Emoji)}
|
||||||
variant="SurfaceVariant"
|
variant="SurfaceVariant"
|
||||||
size="300"
|
size="300"
|
||||||
radii="300"
|
radii="300"
|
||||||
>
|
>
|
||||||
<Icon src={Icons.Smile} filled={emojiBoardTab === EmojiBoardTab.Emoji} />
|
<Icon
|
||||||
|
src={Icons.Smile}
|
||||||
|
filled={
|
||||||
|
mobile ? !!emojiBoardTab : emojiBoardTab === EmojiBoardTab.Emoji
|
||||||
|
}
|
||||||
|
/>
|
||||||
</IconButton>
|
</IconButton>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
@ -532,7 +553,14 @@ export const RoomInput = forwardRef<HTMLDivElement, RoomInputProps>(
|
||||||
</IconButton>
|
</IconButton>
|
||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
bottom={toolbar && <Toolbar />}
|
bottom={
|
||||||
|
toolbar && (
|
||||||
|
<div>
|
||||||
|
<Line variant="SurfaceVariant" size="300" />
|
||||||
|
<Toolbar />
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
@ -3,4 +3,7 @@ export enum KeySymbol {
|
||||||
Shift = '⇧',
|
Shift = '⇧',
|
||||||
Option = '⌥',
|
Option = '⌥',
|
||||||
Control = '⌃',
|
Control = '⌃',
|
||||||
|
Hyper = '✦',
|
||||||
|
Super = '❖',
|
||||||
|
Escape = '⎋',
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue