Skip to content

Commit

Permalink
fix: break out inline-defined components
Browse files Browse the repository at this point in the history
  • Loading branch information
stefl committed Nov 28, 2024
1 parent eca0019 commit 852fed1
Show file tree
Hide file tree
Showing 2 changed files with 135 additions and 125 deletions.
196 changes: 99 additions & 97 deletions apps/nextjs/src/components/AppComponents/Chat/markdown.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { FC } from "react";
import React, { memo } from "react";
import type { Options } from "react-markdown";
import React, { memo, useMemo } from "react";
import type { Components, Options } from "react-markdown";
import ReactMarkdown from "react-markdown";

import * as Tooltip from "@radix-ui/react-tooltip";
Expand All @@ -24,110 +24,112 @@ export type ReactMarkdownWithStylesProps = Readonly<{
className?: string;
}>;

const createComponents = (
className?: string,
lessonPlanSectionDescription?: string,
): Partial<Components> => ({
li: ({ children }) => (
<li className={cn("marker:text-black", className)}>{children}</li>
),
p: ({ children }) => (
<p className={cn("mb-7 last:mb-0", className)}>{children}</p>
),
h1: ({ children }) => (
<Flex align="center" gap="3" className="mt-20">
<Box>
<h2 className="mb-0 mt-0 text-xl font-bold">{children}</h2>
</Box>
{!!lessonPlanSectionDescription && (
<Tooltip.Provider delayDuration={0}>
<Tooltip.Root>
<Tooltip.Trigger asChild>
<Box className="mb-0 mt-0 ">
<button className="my-0 flex h-[24px] w-[24px] items-center justify-center overflow-hidden rounded-full bg-black p-4 ">
<span className=" p-3 text-xs text-white">i</span>
</button>
</Box>
</Tooltip.Trigger>
<Tooltip.Portal>
<Tooltip.Content
className="max-w-[300px] rounded-lg bg-black p-7 text-center text-sm text-white"
sideOffset={5}
>
{lessonPlanSectionDescription}
<Tooltip.Arrow className="TooltipArrow" />
</Tooltip.Content>
</Tooltip.Portal>
</Tooltip.Root>
</Tooltip.Provider>
)}
</Flex>
),
code: (props) => {
const {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
node,
className,
children,
inline,
...restProps
} = props as {
node?: React.ReactNode;
inline?: boolean;
className?: string;
children?: React.ReactNode;
};
if (children && Array.isArray(children) && children.length) {
if (children[0] == "▍") {
return <span className="mt-5 animate-pulse cursor-default"></span>;
}

children[0] = (children[0] as string).replace("`▍`", "▍");
}

const match = /language-(\w+)/.exec(className ?? "");

if (inline) {
return (
<code className={className} {...restProps}>
{children}
</code>
);
}

return (
<CodeBlock
key={Math.random()}
language={match?.[1] ?? ""}
value={String(children).replace(/\n$/, "")}
{...restProps}
/>
);
},
a: ({ children, href }) => {
const isExternal = href?.startsWith("http");
const tags = isExternal
? { target: "_blank", rel: "noopener noreferrer" }
: {};
return (
<a href={href} {...tags}>
{children}
</a>
);
},
});

export const MemoizedReactMarkdownWithStyles = ({
markdown,
lessonPlanSectionDescription,
className,
}: ReactMarkdownWithStylesProps) => {
const components: Partial<Components> = useMemo(() => {
return createComponents(className, lessonPlanSectionDescription);
}, [className, lessonPlanSectionDescription]);
return (
<MemoizedReactMarkdown
className="prose break-words dark:prose-invert prose-p:leading-relaxed prose-pre:p-0"
remarkPlugins={[remarkGfm]}
components={{
li({ children }) {
return (
<li className={cn("marker:text-black", className)}>{children}</li>
);
},
p({ children }) {
return <p className={cn("mb-7 last:mb-0", className)}>{children}</p>;
},
h1({ children }) {
return (
<Flex align="center" gap="3" className="mt-20">
<Box>
<h2 className="mb-0 mt-0 text-xl font-bold">{children}</h2>
</Box>
{!!lessonPlanSectionDescription && (
<Tooltip.Provider delayDuration={0}>
<Tooltip.Root>
<Tooltip.Trigger asChild>
<Box className="mb-0 mt-0 ">
<button className="my-0 flex h-[24px] w-[24px] items-center justify-center overflow-hidden rounded-full bg-black p-4 ">
<span className=" p-3 text-xs text-white">i</span>
</button>
</Box>
</Tooltip.Trigger>
<Tooltip.Portal>
<Tooltip.Content
className="max-w-[300px] rounded-lg bg-black p-7 text-center text-sm text-white"
sideOffset={5}
>
{lessonPlanSectionDescription}
<Tooltip.Arrow className="TooltipArrow" />
</Tooltip.Content>
</Tooltip.Portal>
</Tooltip.Root>
</Tooltip.Provider>
)}
</Flex>
);
},
code(props) {
const {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
node,
className,
children,
inline,
...restProps
} = props as {
node?: React.ReactNode;
inline?: boolean;
className?: string;
children?: React.ReactNode;
};
if (children && Array.isArray(children) && children.length) {
if (children[0] == "▍") {
return (
<span className="mt-5 animate-pulse cursor-default"></span>
);
}

children[0] = (children[0] as string).replace("`▍`", "▍");
}

const match = /language-(\w+)/.exec(className ?? "");

if (inline) {
return (
<code className={className} {...restProps}>
{children}
</code>
);
}

return (
<CodeBlock
key={Math.random()}
language={match?.[1] ?? ""}
value={String(children).replace(/\n$/, "")}
{...restProps}
/>
);
},
a({ children, href }) {
const isExternal = href?.startsWith("http");
const tags = isExternal
? { target: "_blank", rel: "noopener noreferrer" }
: {};
return (
<a href={href} {...tags}>
{children}
</a>
);
},
}}
components={components}
>
{markdown}
</MemoizedReactMarkdown>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useState } from "react";
import { useCallback, useState } from "react";

import { aiLogger } from "@oakai/logger";
import {
Expand Down Expand Up @@ -36,31 +36,43 @@ const ReportContentDialog = ({
surveyName: "Report Content",
});

function close() {
const close = useCallback(() =>{
closeDialog();
closeDialogWithPostHogDismiss();
}
}, [closeDialog, closeDialogWithPostHogDismiss]);

function onSubmit(
e?: React.FormEvent<HTMLFormElement> | React.MouseEvent<HTMLButtonElement>,
) {
log.info("submitting");
e?.preventDefault();
setUserHasSubmitted(true);
submitSurveyWithOutClosing({
//Messages Array
$survey_response: messages ?? "No chat history",
// Last Message Id
$survey_response_1: messages
? messages[messages.length - 1]?.id
: "No chat history",
// Chat Id
$survey_response_2: chatId,
// Comment
$survey_response_3: userInput,
});
setUserInput("");
}
const onSubmit = useCallback(
(
e?:
| React.FormEvent<HTMLFormElement>
| React.MouseEvent<HTMLButtonElement>,
) => {
log.info("submitting");
e?.preventDefault();
setUserHasSubmitted(true);
submitSurveyWithOutClosing({
//Messages Array
$survey_response: messages ?? "No chat history",
// Last Message Id
$survey_response_1: messages
? messages[messages.length - 1]?.id
: "No chat history",
// Chat Id
$survey_response_2: chatId,
// Comment
$survey_response_3: userInput,
});
setUserInput("");
},
[chatId, messages, submitSurveyWithOutClosing, userInput],
);

const actionButtonStates = useCallback(
() => (
<OakPrimaryButton onClick={onSubmit}>Submit feedback</OakPrimaryButton>
),
[onSubmit],
);

return (
<Flex className="h-full w-full" direction="column" justify="between">
Expand Down Expand Up @@ -96,11 +108,7 @@ const ReportContentDialog = ({
/>

<ModalFooterButtons
actionButtonStates={() => (
<OakPrimaryButton onClick={onSubmit}>
Submit feedback
</OakPrimaryButton>
)}
actionButtonStates={actionButtonStates}
closeDialog={close}
/>
</>
Expand Down

0 comments on commit 852fed1

Please sign in to comment.