0.0.24 • Published 2 months ago

be-calculating v0.0.24

Weekly downloads
-
License
MIT
Repository
github
Last release
2 months ago

be-calculating WIP

The Plan

Playwright Tests How big is this package in your project? NPM version

Calculate value of the output element from peer input elements.

be-calculating can't help but admire the brevity and sorcery on display here:

<form oninput="x.value=parseInt(a.value)+parseInt(b.value)">
    <input type="range" name="a" value="50">
    +<input type="number" name="b" value="25">
    =<output name="x" for="a b"></output>
</form>

It is unclear how to leverage that magic outside the confines of this example. How does the context of the names get passed so elegantly into the expression?

Anyway, be-calculating hopes to at least come close when it comes to brevity, while also providing more flexible options.

One critique of the example above is that it recalculates and rebinds the value of the sum anytime any form element inside is modified by the user.

That means if the form has 8 more input elements, the sum will be recalculated, and the value passed to output, even when editing the 8 input elements that aren't part of the sum.

be-calculating doesn't suffer from this scalability limitation.

And what if we want to pass the sum to multiple places? be-calculating can do that as well.

So what be-calculating is wanting to do with this example is shown below:

Example 1a -- The most compact notation

<form>
    <input type="range" id=a value="50">
    +<input type="number" id=b value="25">
    =<output for="a b" be-calculating onchange="a+b"></output>
</form>

Here, we are "commandeering" the onchange built-in attribute (which isn't applicable to the output element anyway).

Why?

We consider it safe to include free-ranging JavaScript expressions inside such attributes, having confidence that sanitizing algorithms will strip such attributes if not explicitly permitted by parties who should have such a say-so.

If the expression is difficult to encode inside an HTML attribute, use a script element preceding the output element:

Example 1b -- using the script/nomodule element

<form>
    <input type="range" id=a value="50">
    +<input type="number" id=b value="25">
    =<script nomodule>
        a + b
    </script><output for="a b" be-calculating onchange></output>
</form>

Think of what we've accomplished here! We have now purified the JavaScript's domain to be independent of the UI.

Code that we can patent and earn Turing Awards with!

Because now, with a little more tender loving care (described below), we can start to see that we can create a reusable function that can be used in multiple contexts -- anywhere we need to add two numbers together. We've been showing inline examples, but the code can be imported via ESM modules, which is discussed below.

This is shorthand for:

<form>
    <input type="range" id=a value="50">
    +<input type="number" id=b value="25">
    =<script nomodule>
        a + b
    </script><output for="a b" be-calculating='{
        "forAttribute": "for",
        "args": ["a", "b"],
        "propertyToSet": "value",
        "searchBy": "id",
        "searchScope":  ["closestOrHost", "form"],
        "scriptRef": "previousElementSibling",
        "recalculateOn": "change",
        "nameOfCalculator": "calculator"
    }'></output>

    
</form>

What this means is we aren't limited to adorning the output element. But if using some element other than output, the developer will need to override the default settings shown above, depending on the particular scenario.

So to specify to act on the input event, we can edit the JSON above, overriding only those values that need to deviate from the default (recalculateOn: change)

If editing JSON inside HTML attributes feels weird, the json-in-html vs-code extension makes it feel much more natural, even when editing README files. Because of the declarative, side-effect-free nature of the extension, it can be used with the web version of VSCode as well.

And the may-it-be package allows us to benefit from TypeScript tooling, and compiles to an HTML file.

be-calculating supports specific syntax for switching to the input element:

Example 1c TODO

<form>
    <input type="range" id=a value="50">
    +<input type="number" id=b value="25">
    =<script nomodule>
        a + b
    </script><output for="a b" be-calculating oninput></output>
</form>

Sharing calculated values

We may want to display the sum in various places. One way to do this is shown below:

<form itemscope be-sharing='
    Share sum from scope.
'>
    <input type="range" id=a value="50">
    +<input type="number" id=b value="25">
    =<script nomodule>
        a + b
    </script><output name=sum for="a b" be-calculating='
        {"notify": "scope"}
    '></output>
        
    <data itemprop=sum aria-live=polite></data>

    
</form>

TODO Bring back transform option?

External Module Renaming

If we want to share our calculating code with the world, we might package it as an npm package. Note that the code is library neutral, so doesn't need to be accompanied by 17 black-hole-o-grams of dependencies, and a cottage industry of boot camps to master. Just saying.

But as things stand, we will need to specify the name of the calculator thusly:

Example 3

//file calculator.js
export const calculator = ({a, b}) => ({
    value: a + b
});
    <form itemscope be-sharing='
      Share sum from scope.
    '>
        <input type="range" id="a" value="23">
        +<input type="number" id="b" value="252334">
        =<script nomodule src="./calculator.js"></script><output name="sum" for="a b" be-calculating='
            {"notify": "scope"}
        '></output>

        <data itemprop=sum></data>
    </form>

If we wish to give it a different name, be-calculating needs to know about that:

Example 4

//file TuringAwardDeservingAlgorithm.js
export const TuringAwardDeservingAlgorithm = ({a, b}) => ({
    value: a + b
});
<form itemscope be-sharing='
    Share sum from scope.
'>
    <input type="range" id="a" value="23">
    +<input type="number" id="b" value="252334">
    =<script nomodule src="./TuringAwardDeservingAlgorithm.js"></script><output name="sum" for="a b" be-calculating='{
        "notify": "scope",
        "nameOfCalculator": "TuringAwardDeservingAlgorithm"
        
    }'></output>

    <data itemprop=sum></data>
</form>

Demo

Obscure note (ignore if it not understanding the context): This behavior probably doesn't make sense to be used where it makes sense to use the trans-render web component. For that reason, not separating the be-hive registration from the be-computed class.

Viewing Locally

Any web server that serves static files will do but...

  1. Install git.
  2. Fork/clone this repo.
  3. Install node.
  4. Open command window to folder where you cloned this repo.
  5. npm install

  6. npm run serve

  7. Open http://localhost:3030/demo in a modern browser.

Importing in ES Modules:

import 'be-calculating/be-calculating.js';

Using from CDN:

<script type=module crossorigin=anonymous>
    import 'https://esm.run/be-calculating';
</script>
0.0.24

2 months ago

0.0.22

8 months ago

0.0.23

8 months ago

0.0.21

12 months ago

0.0.20

1 year ago

0.0.15

2 years ago

0.0.16

2 years ago

0.0.17

2 years ago

0.0.18

2 years ago

0.0.19

2 years ago

0.0.14

2 years ago

0.0.13

2 years ago

0.0.12

2 years ago

0.0.11

2 years ago

0.0.10

2 years ago

0.0.9

2 years ago

0.0.8

2 years ago

0.0.7

2 years ago

0.0.6

2 years ago

0.0.5

2 years ago

0.0.4

2 years ago

0.0.3

2 years ago

0.0.2

2 years ago

0.0.1

2 years ago

0.0.0

2 years ago