style(autocomplete): Dawn popover with mono handles, a fleet row highlight and a violet self-mention chip
This commit is contained in:
parent
baf23f9a45
commit
4c6f662939
7 changed files with 78 additions and 35 deletions
|
|
@ -1,5 +1,5 @@
|
||||||
import { style } from '@vanilla-extract/css';
|
import { style } from '@vanilla-extract/css';
|
||||||
import { DefaultReset, config } from 'folds';
|
import { DefaultReset, color, config, toRem } from 'folds';
|
||||||
|
|
||||||
export const AutocompleteMenuBase = style([
|
export const AutocompleteMenuBase = style([
|
||||||
DefaultReset,
|
DefaultReset,
|
||||||
|
|
@ -19,17 +19,51 @@ export const AutocompleteMenuContainer = style([
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
// Dawn popover shell — a single hairline-bordered panel that floats above the
|
||||||
|
// composer, mirroring the cmdK result-list look (panel #181a20 + faint fleet ring).
|
||||||
export const AutocompleteMenu = style([
|
export const AutocompleteMenu = style([
|
||||||
DefaultReset,
|
DefaultReset,
|
||||||
{
|
{
|
||||||
maxHeight: '30vh',
|
maxHeight: '40vh',
|
||||||
height: '100%',
|
height: '100%',
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
flexDirection: 'column',
|
flexDirection: 'column',
|
||||||
|
backgroundColor: color.SurfaceVariant.Container,
|
||||||
|
border: `${toRem(1)} solid rgba(255, 255, 255, 0.07)`,
|
||||||
|
borderRadius: config.radii.R400,
|
||||||
|
boxShadow: '0 30px 80px rgba(0, 0, 0, 0.6), 0 0 0 1px rgba(149, 128, 255, 0.15)',
|
||||||
|
overflow: 'hidden',
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
// UPPERCASE, letter-spaced, muted mono section label — replaces the folds Header.
|
||||||
export const AutocompleteMenuHeader = style([
|
export const AutocompleteMenuHeader = style([
|
||||||
DefaultReset,
|
DefaultReset,
|
||||||
{ padding: `0 ${config.space.S300}`, flexShrink: 0 },
|
{
|
||||||
|
flexShrink: 0,
|
||||||
|
display: 'block',
|
||||||
|
padding: `${config.space.S200} ${config.space.S300} ${config.space.S100}`,
|
||||||
|
fontFamily: 'var(--font-mono)',
|
||||||
|
fontSize: toRem(10),
|
||||||
|
lineHeight: toRem(14),
|
||||||
|
fontWeight: config.fontWeight.W500,
|
||||||
|
letterSpacing: '0.12em',
|
||||||
|
textTransform: 'uppercase',
|
||||||
|
color: color.SurfaceVariant.OnContainer,
|
||||||
|
opacity: 0.5,
|
||||||
|
},
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
// JetBrains Mono technical handle (@user:server, #alias:server, !id, /command sig)
|
||||||
|
// rendered at a muted tone inside an autocomplete row.
|
||||||
|
export const AutocompleteMono = style({
|
||||||
|
fontFamily: 'var(--font-mono)',
|
||||||
|
opacity: 0.6,
|
||||||
|
});
|
||||||
|
|
||||||
|
// Fleet highlight for the first (Tab-target) row: faint violet wash + a 2px
|
||||||
|
// fleet left-border. Purely visual — reflects the onTabPress 'first item' logic.
|
||||||
|
export const AutocompleteActiveRow = style({
|
||||||
|
backgroundColor: 'rgba(149, 128, 255, 0.08)',
|
||||||
|
boxShadow: `inset ${toRem(2)} 0 0 0 ${color.Primary.Main}`,
|
||||||
|
});
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import React, { ReactNode } from 'react';
|
import React, { ReactNode } from 'react';
|
||||||
import FocusTrap from 'focus-trap-react';
|
import FocusTrap from 'focus-trap-react';
|
||||||
import { isKeyHotkey } from 'is-hotkey';
|
import { isKeyHotkey } from 'is-hotkey';
|
||||||
import { Header, Menu, Scroll, config } from 'folds';
|
import { Menu, Scroll, config } from 'folds';
|
||||||
|
|
||||||
import * as css from './AutocompleteMenu.css';
|
import * as css from './AutocompleteMenu.css';
|
||||||
import { preventScrollWithArrowKey, stopPropagation } from '../../../utils/keyboard';
|
import { preventScrollWithArrowKey, stopPropagation } from '../../../utils/keyboard';
|
||||||
|
|
@ -38,9 +38,7 @@ export function AutocompleteMenu({ headerContent, requestClose, children }: Auto
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Menu className={css.AutocompleteMenu}>
|
<Menu className={css.AutocompleteMenu}>
|
||||||
<Header className={css.AutocompleteMenuHeader} size="400">
|
<span className={css.AutocompleteMenuHeader}>{headerContent}</span>
|
||||||
{headerContent}
|
|
||||||
</Header>
|
|
||||||
<Scroll style={{ flexGrow: 1 }} onKeyDown={preventScrollWithArrowKey}>
|
<Scroll style={{ flexGrow: 1 }} onKeyDown={preventScrollWithArrowKey}>
|
||||||
<div style={{ padding: config.space.S200 }}>{children}</div>
|
<div style={{ padding: config.space.S200 }}>{children}</div>
|
||||||
</Scroll>
|
</Scroll>
|
||||||
|
|
|
||||||
|
|
@ -2,9 +2,11 @@ import React, { KeyboardEvent as ReactKeyboardEvent, useEffect, useMemo } from '
|
||||||
import { Editor } from 'slate';
|
import { Editor } from 'slate';
|
||||||
import { Box, MenuItem, Text, toRem } from 'folds';
|
import { Box, MenuItem, Text, toRem } from 'folds';
|
||||||
import { Room } from 'matrix-js-sdk';
|
import { Room } from 'matrix-js-sdk';
|
||||||
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
import { AutocompleteQuery } from './autocompleteQuery';
|
import { AutocompleteQuery } from './autocompleteQuery';
|
||||||
import { AutocompleteMenu } from './AutocompleteMenu';
|
import { AutocompleteMenu } from './AutocompleteMenu';
|
||||||
|
import * as css from './AutocompleteMenu.css';
|
||||||
import { useMatrixClient } from '../../../hooks/useMatrixClient';
|
import { useMatrixClient } from '../../../hooks/useMatrixClient';
|
||||||
import { UseAsyncSearchOptions, useAsyncSearch } from '../../../hooks/useAsyncSearch';
|
import { UseAsyncSearchOptions, useAsyncSearch } from '../../../hooks/useAsyncSearch';
|
||||||
import { onTabPress } from '../../../utils/keyboard';
|
import { onTabPress } from '../../../utils/keyboard';
|
||||||
|
|
@ -42,6 +44,7 @@ export function EmoticonAutocomplete({
|
||||||
query,
|
query,
|
||||||
requestClose,
|
requestClose,
|
||||||
}: EmoticonAutocompleteProps) {
|
}: EmoticonAutocompleteProps) {
|
||||||
|
const { t } = useTranslation();
|
||||||
const mx = useMatrixClient();
|
const mx = useMatrixClient();
|
||||||
const useAuthentication = useMediaAuthentication();
|
const useAuthentication = useMediaAuthentication();
|
||||||
|
|
||||||
|
|
@ -85,8 +88,8 @@ export function EmoticonAutocomplete({
|
||||||
});
|
});
|
||||||
|
|
||||||
return autoCompleteEmoticon.length === 0 ? null : (
|
return autoCompleteEmoticon.length === 0 ? null : (
|
||||||
<AutocompleteMenu headerContent={<Text size="L400">Emojis</Text>} requestClose={requestClose}>
|
<AutocompleteMenu headerContent={t('Room.autocomplete_emojis')} requestClose={requestClose}>
|
||||||
{autoCompleteEmoticon.map((emoticon) => {
|
{autoCompleteEmoticon.map((emoticon, index) => {
|
||||||
const isCustomEmoji = 'url' in emoticon;
|
const isCustomEmoji = 'url' in emoticon;
|
||||||
const key = isCustomEmoji ? emoticon.url : emoticon.unicode;
|
const key = isCustomEmoji ? emoticon.url : emoticon.unicode;
|
||||||
const customEmojiUrl = mxcUrlToHttp(mx, key, useAuthentication);
|
const customEmojiUrl = mxcUrlToHttp(mx, key, useAuthentication);
|
||||||
|
|
@ -94,6 +97,7 @@ export function EmoticonAutocomplete({
|
||||||
return (
|
return (
|
||||||
<MenuItem
|
<MenuItem
|
||||||
key={emoticon.shortcode + key}
|
key={emoticon.shortcode + key}
|
||||||
|
className={index === 0 ? css.AutocompleteActiveRow : undefined}
|
||||||
as="button"
|
as="button"
|
||||||
radii="300"
|
radii="300"
|
||||||
onKeyDown={(evt: ReactKeyboardEvent<HTMLButtonElement>) =>
|
onKeyDown={(evt: ReactKeyboardEvent<HTMLButtonElement>) =>
|
||||||
|
|
@ -121,7 +125,7 @@ export function EmoticonAutocomplete({
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<Text style={{ flexGrow: 1 }} size="B400" truncate>
|
<Text className={css.AutocompleteMono} style={{ flexGrow: 1 }} size="B400" truncate>
|
||||||
:{emoticon.shortcode}:
|
:{emoticon.shortcode}:
|
||||||
</Text>
|
</Text>
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
|
|
|
||||||
|
|
@ -3,12 +3,14 @@ import { Editor } from 'slate';
|
||||||
import { Avatar, Icon, Icons, MenuItem, Text } from 'folds';
|
import { Avatar, Icon, Icons, MenuItem, Text } from 'folds';
|
||||||
import { JoinRule, MatrixClient } from 'matrix-js-sdk';
|
import { JoinRule, MatrixClient } from 'matrix-js-sdk';
|
||||||
import { useAtomValue } from 'jotai';
|
import { useAtomValue } from 'jotai';
|
||||||
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
import { createMentionElement, moveCursor, replaceWithElement } from '../utils';
|
import { createMentionElement, moveCursor, replaceWithElement } from '../utils';
|
||||||
import { getDirectRoomAvatarUrl } from '../../../utils/room';
|
import { getDirectRoomAvatarUrl } from '../../../utils/room';
|
||||||
import { useMatrixClient } from '../../../hooks/useMatrixClient';
|
import { useMatrixClient } from '../../../hooks/useMatrixClient';
|
||||||
import { AutocompleteQuery } from './autocompleteQuery';
|
import { AutocompleteQuery } from './autocompleteQuery';
|
||||||
import { AutocompleteMenu } from './AutocompleteMenu';
|
import { AutocompleteMenu } from './AutocompleteMenu';
|
||||||
|
import * as css from './AutocompleteMenu.css';
|
||||||
import { getMxIdServer, isRoomAlias } from '../../../utils/matrix';
|
import { getMxIdServer, isRoomAlias } from '../../../utils/matrix';
|
||||||
import { UseAsyncSearchOptions, useAsyncSearch } from '../../../hooks/useAsyncSearch';
|
import { UseAsyncSearchOptions, useAsyncSearch } from '../../../hooks/useAsyncSearch';
|
||||||
import { onTabPress } from '../../../utils/keyboard';
|
import { onTabPress } from '../../../utils/keyboard';
|
||||||
|
|
@ -76,6 +78,7 @@ export function RoomMentionAutocomplete({
|
||||||
query,
|
query,
|
||||||
requestClose,
|
requestClose,
|
||||||
}: RoomMentionAutocompleteProps) {
|
}: RoomMentionAutocompleteProps) {
|
||||||
|
const { t } = useTranslation();
|
||||||
const mx = useMatrixClient();
|
const mx = useMatrixClient();
|
||||||
const mDirects = useAtomValue(mDirectAtom);
|
const mDirects = useAtomValue(mDirectAtom);
|
||||||
|
|
||||||
|
|
@ -86,12 +89,12 @@ export function RoomMentionAutocomplete({
|
||||||
useCallback(
|
useCallback(
|
||||||
(rId) => {
|
(rId) => {
|
||||||
const r = mx.getRoom(rId);
|
const r = mx.getRoom(rId);
|
||||||
if (!r) return 'Unknown Room';
|
if (!r) return t('Room.autocomplete_unknown_room');
|
||||||
const alias = r.getCanonicalAlias();
|
const alias = r.getCanonicalAlias();
|
||||||
if (alias) return [r.name, alias];
|
if (alias) return [r.name, alias];
|
||||||
return r.name;
|
return r.name;
|
||||||
},
|
},
|
||||||
[mx]
|
[mx, t]
|
||||||
),
|
),
|
||||||
SEARCH_OPTIONS
|
SEARCH_OPTIONS
|
||||||
);
|
);
|
||||||
|
|
@ -133,11 +136,11 @@ export function RoomMentionAutocomplete({
|
||||||
});
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<AutocompleteMenu headerContent={<Text size="L400">Rooms</Text>} requestClose={requestClose}>
|
<AutocompleteMenu headerContent={t('Room.autocomplete_rooms')} requestClose={requestClose}>
|
||||||
{autoCompleteRoomIds.length === 0 ? (
|
{autoCompleteRoomIds.length === 0 ? (
|
||||||
<UnknownRoomMentionItem query={query} handleAutocomplete={handleAutocomplete} />
|
<UnknownRoomMentionItem query={query} handleAutocomplete={handleAutocomplete} />
|
||||||
) : (
|
) : (
|
||||||
autoCompleteRoomIds.map((rId) => {
|
autoCompleteRoomIds.map((rId, index) => {
|
||||||
const room = mx.getRoom(rId);
|
const room = mx.getRoom(rId);
|
||||||
if (!room) return null;
|
if (!room) return null;
|
||||||
const dm = mDirects.has(room.roomId);
|
const dm = mDirects.has(room.roomId);
|
||||||
|
|
@ -147,6 +150,7 @@ export function RoomMentionAutocomplete({
|
||||||
return (
|
return (
|
||||||
<MenuItem
|
<MenuItem
|
||||||
key={rId}
|
key={rId}
|
||||||
|
className={index === 0 ? css.AutocompleteActiveRow : undefined}
|
||||||
as="button"
|
as="button"
|
||||||
radii="300"
|
radii="300"
|
||||||
onKeyDown={(evt: ReactKeyboardEvent<HTMLButtonElement>) =>
|
onKeyDown={(evt: ReactKeyboardEvent<HTMLButtonElement>) =>
|
||||||
|
|
@ -154,7 +158,7 @@ export function RoomMentionAutocomplete({
|
||||||
}
|
}
|
||||||
onClick={handleSelect}
|
onClick={handleSelect}
|
||||||
after={
|
after={
|
||||||
<Text size="T200" priority="300" truncate>
|
<Text className={css.AutocompleteMono} size="T200" priority="300" truncate>
|
||||||
{room.getCanonicalAlias() ?? ''}
|
{room.getCanonicalAlias() ?? ''}
|
||||||
</Text>
|
</Text>
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,9 +2,11 @@ import React, { useEffect, KeyboardEvent as ReactKeyboardEvent } from 'react';
|
||||||
import { Editor } from 'slate';
|
import { Editor } from 'slate';
|
||||||
import { Avatar, Icon, Icons, MenuItem, Text } from 'folds';
|
import { Avatar, Icon, Icons, MenuItem, Text } from 'folds';
|
||||||
import { MatrixClient, Room, RoomMember } from 'matrix-js-sdk';
|
import { MatrixClient, Room, RoomMember } from 'matrix-js-sdk';
|
||||||
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
import { AutocompleteQuery } from './autocompleteQuery';
|
import { AutocompleteQuery } from './autocompleteQuery';
|
||||||
import { AutocompleteMenu } from './AutocompleteMenu';
|
import { AutocompleteMenu } from './AutocompleteMenu';
|
||||||
|
import * as css from './AutocompleteMenu.css';
|
||||||
import { useRoomMembers } from '../../../hooks/useRoomMembers';
|
import { useRoomMembers } from '../../../hooks/useRoomMembers';
|
||||||
import { useMatrixClient } from '../../../hooks/useMatrixClient';
|
import { useMatrixClient } from '../../../hooks/useMatrixClient';
|
||||||
import {
|
import {
|
||||||
|
|
@ -90,6 +92,7 @@ export function UserMentionAutocomplete({
|
||||||
query,
|
query,
|
||||||
requestClose,
|
requestClose,
|
||||||
}: UserMentionAutocompleteProps) {
|
}: UserMentionAutocompleteProps) {
|
||||||
|
const { t } = useTranslation();
|
||||||
const mx = useMatrixClient();
|
const mx = useMatrixClient();
|
||||||
const useAuthentication = useMediaAuthentication();
|
const useAuthentication = useMediaAuthentication();
|
||||||
const { roomId } = room;
|
const { roomId } = room;
|
||||||
|
|
@ -137,7 +140,7 @@ export function UserMentionAutocomplete({
|
||||||
getMemberDisplayName(room, member.userId) ?? getMxIdLocalPart(member.userId) ?? member.userId;
|
getMemberDisplayName(room, member.userId) ?? getMxIdLocalPart(member.userId) ?? member.userId;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<AutocompleteMenu headerContent={<Text size="L400">Mentions</Text>} requestClose={requestClose}>
|
<AutocompleteMenu headerContent={t('Room.autocomplete_users')} requestClose={requestClose}>
|
||||||
{query.text === 'room' && (
|
{query.text === 'room' && (
|
||||||
<UnknownMentionItem
|
<UnknownMentionItem
|
||||||
userId={roomAliasOrId}
|
userId={roomAliasOrId}
|
||||||
|
|
@ -152,7 +155,7 @@ export function UserMentionAutocomplete({
|
||||||
handleAutocomplete={handleAutocomplete}
|
handleAutocomplete={handleAutocomplete}
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
autoCompleteMembers.map((roomMember) => {
|
autoCompleteMembers.map((roomMember, index) => {
|
||||||
const avatarMxcUrl = roomMember.getMxcAvatarUrl();
|
const avatarMxcUrl = roomMember.getMxcAvatarUrl();
|
||||||
const avatarUrl = avatarMxcUrl
|
const avatarUrl = avatarMxcUrl
|
||||||
? mx.mxcUrlToHttp(avatarMxcUrl, 32, 32, 'crop', undefined, false, useAuthentication)
|
? mx.mxcUrlToHttp(avatarMxcUrl, 32, 32, 'crop', undefined, false, useAuthentication)
|
||||||
|
|
@ -160,6 +163,9 @@ export function UserMentionAutocomplete({
|
||||||
return (
|
return (
|
||||||
<MenuItem
|
<MenuItem
|
||||||
key={roomMember.userId}
|
key={roomMember.userId}
|
||||||
|
className={
|
||||||
|
index === 0 && query.text !== 'room' ? css.AutocompleteActiveRow : undefined
|
||||||
|
}
|
||||||
as="button"
|
as="button"
|
||||||
radii="300"
|
radii="300"
|
||||||
onKeyDown={(evt: ReactKeyboardEvent<HTMLButtonElement>) =>
|
onKeyDown={(evt: ReactKeyboardEvent<HTMLButtonElement>) =>
|
||||||
|
|
@ -167,7 +173,7 @@ export function UserMentionAutocomplete({
|
||||||
}
|
}
|
||||||
onClick={() => handleAutocomplete(roomMember.userId, getName(roomMember))}
|
onClick={() => handleAutocomplete(roomMember.userId, getName(roomMember))}
|
||||||
after={
|
after={
|
||||||
<Text size="T200" priority="300" truncate>
|
<Text className={css.AutocompleteMono} size="T200" priority="300" truncate>
|
||||||
{roomMember.userId}
|
{roomMember.userId}
|
||||||
</Text>
|
</Text>
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ import React, { KeyboardEvent as ReactKeyboardEvent, useCallback, useEffect, use
|
||||||
import { Editor } from 'slate';
|
import { Editor } from 'slate';
|
||||||
import { Box, config, MenuItem, Text } from 'folds';
|
import { Box, config, MenuItem, Text } from 'folds';
|
||||||
import { Room } from 'matrix-js-sdk';
|
import { Room } from 'matrix-js-sdk';
|
||||||
|
import { useTranslation } from 'react-i18next';
|
||||||
import { Command, useCommands } from '../../hooks/useCommands';
|
import { Command, useCommands } from '../../hooks/useCommands';
|
||||||
import {
|
import {
|
||||||
AutocompleteMenu,
|
AutocompleteMenu,
|
||||||
|
|
@ -10,6 +11,7 @@ import {
|
||||||
moveCursor,
|
moveCursor,
|
||||||
replaceWithElement,
|
replaceWithElement,
|
||||||
} from '../../components/editor';
|
} from '../../components/editor';
|
||||||
|
import * as css from '../../components/editor/autocomplete/AutocompleteMenu.css';
|
||||||
import { UseAsyncSearchOptions, useAsyncSearch } from '../../hooks/useAsyncSearch';
|
import { UseAsyncSearchOptions, useAsyncSearch } from '../../hooks/useAsyncSearch';
|
||||||
import { useMatrixClient } from '../../hooks/useMatrixClient';
|
import { useMatrixClient } from '../../hooks/useMatrixClient';
|
||||||
import { useKeyDown } from '../../hooks/useKeyDown';
|
import { useKeyDown } from '../../hooks/useKeyDown';
|
||||||
|
|
@ -36,6 +38,7 @@ export function CommandAutocomplete({
|
||||||
query,
|
query,
|
||||||
requestClose,
|
requestClose,
|
||||||
}: CommandAutocompleteProps) {
|
}: CommandAutocompleteProps) {
|
||||||
|
const { t } = useTranslation();
|
||||||
const mx = useMatrixClient();
|
const mx = useMatrixClient();
|
||||||
const commands = useCommands(mx, room);
|
const commands = useCommands(mx, room);
|
||||||
const commandNames = useMemo(() => Object.keys(commands) as Command[], [commands]);
|
const commandNames = useMemo(() => Object.keys(commands) as Command[], [commands]);
|
||||||
|
|
@ -71,17 +74,11 @@ export function CommandAutocomplete({
|
||||||
});
|
});
|
||||||
|
|
||||||
return autoCompleteNames.length === 0 ? null : (
|
return autoCompleteNames.length === 0 ? null : (
|
||||||
<AutocompleteMenu
|
<AutocompleteMenu headerContent={t('Room.autocomplete_commands')} requestClose={requestClose}>
|
||||||
headerContent={
|
{autoCompleteNames.map((commandName, index) => (
|
||||||
<Box grow="Yes" direction="Row" gap="200" justifyContent="SpaceBetween">
|
|
||||||
<Text size="L400">Commands</Text>
|
|
||||||
</Box>
|
|
||||||
}
|
|
||||||
requestClose={requestClose}
|
|
||||||
>
|
|
||||||
{autoCompleteNames.map((commandName) => (
|
|
||||||
<MenuItem
|
<MenuItem
|
||||||
key={commandName}
|
key={commandName}
|
||||||
|
className={index === 0 ? css.AutocompleteActiveRow : undefined}
|
||||||
as="button"
|
as="button"
|
||||||
radii="300"
|
radii="300"
|
||||||
style={{ height: 'unset' }}
|
style={{ height: 'unset' }}
|
||||||
|
|
@ -97,7 +94,7 @@ export function CommandAutocomplete({
|
||||||
gap="100"
|
gap="100"
|
||||||
justifyContent="SpaceBetween"
|
justifyContent="SpaceBetween"
|
||||||
>
|
>
|
||||||
<Text style={{ flexGrow: 1 }} size="B400" truncate>
|
<Text className={css.AutocompleteMono} style={{ flexGrow: 1 }} size="B400" truncate>
|
||||||
{`/${commandName}`}
|
{`/${commandName}`}
|
||||||
</Text>
|
</Text>
|
||||||
<Text truncate priority="300" size="T200">
|
<Text truncate priority="300" size="T200">
|
||||||
|
|
|
||||||
|
|
@ -147,9 +147,9 @@ export const Mention = recipe({
|
||||||
base: [
|
base: [
|
||||||
DefaultReset,
|
DefaultReset,
|
||||||
{
|
{
|
||||||
backgroundColor: color.SurfaceVariant.Container,
|
// Flat Dawn pill — violet-tinted fill + lavender text, no boxShadow ring.
|
||||||
color: color.SurfaceVariant.OnContainer,
|
backgroundColor: 'rgba(149, 128, 255, 0.12)',
|
||||||
boxShadow: `0 0 0 ${config.borderWidth.B300} ${color.SurfaceVariant.ContainerLine}`,
|
color: color.Primary.MainHover,
|
||||||
padding: `0 ${toRem(2)}`,
|
padding: `0 ${toRem(2)}`,
|
||||||
borderRadius: config.radii.R300,
|
borderRadius: config.radii.R300,
|
||||||
fontWeight: config.fontWeight.W500,
|
fontWeight: config.fontWeight.W500,
|
||||||
|
|
@ -158,14 +158,14 @@ export const Mention = recipe({
|
||||||
variants: {
|
variants: {
|
||||||
highlight: {
|
highlight: {
|
||||||
true: {
|
true: {
|
||||||
backgroundColor: color.Success.Container,
|
// Self-mention reads as the fleet brand accent (not green status).
|
||||||
color: color.Success.OnContainer,
|
backgroundColor: color.Primary.Container,
|
||||||
boxShadow: `0 0 0 ${config.borderWidth.B300} ${color.Success.ContainerLine}`,
|
color: color.Primary.OnContainer,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
focus: {
|
focus: {
|
||||||
true: {
|
true: {
|
||||||
boxShadow: `0 0 0 ${config.borderWidth.B300} ${color.SurfaceVariant.OnContainer}`,
|
boxShadow: `0 0 0 ${config.borderWidth.B300} ${color.Primary.Main}`,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue