# Custom Component: Counter

**URL:** <https://forums.realmacsoftware.com/t/custom-component-counter/48388>\
**Category:** Elements API\
**Created:** [June 26, 2025, 2:00pm UTC](https://forums.realmacsoftware.com/t/custom-component-counter/48388 "2025-06-26T14:00:51Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![dan](https://dub1.discourse-cdn.com/flex005/user_avatar/forums.realmacsoftware.com/dan/32/28516_2.png) [@dan](https://forums.realmacsoftware.com/u/dan)\
**Post date:** [June 26, 2025, 2:00pm UTC](https://forums.realmacsoftware.com/t/custom-component-counter/48388/1 "2025-06-26T14:00:51Z")

</div>

Yesterday we [“vibe coded” a counter component](https://forums.realmacsoftware.com/t/vibe-coding-animated-stats-counter-component/48349/25) with the @elementsbot here on the forum.

I spent a little extra time today tidying it up and making it more usable. In the project (included below) I also set up a couple of Templates to make it even easier to add to your own projects 🎉

 ![CleanShot 2025-06-26 at 2 .58.41@2x](https://europe1.discourse-cdn.com/flex005/uploads/realmacsoftware1/original/3X/c/3/c3c9b80303da8289f3d433a7d8540996693698cc.png)

[Open this Project in Elements](https://share.cleanshot.com/zgbSgfp7) and watch the video below to see how it all works 😀

Oh, and here’s the final code that you can copy and paste into a custom component (if you want to build it yourself):

## Template Code:

```auto
<div 
  class=""
  x-data="{ count: 0, hasAnimated: false }"
  x-intersect.once="if (!hasAnimated) { hasAnimated = true; $nextTick(() => { let start = 0; let end = +{{myNumber}}; let duration = 1500; let startTime = null; function animate(now) { if(!startTime) startTime = now; let progress = Math.min((now - startTime) / duration, 1); count = Math.floor(progress * (end - start) + start); if(progress < 1){ requestAnimationFrame(animate); } } requestAnimationFrame(animate); }); }"
>
  @if(edit)
    <div class="font-bold {{textColor}} {{headingTextStyles}} {{fontFamily}}">{{myNumber}}</div>
  @else
    <div class="font-bold {{textColor}} {{headingTextStyles}} {{fontFamily}}" x-text="count"></div>
  @endif
</div>

```

## Properties Code:

```auto
{
  "groups": [
    {
      "title": "General",
      "icon": "gearshape",
      "properties": [
        {
          "title": "Number",
          "id": "myNumber",
          "number": {
            "default": 100
          }
        },
        {
          "title": "Font",
          "id": "fontFamily",
          "themeFont": {
            "default": {
              "base": { "name": "body" }
            }
          }
        },
        {
          "title": "Size",
          "id": "headingTextStyles",
          "themeTextStyle": {
            "default": {
              "base": {
                "name": "5xl"
              }
            }
          }
        },
        {
          "title": "Color",
          "id": "textColor",
          "format": "text-{{value}}",
          "themeColor": {
            "default": {
              "name": "text",
              "brightness": 300
            }
          }
        }
      ]
    }
  ]
}

```
