UI: rhythm (line heights)

This commit is contained in:
Enrico Ros
2023-12-29 01:01:10 -08:00
parent e80bc4cea7
commit 7da3b1f4c4
11 changed files with 43 additions and 27 deletions
+3 -2
View File
@@ -6,6 +6,7 @@ import { SxProps } from '@mui/joy/styles/types';
import CloseIcon from '@mui/icons-material/Close';
import { DConversationId, DEphemeral, useChatStore } from '~/common/state/store-chats';
import { lineHeightChatText } from '~/common/app.theme';
const StateLine = styled(Typography)(({ theme }) => ({
@@ -15,7 +16,7 @@ const StateLine = styled(Typography)(({ theme }) => ({
fontSize: theme.fontSize.xs,
fontFamily: theme.fontFamily.code,
marginLeft: theme.spacing(1),
lineHeight: 2,
lineHeight: lineHeightChatText,
}));
function isPrimitive(value: any): boolean {
@@ -93,7 +94,7 @@ function EphemeralItem({ conversationId, ephemeral }: { conversationId: string,
{/* Left pane (console) */}
<Grid xs={12} md={ephemeral.state ? 6 : 12}>
<Typography fontSize='smaller' sx={{ overflowWrap: 'anywhere', whiteSpace: 'break-spaces', lineHeight: 1.75 }}>
<Typography fontSize='smaller' sx={{ overflowWrap: 'anywhere', whiteSpace: 'break-spaces', lineHeight: lineHeightChatText }}>
{ephemeral.text}
</Typography>
</Grid>
@@ -26,6 +26,7 @@ import { DConversationId, useChatStore } from '~/common/state/store-chats';
import { SpeechResult, useSpeechRecognition } from '~/common/components/useSpeechRecognition';
import { countModelTokens } from '~/common/util/token-counter';
import { launchAppCall } from '~/common/app.routes';
import { lineHeightTextarea } from '~/common/app.theme';
import { playSoundUrl } from '~/common/util/audioUtils';
import { supportsClipboardRead } from '~/common/util/clipboardUtils';
import { useDebouncer } from '~/common/components/useDebouncer';
@@ -465,7 +466,7 @@ export function Composer(props: {
'&:focus-within': {
backgroundColor: 'background.popup',
},
lineHeight: 1.75,
lineHeight: lineHeightTextarea,
}} />
{tokenLimit > 0 && (tokensComposer > 0 || (tokensHistory + tokensReponseMax) > 0) && (
@@ -3,7 +3,7 @@ import TimeAgo from 'react-timeago';
import { shallow } from 'zustand/shallow';
import { cleanupEfficiency, Diff as TextDiff, makeDiff } from '@sanity/diff-match-patch';
import { Avatar, Box, Button, CircularProgress, IconButton, ListDivider, ListItem, ListItemDecorator, MenuItem, Stack, Switch, Tooltip, Typography } from '@mui/joy';
import { Avatar, Box, Button, CircularProgress, IconButton, ListDivider, ListItem, ListItemDecorator, MenuItem, Switch, Tooltip, Typography } from '@mui/joy';
import { SxProps } from '@mui/joy/styles/types';
import AccountTreeIcon from '@mui/icons-material/AccountTree';
import ClearIcon from '@mui/icons-material/Clear';
@@ -29,7 +29,7 @@ import { KeyStroke } from '~/common/components/KeyStroke';
import { Link } from '~/common/components/Link';
import { SystemPurposeId, SystemPurposes } from '../../../../data';
import { copyToClipboard } from '~/common/util/clipboardUtils';
import { cssRainbowColorKeyframes } from '~/common/app.theme';
import { cssRainbowColorKeyframes, lineHeightChatText } from '~/common/app.theme';
import { prettyBaseModel } from '~/common/util/modelUtils';
import { useUIPreferencesStore } from '~/common/state/store-ui';
@@ -409,15 +409,19 @@ export function ChatMessage(props: {
// per-blocks css
const blockSx: SxProps = {
my: 'auto',
lineHeight: lineHeightChatText,
};
const typographySx: SxProps = {
lineHeight: lineHeightChatText,
};
const codeSx: SxProps = {
// backgroundColor: fromAssistant ? 'background.level1' : 'background.level1',
backgroundColor: props.codeBackground ? props.codeBackground : fromAssistant ? 'neutral.plainHoverBg' : 'primary.plainActiveBg',
boxShadow: 'xs',
fontFamily: 'code',
fontSize: '14px',
fontSize: '0.875rem',
fontVariantLigatures: 'none',
lineHeight: 1.75,
lineHeight: lineHeightChatText,
borderRadius: 'var(--joy-radius-sm)',
};
@@ -482,7 +486,12 @@ export function ChatMessage(props: {
{/* Edit / Blocks */}
{isEditing
? <InlineTextarea initialText={messageText} onEdit={handleTextEdited} sx={{ ...blockSx, lineHeight: 1.75, flexGrow: 1 }} />
? <InlineTextarea
initialText={messageText} onEdit={handleTextEdited}
sx={{
...blockSx,
flexGrow: 1,
}} />
: <Box
onContextMenu={(ENABLE_SELECTION_RIGHT_CLICK_MENU && props.onMessageEdit) ? event => handleMouseUp(event.nativeEvent) : undefined}
@@ -526,12 +535,12 @@ export function ChatMessage(props: {
: block.type === 'image'
? <RenderImage key={'image-' + index} imageBlock={block} isFirst={!index} allowRunAgain={props.isBottom === true} onRunAgain={handleOpsConversationRestartFrom} />
: block.type === 'latex'
? <RenderLatex key={'latex-' + index} latexBlock={block} />
? <RenderLatex key={'latex-' + index} latexBlock={block} sx={typographySx} />
: block.type === 'diff'
? <RenderTextDiff key={'latex-' + index} diffBlock={block} />
? <RenderTextDiff key={'latex-' + index} diffBlock={block} sx={typographySx} />
: (renderMarkdown && props.noMarkdown !== true && !fromSystem && !(fromUser && block.content.startsWith('/')))
? <RenderMarkdown key={'text-md-' + index} textBlock={block} />
: <RenderText key={'text-' + index} textBlock={block} />)}
? <RenderMarkdown key={'text-md-' + index} textBlock={block} sx={typographySx} />
: <RenderText key={'text-' + index} textBlock={block} sx={typographySx} />)}
{isCollapsed && (
<Button variant='plain' color='neutral' onClick={handleUncollapse}>... expand ...</Button>
@@ -17,7 +17,6 @@ const RenderLatexDynamic = React.lazy(async () => {
export const RenderLatex = ({ latexBlock, sx }: { latexBlock: LatexBlock; sx?: SxProps; }) =>
<Box
sx={{
lineHeight: 1.75,
mx: 1.5,
...(sx || {}),
}}>
@@ -1,15 +1,16 @@
import * as React from 'react';
import type { SxProps } from '@mui/joy/styles/types';
import { Box, useTheme } from '@mui/joy';
import { TextBlock } from './blocks';
import type { TextBlock } from './blocks';
// Dynamically import ReactMarkdown using React.lazy
const ReactMarkdown = React.lazy(async () => {
const [markdownModule, remarkGfmModule] = await Promise.all([
import('react-markdown'),
import('remark-gfm')
import('remark-gfm'),
]);
// Pass the dynamically imported remarkGfm as children
@@ -21,7 +22,7 @@ const ReactMarkdown = React.lazy(async () => {
});
export const RenderMarkdown = ({ textBlock }: { textBlock: TextBlock }) => {
export const RenderMarkdown = (props: { textBlock: TextBlock, sx?: SxProps }) => {
const theme = useTheme();
return (
<Box
@@ -30,13 +31,15 @@ export const RenderMarkdown = ({ textBlock }: { textBlock: TextBlock }) => {
mx: '12px !important', // margin: 1.5 like other blocks
'& table': { width: 'inherit !important' }, // un-break auto-width (tables have 'max-content', which overflows)
'--color-canvas-default': 'transparent !important', // remove the default background color
fontFamily: `inherit !important`, // use the default font family
lineHeight: '1.75 !important', // line-height: 1.75 like the text block
// NOTE: the following are not needed because the CSS is under our control, and we
// disabled the redefintions there
// fontFamily: `inherit !important`, // use the default font family
...(props.sx || {}),
}}>
{/* Using React.Suspense / React.Lazy loading this */}
<React.Suspense fallback={<div>Loading...</div>}>
<ReactMarkdown>{textBlock.content}</ReactMarkdown>
<ReactMarkdown>{props.textBlock.content}</ReactMarkdown>
</React.Suspense>
</Box>
);
@@ -13,7 +13,6 @@ export const RenderText = ({ textBlock, sx }: { textBlock: TextBlock; sx?: SxPro
return (
<Typography
sx={{
lineHeight: 1.75,
mx: 1.5,
display: 'flex', alignItems: 'baseline',
overflowWrap: 'anywhere',
@@ -38,14 +38,13 @@ export const RenderTextDiff = ({ diffBlock, sx }: { diffBlock: DiffBlock; sx?: S
return (
<Typography
sx={{
lineHeight: 1.75,
mx: 1.5,
// display: 'flex', alignItems: 'baseline',
overflowWrap: 'anywhere',
whiteSpace: 'break-spaces',
...(sx || {}),
display: 'block',
zIndex: 200,
...(sx || {}),
}}
>
{textDiffs.map(([op, text], index) =>
@@ -7,6 +7,7 @@ import SearchIcon from '@mui/icons-material/Search';
import TelegramIcon from '@mui/icons-material/Telegram';
import { DConversationId, useChatStore } from '~/common/state/store-chats';
import { lineHeightTextarea } from '~/common/app.theme';
import { navigateToPersonas } from '~/common/app.routes';
import { useUIPreferencesStore } from '~/common/state/store-ui';
@@ -268,7 +269,7 @@ export function PersonaSelector(props: { conversationId: DConversationId, runExa
'&:focus-within': {
backgroundColor: 'background.popup',
},
lineHeight: 1.75,
lineHeight: lineHeightTextarea,
mt: 1,
}} />
)}
+3 -2
View File
@@ -10,6 +10,7 @@ import { GoodModal } from '~/common/components/GoodModal';
import { GoodTooltip } from '~/common/components/GoodTooltip';
import { apiQuery } from '~/common/util/trpc.client';
import { copyToClipboard } from '~/common/util/clipboardUtils';
import { lineHeightChatText, lineHeightTextarea } from '~/common/app.theme';
import { useFormRadioLlmType } from '~/common/components/forms/useFormRadioLlmType';
import { LLMChainStep, useLLMChain } from './useLLMChain';
@@ -174,7 +175,7 @@ export function PersonaCreator() {
'&:focus-within': {
backgroundColor: 'background.popup',
},
lineHeight: 1.75,
lineHeight: lineHeightTextarea,
mb: 1.5,
}}
/>
@@ -219,7 +220,7 @@ export function PersonaCreator() {
<Alert variant='soft' color='success' sx={{ mb: 1 }}>
You may now copy the text below and use it as Custom prompt!
</Alert>
<Typography level='title-sm' sx={{ lineHeight: 1.75 }}>
<Typography level='title-sm' sx={{ lineHeight: lineHeightChatText }}>
{chainOutput}
</Typography>
</CardContent>
+3
View File
@@ -146,6 +146,9 @@ export const themeBgApp = 'background.level1';
export const themeBgAppDarker = 'background.level2';
export const themeBgAppChatComposer = 'background.surface';
export const lineHeightChatText = 1.75;
export const lineHeightTextarea = 1.75;
export const bodyFontClassName = inter.className;
export const themeBreakpoints = appTheme.breakpoints.values;
@@ -11,6 +11,7 @@ import { FormLabelStart } from '~/common/components/forms/FormLabelStart';
import { GoodModal } from '~/common/components/GoodModal';
import { Section } from '~/common/components/Section';
import { countModelTokens } from '~/common/util/token-counter';
import { lineHeightTextarea } from '~/common/app.theme';
import { summerizeToFitContextBudget } from './summerize';
@@ -141,8 +142,7 @@ export function ContentReducer(props: {
minRows={4} maxRows={8}
value={reducedText}
sx={{
fontSize: '14px',
lineHeight: 1.75,
lineHeight: lineHeightTextarea,
}} />
<TokenBadgeMemo direct={reducedTokens} limit={props.tokenLimit} absoluteBottomRight />