@dust-tt/sparkle 0.2.645 → 0.2.646-rc-2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (94) hide show
  1. package/dist/cjs/index.js +1 -1
  2. package/dist/esm/components/DataTable.d.ts +3 -13
  3. package/dist/esm/components/DataTable.d.ts.map +1 -1
  4. package/dist/esm/components/DataTable.js +8 -9
  5. package/dist/esm/components/DataTable.js.map +1 -1
  6. package/dist/esm/components/markdown/BlockquoteBlock.d.ts +3 -1
  7. package/dist/esm/components/markdown/BlockquoteBlock.d.ts.map +1 -1
  8. package/dist/esm/components/markdown/BlockquoteBlock.js +7 -3
  9. package/dist/esm/components/markdown/BlockquoteBlock.js.map +1 -1
  10. package/dist/esm/components/markdown/CodeBlockWithExtendedSupport.d.ts +4 -2
  11. package/dist/esm/components/markdown/CodeBlockWithExtendedSupport.d.ts.map +1 -1
  12. package/dist/esm/components/markdown/CodeBlockWithExtendedSupport.js +11 -6
  13. package/dist/esm/components/markdown/CodeBlockWithExtendedSupport.js.map +1 -1
  14. package/dist/esm/components/markdown/HeaderBlocks.d.ts +24 -0
  15. package/dist/esm/components/markdown/HeaderBlocks.d.ts.map +1 -0
  16. package/dist/esm/components/markdown/HeaderBlocks.js +54 -0
  17. package/dist/esm/components/markdown/HeaderBlocks.js.map +1 -0
  18. package/dist/esm/components/markdown/InputBlock.d.ts +10 -0
  19. package/dist/esm/components/markdown/InputBlock.d.ts.map +1 -0
  20. package/dist/esm/components/markdown/InputBlock.js +26 -0
  21. package/dist/esm/components/markdown/InputBlock.js.map +1 -0
  22. package/dist/esm/components/markdown/LinkBlock.d.ts +10 -0
  23. package/dist/esm/components/markdown/LinkBlock.d.ts.map +1 -0
  24. package/dist/esm/components/markdown/LinkBlock.js +11 -0
  25. package/dist/esm/components/markdown/LinkBlock.js.map +1 -0
  26. package/dist/esm/components/markdown/List.d.ts +17 -3
  27. package/dist/esm/components/markdown/List.d.ts.map +1 -1
  28. package/dist/esm/components/markdown/List.js +21 -7
  29. package/dist/esm/components/markdown/List.js.map +1 -1
  30. package/dist/esm/components/markdown/Markdown.d.ts +2 -9
  31. package/dist/esm/components/markdown/Markdown.d.ts.map +1 -1
  32. package/dist/esm/components/markdown/Markdown.js +45 -66
  33. package/dist/esm/components/markdown/Markdown.js.map +1 -1
  34. package/dist/esm/components/markdown/ParagraphBlock.d.ts +3 -1
  35. package/dist/esm/components/markdown/ParagraphBlock.d.ts.map +1 -1
  36. package/dist/esm/components/markdown/ParagraphBlock.js +7 -3
  37. package/dist/esm/components/markdown/ParagraphBlock.js.map +1 -1
  38. package/dist/esm/components/markdown/PreBlock.d.ts +3 -1
  39. package/dist/esm/components/markdown/PreBlock.d.ts.map +1 -1
  40. package/dist/esm/components/markdown/PreBlock.js +7 -3
  41. package/dist/esm/components/markdown/PreBlock.js.map +1 -1
  42. package/dist/esm/components/markdown/TableBlock.d.ts +17 -11
  43. package/dist/esm/components/markdown/TableBlock.d.ts.map +1 -1
  44. package/dist/esm/components/markdown/TableBlock.js +18 -14
  45. package/dist/esm/components/markdown/TableBlock.js.map +1 -1
  46. package/dist/esm/components/markdown/TextFormattingBlocks.d.ts +10 -0
  47. package/dist/esm/components/markdown/TextFormattingBlocks.d.ts.map +1 -0
  48. package/dist/esm/components/markdown/TextFormattingBlocks.js +12 -0
  49. package/dist/esm/components/markdown/TextFormattingBlocks.js.map +1 -0
  50. package/dist/esm/components/markdown/index.d.ts +4 -0
  51. package/dist/esm/components/markdown/index.d.ts.map +1 -1
  52. package/dist/esm/components/markdown/index.js +4 -0
  53. package/dist/esm/components/markdown/index.js.map +1 -1
  54. package/dist/esm/components/markdown/types.d.ts +13 -0
  55. package/dist/esm/components/markdown/types.d.ts.map +1 -0
  56. package/dist/esm/components/markdown/types.js +2 -0
  57. package/dist/esm/components/markdown/types.js.map +1 -0
  58. package/dist/esm/components/markdown/useAnimatedText.d.ts +2 -0
  59. package/dist/esm/components/markdown/useAnimatedText.d.ts.map +1 -0
  60. package/dist/esm/components/markdown/useAnimatedText.js +31 -0
  61. package/dist/esm/components/markdown/useAnimatedText.js.map +1 -0
  62. package/dist/esm/components/markdown/utils.d.ts +11 -0
  63. package/dist/esm/components/markdown/utils.d.ts.map +1 -1
  64. package/dist/esm/components/markdown/utils.js +21 -0
  65. package/dist/esm/components/markdown/utils.js.map +1 -1
  66. package/dist/esm/stories/DataTable.stories.d.ts +0 -1
  67. package/dist/esm/stories/DataTable.stories.d.ts.map +1 -1
  68. package/dist/esm/stories/DataTable.stories.js +0 -188
  69. package/dist/esm/stories/DataTable.stories.js.map +1 -1
  70. package/dist/esm/styles/global.css +0 -12
  71. package/dist/esm/styles/global_with_tw_base.css +0 -12
  72. package/dist/esm/styles/tailwind.css +0 -11
  73. package/dist/sparkle.css +0 -34
  74. package/package.json +2 -1
  75. package/src/components/DataTable.tsx +2 -31
  76. package/src/components/markdown/BlockquoteBlock.tsx +36 -29
  77. package/src/components/markdown/CodeBlockWithExtendedSupport.tsx +142 -131
  78. package/src/components/markdown/HeaderBlocks.tsx +160 -0
  79. package/src/components/markdown/InputBlock.tsx +60 -0
  80. package/src/components/markdown/LinkBlock.tsx +36 -0
  81. package/src/components/markdown/List.tsx +53 -30
  82. package/src/components/markdown/Markdown.tsx +108 -171
  83. package/src/components/markdown/ParagraphBlock.tsx +18 -12
  84. package/src/components/markdown/PreBlock.tsx +28 -18
  85. package/src/components/markdown/TableBlock.tsx +125 -95
  86. package/src/components/markdown/TextFormattingBlocks.tsx +31 -0
  87. package/src/components/markdown/index.ts +4 -0
  88. package/src/components/markdown/types.ts +5 -0
  89. package/src/components/markdown/useAnimatedText.ts +36 -0
  90. package/src/components/markdown/utils.ts +37 -0
  91. package/src/stories/DataTable.stories.tsx +0 -235
  92. package/src/styles/global.css +0 -12
  93. package/src/styles/global_with_tw_base.css +0 -12
  94. package/src/styles/tailwind.css +0 -11
package/dist/sparkle.css CHANGED
@@ -5409,40 +5409,6 @@ select {
5409
5409
  mask-image: radial-gradient(white,black);
5410
5410
  }
5411
5411
 
5412
- .s-blinking-cursor > :not(pre):last-child::after {
5413
- content: "";
5414
- width: 8px;
5415
- height: 16px;
5416
- --tw-bg-opacity: 1;
5417
- background-color: rgb(145 193 116 / var(--tw-bg-opacity));
5418
- display: inline-block;
5419
- }
5420
-
5421
- @keyframes s-cursor-blink {
5422
- 0% {
5423
- opacity: 1;
5424
- }
5425
-
5426
- 60% {
5427
- opacity: 1;
5428
- }
5429
-
5430
- 70% {
5431
- opacity: 0;
5432
- }
5433
-
5434
- 100% {
5435
- opacity: 0;
5436
- }
5437
- }
5438
-
5439
- .s-blinking-cursor > :not(pre):last-child::after {
5440
- animation: s-cursor-blink 0.9s infinite;;
5441
- margin-left: 5px;
5442
- position: relative;
5443
- top: 4px;
5444
- }
5445
-
5446
5412
  @keyframes bgblink {
5447
5413
  0%,
5448
5414
  100% {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dust-tt/sparkle",
3
- "version": "0.2.645",
3
+ "version": "0.2.646-rc-2",
4
4
  "scripts": {
5
5
  "build": "rm -rf dist && npm run tailwind && npm run build:esm && npm run build:cjs",
6
6
  "tailwind": "tailwindcss -i ./src/styles/tailwind.css -o dist/sparkle.css",
@@ -118,6 +118,7 @@
118
118
  "class-variance-authority": "^0.7.1",
119
119
  "clsx": "^2.1.1",
120
120
  "emoji-mart": "^5.5.2",
121
+ "framer-motion": "^12.23.22",
121
122
  "lottie-react": "^2.4.0",
122
123
  "lottie-web": "^5.12.2",
123
124
  "mermaid": "^11.4.1",
@@ -961,14 +961,12 @@ export interface DataTableMoreButtonProps {
961
961
  React.ComponentPropsWithoutRef<typeof DropdownMenu>,
962
962
  "modal"
963
963
  >;
964
- disabled?: boolean;
965
964
  }
966
965
 
967
966
  DataTable.MoreButton = function MoreButton({
968
967
  className,
969
968
  menuItems,
970
969
  dropdownMenuProps,
971
- disabled,
972
970
  }: DataTableMoreButtonProps) {
973
971
  if (!menuItems?.length) {
974
972
  return null;
@@ -986,15 +984,11 @@ DataTable.MoreButton = function MoreButton({
986
984
  icon={MoreIcon}
987
985
  size="mini"
988
986
  variant="ghost-secondary"
989
- disabled={disabled}
990
- className={cn(
991
- disabled && "s-cursor-not-allowed s-opacity-50",
992
- className
993
- )}
987
+ className={cn(className)}
994
988
  />
995
989
  </DropdownMenuTrigger>
996
990
 
997
- <DropdownMenuContent align="end" hidden={disabled}>
991
+ <DropdownMenuContent align="end">
998
992
  <DropdownMenuGroup>
999
993
  {menuItems.map((item, index) => renderMenuItem(item, index))}
1000
994
  </DropdownMenuGroup>
@@ -1038,11 +1032,6 @@ interface CellContentProps extends React.TdHTMLAttributes<HTMLDivElement> {
1038
1032
  children?: ReactNode;
1039
1033
  description?: string;
1040
1034
  grow?: boolean;
1041
- disabled?: boolean;
1042
- avatarStack?: {
1043
- items: { name: string; visual: string }[];
1044
- nbVisibleItems?: number;
1045
- };
1046
1035
  }
1047
1036
 
1048
1037
  DataTable.CellContent = function CellContent({
@@ -1055,8 +1044,6 @@ DataTable.CellContent = function CellContent({
1055
1044
  iconClassName,
1056
1045
  description,
1057
1046
  grow = false,
1058
- disabled,
1059
- avatarStack,
1060
1047
  ...props
1061
1048
  }: CellContentProps) {
1062
1049
  return (
@@ -1064,10 +1051,8 @@ DataTable.CellContent = function CellContent({
1064
1051
  className={cn(
1065
1052
  "s-flex s-items-center",
1066
1053
  grow ? "s-flex-grow" : "",
1067
- disabled && "s-cursor-not-allowed s-opacity-50",
1068
1054
  className
1069
1055
  )}
1070
- aria-disabled={disabled || undefined}
1071
1056
  {...props}
1072
1057
  >
1073
1058
  {avatarUrl && avatarTooltipLabel && (
@@ -1091,14 +1076,6 @@ DataTable.CellContent = function CellContent({
1091
1076
  isRounded={roundedAvatar ?? false}
1092
1077
  />
1093
1078
  )}
1094
- {avatarStack && (
1095
- <Avatar.Stack
1096
- avatars={avatarStack.items}
1097
- nbVisibleItems={avatarStack.nbVisibleItems}
1098
- size="xs"
1099
- isRounded={roundedAvatar ?? false}
1100
- />
1101
- )}
1102
1079
  {icon && (
1103
1080
  <Icon
1104
1081
  visual={icon}
@@ -1140,7 +1117,6 @@ interface BasicCellContentProps extends React.TdHTMLAttributes<HTMLDivElement> {
1140
1117
  label: string | number;
1141
1118
  tooltip?: string | number;
1142
1119
  textToCopy?: string | number;
1143
- disabled?: boolean;
1144
1120
  }
1145
1121
 
1146
1122
  DataTable.BasicCellContent = function BasicCellContent({
@@ -1148,7 +1124,6 @@ DataTable.BasicCellContent = function BasicCellContent({
1148
1124
  tooltip,
1149
1125
  className,
1150
1126
  textToCopy,
1151
- disabled,
1152
1127
  ...props
1153
1128
  }: BasicCellContentProps) {
1154
1129
  const [isCopied, copyToClipboard] = useCopyToClipboard();
@@ -1175,10 +1150,8 @@ DataTable.BasicCellContent = function BasicCellContent({
1175
1150
  cellHeight,
1176
1151
  "s-group s-flex s-items-center s-gap-2 s-text-sm",
1177
1152
  "s-text-muted-foreground dark:s-text-muted-foreground-night",
1178
- disabled && "s-cursor-not-allowed s-opacity-50",
1179
1153
  className
1180
1154
  )}
1181
- aria-disabled={disabled || undefined}
1182
1155
  {...props}
1183
1156
  >
1184
1157
  <span className="s-truncate">{label}</span>
@@ -1204,10 +1177,8 @@ DataTable.BasicCellContent = function BasicCellContent({
1204
1177
  cellHeight,
1205
1178
  "s-group s-flex s-items-center s-gap-2 s-text-sm",
1206
1179
  "s-text-muted-foreground dark:s-text-muted-foreground-night",
1207
- disabled && "s-cursor-not-allowed s-opacity-50",
1208
1180
  className
1209
1181
  )}
1210
- aria-disabled={disabled || undefined}
1211
1182
  {...props}
1212
1183
  >
1213
1184
  <span className="s-truncate">{label}</span>
@@ -1,8 +1,11 @@
1
1
  import { cva } from "class-variance-authority";
2
- import React from "react";
2
+ import React, { memo } from "react";
3
3
 
4
4
  import { ContentBlockWrapper } from "@sparkle/components";
5
5
 
6
+ import { MarkdownNode } from "./types";
7
+ import { sameNodePosition } from "./utils";
8
+
6
9
  export const blockquoteVariants = cva(
7
10
  ["s-w-full s-text-base s-italic s-rounded-2xl s-py-3 s-pl-5 s-pr-12"],
8
11
  {
@@ -20,33 +23,37 @@ export const blockquoteVariants = cva(
20
23
  interface BlockquoteBlockProps {
21
24
  children: React.ReactNode;
22
25
  variant?: "surface";
26
+ node?: MarkdownNode;
23
27
  }
24
28
 
25
- export function BlockquoteBlock({
26
- children,
27
- variant = "surface",
28
- }: BlockquoteBlockProps) {
29
- const elementAt1 = React.Children.toArray(children)[1];
30
- const childrenContent =
31
- elementAt1 && React.isValidElement(elementAt1)
32
- ? elementAt1.props.children
33
- : null;
34
-
35
- // Convert array content to string if necessary
36
- const contentAsString = Array.isArray(childrenContent)
37
- ? childrenContent.join("")
38
- : childrenContent;
39
-
40
- // Only pass content if it exists
41
- const clipboardContent = contentAsString
42
- ? { "text/plain": contentAsString }
43
- : undefined;
44
-
45
- return (
46
- <ContentBlockWrapper content={clipboardContent} className="s-my-2">
47
- <blockquote className={blockquoteVariants({ variant })}>
48
- {children}
49
- </blockquote>
50
- </ContentBlockWrapper>
51
- );
52
- }
29
+ export const MemoBlockquoteBlock = memo(
30
+ ({ children, variant = "surface" }: BlockquoteBlockProps) => {
31
+ const elementAt1 = React.Children.toArray(children)[1];
32
+ const childrenContent =
33
+ elementAt1 && React.isValidElement(elementAt1)
34
+ ? elementAt1.props.children
35
+ : null;
36
+
37
+ // Convert array content to string if necessary
38
+ const contentAsString = Array.isArray(childrenContent)
39
+ ? childrenContent.join("")
40
+ : childrenContent;
41
+
42
+ // Only pass content if it exists
43
+ const clipboardContent = contentAsString
44
+ ? { "text/plain": contentAsString }
45
+ : undefined;
46
+
47
+ return (
48
+ <ContentBlockWrapper content={clipboardContent} className="s-my-2">
49
+ <blockquote className={blockquoteVariants({ variant })}>
50
+ {children}
51
+ </blockquote>
52
+ </ContentBlockWrapper>
53
+ );
54
+ },
55
+ (prev, next) =>
56
+ sameNodePosition(prev.node, next.node) && prev.variant === next.variant
57
+ );
58
+
59
+ MemoBlockquoteBlock.displayName = "BlockquoteBlock";
@@ -1,5 +1,5 @@
1
1
  import mermaid from "mermaid";
2
- import React, { useContext, useEffect, useRef, useState } from "react";
2
+ import React, { memo, useContext, useEffect, useRef, useState } from "react";
3
3
  import {
4
4
  amber,
5
5
  blue,
@@ -25,6 +25,8 @@ import {
25
25
  JsonValueType,
26
26
  PrettyJsonViewer,
27
27
  } from "@sparkle/components/markdown/PrettyJsonViewer";
28
+ import { MarkdownNode } from "@sparkle/components/markdown/types";
29
+ import { sameNodePosition } from "@sparkle/components/markdown/utils";
28
30
  import { CommandLineIcon, SparklesIcon } from "@sparkle/icons/app";
29
31
  import { cn } from "@sparkle/lib/utils";
30
32
 
@@ -313,150 +315,159 @@ export function StyledMermaidGraph({
313
315
  );
314
316
  }
315
317
 
316
- export function CodeBlockWithExtendedSupport({
317
- children,
318
- className,
319
- inline,
320
- }: {
321
- children?: React.ReactNode;
322
- className?: string;
323
- inline?: boolean;
324
- }) {
325
- const validChildrenContent = String(children).trim();
326
- const [showMermaid, setShowMermaid] = useState<boolean>(false);
327
- const [isValidMermaid, setIsValidMermaid] = useState<boolean>(false);
328
- const [showPrettyJson, setShowPrettyJson] = useState<boolean>(false);
329
- const [parsedJson, setParsedJson] = useState<JsonValueType | null>(null);
330
- const { isStreaming } = useContext(MarkdownContentContext);
331
-
332
- // Detect language from className
333
- const language = className?.split("-")[1];
334
-
335
- // Only create getContentToDownload when we actually want to enable downloads
336
- const getContentToDownload: GetContentToDownloadFunction | undefined =
337
- !inline &&
338
- validChildrenContent &&
339
- (language === "csv" || language === "json")
340
- ? async () => ({
341
- content: validChildrenContent,
342
- filename: `dust_output_${Date.now()}`,
343
- type: language === "csv" ? "text/csv" : "application/json",
344
- })
345
- : undefined;
346
-
347
- // Check for valid Mermaid and JSON.
348
- useEffect(() => {
349
- if (isStreaming || !validChildrenContent) {
350
- return;
351
- }
352
- if (language === "mermaid") {
353
- const checkValidMermaid = async () => {
318
+ export const MemoCodeBlockWithExtendedSupport = memo(
319
+ ({
320
+ children,
321
+ className,
322
+ inline,
323
+ }: {
324
+ children?: React.ReactNode;
325
+ className?: string;
326
+ inline?: boolean;
327
+ node?: MarkdownNode;
328
+ }) => {
329
+ const validChildrenContent = String(children).trim();
330
+ const [showMermaid, setShowMermaid] = useState<boolean>(false);
331
+ const [isValidMermaid, setIsValidMermaid] = useState<boolean>(false);
332
+ const [showPrettyJson, setShowPrettyJson] = useState<boolean>(false);
333
+ const [parsedJson, setParsedJson] = useState<JsonValueType | null>(null);
334
+ const { isStreaming } = useContext(MarkdownContentContext);
335
+
336
+ // Detect language from className
337
+ const language = className?.split("-")[1];
338
+
339
+ // Only create getContentToDownload when we actually want to enable downloads
340
+ const getContentToDownload: GetContentToDownloadFunction | undefined =
341
+ !inline &&
342
+ validChildrenContent &&
343
+ (language === "csv" || language === "json")
344
+ ? async () => ({
345
+ content: validChildrenContent,
346
+ filename: `dust_output_${Date.now()}`,
347
+ type: language === "csv" ? "text/csv" : "application/json",
348
+ })
349
+ : undefined;
350
+
351
+ // Check for valid Mermaid and JSON.
352
+ useEffect(() => {
353
+ if (isStreaming || !validChildrenContent) {
354
+ return;
355
+ }
356
+ if (language === "mermaid") {
357
+ const checkValidMermaid = async () => {
358
+ try {
359
+ await mermaid.parse(validChildrenContent);
360
+ setIsValidMermaid(true);
361
+ setShowMermaid(true);
362
+ } catch (e) {
363
+ setIsValidMermaid(false);
364
+ setShowMermaid(false);
365
+ }
366
+ };
367
+ void checkValidMermaid();
368
+ }
369
+ if (language === "json") {
354
370
  try {
355
- await mermaid.parse(validChildrenContent);
356
- setIsValidMermaid(true);
357
- setShowMermaid(true);
371
+ const parsed = JSON.parse(validChildrenContent);
372
+ setParsedJson(parsed);
373
+ const prettyJsonPreference = getPrettyJsonPreference();
374
+ setShowPrettyJson(prettyJsonPreference);
358
375
  } catch (e) {
359
- setIsValidMermaid(false);
360
- setShowMermaid(false);
376
+ setParsedJson(null);
377
+ setShowPrettyJson(false);
361
378
  }
362
- };
363
- void checkValidMermaid();
364
- }
365
- if (language === "json") {
366
- try {
367
- const parsed = JSON.parse(validChildrenContent);
368
- setParsedJson(parsed);
369
- const prettyJsonPreference = getPrettyJsonPreference();
370
- setShowPrettyJson(prettyJsonPreference);
371
- } catch (e) {
372
- setParsedJson(null);
373
- setShowPrettyJson(false);
374
379
  }
380
+ }, [isStreaming, language, validChildrenContent]);
381
+
382
+ if (inline) {
383
+ return (
384
+ <CodeBlock className={className} inline={inline}>
385
+ {children}
386
+ </CodeBlock>
387
+ );
375
388
  }
376
- }, [isStreaming, language, validChildrenContent]);
377
389
 
378
- if (inline) {
379
- return (
380
- <CodeBlock className={className} inline={inline}>
381
- {children}
382
- </CodeBlock>
383
- );
384
- }
390
+ if (isValidMermaid) {
391
+ return (
392
+ <ContentBlockWrapper
393
+ content={validChildrenContent}
394
+ getContentToDownload={getContentToDownload}
395
+ actions={
396
+ <Button
397
+ className="s-font-sans"
398
+ size="xs"
399
+ variant={"outline"}
400
+ label={showMermaid ? "Markdown" : "Mermaid"}
401
+ icon={showMermaid ? CommandLineIcon : SparklesIcon}
402
+ onClick={() => setShowMermaid(!showMermaid)}
403
+ tooltip={showMermaid ? "Switch to Markdown" : "Switch to Mermaid"}
404
+ />
405
+ }
406
+ >
407
+ {showMermaid ? (
408
+ <MermaidGraph chart={validChildrenContent} />
409
+ ) : (
410
+ <CodeBlock className={className} inline={inline}>
411
+ {children}
412
+ </CodeBlock>
413
+ )}
414
+ </ContentBlockWrapper>
415
+ );
416
+ }
385
417
 
386
- if (isValidMermaid) {
387
- return (
388
- <ContentBlockWrapper
389
- content={validChildrenContent}
390
- getContentToDownload={getContentToDownload}
391
- actions={
392
- <Button
393
- className="s-font-sans"
394
- size="xs"
395
- variant={"outline"}
396
- label={showMermaid ? "Markdown" : "Mermaid"}
397
- icon={showMermaid ? CommandLineIcon : SparklesIcon}
398
- onClick={() => setShowMermaid(!showMermaid)}
399
- tooltip={showMermaid ? "Switch to Markdown" : "Switch to Mermaid"}
400
- />
401
- }
402
- >
403
- {showMermaid ? (
404
- <MermaidGraph chart={validChildrenContent} />
405
- ) : (
406
- <CodeBlock className={className} inline={inline}>
407
- {children}
408
- </CodeBlock>
409
- )}
410
- </ContentBlockWrapper>
411
- );
412
- }
418
+ if (parsedJson !== null) {
419
+ return (
420
+ <ContentBlockWrapper
421
+ content={validChildrenContent}
422
+ getContentToDownload={getContentToDownload}
423
+ actions={
424
+ <Button
425
+ className="s-font-sans"
426
+ size="xs"
427
+ variant={"outline"}
428
+ label={showPrettyJson ? "Raw JSON" : "Pretty JSON"}
429
+ icon={showPrettyJson ? CommandLineIcon : SparklesIcon}
430
+ onClick={() => {
431
+ const newValue = !showPrettyJson;
432
+ setShowPrettyJson(newValue);
433
+ setPrettyJsonPreference(newValue);
434
+ }}
435
+ tooltip={
436
+ showPrettyJson ? "Switch to Raw JSON" : "Switch to Pretty View"
437
+ }
438
+ />
439
+ }
440
+ displayActions="hover"
441
+ buttonDisplay="inside"
442
+ >
443
+ {showPrettyJson ? (
444
+ <PrettyJsonViewer data={parsedJson} />
445
+ ) : (
446
+ <CodeBlock className={className} inline={inline}>
447
+ {children}
448
+ </CodeBlock>
449
+ )}
450
+ </ContentBlockWrapper>
451
+ );
452
+ }
413
453
 
414
- if (parsedJson !== null) {
415
454
  return (
416
455
  <ContentBlockWrapper
417
456
  content={validChildrenContent}
418
457
  getContentToDownload={getContentToDownload}
419
- actions={
420
- <Button
421
- className="s-font-sans"
422
- size="xs"
423
- variant={"outline"}
424
- label={showPrettyJson ? "Raw JSON" : "Pretty JSON"}
425
- icon={showPrettyJson ? CommandLineIcon : SparklesIcon}
426
- onClick={() => {
427
- const newValue = !showPrettyJson;
428
- setShowPrettyJson(newValue);
429
- setPrettyJsonPreference(newValue);
430
- }}
431
- tooltip={
432
- showPrettyJson ? "Switch to Raw JSON" : "Switch to Pretty View"
433
- }
434
- />
435
- }
436
- displayActions="hover"
437
458
  buttonDisplay="inside"
459
+ displayActions="hover"
438
460
  >
439
- {showPrettyJson ? (
440
- <PrettyJsonViewer data={parsedJson} />
441
- ) : (
442
- <CodeBlock className={className} inline={inline}>
443
- {children}
444
- </CodeBlock>
445
- )}
461
+ <CodeBlock className={className} inline={inline}>
462
+ {children}
463
+ </CodeBlock>
446
464
  </ContentBlockWrapper>
447
465
  );
448
- }
466
+ },
467
+ (prev, next) =>
468
+ sameNodePosition(prev.node, next.node) &&
469
+ prev.className === next.className &&
470
+ prev.inline === next.inline
471
+ );
449
472
 
450
- return (
451
- <ContentBlockWrapper
452
- content={validChildrenContent}
453
- getContentToDownload={getContentToDownload}
454
- buttonDisplay="inside"
455
- displayActions="hover"
456
- >
457
- <CodeBlock className={className} inline={inline}>
458
- {children}
459
- </CodeBlock>
460
- </ContentBlockWrapper>
461
- );
462
- }
473
+ MemoCodeBlockWithExtendedSupport.displayName = "CodeBlockWithExtendedSupport";