tool-count-summary.tsx 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152
  1. import { Index, createMemo } from "solid-js"
  2. import { AnimatedCountLabel } from "./tool-count-label"
  3. export type CountItem = {
  4. key: string
  5. count: number
  6. one: string
  7. other: string
  8. }
  9. export function AnimatedCountList(props: { items: CountItem[]; fallback?: string; class?: string }) {
  10. const visible = createMemo(() => props.items.filter((item) => item.count > 0))
  11. const fallback = createMemo(() => props.fallback ?? "")
  12. const showEmpty = createMemo(() => visible().length === 0 && fallback().length > 0)
  13. return (
  14. <span data-component="tool-count-summary" class={props.class}>
  15. <span data-slot="tool-count-summary-empty" data-active={showEmpty() ? "true" : "false"}>
  16. <span data-slot="tool-count-summary-empty-inner">{fallback()}</span>
  17. </span>
  18. <Index each={props.items}>
  19. {(item, index) => {
  20. const active = createMemo(() => item().count > 0)
  21. const hasPrev = createMemo(() => {
  22. for (let i = index - 1; i >= 0; i--) {
  23. if (props.items[i].count > 0) return true
  24. }
  25. return false
  26. })
  27. return (
  28. <>
  29. <span data-slot="tool-count-summary-prefix" data-active={active() && hasPrev() ? "true" : "false"}>
  30. ,
  31. </span>
  32. <span data-slot="tool-count-summary-item" data-active={active() ? "true" : "false"}>
  33. <span data-slot="tool-count-summary-item-inner">
  34. <AnimatedCountLabel
  35. one={item().one}
  36. other={item().other}
  37. count={Math.max(0, Math.round(item().count))}
  38. />
  39. </span>
  40. </span>
  41. </>
  42. )
  43. }}
  44. </Index>
  45. </span>
  46. )
  47. }