@dust-tt/sparkle 0.2.534 → 0.2.536
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.
- package/dist/cjs/index.js +1 -1
- package/dist/esm/components/BarHeader.d.ts +1 -0
- package/dist/esm/components/BarHeader.d.ts.map +1 -1
- package/dist/esm/components/BarHeader.js +1 -1
- package/dist/esm/components/BarHeader.js.map +1 -1
- package/dist/esm/components/markdown/CodeBlockWithExtendedSupport.d.ts.map +1 -1
- package/dist/esm/components/markdown/CodeBlockWithExtendedSupport.js +46 -35
- package/dist/esm/components/markdown/CodeBlockWithExtendedSupport.js.map +1 -1
- package/dist/esm/components/markdown/PrettyJsonViewer.d.ts +11 -0
- package/dist/esm/components/markdown/PrettyJsonViewer.d.ts.map +1 -0
- package/dist/esm/components/markdown/PrettyJsonViewer.js +92 -0
- package/dist/esm/components/markdown/PrettyJsonViewer.js.map +1 -0
- package/dist/esm/components/markdown/index.d.ts +1 -0
- package/dist/esm/components/markdown/index.d.ts.map +1 -1
- package/dist/esm/components/markdown/index.js +1 -0
- package/dist/esm/components/markdown/index.js.map +1 -1
- package/dist/esm/logo/platforms/Stripe.d.ts.map +1 -1
- package/dist/esm/logo/platforms/Stripe.js.map +1 -1
- package/dist/esm/stories/Markdown.stories.d.ts +1 -0
- package/dist/esm/stories/Markdown.stories.d.ts.map +1 -1
- package/dist/esm/stories/Markdown.stories.js +6 -0
- package/dist/esm/stories/Markdown.stories.js.map +1 -1
- package/dist/sparkle.css +13 -0
- package/package.json +1 -1
- package/src/components/BarHeader.tsx +2 -1
- package/src/components/markdown/CodeBlockWithExtendedSupport.tsx +65 -24
- package/src/components/markdown/PrettyJsonViewer.tsx +223 -0
- package/src/components/markdown/index.ts +1 -0
- package/src/logo/platforms/Stripe.tsx +10 -4
- package/src/stories/Markdown.stories.tsx +79 -0
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
|
|
3
|
+
import { Chip } from "@sparkle/components/Chip";
|
|
4
|
+
import { cn } from "@sparkle/lib/utils";
|
|
5
|
+
|
|
6
|
+
// Constants for consistent styling
|
|
7
|
+
const VALUE_CLASSES =
|
|
8
|
+
"s-text-primary-700 dark:s-text-primary-700-night s-pt-1 s-text-sm";
|
|
9
|
+
const EMPTY_CLASSES =
|
|
10
|
+
"s-text-primary-500 dark:s-text-primary-500-night s-pt-1 s-text-sm s-italic";
|
|
11
|
+
const INDENT_CLASSES =
|
|
12
|
+
"s-border-structure-200 dark:s-border-structure-200-night s-max-w-full s-border-l s-pl-4 s-ml-4";
|
|
13
|
+
|
|
14
|
+
export type JsonValueType =
|
|
15
|
+
| string
|
|
16
|
+
| number
|
|
17
|
+
| boolean
|
|
18
|
+
| null
|
|
19
|
+
| undefined
|
|
20
|
+
| JsonValueType[]
|
|
21
|
+
| { [key: string]: JsonValueType };
|
|
22
|
+
|
|
23
|
+
// Helper component for rendering key-value pairs with consistent styling.
|
|
24
|
+
function KeyValuePair({
|
|
25
|
+
keyName,
|
|
26
|
+
value,
|
|
27
|
+
depth,
|
|
28
|
+
chipColor,
|
|
29
|
+
isRootLevel = false,
|
|
30
|
+
}: {
|
|
31
|
+
keyName: string;
|
|
32
|
+
value: JsonValueType;
|
|
33
|
+
depth: number;
|
|
34
|
+
chipColor: "info" | "highlight";
|
|
35
|
+
isRootLevel?: boolean;
|
|
36
|
+
}) {
|
|
37
|
+
const isComplexValue = typeof value === "object" && value !== null;
|
|
38
|
+
|
|
39
|
+
if (isComplexValue) {
|
|
40
|
+
return (
|
|
41
|
+
<>
|
|
42
|
+
<Chip
|
|
43
|
+
size="xs"
|
|
44
|
+
color={chipColor}
|
|
45
|
+
label={formatKey(keyName)}
|
|
46
|
+
className="s-mb-2"
|
|
47
|
+
/>
|
|
48
|
+
<div className={cn("s-max-w-full", isRootLevel && "s-ml-4")}>
|
|
49
|
+
<JsonValue value={value} depth={depth + 1} />
|
|
50
|
+
</div>
|
|
51
|
+
</>
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return (
|
|
56
|
+
<div
|
|
57
|
+
className={cn(
|
|
58
|
+
"s-flex s-items-start",
|
|
59
|
+
isRootLevel ? "s-gap-3" : "s-gap-2"
|
|
60
|
+
)}
|
|
61
|
+
>
|
|
62
|
+
<Chip size="xs" color={chipColor} label={formatKey(keyName)} />
|
|
63
|
+
<JsonValue value={value} depth={depth + 1} />
|
|
64
|
+
</div>
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function JsonValue({
|
|
69
|
+
value,
|
|
70
|
+
depth = 0,
|
|
71
|
+
}: {
|
|
72
|
+
value: JsonValueType;
|
|
73
|
+
depth?: number;
|
|
74
|
+
}) {
|
|
75
|
+
if (value === null || value === undefined) {
|
|
76
|
+
return <span className={EMPTY_CLASSES}>empty</span>;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
if (typeof value === "boolean") {
|
|
80
|
+
return <span className={VALUE_CLASSES}>{value ? "Yes" : "No"}</span>;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
if (typeof value === "number") {
|
|
84
|
+
return <span className={VALUE_CLASSES}>{value}</span>;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
if (typeof value === "string") {
|
|
88
|
+
return (
|
|
89
|
+
<span className={`${VALUE_CLASSES} s-whitespace-pre-wrap s-break-normal`}>
|
|
90
|
+
{value}
|
|
91
|
+
</span>
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
if (Array.isArray(value)) {
|
|
96
|
+
if (value.length === 0) {
|
|
97
|
+
return <span className={EMPTY_CLASSES}>empty list</span>;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// Check if it's a simple array of primitives.
|
|
101
|
+
const isSimpleArray = value.every(
|
|
102
|
+
(item) => typeof item !== "object" || item === null
|
|
103
|
+
);
|
|
104
|
+
|
|
105
|
+
if (isSimpleArray && value.length <= 5) {
|
|
106
|
+
return (
|
|
107
|
+
<span className={VALUE_CLASSES}>
|
|
108
|
+
{value.map((item, index) => (
|
|
109
|
+
<span key={index}>
|
|
110
|
+
<JsonValue value={item} depth={depth + 1} />
|
|
111
|
+
{index < value.length - 1 && ", "}
|
|
112
|
+
</span>
|
|
113
|
+
))}
|
|
114
|
+
</span>
|
|
115
|
+
);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
return (
|
|
119
|
+
<div className="s-mt-2">
|
|
120
|
+
{value.map((item, index) => (
|
|
121
|
+
<div key={index} className={cn(INDENT_CLASSES)}>
|
|
122
|
+
<div className="s-flex s-flex-col s-gap-2">
|
|
123
|
+
<Chip size="xs" color="primary" label={`Item ${index + 1}`} />
|
|
124
|
+
<div className="s-max-w-full">
|
|
125
|
+
<JsonValue value={item} depth={depth + 1} />
|
|
126
|
+
</div>
|
|
127
|
+
</div>
|
|
128
|
+
</div>
|
|
129
|
+
))}
|
|
130
|
+
</div>
|
|
131
|
+
);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
if (typeof value === "object") {
|
|
135
|
+
const entries = Object.entries(value);
|
|
136
|
+
if (entries.length === 0) {
|
|
137
|
+
return <span className={EMPTY_CLASSES}>empty</span>;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// For nested objects, use a card-like layout with vertical bars.
|
|
141
|
+
if (depth > 0) {
|
|
142
|
+
return (
|
|
143
|
+
<div className="s-space-y-2">
|
|
144
|
+
{entries.map(([key, val]) => (
|
|
145
|
+
<div key={key} className={cn(INDENT_CLASSES)}>
|
|
146
|
+
<KeyValuePair
|
|
147
|
+
keyName={key}
|
|
148
|
+
value={val}
|
|
149
|
+
depth={depth}
|
|
150
|
+
chipColor="info"
|
|
151
|
+
/>
|
|
152
|
+
</div>
|
|
153
|
+
))}
|
|
154
|
+
</div>
|
|
155
|
+
);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
// Root level objects use a table-like layout.
|
|
159
|
+
return (
|
|
160
|
+
<div className="s-max-w-full s-space-y-3">
|
|
161
|
+
{entries.map(([key, val]) => (
|
|
162
|
+
<div
|
|
163
|
+
key={key}
|
|
164
|
+
className={cn(
|
|
165
|
+
"s-max-w-full s-border-b s-pb-3 last:s-border-0",
|
|
166
|
+
"s-border-structure-200 dark:s-border-structure-200-night"
|
|
167
|
+
)}
|
|
168
|
+
>
|
|
169
|
+
<KeyValuePair
|
|
170
|
+
keyName={key}
|
|
171
|
+
value={val}
|
|
172
|
+
depth={depth}
|
|
173
|
+
chipColor="highlight"
|
|
174
|
+
isRootLevel
|
|
175
|
+
/>
|
|
176
|
+
</div>
|
|
177
|
+
))}
|
|
178
|
+
</div>
|
|
179
|
+
);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
return (
|
|
183
|
+
<span
|
|
184
|
+
className={cn(
|
|
185
|
+
"s-text-sm",
|
|
186
|
+
"s-text-element-700 dark:s-text-element-700-night"
|
|
187
|
+
)}
|
|
188
|
+
>
|
|
189
|
+
{String(value)}
|
|
190
|
+
</span>
|
|
191
|
+
);
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
function formatKey(key: string): string {
|
|
195
|
+
// Convert snake_case or camelCase to Title Case.
|
|
196
|
+
return key
|
|
197
|
+
.replace(/_/g, " ")
|
|
198
|
+
.replace(/([A-Z])/g, " $1")
|
|
199
|
+
.trim()
|
|
200
|
+
.split(" ")
|
|
201
|
+
.map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())
|
|
202
|
+
.join(" ");
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
interface JsonViewerProps {
|
|
206
|
+
data: JsonValueType;
|
|
207
|
+
className?: string;
|
|
208
|
+
}
|
|
209
|
+
export function PrettyJsonViewer({ data, className }: JsonViewerProps) {
|
|
210
|
+
return (
|
|
211
|
+
<div
|
|
212
|
+
className={cn(
|
|
213
|
+
"s-bg-structure-50 dark:s-bg-structure-50-night",
|
|
214
|
+
"s-overflow-hidden s-rounded-lg s-p-6 s-text-base",
|
|
215
|
+
className
|
|
216
|
+
)}
|
|
217
|
+
>
|
|
218
|
+
<div className="s-max-w-full s-overflow-x-auto">
|
|
219
|
+
<JsonValue value={data} />
|
|
220
|
+
</div>
|
|
221
|
+
</div>
|
|
222
|
+
);
|
|
223
|
+
}
|
|
@@ -10,10 +10,16 @@ const SvgStripe = (props: SVGProps<SVGSVGElement>) => (
|
|
|
10
10
|
fill="#6772e5"
|
|
11
11
|
{...props}
|
|
12
12
|
>
|
|
13
|
-
<path
|
|
14
|
-
|
|
15
|
-
|
|
13
|
+
<path
|
|
14
|
+
d="M111.328 15.602c0-4.97-2.415-8.9-7.013-8.9s-7.423 3.924-7.423 8.863c0 5.85 3.32 8.8 8.036 8.8 2.318 0 4.06-.528 5.377-1.26V19.22a10.246 10.246 0 0 1-4.764 1.075c-1.9 0-3.556-.67-3.774-2.943h9.497a39.64 39.64 0 0 0 .063-1.748zm-9.606-1.835c0-2.186 1.35-3.1 2.56-3.1s2.454.906 2.454 3.1zM89.4 6.712a5.434 5.434 0 0 0-3.801 1.509l-.254-1.208h-4.27v22.64l4.85-1.032v-5.488a5.434 5.434 0 0 0 3.444 1.265c3.472 0 6.64-2.792 6.64-8.957.003-5.66-3.206-8.73-6.614-8.73zM88.23 20.1a2.898 2.898 0 0 1-2.288-.906l-.03-7.2a2.928 2.928 0 0 1 2.315-.96c1.775 0 2.998 2 2.998 4.528.003 2.593-1.198 4.546-2.995 4.546zM79.25.57l-4.87 1.035v3.95l4.87-1.032z"
|
|
15
|
+
fill-rule="evenodd"
|
|
16
|
+
/>
|
|
17
|
+
<path d="M74.38 7.035h4.87V24.04h-4.87z" />
|
|
18
|
+
<path
|
|
19
|
+
d="M69.164 8.47l-.302-1.434h-4.196V24.04h4.848V12.5c1.147-1.5 3.082-1.208 3.698-1.017V7.038c-.646-.232-2.913-.658-4.048 1.43zm-9.73-5.646L54.698 3.83l-.02 15.562c0 2.87 2.158 4.993 5.038 4.993 1.585 0 2.756-.302 3.405-.643v-3.95c-.622.248-3.683 1.138-3.683-1.72v-6.9h3.683V7.035h-3.683zM46.3 11.97c0-.758.63-1.05 1.648-1.05a10.868 10.868 0 0 1 4.83 1.25V7.6a12.815 12.815 0 0 0-4.83-.888c-3.924 0-6.557 2.056-6.557 5.488 0 5.37 7.375 4.498 7.375 6.813 0 .906-.78 1.186-1.863 1.186-1.606 0-3.68-.664-5.307-1.55v4.63a13.461 13.461 0 0 0 5.307 1.117c4.033 0 6.813-1.992 6.813-5.485 0-5.796-7.417-4.76-7.417-6.943zM13.88 9.515c0-1.37 1.14-1.9 2.982-1.9A19.661 19.661 0 0 1 25.6 9.876v-8.27A23.184 23.184 0 0 0 16.862.001C9.762.001 5 3.72 5 9.93c0 9.716 13.342 8.138 13.342 12.326 0 1.638-1.4 2.146-3.37 2.146-2.905 0-6.657-1.202-9.6-2.802v8.378A24.353 24.353 0 0 0 14.973 32C22.27 32 27.3 28.395 27.3 22.077c0-10.486-13.42-8.613-13.42-12.56z"
|
|
20
|
+
fill-rule="evenodd"
|
|
21
|
+
/>
|
|
16
22
|
</svg>
|
|
17
23
|
);
|
|
18
24
|
|
|
19
|
-
export default SvgStripe;
|
|
25
|
+
export default SvgStripe;
|
|
@@ -345,3 +345,82 @@ export const ExtendedMarkdownStory: Story = {
|
|
|
345
345
|
content: example,
|
|
346
346
|
},
|
|
347
347
|
};
|
|
348
|
+
|
|
349
|
+
const mermaidAndJSON = `
|
|
350
|
+
\`\`\`mermaid pie chart
|
|
351
|
+
pie title Distribution
|
|
352
|
+
"Category A" : 30
|
|
353
|
+
"Category B" : 20
|
|
354
|
+
"Category C" : 15
|
|
355
|
+
"Category D" : 10
|
|
356
|
+
"Category E" : 25
|
|
357
|
+
\`\`\`
|
|
358
|
+
|
|
359
|
+
|
|
360
|
+
\`\`\`json
|
|
361
|
+
{
|
|
362
|
+
"message": "Invalid JSON should not be pretty printed",
|
|
363
|
+
"status": "success",
|
|
364
|
+
}
|
|
365
|
+
\`\`\`
|
|
366
|
+
|
|
367
|
+
\`\`\`json
|
|
368
|
+
{
|
|
369
|
+
"message": "Soupi soupi soupinou ! Youhou !",
|
|
370
|
+
"status": "success",
|
|
371
|
+
"data": null
|
|
372
|
+
}
|
|
373
|
+
\`\`\`
|
|
374
|
+
|
|
375
|
+
\`\`\`json
|
|
376
|
+
{
|
|
377
|
+
"query": "SELECT COUNT() FROM Account"
|
|
378
|
+
}
|
|
379
|
+
\`\`\`
|
|
380
|
+
|
|
381
|
+
\`\`\`json
|
|
382
|
+
{
|
|
383
|
+
"records": [
|
|
384
|
+
{
|
|
385
|
+
"attributes": {
|
|
386
|
+
"type": "Account",
|
|
387
|
+
"url": "/services/data/v57.0/sobjects/Account/001Qy00000ccRXcIAM"
|
|
388
|
+
},
|
|
389
|
+
"Name": "Awesome Company",
|
|
390
|
+
"Type": "Customer - Direct",
|
|
391
|
+
"Industry": "Apparel",
|
|
392
|
+
"BillingCountry": "USA"
|
|
393
|
+
},
|
|
394
|
+
{
|
|
395
|
+
"attributes": {
|
|
396
|
+
"type": "Account",
|
|
397
|
+
"url": "/services/data/v57.0/sobjects/Account/001Qy00000ccRXeIAM"
|
|
398
|
+
},
|
|
399
|
+
"Name": "Awesomest Company",
|
|
400
|
+
"Type": "Customer - Channel",
|
|
401
|
+
"Industry": "Consulting",
|
|
402
|
+
"BillingCountry": "USA"
|
|
403
|
+
},
|
|
404
|
+
{
|
|
405
|
+
"attributes": {
|
|
406
|
+
"type": "Account",
|
|
407
|
+
"url": "/services/data/v57.0/sobjects/Account/001Qy00000ccRXbIAM"
|
|
408
|
+
},
|
|
409
|
+
"Name": "Awesomer Company",
|
|
410
|
+
"Type": "Customer - Direct",
|
|
411
|
+
"Industry": "Electronics",
|
|
412
|
+
"BillingCountry": null
|
|
413
|
+
}
|
|
414
|
+
],
|
|
415
|
+
"totalSize": 18,
|
|
416
|
+
"done": true
|
|
417
|
+
}
|
|
418
|
+
\`\`\`
|
|
419
|
+
|
|
420
|
+
`;
|
|
421
|
+
|
|
422
|
+
export const JSONMarkdownStory: Story = {
|
|
423
|
+
args: {
|
|
424
|
+
content: mermaidAndJSON,
|
|
425
|
+
},
|
|
426
|
+
};
|