npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

alpine-calculations

v0.2.2

Published

Easily collect values and perform calculations in Alpine.js

Readme

Alpine Calculations

Easily collect values and perform calculations in Alpine.js. Personally, I use this to perform calculations on FilamentPHP forms, but it can be used in any environment where Alpine.js is used.

NPM Version Run tests Coverage Status

[!NOTE] This plugin is a proof-of-concept. I have not yet decided if I will continue maintaining this plugin, but I will keep it available for now. Alpine.js can already do all this with x-model and x-effect, but the main goal for me was to see if I could make the front-end for calculations in FilamentPHP cleaner and more readable.

💽 Installation

You can install this plugin in your project using either a CDN or NPM.

CDN

Include the following script in your HTML:

<script src="https://cdn.jsdelivr.net/npm/alpine-calculations/dist/alpine-calculations.js" defer></script>

NPM

npm install alpine-calculations

Enable the directives attributes in your project by registering the plugin with Alpine.js.

import Alpine from 'alpinejs'
import Calculations from 'alpine-calculations'

Alpine.plugin(Calculations)

window.Alpine = Alpine
window.Alpine.start()

🛠️ Usage

» See examples/repeater.html for a detailed example

To perform calculations, let's work with a simple example of a calculator that computes the total price based on a price and quantity input:

<div x-data="{}">
    <h3>Simple Calculator</h3>
    
    <label>Price: 
        <input type="number" x-calculator-source="price" value="10">
    </label>
    
    <label>Quantity: 
        <input type="number" x-calculator-source="quantity" value="2">
    </label>
    
    <p>Total: $<span x-calculator-expression="price * quantity"></span></p>
</div>

[!WARNING] This plugin uses new Function() to evaluate expressions, which is safe when expressions are static and developer-controlled, but becomes a security risk when user input is involved.

Take note that the plugin is designed so that:

  • Source values: are automatically sanitized and may contain user content
  • Expression content: must always be developer-controlled and never contain user content
  • User input in expressions: are never supported!

❌ UNSAFE: Dynamic Expression Building

NEVER concatenate user input into x-calculator-expression:

<!-- DANGEROUS: Don't do this -->
<span x-calculator-expression="price + ${userInput}"></span>

<!-- DANGEROUS: Don't do this -->
<span x-calculator-expression="price * getMultiplier('${userSelection}')"></span>

❌ UNSAFE: Server-Side Expression Generation

NEVER build expressions from user input on the server:

<!-- DANGEROUS: Don't do this -->
<span x-calculator-expression="<?php echo $baseExpression . $userFormula; ?>"></span>

Using sumValuesWithId() Function

When you have multiple elements with the same source identifier, you can sum them up:

<div x-data="{}">
    <h3>Multiple Items</h3>
    
    <div>Item 1: <input type="number" x-calculator-source="item_price" value="10"></div>
    <div>Item 2: <input type="number" x-calculator-source="item_price" value="15"></div>
    <div>Item 3: <input type="number" x-calculator-source="item_price" value="20"></div>
    
    <h4>Total: $<span x-calculator-expression="sumValuesWithId('item_price')"></span></h4>
</div>

The price behind Total: $ will automatically update as you change the values in the input fields. When opening the page it would show Total: $45.

Using this in FilamentPHP

You can use this plugin in FilamentPHP forms to perform calculations on form fields. For example, you can create a form that calculates the total price based on multiple items in a repeater field:

Load it in your AppServiceProvider:

use Filament\Support\Facades\FilamentAsset;
use Filament\Support\Assets\Js;

class AppServiceProvider extends ServiceProvider
{
    // ...

    public function boot(): void
    {
        FilamentAsset::register([
            Js::make('alpine-calculations', 'https://cdn.jsdelivr.net/npm/alpine-calculations/dist/alpine-calculations.js')
                ->core(),
        ]);
    }
}

Then implement it in your form:

public function form(Form $form): Form
{
    return $form
        ->schema([
            Forms\Components\Repeater::make('items')
                ->schema([
                    Forms\Components\TextInput::make('name')
                        ->required(),
                    Forms\Components\TextInput::make('price')
                        ->numeric()
                        ->required()
                        ->extraInputAttributes([
                            'x-calculator-source' => 'price',
                        ]),
                ])
                ->columns(2),
            Forms\Components\TextInput::make('total')
                ->label('Total Price')
                ->readOnly()
                ->dehydrated(false)
                ->extraInputAttributes([
                    'x-calculator-expression' => 'sumValuesWithId("price")',
                ]),
        ]);
}

📚 Attribute Explanations

1. x-calculator-source

Purpose: Marks elements as data sources for calculations

Usage: x-calculator-source="identifier"

This directive tells the plugin to track the value of an element and make it available to calculations using the specified identifier.

Example:

<input type="number" x-calculator-source="price" value="10">
<input type="number" x-calculator-source="quantity" value="2">

2. x-calculator-expression

Purpose: Evaluates mathematical expressions and displays results

Usage: x-calculator-expression="mathematical_expression"

This directive calculates the result of an expression and displays it in the element. The expression can reference any source identifiers.

Example:

<span x-calculator-expression="price * quantity"></span>

3. x-calculator-scope

Purpose: Limits calculations to specific sections of your page

Usage: x-calculator-scope or x-calculator-scope="css_selector"

This attribute demarcates boundaries for calculations, useful when you have repeating sections that should calculate independently.

4. x-calculator-precision

Purpose: Controls the number of decimal places in calculations

Usage: x-calculator-precision="number_of_decimal_places"

This attribute specifies how many decimal places to show in the result of a calculation. It can be applied to any element with x-calculator-expression.

5. x-calculator-locale

Purpose: Sets the locale for number formatting

Usage: x-calculator-locale="locale_string"

This plugin will look for the x-calculator-locale attribute on the scope or body to determine the locale for number formatting. If not set, it defaults to whatever the user's browser setting is. This will affect how numbers are parsed and formatted from input elements of type text and non-input elements.

To override the number formatting locale, you can set the x-calculator-locale attribute on:

  1. The element with x-calculator-source or x-calculator-expression
  2. The source element's scope described with x-calculator-scope
  3. On the <body> tag.

The plugin checks these in order and uses the first one it finds. If none are found, it defaults to whatever the user's browser setting is (through new Intl.NumberFormat().resolvedOptions().locale).

<body x-calculator-locale="en-US">

The value should be a valid locale string, such as en-US, fr-FR, etc.

[!NOTE] Dynamically changing the locale attribute value is not yet supported.

You can change the name of the attribute used for localization in the plugin configuration.

🐦‍🔥 Advanced Features

Scoped Calculations

Use x-calculator-scope to create independent calculation areas:

<div x-data="{}">
    <h3>Multiple Calculators</h3>
    
    <!-- Calculator 1 -->
    <div x-calculator-scope class="calculator">
        <h4>Calculator 1</h4>
        <input type="number" x-calculator-source="price" value="10">
        x
        <input type="number" x-calculator-source="quantity" value="2">
        <p>Total: <span x-calculator-expression="price * quantity"></span></p>
    </div>
    
    <!-- Calculator 2 -->
    <div x-calculator-scope class="calculator">
        <h4>Calculator 2</h4>
        <input type="number" x-calculator-source="price" value="5">
        x
        <input type="number" x-calculator-source="quantity" value="3">
        <p>Total: <span x-calculator-expression="price * quantity"></span></p>
    </div>
</div>

Number Formatting

Use x-calculator-precision to control decimal places, for example to show tax with two decimal places:

<div x-data="{}">
    <input type="number" x-calculator-source="price" value="10.99" step="0.01">
    <input type="number" x-calculator-source="tax_rate" value="0.08" step="0.01">
    
    <p>Tax: $<span x-calculator-expression="price * tax_rate" x-calculator-precision="2"></span></p>
</div>

🧩 Configuration

You can configure the plugin to change its behavior globally when initializing Alpine.js:

import AlpineCalculator from 'alpine-calculations';

Alpine.plugin(
    AlpineCalculator.configure({
        handleNaN: () => 'N/A' // Return 'N/A' instead of NaN for invalid calculations
    })
);

Alpine.start();

Handling NaN Values

You can set a custom handler for NaN values that may occur during calculations:

AlpineCalculator.configure({
    handleNaN: () => 'N/A' // Return 'N/A' instead of NaN for invalid calculations
})

Localization Attribute

You can change what the number formatting localization attribute is by configuring the plugin:

AlpineCalculator.configure({
    localeAttribute: 'x-lang' // Change it to match your project's conventions
});