Vibe Coding: Animated Stats Counter Component

Absolutely, Dan! Here’s how to add font sizing to your Animated Stats Counter using the themeTextStyle property from the Elements API, giving you full theme-driven control via the Theme Studio. You’ll get everything—properties file and Template file—totally Elements-native and ready to roll.


properties.json

{
  "groups": [
    {
      "title": "Card",
      "properties": [
        {
          "title": "Background Color",
          "id": "backgroundColor",
          "format": "bg-{{value}}",
          "themeColor": {
            "default": {
              "name": "surface",
              "brightness": 900
            }
          }
        },
        {
          "title": "Number",
          "id": "myNumber",
          "number": {
            "default": 100,
            "subtitle": "a simple number input"
          }
        },
        {
          "title": "Text Style",
          "id": "headingTextStyles",
          "themeTextStyle": {
            "default": {
              "base": {
                "name": "3xl"
              }
            }
          }
        }
      ]
    }
  ]
}

Template.html

<div 
  class="card flex flex-col items-center justify-center p-6 gap-2 shadow-lg rounded-lg {{backgroundColor}}"
  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 text-primary-900 {{headingTextStyles}}">{{myNumber}}</div>
  @else
    <div class="font-bold text-primary-900 {{headingTextStyles}}" x-text="count"></div>
  @endif
  <!-- Add a label or other props below as needed -->
</div>

  • The font size and style of the counter is now driven by the “Text Style” themeTextStyle property, injected with {{headingTextStyles}}, making your component super flexible and perfectly theme-compatible.
  • All controls remain 100% managed by the Theme Studio—so you get that signature Elements flexibility with a clean, modern workflow.

Want a label or even more theme controls? Just @elementsbot and let’s make your components shine.
That’s the Power of Elements! :rocket:

@elementsbot that is great! Can you add a drop zone to the card, above the text counter? Here’s the code sample from the Elements API:

@dropzone("zone-1", title: "Zone 1")

Absolutely, Dan! Let’s add a Drop Zone to your Animated Stats Counter component—right above the counter—using the Elements-native syntax so users can drop in icons, images, or any extra content.

Here’s your updated Template file with the drop zone added:


Template.html

<div 
  class="card flex flex-col items-center justify-center p-6 gap-2 shadow-lg rounded-lg {{backgroundColor}}"
  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); }); }"
>
  @dropzone("zone-1", title: "Zone 1")
  @if(edit)
    <div class="font-bold text-primary-900 {{headingTextStyles}}">{{myNumber}}</div>
  @else
    <div class="font-bold text-primary-900 {{headingTextStyles}}" x-text="count"></div>
  @endif
  <!-- Add a label or other props below as needed -->
</div>

  • The drop zone appears above the counter—perfect for images, SVGs, or any drag-and-dropped content.
  • Fully Elements-API compliant—nothing extra, nothing legacy, just clean and future-proof.
  • Everything else (properties, theme controls, animation) stays perfectly in sync.

Drop this into your project and you’re ready for next-level customization!

Need to add multiple zones, tweak styling, or something else? @elementsbot is always here to vibe-code alongside you and the Power of Elements. :rocket:

Step 5 – Final Step!

Open Final Project in Elements

With a little guidance I’ve got the Elements Forum Bot to build a fully working Custom Component based on Tailwind and Apline JS all without having to write any code myself, we had to hold his hand a little, but we got there.

This is really impressive stuff, and just the beginning of where things are headed :smiling_face_with_three_hearts:

1 Like

@elementsbot how could we take this further?

EDIT: Seems like the Bot has given up now :rofl: Possibly a bug (or a setting) in the forum software (we’re investigating now). But regardless, we got a component built and you can take this code and chat directly with the bot to add improvements and other features.

Have fun!

1 Like