@heyramzi/ui 6.1.0 → 7.0.0

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 (98) hide show
  1. package/COMPONENTS.md +6 -25
  2. package/README.md +6 -4
  3. package/package.json +7 -15
  4. package/scripts/sync-shadcn.mjs +12 -3
  5. package/src/ai/index.ts +0 -18
  6. package/src/animations/README.md +3 -3
  7. package/src/lib/sliding-pill.ts +68 -0
  8. package/src/lib/theme-transition.ts +4 -2
  9. package/src/shadcn/code-block/code-block-actions.svelte +23 -0
  10. package/src/shadcn/code-block/code-block-content.svelte +55 -0
  11. package/src/shadcn/code-block/code-block-copy-button.svelte +59 -0
  12. package/src/shadcn/code-block/code-block-footer.svelte +20 -0
  13. package/src/shadcn/code-block/code-block-header.svelte +23 -0
  14. package/src/shadcn/code-block/code-block-line.svelte +71 -0
  15. package/src/shadcn/code-block/code-block-title.svelte +23 -0
  16. package/src/shadcn/code-block/code-block.svelte +47 -0
  17. package/src/shadcn/code-block/index.ts +42 -0
  18. package/src/shadcn/hooks/highlighter.ts +132 -0
  19. package/src/shadcn/hooks/use-highlighted-code.svelte.ts +98 -0
  20. package/src/shadcn/kbd/index.ts +10 -0
  21. package/src/shadcn/kbd/kbd-group.svelte +20 -0
  22. package/src/shadcn/kbd/kbd.svelte +23 -0
  23. package/src/shadcn/message-scroller/index.ts +28 -0
  24. package/src/shadcn/message-scroller/message-scroller-button.svelte +52 -0
  25. package/src/shadcn/message-scroller/message-scroller-content.svelte +17 -0
  26. package/src/shadcn/message-scroller/message-scroller-item.svelte +22 -0
  27. package/src/shadcn/message-scroller/message-scroller-provider.svelte +7 -0
  28. package/src/shadcn/message-scroller/message-scroller-viewport.svelte +20 -0
  29. package/src/shadcn/message-scroller/message-scroller.svelte +20 -0
  30. package/src/shadcn/tabs/tabs-list.svelte +13 -2
  31. package/src/shadcn/tabs/tabs-trigger.svelte +1 -1
  32. package/src/shadcn/trace/index.ts +29 -0
  33. package/src/shadcn/trace/trace-collapsible-content.svelte +29 -0
  34. package/src/shadcn/trace/trace-collapsible-trigger.svelte +29 -0
  35. package/src/shadcn/trace/trace-collapsible.svelte +20 -0
  36. package/src/shadcn/trace/trace-description.svelte +20 -0
  37. package/src/shadcn/trace/trace-icon.svelte +24 -0
  38. package/src/shadcn/trace/trace-line.svelte +31 -0
  39. package/src/shadcn/trace/trace-title.svelte +20 -0
  40. package/src/shadcn/trace/trace.svelte +23 -0
  41. package/src/showcase/AiSection.svelte +0 -7
  42. package/src/showcase/demos/shadcn/code-block.svelte +80 -0
  43. package/src/showcase/demos/shadcn/index.ts +24 -0
  44. package/src/showcase/demos/shadcn/message-scroller.svelte +44 -0
  45. package/src/showcase/demos/shadcn/trace.svelte +51 -0
  46. package/src/showcase/kit.ts +1 -2
  47. package/src/ai/conversation/Conversation.svelte +0 -28
  48. package/src/ai/conversation/ConversationContent.svelte +0 -35
  49. package/src/ai/conversation/ConversationEmptyState.svelte +0 -46
  50. package/src/ai/conversation/ConversationScrollButton.svelte +0 -51
  51. package/src/ai/conversation/index.ts +0 -33
  52. package/src/ai/conversation/stick-to-bottom-context.svelte.ts +0 -131
  53. package/src/charts/animated-value.css +0 -7
  54. package/src/charts/animated-value.svelte +0 -110
  55. package/src/charts/area-chart.css +0 -29
  56. package/src/charts/area-chart.svelte +0 -195
  57. package/src/charts/bar-chart.css +0 -119
  58. package/src/charts/bar-chart.svelte +0 -269
  59. package/src/charts/charts.css +0 -201
  60. package/src/charts/crosshair.svelte +0 -35
  61. package/src/charts/donut-chart.css +0 -56
  62. package/src/charts/donut-chart.svelte +0 -158
  63. package/src/charts/edge-fade.svelte +0 -43
  64. package/src/charts/edge-fade.ts +0 -16
  65. package/src/charts/figure.css +0 -100
  66. package/src/charts/figure.svelte +0 -122
  67. package/src/charts/gauge-chart.css +0 -94
  68. package/src/charts/gauge-chart.svelte +0 -303
  69. package/src/charts/hover-band.test.ts +0 -30
  70. package/src/charts/hover-band.ts +0 -21
  71. package/src/charts/hover-focus.svelte +0 -85
  72. package/src/charts/index.ts +0 -30
  73. package/src/charts/legend.css +0 -131
  74. package/src/charts/legend.svelte +0 -112
  75. package/src/charts/line-chart.css +0 -26
  76. package/src/charts/line-chart.svelte +0 -256
  77. package/src/charts/motion.ts +0 -19
  78. package/src/charts/number-chart.css +0 -168
  79. package/src/charts/number-chart.svelte +0 -177
  80. package/src/charts/primitives/chart-container.svelte +0 -57
  81. package/src/charts/primitives/chart-style.svelte +0 -36
  82. package/src/charts/primitives/chart-tooltip.svelte +0 -161
  83. package/src/charts/primitives/chart-utils.ts +0 -54
  84. package/src/charts/primitives/index.ts +0 -11
  85. package/src/charts/reveal.svelte +0 -61
  86. package/src/charts/ring-chart.css +0 -96
  87. package/src/charts/ring-chart.svelte +0 -158
  88. package/src/charts/sparkline.css +0 -45
  89. package/src/charts/sparkline.svelte +0 -140
  90. package/src/charts/stat-card.css +0 -103
  91. package/src/charts/stat-card.svelte +0 -267
  92. package/src/charts/time-series-chart.css +0 -28
  93. package/src/charts/time-series-chart.svelte +0 -179
  94. package/src/charts/trend-pill.css +0 -38
  95. package/src/charts/trend-pill.svelte +0 -48
  96. package/src/lib/hooks/is-mobile.svelte.ts +0 -11
  97. package/src/showcase/ChartsSection.svelte +0 -458
  98. package/src/showcase/demos/ai/conversation.svelte +0 -59
@@ -0,0 +1,20 @@
1
+ <script lang="ts">
2
+ import { cn, type WithElementRef } from "@heyramzi/utils";
3
+ import type { HTMLAttributes } from "svelte/elements";
4
+
5
+ let {
6
+ ref = $bindable(null),
7
+ class: className,
8
+ children,
9
+ ...restProps
10
+ }: WithElementRef<HTMLAttributes<HTMLSpanElement>> = $props();
11
+ </script>
12
+
13
+ <span
14
+ bind:this={ref}
15
+ data-slot="trace-description"
16
+ class={cn("shrink-0 text-muted-foreground/70 tabular-nums", className)}
17
+ {...restProps}
18
+ >
19
+ {@render children?.()}
20
+ </span>
@@ -0,0 +1,24 @@
1
+ <script lang="ts">
2
+ import { cn, type WithElementRef } from "@heyramzi/utils";
3
+ import type { HTMLAttributes } from "svelte/elements";
4
+
5
+ let {
6
+ ref = $bindable(null),
7
+ class: className,
8
+ children,
9
+ ...restProps
10
+ }: WithElementRef<HTMLAttributes<HTMLSpanElement>> = $props();
11
+ </script>
12
+
13
+ <span
14
+ bind:this={ref}
15
+ data-slot="trace-icon"
16
+ aria-hidden="true"
17
+ class={cn(
18
+ "size-4 [&_svg:not([class*='size-'])]:size-4 [[data-slot=trace-title]~&]:-ml-1 flex shrink-0 items-center justify-center [&_svg]:pointer-events-none",
19
+ className
20
+ )}
21
+ {...restProps}
22
+ >
23
+ {@render children?.()}
24
+ </span>
@@ -0,0 +1,31 @@
1
+ <script lang="ts" module>
2
+ export type TraceLineStatus = "running" | "error" | "pending";
3
+ </script>
4
+
5
+ <script lang="ts">
6
+ import { cn, type WithElementRef } from "@heyramzi/utils";
7
+ import type { HTMLAttributes } from "svelte/elements";
8
+
9
+ let {
10
+ ref = $bindable(null),
11
+ class: className,
12
+ status,
13
+ children,
14
+ ...restProps
15
+ }: WithElementRef<HTMLAttributes<HTMLSpanElement>> & {
16
+ status?: TraceLineStatus;
17
+ } = $props();
18
+ </script>
19
+
20
+ <span
21
+ bind:this={ref}
22
+ data-slot="trace-line"
23
+ data-status={status}
24
+ class={cn(
25
+ "gap-2 text-sm flex w-fit max-w-full min-w-0 items-center text-muted-foreground transition-colors in-[a,button]:cursor-pointer in-[a:hover,button:hover]:text-foreground data-[status=error]:text-destructive data-[status=error]:in-[a:hover,button:hover]:text-destructive data-[status=pending]:opacity-60 data-[status=running]:*:data-[slot=trace-title]:shimmer",
26
+ className
27
+ )}
28
+ {...restProps}
29
+ >
30
+ {@render children?.()}
31
+ </span>
@@ -0,0 +1,20 @@
1
+ <script lang="ts">
2
+ import { cn, type WithElementRef } from "@heyramzi/utils";
3
+ import type { HTMLAttributes } from "svelte/elements";
4
+
5
+ let {
6
+ ref = $bindable(null),
7
+ class: className,
8
+ children,
9
+ ...restProps
10
+ }: WithElementRef<HTMLAttributes<HTMLSpanElement>> = $props();
11
+ </script>
12
+
13
+ <span
14
+ bind:this={ref}
15
+ data-slot="trace-title"
16
+ class={cn("min-w-0 truncate motion-reduce:shimmer-none", className)}
17
+ {...restProps}
18
+ >
19
+ {@render children?.()}
20
+ </span>
@@ -0,0 +1,23 @@
1
+ <script lang="ts">
2
+ import { cn, type WithElementRef } from "@heyramzi/utils";
3
+ import type { HTMLAttributes } from "svelte/elements";
4
+
5
+ let {
6
+ ref = $bindable(null),
7
+ class: className,
8
+ children,
9
+ ...restProps
10
+ }: WithElementRef<HTMLAttributes<HTMLDivElement>> = $props();
11
+ </script>
12
+
13
+ <div
14
+ bind:this={ref}
15
+ data-slot="trace"
16
+ class={cn(
17
+ "gap-2 *:has-[>[data-slot=trace-line]]:rounded-md *:has-[>[data-slot=trace-line]]:focus-visible:ring-3 *:has-[>[data-slot=trace-line]]:focus-visible:ring-ring/50 flex w-full min-w-0 flex-col *:has-[>[data-slot=trace-line]]:flex *:has-[>[data-slot=trace-line]]:w-fit *:has-[>[data-slot=trace-line]]:max-w-full *:has-[>[data-slot=trace-line]]:min-w-0 *:has-[>[data-slot=trace-line]]:text-left *:has-[>[data-slot=trace-line]]:outline-none",
18
+ className
19
+ )}
20
+ {...restProps}
21
+ >
22
+ {@render children?.()}
23
+ </div>
@@ -3,7 +3,6 @@
3
3
  <!-- ========================== -->
4
4
  <script lang="ts">
5
5
  import ShowcaseStage from "./ShowcaseStage.svelte";
6
- import Convo from "./demos/ai/conversation.svelte";
7
6
  import Prompt from "./demos/ai/prompt-input.svelte";
8
7
  import LoadingStateDemo from "./demos/ai/loading-state.svelte";
9
8
  import ThinkingDotsDemo from "./demos/ai/thinking-dots.svelte";
@@ -22,12 +21,6 @@
22
21
  // =========================
23
22
  // The order is the order a turn happens in: the surface it is said on, the waiting, the thinking, the decision, and last the voice.
24
23
  const demos: Demo[] = [
25
- {
26
- title: "Conversation",
27
- note: "Chat bubbles, responses and per-message actions.",
28
- Comp: Convo,
29
- path: "import { Conversation, ConversationContent, Response } from '@heyramzi/ui/ai';\nimport * as Message from '@heyramzi/ui/shadcn/message';\nimport * as Bubble from '@heyramzi/ui/shadcn/bubble';",
30
- },
31
24
  {
32
25
  title: "PromptInput",
33
26
  note: "Suggestions, textarea, status-aware submit.",
@@ -0,0 +1,80 @@
1
+ <script lang="ts">
2
+ import DownloadIcon from "@lucide/svelte/icons/download";
3
+ import FileCodeIcon from "@lucide/svelte/icons/file-code";
4
+ import WrapTextIcon from "@lucide/svelte/icons/text-wrap";
5
+ import * as CodeBlock from "../../../shadcn/code-block/index.js";
6
+ import { useHighlightedCode } from "../../../shadcn/hooks/use-highlighted-code.svelte.js";
7
+ import { Button } from "../../../shadcn/button/index.js";
8
+
9
+ const code = `import { streamText } from "ai"
10
+
11
+ export async function POST(request: Request) {
12
+ const { messages } = await request.json()
13
+
14
+ const result = streamText({
15
+ model: "anthropic/claude-sonnet-4.5",
16
+ system: "You are a helpful assistant. Answer in one short paragraph.",
17
+ messages,
18
+ })
19
+
20
+ return result.toUIMessageStreamResponse()
21
+ }`;
22
+
23
+ function download(value: string, filename: string) {
24
+ const url = URL.createObjectURL(new Blob([value], { type: "text/plain" }));
25
+ const link = document.createElement("a");
26
+ link.href = url;
27
+ link.download = filename;
28
+ link.click();
29
+ URL.revokeObjectURL(url);
30
+ }
31
+
32
+ let wrap = $state(false);
33
+
34
+ const lines = useHighlightedCode(
35
+ () => code,
36
+ () => "ts"
37
+ );
38
+ </script>
39
+
40
+ <div class="w-full max-w-lg">
41
+ <CodeBlock.Root>
42
+ <CodeBlock.Header>
43
+ <CodeBlock.Title>
44
+ <FileCodeIcon />
45
+ app/api/chat/route.ts
46
+ </CodeBlock.Title>
47
+ <CodeBlock.Actions>
48
+ <Button
49
+ variant="ghost"
50
+ size="sm"
51
+ icon
52
+ aria-label="Wrap lines"
53
+ aria-pressed={wrap}
54
+ class="aria-pressed:text-foreground"
55
+ onclick={() => (wrap = !wrap)}
56
+ >
57
+ <WrapTextIcon />
58
+ </Button>
59
+ <Button
60
+ variant="ghost"
61
+ size="sm"
62
+ icon
63
+ aria-label="Download"
64
+ onclick={() => download(code, "route.ts")}
65
+ >
66
+ <DownloadIcon />
67
+ </Button>
68
+ <CodeBlock.CopyButton value={code} />
69
+ </CodeBlock.Actions>
70
+ </CodeBlock.Header>
71
+ <CodeBlock.Content {wrap} lineNumbers>
72
+ {#each lines.current as line, index (index)}
73
+ <CodeBlock.Line
74
+ variant={index >= 5 && index <= 9 ? "highlighted" : "default"}
75
+ code={line}
76
+ />
77
+ {/each}
78
+ </CodeBlock.Content>
79
+ </CodeBlock.Root>
80
+ </div>
@@ -13,6 +13,7 @@ import ButtonDemo from "./button.svelte";
13
13
  import CalendarDemo from "./calendar.svelte";
14
14
  import CardDemo from "./card.svelte";
15
15
  import CheckboxDemo from "./checkbox.svelte";
16
+ import CodeBlockDemo from "./code-block.svelte";
16
17
  import CollapsibleDemo from "./collapsible.svelte";
17
18
  import CommandDemo from "./command.svelte";
18
19
  import ContextMenuDemo from "./context-menu.svelte";
@@ -26,6 +27,7 @@ import InputOtpDemo from "./input-otp.svelte";
26
27
  import LabelDemo from "./label.svelte";
27
28
  import MarkerDemo from "./marker.svelte";
28
29
  import MessageDemo from "./message.svelte";
30
+ import MessageScrollerDemo from "./message-scroller.svelte";
29
31
  import PopoverDemo from "./popover.svelte";
30
32
  import ProgressDemo from "./progress.svelte";
31
33
  import RadioGroupDemo from "./radio-group.svelte";
@@ -44,6 +46,7 @@ import TextareaDemo from "./textarea.svelte";
44
46
  import ToggleDemo from "./toggle.svelte";
45
47
  import ToggleGroupDemo from "./toggle-group.svelte";
46
48
  import TooltipDemo from "./tooltip.svelte";
49
+ import TraceDemo from "./trace.svelte";
47
50
 
48
51
  export type ShadcnDemo = {
49
52
  name: string;
@@ -138,6 +141,13 @@ export const SHADCN_DEMOS: ShadcnDemo[] = [
138
141
  path: 'import { Checkbox } from "@heyramzi/ui/shadcn/checkbox";\nimport { Label } from "@heyramzi/ui/shadcn/label";',
139
142
  Comp: CheckboxDemo,
140
143
  },
144
+ {
145
+ name: "code-block",
146
+ title: "Code Block",
147
+ note: "Displays code, terminal output and diffs with an optional header, line numbers and a copy button.",
148
+ path: 'import * as CodeBlock from "@heyramzi/ui/shadcn/code-block";\nimport { useHighlightedCode } from "@heyramzi/ui/shadcn/hooks/use-highlighted-code.svelte.js";\nimport { Button } from "@heyramzi/ui/shadcn/button";',
149
+ Comp: CodeBlockDemo,
150
+ },
141
151
  {
142
152
  name: "collapsible",
143
153
  title: "Collapsible",
@@ -229,6 +239,13 @@ export const SHADCN_DEMOS: ShadcnDemo[] = [
229
239
  path: 'import * as Avatar from "@heyramzi/ui/shadcn/avatar";\nimport * as Bubble from "@heyramzi/ui/shadcn/bubble";\nimport * as Marker from "@heyramzi/ui/shadcn/marker";\nimport * as Message from "@heyramzi/ui/shadcn/message";',
230
240
  Comp: MessageDemo,
231
241
  },
242
+ {
243
+ name: "message-scroller",
244
+ title: "Message Scroller",
245
+ note: "A chat scroll container that anchors turns, opens saved transcripts, follows streamed responses, loads history without jumping, and jumps to any message.",
246
+ path: 'import * as Card from "@heyramzi/ui/shadcn/card";\nimport * as DropdownMenu from "@heyramzi/ui/shadcn/dropdown-menu";\nimport * as Empty from "@heyramzi/ui/shadcn/empty";\nimport * as InputGroup from "@heyramzi/ui/shadcn/input-group";\nimport * as MessageScroller from "@heyramzi/ui/shadcn/message-scroller";\nimport * as Tooltip from "@heyramzi/ui/shadcn/tooltip";\nimport { Button } from "@heyramzi/ui/shadcn/button";',
247
+ Comp: MessageScrollerDemo,
248
+ },
232
249
  {
233
250
  name: "popover",
234
251
  title: "Popover",
@@ -355,4 +372,11 @@ export const SHADCN_DEMOS: ShadcnDemo[] = [
355
372
  path: 'import * as Tooltip from "@heyramzi/ui/shadcn/tooltip";\nimport { buttonVariants } from "@heyramzi/ui/shadcn/button";',
356
373
  Comp: TooltipDemo,
357
374
  },
375
+ {
376
+ name: "trace",
377
+ title: "Trace",
378
+ note: "The building block for reasoning, tool calls, sources and more.",
379
+ path: 'import * as Bubble from "@heyramzi/ui/shadcn/bubble";\nimport * as CodeBlock from "@heyramzi/ui/shadcn/code-block";\nimport * as Message from "@heyramzi/ui/shadcn/message";\nimport * as Trace from "@heyramzi/ui/shadcn/trace";\nimport { Button } from "@heyramzi/ui/shadcn/button";',
380
+ Comp: TraceDemo,
381
+ },
358
382
  ];
@@ -0,0 +1,44 @@
1
+ <!-- Ours, not upstream's: theirs streams through @ai-sdk/svelte and docs-only helpers this package doesn't ship. -->
2
+ <script lang="ts">
3
+ import * as Bubble from "../../../shadcn/bubble/index.js";
4
+ import * as Message from "../../../shadcn/message/index.js";
5
+ import * as MessageScroller from "../../../shadcn/message-scroller/index.js";
6
+ import { Response } from "../../../ai/index.js";
7
+
8
+ const turns = [
9
+ { id: "q1", role: "user", text: "How should I clean up our beam effects?" },
10
+ {
11
+ id: "a1",
12
+ role: "assistant",
13
+ text: "Here is the plan:\n\n1. **Extract** the beam into the shared package\n2. **Showcase** it on the Effects page\n3. **Migrate** both apps onto the shared copy",
14
+ },
15
+ { id: "q2", role: "user", text: "And the old copies?" },
16
+ { id: "a2", role: "assistant", text: "Delete them in the same change, so nothing imports the stale one." },
17
+ ] as const;
18
+ </script>
19
+
20
+ <div class="h-68 w-full max-w-md">
21
+ <MessageScroller.Provider>
22
+ <MessageScroller.Root>
23
+ <MessageScroller.Viewport>
24
+ <MessageScroller.Content class="gap-4 p-1">
25
+ {#each turns as turn (turn.id)}
26
+ {@const user = turn.role === "user"}
27
+ <MessageScroller.Item messageId={turn.id} scrollAnchor={user}>
28
+ <Message.Root align={user ? "end" : "start"}>
29
+ <Message.Content>
30
+ <Bubble.Root variant={user ? "default" : "muted"} align={user ? "end" : "start"}>
31
+ <Bubble.Content>
32
+ {#if user}{turn.text}{:else}<Response content={turn.text} />{/if}
33
+ </Bubble.Content>
34
+ </Bubble.Root>
35
+ </Message.Content>
36
+ </Message.Root>
37
+ </MessageScroller.Item>
38
+ {/each}
39
+ </MessageScroller.Content>
40
+ </MessageScroller.Viewport>
41
+ <MessageScroller.Button />
42
+ </MessageScroller.Root>
43
+ </MessageScroller.Provider>
44
+ </div>
@@ -0,0 +1,51 @@
1
+ <!-- Ours, not upstream's: theirs streams through @ai-sdk/svelte and docs-only helpers this package doesn't ship. -->
2
+ <script lang="ts">
3
+ import CircleAlertIcon from "@lucide/svelte/icons/circle-alert";
4
+ import CircleCheckIcon from "@lucide/svelte/icons/circle-check";
5
+ import LoaderCircleIcon from "@lucide/svelte/icons/loader-circle";
6
+ import * as CodeBlock from "../../../shadcn/code-block/index.js";
7
+ import * as Trace from "../../../shadcn/trace/index.js";
8
+
9
+ const steps = [
10
+ { command: "pnpm --version", output: "12.10.1" },
11
+ {
12
+ command: "git diff --stat HEAD~1 -- package.json pnpm-lock.yaml",
13
+ output: " package.json | 2 +-\n 1 file changed, 1 insertion(+), 1 deletion(-)",
14
+ },
15
+ {
16
+ command: "pnpm install --frozen-lockfile",
17
+ error: "ERR_PNPM_OUTDATED_LOCKFILE pnpm-lock.yaml is not up to date with package.json",
18
+ },
19
+ ];
20
+ </script>
21
+
22
+ <div class="w-full max-w-md">
23
+ <Trace.Root>
24
+ <Trace.Line>
25
+ <Trace.Icon><CircleCheckIcon /></Trace.Icon>
26
+ <Trace.Title>Thought for 5s</Trace.Title>
27
+ </Trace.Line>
28
+ {#each steps as step (step.command)}
29
+ <Trace.Collapsible>
30
+ <Trace.CollapsibleTrigger>
31
+ <Trace.Line status={step.error ? "error" : undefined}>
32
+ <Trace.Icon>
33
+ {#if step.error}<CircleAlertIcon />{:else}<CircleCheckIcon />{/if}
34
+ </Trace.Icon>
35
+ <Trace.Title>{step.error ? "Failed to run" : "Ran"} {step.command}</Trace.Title>
36
+ </Trace.Line>
37
+ </Trace.CollapsibleTrigger>
38
+ <Trace.CollapsibleContent>
39
+ <CodeBlock.Root size="sm" variant={step.error ? "destructive" : "default"}>
40
+ <CodeBlock.Content wrap class="max-h-64" code={step.error ?? step.output} />
41
+ </CodeBlock.Root>
42
+ </Trace.CollapsibleContent>
43
+ </Trace.Collapsible>
44
+ {/each}
45
+ <Trace.Line status="running">
46
+ <Trace.Icon><LoaderCircleIcon class="animate-spin" /></Trace.Icon>
47
+ <Trace.Title>Writing the fix</Trace.Title>
48
+ <Trace.Description>2 sources</Trace.Description>
49
+ </Trace.Line>
50
+ </Trace.Root>
51
+ </div>
@@ -1,5 +1,5 @@
1
1
  // The showcase of @heyramzi/ui itself: its shadcn primitives,
2
- // its motion vocabulary, its visual effects, its chart set and its AI surface.
2
+ // its motion vocabulary, its visual effects and its AI surface. The chart set's own section ships with `@heyramzi/charts/showcase`.
3
3
 
4
4
  // WHY they ship with the package and not with the app showing them: they demo
5
5
 
@@ -13,5 +13,4 @@
13
13
  export { default as AnimationsSection } from "./AnimationsSection.svelte";
14
14
  export { default as ShadcnSection } from "./ShadcnSection.svelte";
15
15
  export { default as EffectsSection } from "./EffectsSection.svelte";
16
- export { default as ChartsSection } from "./ChartsSection.svelte";
17
16
  export { default as AiSection } from "./AiSection.svelte";
@@ -1,28 +0,0 @@
1
- <script lang="ts" module>
2
- import type { Snippet } from "svelte";
3
- import type { HTMLAttributes } from "svelte/elements";
4
-
5
- export interface ConversationProps extends HTMLAttributes<HTMLDivElement> {
6
- children?: Snippet;
7
- class?: string;
8
- }
9
- </script>
10
-
11
- <script lang="ts">
12
- import { cn } from "@heyramzi/utils";
13
- import { setStickToBottomContext } from "./stick-to-bottom-context.svelte.js";
14
-
15
- let { class: className, children, ...rest }: ConversationProps = $props();
16
-
17
- setStickToBottomContext();
18
- </script>
19
-
20
- <div
21
- class={cn("relative flex h-full flex-col overflow-hidden", className)}
22
- role="log"
23
- aria-live="polite"
24
- aria-atomic="false"
25
- {...rest}
26
- >
27
- {@render children?.()}
28
- </div>
@@ -1,35 +0,0 @@
1
- <script lang="ts" module>
2
- import type { Snippet } from "svelte";
3
- import type { HTMLAttributes } from "svelte/elements";
4
-
5
- export interface ConversationContentProps extends HTMLAttributes<HTMLDivElement> {
6
- children?: Snippet;
7
- class?: string;
8
- }
9
- </script>
10
-
11
- <script lang="ts">
12
- import { cn } from "@heyramzi/utils";
13
- import { onDestroy } from "svelte";
14
- import { getStickToBottomContext } from "./stick-to-bottom-context.svelte.js";
15
-
16
- let { class: className, children, ...rest }: ConversationContentProps = $props();
17
-
18
- const context = getStickToBottomContext();
19
- let element = $state<HTMLDivElement | null>(null);
20
-
21
- $effect(() => {
22
- if (element) {
23
- context.setElement(element);
24
- context.scrollToBottom("smooth");
25
- }
26
- });
27
-
28
- onDestroy(() => {
29
- context.destroy();
30
- });
31
- </script>
32
-
33
- <div bind:this={element} class={cn("flex-1 overflow-y-auto", className)} {...rest}>
34
- {@render children?.()}
35
- </div>
@@ -1,46 +0,0 @@
1
- <script lang="ts" module>
2
- import type { Snippet } from "svelte";
3
- import type { HTMLAttributes } from "svelte/elements";
4
-
5
- export interface ConversationEmptyStateProps extends HTMLAttributes<HTMLDivElement> {
6
- title?: string;
7
- description?: string;
8
- icon?: Snippet;
9
- children?: Snippet;
10
- class?: string;
11
- }
12
- </script>
13
-
14
- <script lang="ts">
15
- import { cn } from "@heyramzi/utils";
16
-
17
- let {
18
- class: className,
19
- title,
20
- description,
21
- icon,
22
- children,
23
- ...rest
24
- }: ConversationEmptyStateProps = $props();
25
- </script>
26
-
27
- <div
28
- class={cn("flex size-full flex-col items-center justify-center gap-3 p-6 text-center", className)}
29
- {...rest}
30
- >
31
- {#if children}
32
- {@render children()}
33
- {:else}
34
- {#if icon}
35
- <div class="text-[color:var(--muted-foreground,inherit)]">
36
- {@render icon()}
37
- </div>
38
- {/if}
39
- <div class="space-y-1">
40
- {#if title}<h3 class="text-sm font-medium">{title}</h3>{/if}
41
- {#if description}
42
- <p class="text-[color:var(--muted-foreground,inherit)] text-sm">{description}</p>
43
- {/if}
44
- </div>
45
- {/if}
46
- </div>
@@ -1,51 +0,0 @@
1
- <script lang="ts" module>
2
- import type { ButtonProps } from "../../shadcn/button/index.js";
3
-
4
- export interface ConversationScrollButtonProps extends Omit<ButtonProps, "onclick"> {
5
- class?: string;
6
- onclick?: (event: MouseEvent) => void;
7
- }
8
- </script>
9
-
10
- <script lang="ts">
11
- import { cn } from "@heyramzi/utils";
12
- import { Button } from "../../shadcn/button/index.js";
13
- import ArrowDown from "phosphor-svelte/lib/ArrowDown";
14
- import { fly } from "svelte/transition";
15
- import { backOut } from "svelte/easing";
16
- import { getStickToBottomContext } from "./stick-to-bottom-context.svelte.js";
17
-
18
- let { class: className, onclick, ...rest }: ConversationScrollButtonProps = $props();
19
-
20
- const context = getStickToBottomContext();
21
-
22
- function handleClick(event: MouseEvent) {
23
- context.scrollToBottom();
24
- onclick?.(event);
25
- }
26
- </script>
27
-
28
- {#if !context.isAtBottom}
29
- <div
30
- in:fly={{ duration: 300, y: 10, easing: backOut }}
31
- out:fly={{ duration: 200, y: 10, easing: backOut }}
32
- class="pointer-events-auto absolute bottom-3 left-1/2 -translate-x-1/2"
33
- >
34
- <Button
35
- class={cn(
36
- "rounded-full shadow-lg backdrop-blur-sm",
37
- "bg-[color:var(--background,white)]/80 hover:bg-[color:var(--background,white)]/95",
38
- "border-[color:var(--border,rgba(0,0,0,0.1))]",
39
- className,
40
- )}
41
- onclick={handleClick}
42
- icon
43
- type="button"
44
- variant="outline"
45
- aria-label="Scroll to latest"
46
- {...rest}
47
- >
48
- <ArrowDown class="size-4" />
49
- </Button>
50
- </div>
51
- {/if}
@@ -1,33 +0,0 @@
1
- import Conversation from "./Conversation.svelte";
2
- import ConversationContent from "./ConversationContent.svelte";
3
- import ConversationEmptyState from "./ConversationEmptyState.svelte";
4
- import ConversationScrollButton from "./ConversationScrollButton.svelte";
5
- import {
6
- StickToBottomContext,
7
- getStickToBottomContext,
8
- setStickToBottomContext,
9
- } from "./stick-to-bottom-context.svelte.js";
10
-
11
- import type { ConversationProps } from "./Conversation.svelte";
12
- import type { ConversationContentProps } from "./ConversationContent.svelte";
13
- import type { ConversationEmptyStateProps } from "./ConversationEmptyState.svelte";
14
- import type { ConversationScrollButtonProps } from "./ConversationScrollButton.svelte";
15
-
16
- export {
17
- Conversation,
18
- ConversationContent,
19
- ConversationEmptyState,
20
- ConversationScrollButton,
21
- StickToBottomContext,
22
- getStickToBottomContext,
23
- setStickToBottomContext,
24
- type ConversationProps,
25
- type ConversationContentProps,
26
- type ConversationEmptyStateProps,
27
- type ConversationScrollButtonProps,
28
- //
29
- Conversation as Root,
30
- ConversationContent as Content,
31
- ConversationEmptyState as EmptyState,
32
- ConversationScrollButton as ScrollButton,
33
- };