@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
@@ -1,158 +0,0 @@
1
- <script lang="ts">
2
- // =========================
3
- // IMPORTS
4
- // =========================
5
- import "./ring-chart.css";
6
- import { cn } from "@heyramzi/utils";
7
- import AnimatedValue from "./animated-value.svelte";
8
-
9
- // =========================
10
- // TYPES
11
- // =========================
12
- type RingData = {
13
- label: string;
14
- value: number;
15
- /** Denominator for the progress arc. */
16
- maxValue: number;
17
- /** CSS color or var. Falls back to --chart-1..5. */
18
- color?: string;
19
- };
20
-
21
- type Props = {
22
- data: RingData[];
23
- /** Fixed square size in px. Omit to fill the parent (responsive). */
24
- size?: number;
25
- /** Ring thickness in viewBox units. */
26
- strokeWidth?: number;
27
- /** Gap between concentric rings in viewBox units. */
28
- ringGap?: number;
29
- /** Inner radius of the innermost ring in viewBox units. */
30
- baseInnerRadius?: number;
31
- lineCap?: "round" | "butt";
32
- /** Center label when nothing is hovered. */
33
- defaultLabel?: string;
34
- formatValue?: (v: number) => string;
35
- /** Animate arcs on mount. */
36
- animate?: boolean;
37
- /** Glow the hovered ring. */
38
- showGlow?: boolean;
39
- /** Hovered ring index, bindable for legend hover-sync. */
40
- hoveredIndex?: number | null;
41
- onHoverChange?: (index: number | null) => void;
42
- minWidth?: number;
43
- ariaLabel?: string;
44
- class?: string;
45
- };
46
-
47
- // =========================
48
- // PROPS
49
- // =========================
50
- let {
51
- data,
52
- size,
53
- strokeWidth = 11,
54
- ringGap = 6,
55
- baseInnerRadius = 48,
56
- lineCap = "round",
57
- defaultLabel = "Total",
58
- formatValue = (v) => v.toLocaleString(),
59
- animate = true,
60
- showGlow = true,
61
- hoveredIndex = $bindable(null),
62
- onHoverChange,
63
- minWidth = 170,
64
- ariaLabel,
65
- class: className,
66
- }: Props = $props();
67
-
68
- // =========================
69
- // DERIVED
70
- // =========================
71
- const rings = $derived.by(() =>
72
- data.map((d, i) => {
73
- const radius = baseInnerRadius + i * (strokeWidth + ringGap) + strokeWidth / 2;
74
- const progress = d.maxValue > 0 ? Math.max(0, Math.min(1, d.value / d.maxValue)) : 0;
75
- return {
76
- ...d,
77
- index: i,
78
- radius,
79
- progress,
80
- color: d.color ?? `var(--chart-${(i % 5) + 1})`,
81
- };
82
- }),
83
- );
84
- const maxRadius = $derived(
85
- rings.length ? rings[rings.length - 1].radius + strokeWidth / 2 : baseInnerRadius,
86
- );
87
- const vb = $derived(maxRadius * 2 + 4);
88
- const center = $derived(vb / 2);
89
- const total = $derived(data.reduce((sum, d) => sum + d.value, 0));
90
- const hoveredRing = $derived(hoveredIndex != null ? (rings[hoveredIndex] ?? null) : null);
91
-
92
- // =========================
93
- // FUNCTIONS
94
- // =========================
95
- function setHover(index: number | null) {
96
- hoveredIndex = index;
97
- onHoverChange?.(index);
98
- }
99
- </script>
100
-
101
- <!-- =========================== -->
102
- <!-- MARKUP -->
103
- <!-- =========================== -->
104
- <div
105
- class={cn("hr-ring", className)}
106
- class:glow={showGlow}
107
- style:width={size ? `${size}px` : "100%"}
108
- style:min-width="{minWidth}px"
109
- role="img"
110
- aria-label={ariaLabel ?? `${defaultLabel}: ${formatValue(total)}`}
111
- >
112
- <!-- no-inline-svg-ignore -->
113
- <svg viewBox="0 0 {vb} {vb}" aria-hidden="true">
114
- <g transform="rotate(-90 {center} {center})">
115
- {#each rings as ring (ring.index)}
116
- <circle
117
- class="track"
118
- cx={center}
119
- cy={center}
120
- r={ring.radius}
121
- fill="none"
122
- stroke={ring.color}
123
- stroke-width={strokeWidth}
124
- />
125
- {/each}
126
- {#each rings as ring (ring.index)}
127
- {@const dimmed = hoveredIndex !== null && hoveredIndex !== ring.index}
128
- <circle
129
- class="fill"
130
- class:animate
131
- cx={center}
132
- cy={center}
133
- r={ring.radius}
134
- pathLength="100"
135
- fill="none"
136
- stroke={ring.color}
137
- stroke-width={strokeWidth}
138
- stroke-linecap={lineCap}
139
- style:stroke-dashoffset={100 - ring.progress * 100}
140
- style:opacity={dimmed ? 0.25 : 1}
141
- style:animation-delay="{160 + ring.index * 120}ms"
142
- style:--ring-color={ring.color}
143
- onmouseenter={() => setHover(ring.index)}
144
- onmouseleave={() => setHover(null)}
145
- ></circle>
146
- {/each}
147
- </g>
148
- </svg>
149
-
150
- <div class="center">
151
- <span class="value">
152
- <AnimatedValue value={hoveredRing ? hoveredRing.value : total} format={formatValue} />
153
- </span>
154
- {#key hoveredRing?.label ?? defaultLabel}
155
- <span class="label">{hoveredRing ? hoveredRing.label : defaultLabel}</span>
156
- {/key}
157
- </div>
158
- </div>
@@ -1,45 +0,0 @@
1
- /* Styles for Sparkline. Plain stylesheet (see area-chart.css for why).
2
- Selectors are namespaced under `.hr-sparkline`. */
3
-
4
- .hr-sparkline {
5
- display: flex;
6
- align-items: center;
7
- gap: 0.625rem;
8
- width: 100%;
9
- }
10
- .hr-sparkline-chart {
11
- flex: 1 1 auto;
12
- min-width: 0;
13
- }
14
- /* Bare is an ornament inside another control: no inline value, so no gap. */
15
- .hr-sparkline[data-bare] {
16
- gap: 0;
17
- }
18
- .hr-sparkline-value {
19
- flex-shrink: 0;
20
- font-size: 0.8125rem;
21
- font-weight: 600;
22
- font-feature-settings: "tnum";
23
- font-family: ui-monospace, SFMono-Regular, monospace;
24
- }
25
-
26
- .hr-sparkline .hr-sparkline-end {
27
- filter: drop-shadow(0 0 3px currentColor);
28
- opacity: 0.9;
29
- transform-box: fill-box;
30
- transform-origin: center;
31
- /* WHY: the dot lands as the reveal reaches the end of the line. */
32
- animation: hr-sparkline-pop var(--duration-fast, 250ms) var(--ease-smooth-out)
33
- calc(var(--chart-motion-reveal, 1100ms) * 0.85) both;
34
- }
35
- @keyframes hr-sparkline-pop {
36
- from {
37
- opacity: 0;
38
- transform: scale(0);
39
- }
40
- }
41
- @media (prefers-reduced-motion: reduce) {
42
- .hr-sparkline .hr-sparkline-end {
43
- animation: none;
44
- }
45
- }
@@ -1,140 +0,0 @@
1
- <script lang="ts" generics="TData extends Record<string, unknown>">
2
- // =========================
3
- // IMPORTS
4
- // =========================
5
- import "./sparkline.css";
6
- import { Area, Chart, Highlight, LinearGradient, Points, Spline, Svg, Tooltip } from "layerchart";
7
- import { curveMonotoneX } from "d3-shape";
8
- import Reveal from "./reveal.svelte";
9
-
10
- // =========================
11
- // TYPES
12
- // =========================
13
- type Props = {
14
- data: TData[];
15
- xKey: keyof TData & string;
16
- yKey: keyof TData & string;
17
- color?: string;
18
- height?: number;
19
- smooth?: boolean;
20
- /** Show a dot at the latest point */
21
- endCap?: boolean;
22
- /** Show the latest value as inline text */
23
- showLast?: boolean;
24
- /**
25
- * Ornament mode: no tooltip, no highlight, no end cap, and the plot runs to the edges of its box.
26
- */
27
-
28
- /*
29
- * For a line inside a control that already states the number and owns the pointer, such as a stat card that links.
30
- */
31
- bare?: boolean;
32
- formatValue?: (v: number) => string;
33
- class?: string;
34
- };
35
-
36
- // =========================
37
- // PROPS
38
- // =========================
39
- let {
40
- data,
41
- xKey,
42
- yKey,
43
- color = "var(--chart-1)",
44
- height = 44,
45
- smooth = true,
46
- endCap = true,
47
- showLast = false,
48
- bare = false,
49
- formatValue = (v) => v.toLocaleString(),
50
- class: className,
51
- }: Props = $props();
52
-
53
- // =========================
54
- // STATE
55
- // =========================
56
- let active = $state<TData | null>(null);
57
-
58
- // ========================= FUNCTIONS ========================= WHY: called from the tooltip header's value expression so it re-runs on every active-point change; an unread {@const} side effect only evaluates once.
59
-
60
- // The microtask defers the state write out of template evaluation.
61
- function trackActive(d: TData): string {
62
- queueMicrotask(() => {
63
- active = d;
64
- });
65
- return String(d[xKey]);
66
- }
67
-
68
- // =========================
69
- // DERIVED
70
- // =========================
71
- const uid = `hr-spark-${Math.random().toString(36).slice(2, 8)}`;
72
- const curve = $derived(smooth ? curveMonotoneX : undefined);
73
- const last = $derived(data.length > 0 ? data[data.length - 1] : null);
74
- const display = $derived(active ?? last);
75
- const dot = $derived(endCap && !bare);
76
- // Bare runs to the edges: the fill reaches the bottom of the box and the line keeps three pixels of head so its stroke is not cut at the series
77
-
78
- // maximum.
79
- const padding = $derived(
80
- bare
81
- ? { top: 3, bottom: 0, left: 0, right: 0 }
82
- : { top: 4, bottom: 4, left: 0, right: dot ? 6 : 0 },
83
- );
84
- </script>
85
-
86
- <!-- =========================== -->
87
- <!-- SPARKLINE -->
88
- <!-- =========================== -->
89
- <div
90
- class="hr-sparkline {className ?? ''}"
91
- role={bare ? undefined : "img"}
92
- aria-label={bare ? undefined : "Sparkline"}
93
- aria-hidden={bare ? "true" : undefined}
94
- data-bare={bare ? "" : undefined}
95
- onpointerleave={() => (active = null)}
96
- >
97
- {#if data.length > 0}
98
- <div class="hr-sparkline-chart" style:height="{height}px">
99
- <Chart {data} x={xKey} y={yKey} {padding} tooltipContext={{ mode: "bisect-x" }}>
100
- <Svg>
101
- <LinearGradient id={uid} vertical>
102
- {#snippet stopsContent()}
103
- <stop offset="0%" stop-color={color} stop-opacity="0.38" />
104
- <stop offset="100%" stop-color={color} stop-opacity="0" />
105
- {/snippet}
106
- </LinearGradient>
107
- <Reveal bleed={3}>
108
- <!-- WHY no `y0`: it defaults to the bottom of the plot, which is what
109
- a fill under a sparkline wants whatever its domain is. -->
110
- <Area y1={yKey} {curve} fill="url(#{uid})" />
111
- <Spline {curve} style="stroke: {color}; fill: none" stroke-width="1.5" />
112
- </Reveal>
113
- {#if dot && last}
114
- <!-- WHY: Points resolves its own data and hands the inner circle pixel coords; Circle's data mode clobbers the sibling Spline's data in -->
115
- <!-- this layerchart prerelease (and a bare object left the dot at the chart origin). -->
116
- <Points data={[last]} r={3} fill={color} class="hr-sparkline-end" />
117
- {/if}
118
- {#if !bare}
119
- <Highlight points lines={false} />
120
- {/if}
121
- </Svg>
122
- {#if !bare}
123
- <Tooltip.Root>
124
- {#snippet children({ data: d })}
125
- <Tooltip.Header value={trackActive(d as TData)} />
126
- <Tooltip.List>
127
- <Tooltip.Item label={String(yKey)} value={formatValue(Number(d[yKey]))} />
128
- </Tooltip.List>
129
- {/snippet}
130
- </Tooltip.Root>
131
- {/if}
132
- </Chart>
133
- </div>
134
- {#if showLast && display}
135
- <span class="hr-sparkline-value" style:color>
136
- {formatValue(Number(display[yKey]))}
137
- </span>
138
- {/if}
139
- {/if}
140
- </div>
@@ -1,103 +0,0 @@
1
- /* Styles for StatCard. Plain stylesheet (see area-chart.css for why). All
2
- selectors are already namespaced under `.hr-stat-card`. */
3
-
4
- .hr-stat-card {
5
- display: flex;
6
- flex-direction: column;
7
- gap: 0.375rem;
8
- padding: 1.25rem 1.5rem;
9
- border: 1px solid var(--border, oklch(0.92 0.004 286));
10
- border-radius: 1rem;
11
- background: var(--card, white);
12
- box-shadow: var(--chart-card-shadow);
13
- min-width: 0;
14
- /* WHY: clips the edge-to-edge chart to the card's rounded corners. */
15
- overflow: hidden;
16
- transition: border-color var(--chart-motion, 250ms) var(--chart-ease-out, ease);
17
- }
18
- .hr-stat-card:hover {
19
- border-color: color-mix(in srgb, var(--ring, var(--chart-1)) 28%, var(--border, transparent));
20
- }
21
- /* WHY: a bare figure, not a card. Dropping the chrome avoids a card-in-card
22
- when the figure is placed inside another surface, and lets the chart be the
23
- whole element. */
24
- .hr-stat-figure-only {
25
- padding: 0;
26
- gap: 0;
27
- border: 0;
28
- border-radius: 0;
29
- background: none;
30
- box-shadow: none;
31
- }
32
-
33
- /* WHY: the gauge variant sits the figure and a radial gauge side by side
34
- instead of bleeding a chart to the bottom edge; no negative margins here. */
35
- .hr-stat-gauge-row {
36
- display: flex;
37
- flex-wrap: wrap;
38
- align-items: center;
39
- gap: 1rem;
40
- }
41
- /* WHY the floor: below the width a gauge and a figure share, the row wraps the
42
- gauge to its own line rather than squeezing the figure to nothing. */
43
- .hr-stat-gauge-row .hr-stat-gauge-figure {
44
- flex: 1 1 auto;
45
- min-width: 6rem;
46
- }
47
- .hr-stat-gauge-row .hr-gauge {
48
- flex: 0 0 auto;
49
- }
50
-
51
- /* WHY: the chart bleeds past the card padding to the left/right/bottom edges,
52
- matching bklit's edge-to-edge stat-card chart; overflow:hidden on the card
53
- clips the corners to the radius. */
54
- .hr-stat-chart {
55
- margin: 0.5rem -1.5rem -1.25rem;
56
- width: auto;
57
- }
58
- .hr-stat-figure-only .hr-stat-chart {
59
- margin: 0;
60
- }
61
-
62
- .hr-stat-card .hr-stat-spline {
63
- transition: opacity var(--chart-motion-fast, 150ms) ease;
64
- }
65
- .hr-stat-card .hr-stat-bars {
66
- transform-box: fill-box;
67
- transform-origin: bottom;
68
- animation: hr-stat-grow var(--chart-motion-reveal, 1100ms)
69
- var(--chart-ease-reveal, cubic-bezier(0.85, 0, 0.15, 1)) both;
70
- }
71
- .hr-stat-card .hr-stat-bars:nth-of-type(2) {
72
- animation-delay: var(--chart-stagger, 30ms);
73
- }
74
- .hr-stat-card .hr-stat-bars:nth-of-type(3) {
75
- animation-delay: calc(var(--chart-stagger, 30ms) * 2);
76
- }
77
- .hr-stat-card .hr-stat-bars:nth-of-type(4) {
78
- animation-delay: calc(var(--chart-stagger, 30ms) * 3);
79
- }
80
- .hr-stat-card .hr-stat-bars:nth-of-type(5) {
81
- animation-delay: calc(var(--chart-stagger, 30ms) * 4);
82
- }
83
- .hr-stat-card .hr-stat-bars:nth-of-type(6) {
84
- animation-delay: calc(var(--chart-stagger, 30ms) * 5);
85
- }
86
- .hr-stat-card .hr-stat-bars:nth-of-type(n + 7) {
87
- animation-delay: calc(var(--chart-stagger, 30ms) * 6);
88
- }
89
- @keyframes hr-stat-grow {
90
- from {
91
- transform: scaleY(0);
92
- }
93
- }
94
- .hr-stat-card .hr-stat-bar-active {
95
- filter: brightness(1.08);
96
- pointer-events: none;
97
- }
98
-
99
- @media (prefers-reduced-motion: reduce) {
100
- .hr-stat-card .hr-stat-bars {
101
- animation: none;
102
- }
103
- }