bitty.js
Hello, bitty
Bitty is a web component. Wrapping it around elements makes them reactive.
This page has examples of all of bitty's features. The first is this counter. Click it to make the number go up.
Everything works by mapping data-*
attributes to functions.
For example, the counter's code looks like this:
<bitty-js
data-bridge="./counter.js">
<button
data-r="showNum"
data-c="addOne"
data-s="showNum"
>Click Me
</button>
</bitty-js>
export default class {
#num = 0;
_addOne(_) {
this.#num += 1;
}
$showNum(el, _) {
el.innerHTML = this.#num;
}
}
-
data-bridge
connects the element to thecounter.js
module -
data-r
registeres the button to receive updates whenshowNum
signals are sent -
data-c
calls the_addOne
function when the button is clicked (prepending the funciton name with a_
is part of the naming convention) -
data-s
sends theshowNum
signal when the button is clicked. It fires the$showNum
fuction which performs the updates (prepending the function name with a$
is another part of the naming convention)
There are more features, but that's everything you need to know to get started.
Using bitty
The sections below provide details about how everything works. Check them out to dig in.
Quick-Start
bitty is still under development. Quick-start instructions are on the way.
[This is a place holder stub while the content is being written]
Counter Details (Basic Functionality Overview)
Preface
This section uses a detailed breakdown of the counter example to look at the core reactive functionality bitty provides. Skip down to the Basic Examples section if you'd prefer looking at code samples to get a handle on things. They're laid out starting with the basics to support a general run through.
Starting With The Pieces
Three pieces of code come together to generate the counter example:
-
A script tag that loads the
bitty.js
file as a module:<script type="module" src="bitty.js"></script>
-
A
bitty-js
tag with abutton
in it:<bitty-js data-bridge="./counter.js"> <button data-r="showNum" data-c="addOne" data-s="showNum" >Click Me </button> </bitty-js>
-
A
counter.js
file:export default class { #num = 0; _addOne(_) { this.#num += 1; } $showNum(el, _) { el.innerHTML = this.#num; } }
The bitty-js
tag
-
bitty.js
is a web component file. It provides a<bitty-js></bitty-js>
tag. Wrapping other tags with it gives them reactive powers.Temporarily removing the
button
from our example gives us thisbitty-js
tag as a starting point:<bitty-js data-bridge="./counter.js" data-send="showNumber"> </bitty-js>
-
<bitty-js></bitty-js>
tags require adata-bridge
attribute.The
data-bridge
attribute value is a path to a JavaScript module file (counter.js
in our case). bitty imports that file an loads a class that provides the funcitons that are called when interations happen. (Widget
by default but you can change that.(TODO: See about loading a default export instead of implicitly looking for Widget.)
-
Other
data-*
attributes are optionalbitty-js
. For example, thedata-send
attribute which will come back to shortly.
The data-r
, data-c
, and
data-s
attributes
-
The reactivity bitty provides is managed by adding
data-*
attributes to tags/elements. The three main attributes are:-
data-r
Registers an element to receive notification sent viadata-s
attributes. -
data-c
Calls functions without sending notifications. -
data-s
Sends notifications to elements with correspondingdata-r
attributes.
-
button
Tag Registration
-
The button in our counter example has all three of the main
data-*
attributes:<button data-r="showNumber" data-c="addOne" data-s="showNumber"> </button>
-
bitty-js
elements go through all their children looking fordata-r
attributes when they initialize. Any children with the attribute get added (aka registered) to a list of elements whosedata-r
attributes all have the same value (showNumber
in our example). - [TKTKTK: describe how the callback function is defined]
-
bitty-js
elements attach generic event listeners to themselves after creating the element lists. Events from our example button bubble up into those listeners.
Clicking the button
Four things happen when you click the button in our example. They occur in this order:
-
The button fires a click event that gets picked up by the
bitty-js
element. -
The
bitty-js
element checks to see if the element that sent the click event (i.e. our button) has adata-c
attribute. When it finds it, it uses the attribute's value (addOne
) to call the_addOne
function from theWires
class export. We'll look at that function's code a momentarily.(NOTE: The
_
(underscore) is prepended to the function name automatically. It's part of the overall naming convention that's details in the Naming Convention section below.) -
After the
_addOne
function runs, thebitty-js
element looks back at the button element to see if it has adata-s
attribute.When it finds it, it uses its value (
showNumber
) to run through all the elements in the list with that name that was assembled earlier with all the elements that have adata-r="showNumber"
attribute.[TKTKTK: rephrase this and the earlier note to describe the list as a list of receivers].
Each element in the list is run through the
$showNumber
function from theWires
export. As with the_
on_addOne
, the$
is prepended to call the$showNumber
function automatically as part of the naming convention. -
Since our button has a
data-r
attribute with theshowNumber
value it goes through the function which call runs an.innerHTML
update on it to change the value.
With those steps completed, the button ends up with the new number
The counter.js
File
[TKTKTK: this is a placeholder stub until the content has actually been written]
Even More Things
There are other features (e.g. initialing data, batch updates, using templates, etc...), but the core functionality comes down to those three attributes.
Basic Examples
Updating HTML
<bitty-js
data-bridge="./updating-html.js">
<div data-r="updateText">
Waiting
</div>
<button
data-s="updateText">
Click me
</button>
</bitty-js>
Storing State
<bitty-js
data-bridge="./storing-state.js">
<div data-r="displayCount">x</div>
<button
data-c="increment"
data-s="displayCount">
Click Me
</button>
</bitty-js>
Loading Initial State
<bitty-js
data-bridge="./loading-initial-state.js"
data-send="displayCount">
<div data-r="displayCount"></div>
<button
data-c="increment"
data-s="displayCount">
Click Me
</button>
</bitty-js>
Updating Self
<bitty-js
data-bridge="./updating-self.js"
data-send="displayCount">
<div></div>
<button
data-c="increment"
data-s="displayCount"
data-r="displayCount">
Click Me
</button>
</bitty-js>
Update Classes
<bitty-js
data-bridge="./delta.js">
<div
data-r="setClass"
>Sample Text</div>
<div>
<button
data-c="setColor"
data-s="setClass"
data-color="red">
Red
</button>
<button
data-c="setColor"
data-s="setClass"
data-color="green">
Green
</button>
<button
data-c="setColor"
data-s="setClass"
data-color="blue">
Blue
</button>
</div>
</bitty-js>
Updating Values
<bitty-js
data-bridge="./charlie.js">
<div>
<label
for="update-values-output-slider">
Output Slider
</label>
<input
type="range"
id="update-values-output-slider"
min="0"
max="100"
data-r="sliderValue">
</div>
<div>
<label
for="update-values-input-slider">
Input Slider
</label>
<input
type="range"
id="update-values-input-slider"
min="0"
max="100"
data-c="setValue"
data-s="sliderValue">
</div>
</bitty-js>
Avoiding Feedback
<bitty-js data-bridge="./echo.js">
<div>
<label for="avoid-feedback-slider-b">Slider B</label>
<input
type="range"
id="avoid-feedback-slider-b"
data-c="setValue"
data-s="setSliderA"
data-r="setSliderB"
/>
</div>
<div>
<label for="avoid-feedback-slider-a">Slider A</label>
<input
type="range"
id="avoid-feedback-slider-a"
data-c="setValue"
data-s="setSliderB"
data-r="setSliderA"
/>
</div>
</bitty-js>
Sent Multiple Signals
Output Text: Waiting
<bitty-js data-bridge="./foxtrot.js">
<div>
<p>
Output Text:
<span data-r="displayNumber">Waiting</span>
</p>
<label for="multiple-updates-output-slider">
Output Slider
</label>
<input
type="range"
id="multiple-updates-output-slider"
data-r="setNumberValue">
</div>
<div>
<label for="multiple-updates-input-slider">
Input Slider
</label>
<input
type="range"
id="multiple-updates-input-slider"
data-c="setNumber"
data-s="displayNumber|setNumberValue">
</div>
</bitty-js>
Use Multiple Receivers
<bitty-js data-bridge="./golf.js">
<div>
<div>Copy 1: <span data-r="displayNumber"></span></div>
<div>Copy 2: <span data-r="displayNumber"></span></div>
<div>Copy 3: <span data-r="displayNumber"></span></div>
<div>Copy 4: <span data-r="displayNumber"></span></div>
<div>Copy 5: <span data-r="displayNumber"></span></div>
<div>Copy 6: <span data-r="displayNumber"></span></div>
</div>
<div>
<label for="multiple-receivers-input-slider">
Input Slider
</label>
<input
type="range"
id="multiple-receivers-input-slider"
min="0"
max="100"
data-c="setNumber"
data-s="displayNumber">
</div>
</bitty-js>
Initializing Values
<bitty-js
data-send="setSliderA|setSliderB"
data-bridge="./hotel.js">
<div>
<label for="init-slider-b">
Slider B
</label>
<input
id="init-slider-b"
type="range"
min="0"
max="100"
data-c="setValue"
data-s="setSliderA"
data-r="setSliderB">
</div>
<div>
<label for="init-slider-a">
Slider A
</label>
<input
id="init-slider-a"
type="range"
min="0"
max="100"
data-c="setValue"
data-s="setSliderB"
data-r="setSliderA">
</div>
</bitty-js>
Create Element
<bitty-js
data-send="buttonValue"
data-bridge="./create-element.js"
>
<div>
<button data-c="makeSlider" data-r="buttonValue"></button>
</div>
<div>
<div>Output</div>
<div class="output"></div>
</div>
</bitty-js>
Call Wires init
<div class="make-two-columns">
<bitty-js data-bridge="./call-wires-init.js"></bitty-js>
</div>
Template Loading Via Wires
<bitty-js
data-send="showValue"
data-bridge="./template-loading.js"
></bitty-js>
Nested Components
<bitty-js
data-send="showValue"
data-bridge="./nested-parent.js"
></bitty-js>
Nested Components with Ignore
<bitty-js
data-bridge="./nested-parent-ignore.js"
data-ignore="increment"
></bitty-js>
Getting Data From Children
<bitty-js
data-bridge="./nested-parent-calc.js"
data-ignore="increment"
data-send="showValue"
></bitty-js>
Batch Updates
<bitty-js
data-send="setValue"
data-bridge="./batch-updates.js">
<div>
<div>Greater that 10: <span data-r="check10"></span></div>
<div>Greater that 20: <span data-r="check20"></span></div>
<div>Greater that 30: <span data-r="check30"></span></div>
<div>Greater that 40: <span data-r="check40"></span></div>
<div>Greater that 50: <span data-r="check50"></span></div>
<div>Greater that 60: <span data-r="check60"></span></div>
<div>Greater that 70: <span data-r="check70"></span></div>
<div>Greater that 80: <span data-r="check80"></span></div>
<div>Greater that 90: <span data-r="check90"></span></div>
</div>
<div>
<label for="batch-update-input-slider">
Input
</label>
<input
id="batch-updates-input-slider"
type="range"
min="0"
max="100"
data-c="updateNumber"
data-b="checkNumbers"
data-r="setValue"
/>
</div>
</bitty-js>
Batch Initialization
<bitty-js
data-batch="checkNumbers"
data-send="setValue"
data-bridge="./batch-updates.js">
<div>
<div>Greater that 10: <span data-r="check10"></span></div>
<div>Greater that 20: <span data-r="check20"></span></div>
<div>Greater that 30: <span data-r="check30"></span></div>
<div>Greater that 40: <span data-r="check40"></span></div>
<div>Greater that 50: <span data-r="check50"></span></div>
<div>Greater that 60: <span data-r="check60"></span></div>
<div>Greater that 70: <span data-r="check70"></span></div>
<div>Greater that 80: <span data-r="check80"></span></div>
<div>Greater that 90: <span data-r="check90"></span></div>
</div>
<div>
<label for="batch-update-input-slider">Input</label>
<input
id="batch-updates-input-slider"
type="range"
data-c="updateNumber"
data-b="checkNumbers"
data-r="setValue">
</div>
</bitty-js>
Customize Event Listeners
<bitty-js
data-listeners="mouseover|mouseout"
data-bridge="./set-listeners.js">
<div data-r="sawMouse">Waiting...</div>
<button data-s="sawMouse">Mouse Instead of Click</button>
</bitty-js>
Element Access
<style>
.element-access-class {
background-color: var(--element-access-background);
}
</style>
<bitty-js
data-bridge="./element-access.js">
<div class="element-access-class">
the quick fox
</div>
<button data-c="randomizeBackground">
Randomize Background
</button>
</bitty-js>
Isolated Elements
<style>
.isolated-element {
background-color: var(--isolated-element-background);
}
</style>
<div>
TODO: change so div backgrounds are changed since you can't see the button
backgrounds change when the over CSS is in play
</div>
<bitty-js data-bridge="./isolate-element.js">
<button data-c="randomizeBackground" class="isolated-element">
Randomize Background
</button>
</bitty-js>
<bitty-js data-bridge="./isolate-element.js">
<button data-c="randomizeBackground" class="isolated-element">
Randomize Background
</button>
</bitty-js>
Examples To Make
- pass data to template via data-*
- 3+ levels of nesting
- global send/receive
- Example using templates from the HTML
- Update values in data attrs and show other components picking up the changes.
- Change attrs and HTML of elements outside the component
-
Explicit example of an element which has multiple
data-r
receivers -
Show example of event which calls a function with
data-c
but doesn't send adata-s
event.
Color Picker Example
Status: Beta
I'm still working on the initial feature set. Everything you see in the examples below is working. More to come with the TODOs further below.
I'll move views of the source code into the examples soon. For now, you'll need to peak at the .js files themselves to get and idea.
Here's the bitty.js web component file.
Other files are in the examples folder.
Usage
I'll push to npm soon. Copy the .js file down and use it directly for now.
- Copy the bitty.js component file somewhere you can get to it without CORS issues.
-
Make a file called
example.js
and paste this into it:export class Wires { #counter = 0; _increment(_) { this.#counter += 1; } $displayCount(el, _) { el.innerHTML = this.#counter; } }
-
Add this to your web page:
<bitty-js data-wires="./example.js"> <button data-c="increment" data-s="displayCount"> Click Me </button> <div data-r="displayCount">No initial state</div> </bitty-js>
[Change the
data-wires
attribute to point to yourexample.js
file as necessary] -
Call bitty one time on your page with:
<script type="module" src="bitty.js"></script>
[Change the
src
path as necessary]
That's it.
You should have your own working copy of Storing State example from below.
Quick Notes
I'm working on docs. For now, the important things to know are:
-
data-c
attributes call functions. They map to functions in theWires
class that start with an underscore followed by the name from the attribute.For example:
data-c="increment"
calls_increment
. -
After the functions are run, the
data-s
anddata-r
attributes send and receive updates, respectively. The updates are handed via functions in theWires
class that start with a$
followed by the same name.For example,
data-s="displayCount"
anddata-r="displayCount"
connect via the$displayCount
function in theWires
class. -
The first argument passed to a
data-s
/data-r
function (i.e. the ones that start with a$
) is the element that's using it via adata-r="FUNCTION_NAME"
attribute.You can do all the standard stuff with the element.
That should get you started. Poke around the examples to see more until I get more docs up
Getting Updates
Checkout the scratch notes at the end of the page for things I'm working on and considering. Follow me on mastodon, bluesky, or my RSS feed for updates. And, if you have feedback, please let me know!
-a
Design Goals
[NOTE: these are scratch notes. some of this will got to the features list below]
- [x] No build steps required
- [x] Single file usage
- [x] Minimal API. Minimal boilerplate.
- As simple as possible. As complex as necessary.
-
[x] Default
data-s
is limited to a specific instances and its ancestors - [] First class error reporting
-
[x] Functionality defied by loading an arbitrary
Wires
class - [x] Separation of concerts between function calls, sending signals, and receiving signals
- [x] Allow any standard manipulation of the receiving element (e.g. can change innerHTML, value, classes, etc.)
- [x] Use naming conventions for all core functionality
- [x] Style directly from the parent page
- [x] New elements participate in the function execution and signals
- [x] Rely on built-in functionality as much as possible
-
[x] Event throttling through
.requestAnimationFrame
- [x] Provide synchronous function calls
- [] Provide asynchronous function calls
- [] Provide asynchronous await function calls
- [] Provide asynchronous then function calls
- [x] Provide synchronous signals
- [] Provide asynchronous signals
- [] Provide asynchronous await signals
- [] Provide asynchronous then signals
- [x] Multiple instances work independently a single page by default
- [] Monitor elements outside the component for changes by attaching listeners to them via query selector
-
Wires components can communicate with their parent
bitty-js
through a bridge (e.g. to run.querySelector()
calls on thebitty-js
element - TODO: Multiple instances on the same page can cross communicate with and update each other
- TODO: Set instance specific style variables from inside the component
- Use values directly (i.e. don't have to call out to an external function to update a slider value you just changes)
- TODO: Components can be nested
- MAYBE: Child components can communicate with parent through bridge
- MAYBE: Parent components can communicate with children through bridge
- Intuitive data passing
Naming Convention
[This section is currently just a placeholder stub. Content will populate as progress continues]
Error Handling
Providing good, actionable error messages is an explicit design goal. Details about them will be added here as work continues.
Things to add
- Describe error messages
- example of using CSS styles added to components and elements with errors to highlight them
Features
This section is currently at the level of draft/scratch notes. Expect some duplication and possibly conflicting items.
- [] First class errors and debugging.
- [] All reactive elements have unique IDs.
- [] loadReactors is an event that bubbles so all ancestors can reload.
-
[]
data-ignore
on elements tells it to ignore specific signals. -
[]
data-include
attr for elements. Only the signals named in it are reacted to. All others are ignored. TBD on interaction withdata-ignore
. -
[] An empty
data-include
in one way to turn off all reactions. -
[]
data-inert
attr is an explicit way to turn off all reactions. - [] Each element is checked to make sure it's still set up to react to a given signal every time it receives one before the update occurs.
- [] All reactive elements have unique ids.
-
[] Name-spaced signals (i.e. signals with the format
NAMESPACE:SIGNAL
) are broadcast globally. - [] Elements can receive name-spaced signals regardless of their relationship to the broadcaster.
- [] Error CSS class added to elements where errors occur.
-
[] Built in debugger (TBD on specifics. Some stuff will happen
automatically like a class being added to error elements. Thinking
adding a watch for a
&debug
query param to add a close to show them is probably worth it). - [] Rust level error message: It's a bug if an error message does give you enough information on how to fix it whatever caused it.
- [] Load template from the return value of a method call.
- [] Load template from a selector query on the parent page.
- [] Can nest multiple layers with everything becoming reactive.
- [] Improve error handling and messages.
- [] Automatically load templates.
- [x] Throttling done by
.requestAnimationFrame()
. - [x]
data-call
to send functions for init. - [x]
data-b
to send batches. -
[x]
data-batch
for the init version of batch send. - [x] Parents can ignore children signals.
- [x] Parents can communicate with children through bridge.
- [x] Children can communicate with parents through bridge.
- [] Global senders.
- [] Global receivers.
- [] Query arbitrary instances for their data.
-
[x] Call
.init()
onWires
if available. - [x] bitty-js init happens after wires init so send signals can be sent to templates the wires loads.
- [x] Loading a template automatically adds call/sender/receiver functionality to it.
- [] Load other web components.
- [] Loaded web components can use
bitty-js
. -
[x] Arbitrary
data-*
attributes can be used to send data to function calls. - [] Send/receive functions can access data from the triggering event.
-
[x] Core bitty.js functionality comes in the stand alone component.
Specific behavior is defined by making a JavaScript module with a
Wires
class in it. - [x] Based off a naming convention to wire everything together.
- [x] Multiple instances can be placed on a single page.
- [x] The component uses the light DOM. Page level CSS can be applied to content inside the wires.
-
[x] Initialize data with
data-send
which does a send before the listeners are added. -
[x]: The
data-call
runs functions before doing the send events indata-send
. -
[x] Defaults to listening for
click
andinput
events. -
[x] Customize the event listeners with
data-listeners
in thebitty-js
component tag. - [x] CSS style variables/properties can be updated at the page/root level.
-
[x] CSS style variables/properties can be updated scoped to the
individual
bitty-js
element instance. - [x] Classes can be updated.
- [x] .innerHTML can be updated.
- [x] .values can be updated.
- [] datasets can be updated.
- [] aria labels can be updated.
-
[x] Can use
data-batch
anddata-b
for sending batches of signals. - [x] The data-send attribute on the main component tag sends those signals at the start.
- [] Errors are thrown if the requested wires import doesn't exist or doesn't load.
- [] Preflight check to make sure functions exist and provide warnings if they don't.
- [] Stress test with increasing numbers of instances and updates.
- [] Send signals from internal functions in the wires? (e.g. a type of redirect).
- [] Defined, ID based error messages. Each message contains a description and, ideally help text.
- [] Documentation on adding custom errors from the tool classes (thinking they'll start with 9000 so they can be integers but be safe from collisions).
-
[] Example of using
data-widget
to call something other than the defaultWidget()
class. -
[x] Add a
bitty-component-error
class to components that have errors. -
[x] Add a
bitty-element-error
class to elements that have errors.
Out-Of-Scope
These items are not in scope for bitty.js
. They are the
responsibility of Wires
classes:
- OUT-OF-SCOPE: Preventing DOM updates if an event sends the same value that's already set for an output
- OUT-OF-SCOPE: Preventing infinite nesting attempts
- OUT-OF-SCOPE: Routing between pages
-
OUT-OF-SCOPE: Advanced throttling beyond
.requestAnimationFrame
- OUT-OF-SCOPE: Debouncing events
- OUT-OF-SCOPE: Data storage
- OUT-OF-SCOPE: JSX
Known Bugs
This is largely a placeholder. Things will be added as features become stable
- Code blocks in light mode are hard to read. (styles are currently hard coded. they need to be moved to classes so the can switch between accessible colors for both light and dark mode)
- Debugging output shows the line number from the debug function instead of where it was called from
Queue
- TODO: Move to classes for syntax highlighting so code snippets have good contrast in both light and dark modes
- TODO: Refactored color picker to multiple components
- TODO: Custom error messages can be added from individual tools/modules/whatever they end up being called
- TODO: Moved examples into individual file sets to output code samples along with the examples themselves.
Release Notes
-
Version: 0.2.3
June 5, 2025
Lots of error handling work in this one.
-
Moved UUID generation for the
bitty-js
and alldata-*
reactive elements to the first thing inconnectedCallback()
to aid in error messaging. -
Made
connectedCallback()
andasync
function to throw loading the widget module into its own funcitoun -
Created an
#errors
private var to store error messages and help by ID. - Added the first few error messages
-
Added
this.error()
for outputting errors. It takes two optional arguments: an ID and an Element. The ID maps to the IDs in#errors
. They're used to add detail and help message to the error output.The ID defaults to
0
which is an unclassified error type. The message for that ID includes a note to the developer to use an ID to classify the error. I consider it a bug if an appropriate ID doesn't exist and request an issue be open to fix it.The
this.error()
method dumps thebitty-js
elemnet after the message.If an element was passed to
this.error()
it's dumped out as well.The error message end up being pretty long. The end up adding a bunch of lines to the source file. That's an explicit decision aimed at making bitty easier to work with.
-
Added top level
debug
function that uses adebug
search query param from thewindow.location
to see if it should output.Only thing I don't like about it is that it shows the function's line number instead of the line number from where it was called. Something to look into.
-
The
debug
function takes an optional element. It dumps it to the console if one comes in. -
Renamed
data-wires
todata-bridge
. Fits better and maps nicer to the.bridge
coming back in from the support class. - Set up to load the default class exported from a widget module if no other class is defined (which happens with 'data-widget')
- Moved all examples to use a default class export instead of a named class
-
Added a
data-widget
attribute to thebitty-js
elements to allow using multiple classes from inside a single supporting .js module file. -
bitty-component-error
andbitty-element-error
classes are added to the class list of elements where errors occur.
-
Moved UUID generation for the
-
Version: 0.2.2
June 4, 2025
Added UUIDs for pending error handling. Shuffeld a bunch of stuff around to make the examples look nicer.
-
Added uuids as
data-uuid
attrs to all elements with relateddata-*
attributes. Added them to thebitty-js
elements too. I was originally thinking I'd add the UUIDs on the elements internally (i.e.el.uuid
instead ofel.dataset.uuid
).I decided on the attribute approach because it offers two benefits: 1. You can see the IDs in the Element tree view of developer consoles, and 2. You can address them with CSS to update styles based on the UUID. Both of those thing will go to supporting better error messages and bug hunting.
- Mostly content updates largely focused on detailing the opening counter example.
- Added CONTRIBUTING file.
- Added watcher script to build site when files change.
-
Refined the initial counter example to remove the text and
change the private variable to
this.num
to make the examples look nicer. - Moved the Examples section directly below the initial basic functionality overview section.
- Added reminders all over the place to edit the template and instead of the output for HTML page (which would be overwritten. ask me how I know).
-
Started adding
prettier-ignore
comments to code snippets to prevent the display output from being mangled. -
Started stripping
prettier-ignore
comments from the HTML output so it doesn't show in the example -
Same goes for
// deno-fmt-ignore-file
in .js files - Added script to maintain the open open/closed states of the section details elements across page loads. (Having them close every time I made a change was maddening)
-
Moved all the example
.js
files into the site root. Not a fan of that in general, but it makes the examples look better since the path is shorter.
-
-
Version: 0.2.1
June 3, 2025
Some more wiring and some support tools for making the demo/docs site.
- Made a Hello, World example that shows basic features. (Compared to the single button press from the prior first example.)
- Showing Hello, World code as part of the example.
- Load templates automatically.
- Throttling via
.requestAnimationFrame()
. -
Renamed
data-f
todata-c
(i.e. "call") for clarity. -
Renamed
data-prep
attribute onbitty-js
tag todata-call
(i.e. "call") for clarity. -
Renamed
data-init
attribute onbitty-js
tag todata-send
so it matchesdata-s
more closely. - Made basic site builder for landing page.
-
Moved everything into
details
elements for the landing page.
-
Version: 0.2.0
June 3, 2025
Setting up a bunch of the basic wiring.
-
Rewrite to provide direct access to receiving elements. They are
fully accessible in the send/receive functions. (As compared to
the 0.1.0 approach which required explicitly defining what would
happen via an update (e.g. update
.innerHTML
or.value
). -
Renamed
data-wrapper
and the targetWrapper
class todata-wires
andWires
. (bitty.js
is the wrapper. TheWires
class is how things are hooked up.). -
Added
data-call
attribute parsing tobitty-js
tag. It runs functions likedata-c
but does so prior to adding the event listeners to the element. -
Added
data-batch
attribute processing tobitty-js
tags. It operates likedata-b
but fires before event listeners are added. -
Added
data-ignore
attribute to allow components to avoid calls to the named functions. (Send signals bubble up to parents of nested components by default. This provides a way to ignore them). -
The
bitty-js
element looks for an.init()
method in theWires
class. If it finds one it calls it during the initialization process. - Passing both the element and the triggering event to the send/receive functions.
-
Moved to using
data-b
explicitly to separate block calls from individual function calls. - Order of operations is: function calls, batch calls, single send calls.
- Temporarily removed preflight check until global functionality is defined.
-
Created example of loading a template via the
.init()
call back to theWires
class. - Created example with nested components.
- Created example with parent of child components pulling data from the children to do a calculation.
- Created example showing parent ignoring send signals from children.
- Created example showing on components loading a child component via a template that becomes fully reactive.
-
Rewrite to provide direct access to receiving elements. They are
fully accessible in the send/receive functions. (As compared to
the 0.1.0 approach which required explicitly defining what would
happen via an update (e.g. update
-
Version: 0.1.0
June 2, 2025
Getting the project started.
- Initial prototype.
-
<bitty-js>
wraps elements to provide them with reactive capabilities. -
Basic
data-c
,data-s
, anddata-r
in place to call functions, send, and receive updates, respectively. -
Functionality is loaded using
data-wrapper
to point to a module to load. The module must export aWrapper
class that gets loaded and used to provide functions and send/receive callbacks. -
Uses string prefixes to make determinations about how to handle
data through the send/receive channels (e.g.
htmlSOMETHING
updates.innerHTML
of an element whilevalueSOMETHING
updates the.value
). -
Defined convention for functions.
data-c
maps to functions in theWrapper
class that start with a_
(underscore). Thedata-s
anddata-r
attributes map to functions in theWrapper
class that start with a$
(dollar sign). -
Decided against using
data-c data-s and data-r
on thebitty.js
tags. That would involved a lot of extra overhead in parsing to differentiate between the top level element and the content it wraps. Usingdata-send
instead as a replacement fordata-c
. Others, TBD. -
Set up
data-c="batchSOMETHIGN"
functionality to send a single single that gets turned into multiple signals in theWrapper
. -
Defined convention of using
.batches
to look for batches. It must be a hash where the keys match the incoming request and the value is an array of functions to run. -
Defined
.bridge
to allowWrapper
functions to access the parentbitty-js
element. -
Scoped event listeners to the
bitty-js
elements. -
Set up
data-listeners
attribute onbitty-js
tags to override the default listeners (which areinput
andclick
). - Created example that stores its own state.
- Created example that updates an element with the same content it sent (i.e. verified feedback can be avoided).
-
Created example using
data-send
to load initial values. - Created example that sends multiple signals.
- Created example with multiple elements receiving the same signal.
- Created example showing how to update global CSS variables/properties.
- Created example showing custom event listeners.
-
Created example showing how to update CSS variables/properties
scoped to the content of individual
bitty-js
tags. - Examples use parent page's CSS for styling. It confirms I'm happy with the choice to use the light DOM instead of the shadow DOM.
- Set up initial preflight check to ensure functions are in place.