# Counter (Example) This tutorial walks through building a simple counter application to demonstrate VoltX.js fundamentals: reactive state, event handling, computed values, and declarative markup. ## Basic Counter (Declarative) The simplest way to build a counter is using declarative state and bindings directly in HTML. Create an HTML file with this structure: ```html Counter - VoltX.js

0

``` **How it works:** The `data-volt` attribute marks the root element for mounting. Inside, `data-volt-state` declares initial state as inline JSON. The framework converts `count` into a reactive signal automatically. The `data-volt-text` binding displays the current count value. When the signal changes, the text content updates automatically. The `data-volt-on-click` binding attaches a click handler that increments the count. We call `count.get()` to read the current value and `count.set()` to update it. Finally, `charge()` discovers all `[data-volt]` elements and mounts them with their declared state. ## Adding Decrement Extend the counter with both increment and decrement buttons: ```html

0

``` Each button calls `count.set()` with a different expression. The decrement button subtracts 1, while increment adds 1. ## Computed Values Add derived state using `data-volt-computed` to show whether the count is positive, negative, or zero: ```html

0

Status: zero

``` The `data-volt-computed:status` attribute creates a computed signal named `status`. It uses a ternary expression to classify the count. When `count` changes, `status` recalculates automatically. ## Conditional Rendering Show different messages based on the count value using conditional bindings: ```html

0

The count is zero

``` The `data-volt-if` binding conditionally renders elements. Only one paragraph displays at a time based on the count value. A reset button sets the count back to zero. ## Styling with Classes Apply dynamic CSS classes based on state: ```html ``` ```html

0

``` The `data-volt-class` binding takes an object where keys are class names and values are conditions. When `count` is positive, the `positive` class applies. When negative, the `negative` class applies. When zero, the `zero` class applies. ## Persisting State Use the persist plugin to save the count across page reloads: ```html

0

``` The `data-volt-persist:count="localStorage"` binding synchronizes the `count` signal with browser localStorage. When the count changes, it's saved automatically. When the page loads, the saved value is restored. ## Step Counter Build a counter that increments by a configurable step value: ```html

0

``` The `data-volt-model` binding creates two-way synchronization between the input and the `step` signal. As you type, the step value updates. The increment and decrement buttons use the current step value. ## Bounded Counter Add minimum and maximum bounds with disabled button states: ```html

0

Range: to

``` The `data-volt-bind:disabled` binding disables buttons when the count reaches the minimum or maximum. The decrement button disables at the minimum, and the increment button disables at the maximum. ## Programmatic Counter For applications requiring initialization logic or custom functions, use the programmatic API: ```html ``` This approach creates signals explicitly using `signal()` and `computed()`. Functions are defined for event handlers and passed to the scope object. The `mount()` function attaches bindings to the element. Use programmatic mounting when you need: - Complex initialization logic - Integration with external libraries - Signals shared across multiple components - Custom validation or transformation ## Summary This counter demonstrates core VoltX.js concepts: - Reactive state with signals - Event handling with `data-volt-on-*` - Computed values deriving from state - Conditional rendering with `data-volt-if` - Two-way form binding with `data-volt-model` - Attribute binding with `data-volt-bind:*` - Dynamic classes with `data-volt-class` - State persistence with plugins ## Further Reading - [State Management](./state) for advanced signal patterns - [Bindings](./bindings) for complete binding reference - [Expressions](./expressions) for template syntax details - [Lifecycle](./lifecycle) for mount/unmount hooks - [Server-Side Rendering](./ssr) for hydration strategies