summaryrefslogtreecommitdiffhomepage
path: root/packages/ui/src/components/tool-count-summary.tsx
diff options
context:
space:
mode:
authorKit Langton <[email protected]>2026-03-02 17:24:32 -0500
committerGitHub <[email protected]>2026-03-02 16:24:32 -0600
commit9d7852b5c39b64b96fe1bc14a80a344a0667f0b7 (patch)
treebcbe5c2bac7e5dc203c5e1bf242a83ba5b32aaac /packages/ui/src/components/tool-count-summary.tsx
parent78069369e2253c9788c09b7a71478d140c9741f2 (diff)
downloadopencode-9d7852b5c39b64b96fe1bc14a80a344a0667f0b7.tar.gz
opencode-9d7852b5c39b64b96fe1bc14a80a344a0667f0b7.zip
Animation Smorgasbord (#15637)
Co-authored-by: Adam <[email protected]>
Diffstat (limited to 'packages/ui/src/components/tool-count-summary.tsx')
-rw-r--r--packages/ui/src/components/tool-count-summary.tsx52
1 files changed, 52 insertions, 0 deletions
diff --git a/packages/ui/src/components/tool-count-summary.tsx b/packages/ui/src/components/tool-count-summary.tsx
new file mode 100644
index 000000000..a5cb5b40d
--- /dev/null
+++ b/packages/ui/src/components/tool-count-summary.tsx
@@ -0,0 +1,52 @@
+import { Index, createMemo } from "solid-js"
+import { AnimatedCountLabel } from "./tool-count-label"
+
+export type CountItem = {
+ key: string
+ count: number
+ one: string
+ other: string
+}
+
+export function AnimatedCountList(props: { items: CountItem[]; fallback?: string; class?: string }) {
+ const visible = createMemo(() => props.items.filter((item) => item.count > 0))
+ const fallback = createMemo(() => props.fallback ?? "")
+ const showEmpty = createMemo(() => visible().length === 0 && fallback().length > 0)
+
+ return (
+ <span data-component="tool-count-summary" class={props.class}>
+ <span data-slot="tool-count-summary-empty" data-active={showEmpty() ? "true" : "false"}>
+ <span data-slot="tool-count-summary-empty-inner">{fallback()}</span>
+ </span>
+
+ <Index each={props.items}>
+ {(item, index) => {
+ const active = createMemo(() => item().count > 0)
+ const hasPrev = createMemo(() => {
+ for (let i = index - 1; i >= 0; i--) {
+ if (props.items[i].count > 0) return true
+ }
+ return false
+ })
+
+ return (
+ <>
+ <span data-slot="tool-count-summary-prefix" data-active={active() && hasPrev() ? "true" : "false"}>
+ ,
+ </span>
+ <span data-slot="tool-count-summary-item" data-active={active() ? "true" : "false"}>
+ <span data-slot="tool-count-summary-item-inner">
+ <AnimatedCountLabel
+ one={item().one}
+ other={item().other}
+ count={Math.max(0, Math.round(item().count))}
+ />
+ </span>
+ </span>
+ </>
+ )
+ }}
+ </Index>
+ </span>
+ )
+}