From 65750272d5b65a1ad842d3d9cab70d4e3606628a Mon Sep 17 00:00:00 2001 From: leo-paz Date: Tue, 12 Nov 2024 01:12:34 -0500 Subject: [PATCH 1/5] fix: no key on TokenizedText --- src/components/AnimatedMarkdown.tsx | 39 +++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/src/components/AnimatedMarkdown.tsx b/src/components/AnimatedMarkdown.tsx index a05998d..3d8baa3 100644 --- a/src/components/AnimatedMarkdown.tsx +++ b/src/components/AnimatedMarkdown.tsx @@ -120,6 +120,37 @@ export const customCodeRenderer = ({ animation, animationDuration, animationTimi )); }; +/** + * A React component that renders markdown content with customizable animations. + * + * @component + * @example + * ```tsx + * + * 'custom': ({ id }: { id: string }) => {id}, + * '/regex/': ({ children }: { children: React.ReactNode }) =>
  • {children}
  • , + * }} + * /> + * ``` + * + * @param {Object} props + * @param {string} props.content - The markdown content to render + * @param {'word' | 'char'} [props.sep='word'] - Separator for animation ('word' or 'char') + * @param {string | null} [props.animation='fadeIn'] - The animation name to apply (set to null to disable) + * @param {string} [props.animationDuration='1s'] - Duration of the animation + * @param {string} [props.animationTimingFunction='ease-in-out'] - Timing function for the animation + * @param {Object} [props.codeStyle=null] - Custom style for code blocks + * @param {Object} [props.htmlComponents={}] - Custom HTML component overrides + * @param {Object} [props.customComponents={}] - Custom component patterns to match and render + * + * @returns {JSX.Element} Animated markdown content + */ const MarkdownAnimateText: React.FC = ({ content, sep = "word", @@ -178,11 +209,15 @@ const MarkdownAnimateText: React.FC = ({ let parts: React.ReactNode[] = []; let lastIndex = 0; + const instanceId = React.useId(); + let tokenCounter = 0; + // Use matchAll to find each match and its position for (const match of remainingText.matchAll(regex)) { // Add the substring before the match if (match.index > lastIndex) { parts.push( = ({ }, {}); parts.push( = ({ } else { // For non-HTML regex matches, just pass the content parts.push(} sep={sep} animation={animation} @@ -251,6 +288,7 @@ const MarkdownAnimateText: React.FC = ({ if (beforePartial) { parts.push( = ({ } } else { parts.push( Date: Tue, 12 Nov 2024 01:13:11 -0500 Subject: [PATCH 2/5] update README example --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 88cb0c5..7c70265 100644 --- a/README.md +++ b/README.md @@ -97,7 +97,7 @@ export default function Chat() { ### Custom Components -You can use custom components by passing a `customComponents` prop to the `AnimatedMarkdown` component where the key is the regex pattern (ex. `/\{\{.*?\}\}/`) or HTML tag (ex. `MyComponent`) to match and the value is the component to render. Then just prompt your LLM to output the custom component syntax and it will be rendered with your custom component. +You can use custom components by passing a `customComponents` prop to the `AnimatedMarkdown` component where the key is the regex pattern (ex. `/\{\{.*?\}\}/`) or HTML tag (ex. `MyComponent` for ``) to match and the value is the component to render. Then just prompt your LLM to output the custom component syntax and it will be rendered with your custom component. #### Example From 9429a3889f67e4fe4aa87aa076485655d92d9f2c Mon Sep 17 00:00:00 2001 From: leo-paz Date: Tue, 12 Nov 2024 01:26:45 -0500 Subject: [PATCH 3/5] version bump --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 9fe7a34..28aa66b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "flowtoken", - "version": "1.0.17", + "version": "1.0.18", "description": "", "main": "dist/index.js", "scripts": { From 0df4ac366d992858bfe04d8dd9940d36cae49914 Mon Sep 17 00:00:00 2001 From: leo-paz Date: Tue, 12 Nov 2024 17:32:17 -0500 Subject: [PATCH 4/5] removing key property causing flickering... --- src/components/AnimatedMarkdown.tsx | 21 ++++++--------------- 1 file changed, 6 insertions(+), 15 deletions(-) diff --git a/src/components/AnimatedMarkdown.tsx b/src/components/AnimatedMarkdown.tsx index 3d8baa3..84ea0ea 100644 --- a/src/components/AnimatedMarkdown.tsx +++ b/src/components/AnimatedMarkdown.tsx @@ -209,21 +209,17 @@ const MarkdownAnimateText: React.FC = ({ let parts: React.ReactNode[] = []; let lastIndex = 0; - const instanceId = React.useId(); - let tokenCounter = 0; - // Use matchAll to find each match and its position for (const match of remainingText.matchAll(regex)) { // Add the substring before the match if (match.index > lastIndex) { parts.push(); } // Add the match itself - either as custom component or tokenized text @@ -246,9 +242,7 @@ const MarkdownAnimateText: React.FC = ({ } return acc; }, {}); - parts.push( = ({ } else { // For non-HTML regex matches, just pass the content parts.push(} sep={sep} animation={animation} @@ -288,7 +281,6 @@ const MarkdownAnimateText: React.FC = ({ if (beforePartial) { parts.push( = ({ } } else { parts.push( Date: Tue, 12 Nov 2024 17:35:02 -0500 Subject: [PATCH 5/5] linting --- src/components/AnimatedMarkdown.tsx | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/components/AnimatedMarkdown.tsx b/src/components/AnimatedMarkdown.tsx index 84ea0ea..12d5915 100644 --- a/src/components/AnimatedMarkdown.tsx +++ b/src/components/AnimatedMarkdown.tsx @@ -214,13 +214,13 @@ const MarkdownAnimateText: React.FC = ({ // Add the substring before the match if (match.index > lastIndex) { parts.push(); + input={remainingText.slice(lastIndex, match.index)} + sep={sep} + animation={animation} + animationDuration={animationDuration} + animationTimingFunction={animationTimingFunction} + animationIterationCount={1} + />); } // Add the match itself - either as custom component or tokenized text const matchText = match[0];