@heyramzi/ui 6.0.1 → 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 (114) hide show
  1. package/COMPONENTS.md +7 -26
  2. package/README.md +12 -5
  3. package/package.json +14 -16
  4. package/scripts/sync-shadcn.mjs +12 -3
  5. package/src/agents/agent-avatar.svelte +639 -0
  6. package/src/agents/agent-cast.svelte +173 -0
  7. package/src/agents/demo.svelte +78 -0
  8. package/src/agents/index.ts +11 -0
  9. package/src/agents/types.ts +72 -0
  10. package/{LICENSE → src/agents/vendor/LICENSE} +1 -1
  11. package/src/agents/vendor/color.ts +155 -0
  12. package/src/agents/vendor/draw.ts +840 -0
  13. package/src/agents/vendor/engine.ts +845 -0
  14. package/src/agents/vendor/mesh.ts +838 -0
  15. package/src/agents/vendor/plastic.ts +4958 -0
  16. package/src/agents/vendor/presets.ts +103 -0
  17. package/src/agents/vendor/shapes.ts +41 -0
  18. package/src/agents/vendor/ticker.ts +67 -0
  19. package/src/agents/vendor/types.ts +261 -0
  20. package/src/agents/vendor/wear.ts +1699 -0
  21. package/src/ai/index.ts +0 -18
  22. package/src/animations/README.md +3 -3
  23. package/src/lib/sliding-pill.ts +68 -0
  24. package/src/lib/theme-transition.ts +4 -2
  25. package/src/shadcn/code-block/code-block-actions.svelte +23 -0
  26. package/src/shadcn/code-block/code-block-content.svelte +55 -0
  27. package/src/shadcn/code-block/code-block-copy-button.svelte +59 -0
  28. package/src/shadcn/code-block/code-block-footer.svelte +20 -0
  29. package/src/shadcn/code-block/code-block-header.svelte +23 -0
  30. package/src/shadcn/code-block/code-block-line.svelte +71 -0
  31. package/src/shadcn/code-block/code-block-title.svelte +23 -0
  32. package/src/shadcn/code-block/code-block.svelte +47 -0
  33. package/src/shadcn/code-block/index.ts +42 -0
  34. package/src/shadcn/hooks/highlighter.ts +132 -0
  35. package/src/shadcn/hooks/use-highlighted-code.svelte.ts +98 -0
  36. package/src/shadcn/kbd/index.ts +10 -0
  37. package/src/shadcn/kbd/kbd-group.svelte +20 -0
  38. package/src/shadcn/kbd/kbd.svelte +23 -0
  39. package/src/shadcn/message-scroller/index.ts +28 -0
  40. package/src/shadcn/message-scroller/message-scroller-button.svelte +52 -0
  41. package/src/shadcn/message-scroller/message-scroller-content.svelte +17 -0
  42. package/src/shadcn/message-scroller/message-scroller-item.svelte +22 -0
  43. package/src/shadcn/message-scroller/message-scroller-provider.svelte +7 -0
  44. package/src/shadcn/message-scroller/message-scroller-viewport.svelte +20 -0
  45. package/src/shadcn/message-scroller/message-scroller.svelte +20 -0
  46. package/src/shadcn/tabs/tabs-list.svelte +13 -2
  47. package/src/shadcn/tabs/tabs-trigger.svelte +1 -1
  48. package/src/shadcn/trace/index.ts +29 -0
  49. package/src/shadcn/trace/trace-collapsible-content.svelte +29 -0
  50. package/src/shadcn/trace/trace-collapsible-trigger.svelte +29 -0
  51. package/src/shadcn/trace/trace-collapsible.svelte +20 -0
  52. package/src/shadcn/trace/trace-description.svelte +20 -0
  53. package/src/shadcn/trace/trace-icon.svelte +24 -0
  54. package/src/shadcn/trace/trace-line.svelte +31 -0
  55. package/src/shadcn/trace/trace-title.svelte +20 -0
  56. package/src/shadcn/trace/trace.svelte +23 -0
  57. package/src/showcase/AiSection.svelte +0 -7
  58. package/src/showcase/demos/shadcn/code-block.svelte +80 -0
  59. package/src/showcase/demos/shadcn/index.ts +24 -0
  60. package/src/showcase/demos/shadcn/message-scroller.svelte +44 -0
  61. package/src/showcase/demos/shadcn/trace.svelte +51 -0
  62. package/src/showcase/kit.ts +1 -2
  63. package/src/ai/conversation/Conversation.svelte +0 -28
  64. package/src/ai/conversation/ConversationContent.svelte +0 -35
  65. package/src/ai/conversation/ConversationEmptyState.svelte +0 -46
  66. package/src/ai/conversation/ConversationScrollButton.svelte +0 -51
  67. package/src/ai/conversation/index.ts +0 -33
  68. package/src/ai/conversation/stick-to-bottom-context.svelte.ts +0 -131
  69. package/src/charts/animated-value.css +0 -7
  70. package/src/charts/animated-value.svelte +0 -110
  71. package/src/charts/area-chart.css +0 -29
  72. package/src/charts/area-chart.svelte +0 -195
  73. package/src/charts/bar-chart.css +0 -119
  74. package/src/charts/bar-chart.svelte +0 -269
  75. package/src/charts/charts.css +0 -201
  76. package/src/charts/crosshair.svelte +0 -35
  77. package/src/charts/donut-chart.css +0 -56
  78. package/src/charts/donut-chart.svelte +0 -158
  79. package/src/charts/edge-fade.svelte +0 -43
  80. package/src/charts/edge-fade.ts +0 -16
  81. package/src/charts/figure.css +0 -100
  82. package/src/charts/figure.svelte +0 -122
  83. package/src/charts/gauge-chart.css +0 -94
  84. package/src/charts/gauge-chart.svelte +0 -303
  85. package/src/charts/hover-band.test.ts +0 -30
  86. package/src/charts/hover-band.ts +0 -21
  87. package/src/charts/hover-focus.svelte +0 -85
  88. package/src/charts/index.ts +0 -30
  89. package/src/charts/legend.css +0 -131
  90. package/src/charts/legend.svelte +0 -112
  91. package/src/charts/line-chart.css +0 -26
  92. package/src/charts/line-chart.svelte +0 -256
  93. package/src/charts/motion.ts +0 -19
  94. package/src/charts/number-chart.css +0 -168
  95. package/src/charts/number-chart.svelte +0 -177
  96. package/src/charts/primitives/chart-container.svelte +0 -57
  97. package/src/charts/primitives/chart-style.svelte +0 -36
  98. package/src/charts/primitives/chart-tooltip.svelte +0 -161
  99. package/src/charts/primitives/chart-utils.ts +0 -54
  100. package/src/charts/primitives/index.ts +0 -11
  101. package/src/charts/reveal.svelte +0 -61
  102. package/src/charts/ring-chart.css +0 -96
  103. package/src/charts/ring-chart.svelte +0 -158
  104. package/src/charts/sparkline.css +0 -45
  105. package/src/charts/sparkline.svelte +0 -140
  106. package/src/charts/stat-card.css +0 -103
  107. package/src/charts/stat-card.svelte +0 -267
  108. package/src/charts/time-series-chart.css +0 -28
  109. package/src/charts/time-series-chart.svelte +0 -179
  110. package/src/charts/trend-pill.css +0 -38
  111. package/src/charts/trend-pill.svelte +0 -48
  112. package/src/lib/hooks/is-mobile.svelte.ts +0 -11
  113. package/src/showcase/ChartsSection.svelte +0 -458
  114. package/src/showcase/demos/ai/conversation.svelte +0 -59
@@ -0,0 +1,98 @@
1
+ import {
2
+ loadHighlighter,
3
+ type Highlighter,
4
+ type HighlightedLine,
5
+ } from "./highlighter.js";
6
+ import type { GrammarState } from "shiki/core";
7
+
8
+ /**
9
+ * Highlights `code` in `language`. `current` holds one entry per line: a plain
10
+ * string until the highlighter loads, then the line's tokens. Pass each one to
11
+ * the `code` prop of a `CodeBlock.Line`.
12
+ *
13
+ * ```svelte
14
+ * <script lang="ts">
15
+ * const lines = useHighlightedCode(() => code, () => "json");
16
+ * </script>
17
+ *
18
+ * {#each lines.current as line, index (index)}
19
+ * <CodeBlock.Line code={line} />
20
+ * {/each}
21
+ * ```
22
+ */
23
+ export function useHighlightedCode(value: () => string, language: () => string) {
24
+ let loaded = $state.raw<{
25
+ language: string;
26
+ highlighter: Highlighter | null;
27
+ } | null>(null);
28
+
29
+ $effect(() => {
30
+ const lang = language();
31
+ let cancelled = false;
32
+
33
+ loadHighlighter(lang)
34
+ .then((next) => {
35
+ if (!cancelled) {
36
+ loaded = { language: lang, highlighter: next };
37
+ }
38
+ })
39
+ .catch(() => {});
40
+
41
+ return () => {
42
+ cancelled = true;
43
+ };
44
+ });
45
+
46
+ // The complete lines, highlighted. While the code streams, only the new
47
+ // lines are tokenized, starting from the grammar state of the last one.
48
+ let done: {
49
+ highlighter: Highlighter | null;
50
+ text: string;
51
+ lines: HighlightedLine[];
52
+ state?: GrammarState;
53
+ } = { highlighter: null, text: "", lines: [] };
54
+
55
+ const lines = $derived.by((): HighlightedLine[] => {
56
+ const raw = value();
57
+ // A trailing newline would render as an extra empty line.
58
+ const code = raw.endsWith("\n") ? raw.slice(0, -1) : raw;
59
+ const lang = language();
60
+ const highlighter = loaded?.language === lang ? loaded.highlighter : null;
61
+
62
+ if (!highlighter) {
63
+ return code.split("\n");
64
+ }
65
+
66
+ let next = done;
67
+
68
+ if (next.highlighter !== highlighter || !code.startsWith(next.text)) {
69
+ next = { highlighter, text: "", lines: [] };
70
+ }
71
+
72
+ const end = code.lastIndexOf("\n") + 1;
73
+
74
+ if (end > next.text.length) {
75
+ const result = highlighter.highlight(code.slice(next.text.length, end - 1), next.state);
76
+
77
+ next = {
78
+ highlighter,
79
+ text: code.slice(0, end),
80
+ lines: [...next.lines, ...result.lines],
81
+ state: result.state,
82
+ };
83
+ }
84
+
85
+ done = next;
86
+
87
+ // The last line is still being written, so it is tokenized every time.
88
+ const tail = code.slice(end);
89
+
90
+ return [...next.lines, highlighter.highlight(tail, next.state).lines[0]];
91
+ });
92
+
93
+ return {
94
+ get current() {
95
+ return lines;
96
+ },
97
+ };
98
+ }
@@ -0,0 +1,10 @@
1
+ import Root from "./kbd.svelte";
2
+ import Group from "./kbd-group.svelte";
3
+
4
+ export {
5
+ Root,
6
+ Group,
7
+ //
8
+ Root as Kbd,
9
+ Group as KbdGroup,
10
+ };
@@ -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<HTMLElement>> = $props();
11
+ </script>
12
+
13
+ <kbd
14
+ bind:this={ref}
15
+ data-slot="kbd-group"
16
+ class={cn("inline-flex items-center gap-1", className)}
17
+ {...restProps}
18
+ >
19
+ {@render children?.()}
20
+ </kbd>
@@ -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<HTMLElement>> = $props();
11
+ </script>
12
+
13
+ <kbd
14
+ bind:this={ref}
15
+ data-slot="kbd"
16
+ class={cn(
17
+ "bg-muted text-muted-foreground pointer-events-none inline-flex h-5 w-fit min-w-5 items-center justify-center gap-1 rounded-sm px-1 font-sans text-xs font-medium tabular-nums select-none [&_svg:not([class*='size-'])]:size-3",
18
+ className,
19
+ )}
20
+ {...restProps}
21
+ >
22
+ {@render children?.()}
23
+ </kbd>
@@ -0,0 +1,28 @@
1
+ import Button from "./message-scroller-button.svelte";
2
+ import Content from "./message-scroller-content.svelte";
3
+ import Item from "./message-scroller-item.svelte";
4
+ import Provider from "./message-scroller-provider.svelte";
5
+ import Viewport from "./message-scroller-viewport.svelte";
6
+ import Root from "./message-scroller.svelte";
7
+
8
+ export {
9
+ useMessageScroller,
10
+ useMessageScrollerScrollable,
11
+ useMessageScrollerVisibility,
12
+ } from "@shadcn-svelte/primitives/message-scroller";
13
+
14
+ export {
15
+ Provider,
16
+ Root,
17
+ Viewport,
18
+ Content,
19
+ Item,
20
+ Button,
21
+ //
22
+ Provider as MessageScrollerProvider,
23
+ Root as MessageScroller,
24
+ Viewport as MessageScrollerViewport,
25
+ Content as MessageScrollerContent,
26
+ Item as MessageScrollerItem,
27
+ Button as MessageScrollerButton,
28
+ };
@@ -0,0 +1,52 @@
1
+ <script lang="ts">
2
+ import { MessageScroller as MessageScrollerPrimitive } from "@shadcn-svelte/primitives/message-scroller";
3
+ import ArrowDownIcon from "@lucide/svelte/icons/arrow-down";
4
+ import { Button } from "../button/index.js";
5
+ import type { ButtonSize, ButtonVariant } from "../button/index.js";
6
+ import { cn } from "@heyramzi/utils";
7
+
8
+ let {
9
+ ref = $bindable(null),
10
+ direction = "end",
11
+ class: className,
12
+ children,
13
+ child: childProp,
14
+ variant = "outline",
15
+ size = "sm",
16
+ ...restProps
17
+ }: MessageScrollerPrimitive.ButtonProps & {
18
+ variant?: ButtonVariant;
19
+ size?: ButtonSize;
20
+ } = $props();
21
+ </script>
22
+
23
+ <MessageScrollerPrimitive.Button
24
+ bind:ref
25
+ data-slot="message-scroller-button"
26
+ data-direction={direction}
27
+ data-variant={variant}
28
+ data-size={size}
29
+ {direction}
30
+ class={cn(
31
+ "absolute inset-s-1/2 -translate-x-1/2 border-border bg-background text-foreground transition-[translate,scale,opacity] duration-200 hover:bg-muted hover:text-foreground data-[active=false]:pointer-events-none data-[active=false]:scale-95 data-[active=false]:opacity-0 data-[active=false]:duration-400 data-[active=false]:ease-[cubic-bezier(0.7,0,0.84,0)] data-[active=true]:translate-y-0 data-[active=true]:scale-100 data-[active=true]:opacity-100 data-[active=true]:ease-[cubic-bezier(0.23,1,0.32,1)] data-[direction=end]:bottom-4 data-[direction=end]:data-[active=false]:translate-y-full data-[direction=start]:top-4 data-[direction=start]:data-[active=false]:-translate-y-full rtl:translate-x-1/2 data-[direction=start]:[&_svg]:rotate-180",
32
+ className
33
+ )}
34
+ {...restProps}
35
+ >
36
+ {#snippet child(state)}
37
+ {#if childProp}
38
+ {@render childProp(state)}
39
+ {:else}
40
+ <Button {variant} {size} icon={!children} {...state.props}>
41
+ {#if children}
42
+ {@render children()}
43
+ {:else}
44
+ <ArrowDownIcon />
45
+ <span class="sr-only">
46
+ {direction === "end" ? "Scroll to end" : "Scroll to start"}
47
+ </span>
48
+ {/if}
49
+ </Button>
50
+ {/if}
51
+ {/snippet}
52
+ </MessageScrollerPrimitive.Button>
@@ -0,0 +1,17 @@
1
+ <script lang="ts">
2
+ import { MessageScroller as MessageScrollerPrimitive } from "@shadcn-svelte/primitives/message-scroller";
3
+ import { cn } from "@heyramzi/utils";
4
+
5
+ let {
6
+ ref = $bindable(null),
7
+ class: className,
8
+ ...restProps
9
+ }: MessageScrollerPrimitive.ContentProps = $props();
10
+ </script>
11
+
12
+ <MessageScrollerPrimitive.Content
13
+ bind:ref
14
+ data-slot="message-scroller-content"
15
+ class={cn("gap-8 flex h-max min-h-full flex-col", className)}
16
+ {...restProps}
17
+ />
@@ -0,0 +1,22 @@
1
+ <script lang="ts">
2
+ import { MessageScroller as MessageScrollerPrimitive } from "@shadcn-svelte/primitives/message-scroller";
3
+ import { cn } from "@heyramzi/utils";
4
+
5
+ let {
6
+ ref = $bindable(null),
7
+ class: className,
8
+ scrollAnchor = false,
9
+ ...restProps
10
+ }: MessageScrollerPrimitive.ItemProps = $props();
11
+ </script>
12
+
13
+ <MessageScrollerPrimitive.Item
14
+ bind:ref
15
+ data-slot="message-scroller-item"
16
+ {scrollAnchor}
17
+ class={cn(
18
+ "min-w-0 shrink-0 [contain-intrinsic-size:auto_10rem] [content-visibility:auto]",
19
+ className
20
+ )}
21
+ {...restProps}
22
+ />
@@ -0,0 +1,7 @@
1
+ <script lang="ts">
2
+ import { MessageScroller as MessageScrollerPrimitive } from "@shadcn-svelte/primitives/message-scroller";
3
+
4
+ let { ...restProps }: MessageScrollerPrimitive.ProviderProps = $props();
5
+ </script>
6
+
7
+ <MessageScrollerPrimitive.Provider {...restProps} />
@@ -0,0 +1,20 @@
1
+ <script lang="ts">
2
+ import { MessageScroller as MessageScrollerPrimitive } from "@shadcn-svelte/primitives/message-scroller";
3
+ import { cn } from "@heyramzi/utils";
4
+
5
+ let {
6
+ class: className,
7
+ ref = $bindable(null),
8
+ ...restProps
9
+ }: MessageScrollerPrimitive.ViewportProps = $props();
10
+ </script>
11
+
12
+ <MessageScrollerPrimitive.Viewport
13
+ bind:ref
14
+ data-slot="message-scroller-viewport"
15
+ class={cn(
16
+ "size-full min-h-0 min-w-0 scroll-fade-b scrollbar-thin scrollbar-gutter-stable overflow-y-auto overscroll-contain contain-content data-autoscrolling:scrollbar-thumb-transparent data-autoscrolling:scrollbar-track-transparent data-pending-scroll:invisible",
17
+ className
18
+ )}
19
+ {...restProps}
20
+ />
@@ -0,0 +1,20 @@
1
+ <script lang="ts">
2
+ import { MessageScroller as MessageScrollerPrimitive } from "@shadcn-svelte/primitives/message-scroller";
3
+ import { cn } from "@heyramzi/utils";
4
+
5
+ let {
6
+ class: className,
7
+ ref = $bindable(null),
8
+ ...restProps
9
+ }: MessageScrollerPrimitive.RootProps = $props();
10
+ </script>
11
+
12
+ <MessageScrollerPrimitive.Root
13
+ bind:ref
14
+ data-slot="message-scroller"
15
+ class={cn(
16
+ "group/message-scroller relative flex size-full min-h-0 flex-col overflow-hidden",
17
+ className
18
+ )}
19
+ {...restProps}
20
+ />
@@ -1,11 +1,13 @@
1
1
  <script lang="ts">
2
2
  import { Tabs as TabsPrimitive } from "bits-ui";
3
3
  import { cn } from "@heyramzi/utils";
4
+ import { slidingPill } from "../../lib/sliding-pill.js";
4
5
 
5
6
  let {
6
7
  ref = $bindable(null),
7
8
  class: className,
8
9
  size = "default",
10
+ children,
9
11
  ...restProps
10
12
  }: TabsPrimitive.ListProps & {
11
13
  /** Same steps as Button: sm 28, default 32, lg 36. */
@@ -18,8 +20,17 @@
18
20
  data-slot="tabs-list"
19
21
  data-size={size}
20
22
  class={cn(
21
- "bg-muted text-muted-foreground group/tabs-list inline-flex data-[size=sm]:h-7 data-[size=default]:h-8 data-[size=lg]:h-9 w-fit items-center justify-center rounded-lg p-[3px]",
23
+ "bg-muted text-muted-foreground group/tabs-list relative inline-flex data-[size=sm]:h-7 data-[size=default]:h-8 data-[size=lg]:h-9 w-fit items-center justify-center rounded-lg p-[3px]",
22
24
  className,
23
25
  )}
24
26
  {...restProps}
25
- />
27
+ >
28
+ <!-- Zero width until the attachment measures, so a server-rendered list
29
+ shows the trigger's own active background and never an empty pill. -->
30
+ <span
31
+ aria-hidden="true"
32
+ class="bg-background dark:border-input dark:bg-input/30 pointer-events-none absolute inset-y-[3px] left-0 z-0 w-0 rounded-md border border-transparent opacity-0 shadow-sm transition-[transform,width,opacity] duration-[var(--duration-fast,250ms)] ease-[var(--ease-smooth-out,cubic-bezier(0.22,1,0.36,1))] will-change-[transform,width] motion-reduce:transition-opacity"
33
+ {@attach slidingPill}
34
+ ></span>
35
+ {@render children?.()}
36
+ </TabsPrimitive.List>
@@ -13,7 +13,7 @@
13
13
  bind:ref
14
14
  data-slot="tabs-trigger"
15
15
  class={cn(
16
- "data-[state=active]:bg-background dark:data-[state=active]:text-foreground focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:outline-ring dark:data-[state=active]:border-input dark:data-[state=active]:bg-input/30 text-foreground dark:text-muted-foreground relative inline-flex h-full flex-1 items-center justify-center gap-1.5 rounded-md border border-transparent px-2 text-sm group-data-[size=sm]/tabs-list:text-[0.8rem] font-medium whitespace-nowrap after:absolute after:top-1/2 after:left-0 after:h-[max(100%,2rem)] after:w-full after:-translate-y-1/2 any-pointer-coarse:after:h-[max(100%,2.75rem)] transition-[color,box-shadow] focus-visible:ring-[3px] focus-visible:outline-1 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:shadow-sm [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
16
+ "data-[state=active]:bg-background dark:data-[state=active]:text-foreground focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:outline-ring dark:data-[state=active]:border-input dark:data-[state=active]:bg-input/30 text-foreground dark:text-muted-foreground group-data-[pill=on]/tabs-list:data-[state=active]:border-transparent group-data-[pill=on]/tabs-list:data-[state=active]:bg-transparent group-data-[pill=on]/tabs-list:data-[state=active]:shadow-none dark:group-data-[pill=on]/tabs-list:data-[state=active]:bg-transparent relative z-[1] inline-flex h-full flex-1 items-center justify-center gap-1.5 rounded-md border border-transparent px-2 text-sm group-data-[size=sm]/tabs-list:text-[0.8rem] font-medium whitespace-nowrap after:absolute after:top-1/2 after:left-0 after:h-[max(100%,2rem)] after:w-full after:-translate-y-1/2 any-pointer-coarse:after:h-[max(100%,2.75rem)] transition-[color,box-shadow] focus-visible:ring-[3px] focus-visible:outline-1 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:shadow-sm [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
17
17
  className,
18
18
  )}
19
19
  {...restProps}
@@ -0,0 +1,29 @@
1
+ import CollapsibleContent from "./trace-collapsible-content.svelte";
2
+ import CollapsibleTrigger from "./trace-collapsible-trigger.svelte";
3
+ import Collapsible from "./trace-collapsible.svelte";
4
+ import Description from "./trace-description.svelte";
5
+ import Icon from "./trace-icon.svelte";
6
+ import Title from "./trace-title.svelte";
7
+ import Root from "./trace.svelte";
8
+ import Line, { type TraceLineStatus } from "./trace-line.svelte";
9
+
10
+ export {
11
+ Root,
12
+ Line,
13
+ Icon,
14
+ Title,
15
+ Description,
16
+ Collapsible,
17
+ CollapsibleTrigger,
18
+ CollapsibleContent,
19
+ type TraceLineStatus,
20
+ //
21
+ Root as Trace,
22
+ Line as TraceLine,
23
+ Icon as TraceIcon,
24
+ Title as TraceTitle,
25
+ Description as TraceDescription,
26
+ Collapsible as TraceCollapsible,
27
+ CollapsibleTrigger as TraceCollapsibleTrigger,
28
+ CollapsibleContent as TraceCollapsibleContent,
29
+ };
@@ -0,0 +1,29 @@
1
+ <script lang="ts">
2
+ import * as Collapsible from "../collapsible/index.js";
3
+ import { cn, type WithoutChild } from "@heyramzi/utils";
4
+ import type { Collapsible as CollapsiblePrimitive } from "bits-ui";
5
+
6
+ let {
7
+ ref = $bindable(null),
8
+ class: className,
9
+ children,
10
+ ...restProps
11
+ }: WithoutChild<CollapsiblePrimitive.ContentProps> = $props();
12
+ </script>
13
+
14
+ <Collapsible.Content
15
+ bind:ref
16
+ data-slot="trace-collapsible-content"
17
+ class="duration-200 min-w-0 overflow-hidden [--bits-accordion-content-height:var(--bits-collapsible-content-height)] data-open:animate-accordion-down data-closed:animate-accordion-up"
18
+ {...restProps}
19
+ >
20
+ <div
21
+ data-slot="trace-collapsible-content-inner"
22
+ class={cn(
23
+ "mt-2 mb-1 ml-[calc(--spacing(2)_-_1px)] border-l pr-1 pl-4 leading-relaxed min-w-0 wrap-break-word text-muted-foreground",
24
+ className
25
+ )}
26
+ >
27
+ {@render children?.()}
28
+ </div>
29
+ </Collapsible.Content>
@@ -0,0 +1,29 @@
1
+ <script lang="ts">
2
+ import * as Collapsible from "../collapsible/index.js";
3
+ import ChevronRightIcon from "@lucide/svelte/icons/chevron-right";
4
+ import { cn, type WithoutChild } from "@heyramzi/utils";
5
+ import TraceIcon from "./trace-icon.svelte";
6
+ import type { Collapsible as CollapsiblePrimitive } from "bits-ui";
7
+
8
+ let {
9
+ ref = $bindable(null),
10
+ class: className,
11
+ children,
12
+ ...restProps
13
+ }: WithoutChild<CollapsiblePrimitive.TriggerProps> = $props();
14
+ </script>
15
+
16
+ <Collapsible.Trigger
17
+ bind:ref
18
+ data-slot="trace-collapsible-trigger"
19
+ class={cn(
20
+ "gap-1 rounded-md focus-visible:ring-3 focus-visible:ring-ring/50 group/trace-collapsible-trigger flex w-fit max-w-full min-w-0 cursor-pointer items-center text-left text-muted-foreground transition-colors outline-none hover:text-foreground has-[[data-status=error]]:text-destructive",
21
+ className
22
+ )}
23
+ {...restProps}
24
+ >
25
+ {@render children?.()}
26
+ <TraceIcon class="transition-transform group-aria-expanded/trace-collapsible-trigger:rotate-90">
27
+ <ChevronRightIcon />
28
+ </TraceIcon>
29
+ </Collapsible.Trigger>
@@ -0,0 +1,20 @@
1
+ <script lang="ts">
2
+ import * as Collapsible from "../collapsible/index.js";
3
+ import { cn } from "@heyramzi/utils";
4
+ import type { Collapsible as CollapsiblePrimitive } from "bits-ui";
5
+
6
+ let {
7
+ ref = $bindable(null),
8
+ open = $bindable(false),
9
+ class: className,
10
+ ...restProps
11
+ }: CollapsiblePrimitive.RootProps = $props();
12
+ </script>
13
+
14
+ <Collapsible.Root
15
+ bind:ref
16
+ bind:open
17
+ data-slot="trace-collapsible"
18
+ class={cn("flex w-full min-w-0 flex-col", className)}
19
+ {...restProps}
20
+ />
@@ -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.",