From 7da3b1f4c46fdd970f8a10fdbafbba8563d86a80 Mon Sep 17 00:00:00 2001 From: Enrico Ros Date: Fri, 29 Dec 2023 01:01:10 -0800 Subject: [PATCH] UI: rhythm (line heights) --- src/apps/chat/components/Ephemerals.tsx | 5 ++-- .../chat/components/composer/Composer.tsx | 3 ++- .../chat/components/message/ChatMessage.tsx | 27 ++++++++++++------- .../chat/components/message/RenderLatex.tsx | 1 - .../components/message/RenderMarkdown.tsx | 15 ++++++----- .../chat/components/message/RenderText.tsx | 1 - .../components/message/RenderTextDiff.tsx | 3 +-- .../persona-selector/PersonaSelector.tsx | 3 ++- src/apps/personas/PersonaCreator.tsx | 5 ++-- src/common/app.theme.ts | 3 +++ src/modules/aifn/summarize/ContentReducer.tsx | 4 +-- 11 files changed, 43 insertions(+), 27 deletions(-) diff --git a/src/apps/chat/components/Ephemerals.tsx b/src/apps/chat/components/Ephemerals.tsx index 1ed297bfa..30a5ed24b 100644 --- a/src/apps/chat/components/Ephemerals.tsx +++ b/src/apps/chat/components/Ephemerals.tsx @@ -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) */} - + {ephemeral.text} diff --git a/src/apps/chat/components/composer/Composer.tsx b/src/apps/chat/components/composer/Composer.tsx index d1e43f926..61a20c8c5 100644 --- a/src/apps/chat/components/composer/Composer.tsx +++ b/src/apps/chat/components/composer/Composer.tsx @@ -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) && ( diff --git a/src/apps/chat/components/message/ChatMessage.tsx b/src/apps/chat/components/message/ChatMessage.tsx index e1ea2b5e7..8d586f1d7 100644 --- a/src/apps/chat/components/message/ChatMessage.tsx +++ b/src/apps/chat/components/message/ChatMessage.tsx @@ -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 - ? + ? : handleMouseUp(event.nativeEvent) : undefined} @@ -526,12 +535,12 @@ export function ChatMessage(props: { : block.type === 'image' ? : block.type === 'latex' - ? + ? : block.type === 'diff' - ? + ? : (renderMarkdown && props.noMarkdown !== true && !fromSystem && !(fromUser && block.content.startsWith('/'))) - ? - : )} + ? + : )} {isCollapsed && ( diff --git a/src/apps/chat/components/message/RenderLatex.tsx b/src/apps/chat/components/message/RenderLatex.tsx index 8449bace3..fb3814c98 100644 --- a/src/apps/chat/components/message/RenderLatex.tsx +++ b/src/apps/chat/components/message/RenderLatex.tsx @@ -17,7 +17,6 @@ const RenderLatexDynamic = React.lazy(async () => { export const RenderLatex = ({ latexBlock, sx }: { latexBlock: LatexBlock; sx?: SxProps; }) => diff --git a/src/apps/chat/components/message/RenderMarkdown.tsx b/src/apps/chat/components/message/RenderMarkdown.tsx index 972fb951e..fddb8c331 100644 --- a/src/apps/chat/components/message/RenderMarkdown.tsx +++ b/src/apps/chat/components/message/RenderMarkdown.tsx @@ -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 ( { 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 */} Loading...}> - {textBlock.content} + {props.textBlock.content} ); diff --git a/src/apps/chat/components/message/RenderText.tsx b/src/apps/chat/components/message/RenderText.tsx index 3fa7cd899..7bbacae8e 100644 --- a/src/apps/chat/components/message/RenderText.tsx +++ b/src/apps/chat/components/message/RenderText.tsx @@ -13,7 +13,6 @@ export const RenderText = ({ textBlock, sx }: { textBlock: TextBlock; sx?: SxPro return ( {textDiffs.map(([op, text], index) => diff --git a/src/apps/chat/components/persona-selector/PersonaSelector.tsx b/src/apps/chat/components/persona-selector/PersonaSelector.tsx index f0cbc906f..25bde5e14 100644 --- a/src/apps/chat/components/persona-selector/PersonaSelector.tsx +++ b/src/apps/chat/components/persona-selector/PersonaSelector.tsx @@ -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, }} /> )} diff --git a/src/apps/personas/PersonaCreator.tsx b/src/apps/personas/PersonaCreator.tsx index bbf0a22e1..7efa77f80 100644 --- a/src/apps/personas/PersonaCreator.tsx +++ b/src/apps/personas/PersonaCreator.tsx @@ -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() { You may now copy the text below and use it as Custom prompt! - + {chainOutput} diff --git a/src/common/app.theme.ts b/src/common/app.theme.ts index dca579338..89d0e6cc5 100644 --- a/src/common/app.theme.ts +++ b/src/common/app.theme.ts @@ -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; diff --git a/src/modules/aifn/summarize/ContentReducer.tsx b/src/modules/aifn/summarize/ContentReducer.tsx index 0049f118e..b589e2e69 100644 --- a/src/modules/aifn/summarize/ContentReducer.tsx +++ b/src/modules/aifn/summarize/ContentReducer.tsx @@ -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, }} />