Welcome To Mini

Mini lets you add interactivity to your web apps without leaving your HTML.

Mini is currently in Alpha. While we don't anticipate any major API changes, there are several known issues. We're actively working on improvements and don't expect to release a beta version until 2025.

Getting Started

To add Mini to your project, simply save this file to your codebase and load it when your page loads.

<script src="/mini.js" ></script>

Alternatively you can also load Mini directly from a CDN if you prefer.

<script src="https://cdn.jsdelivr.net/npm/@rgslabs/mini.js@v0.0.5/dist/minijs.umd.js" ></script>

What can Mini do?

Mini is an extremely easy to use way to add UI Behaviour to your web software. It's not designed to store all of your state — for example it doesn't include routing or authentication — so it works best when paired with a Server-side Rendered approach.

The best way to understand where Mini shines is to see some examples.

Add classes to elements when clicked

  • Simple Dropdown Menu: "When a user clicks the button, add some classes to the arrow icon, and the hidden div that holds the menu."
<state show-menu="false">
  <button js-click="showMenu = !showMenu" js-clickout="showMenu = false">
    <div js-class="showMenu ? 'rotate-180' : '' " ></div>
    Show Menu
  </button>
  <div js-class="showMenu ? 'transform opacity-100 scale-100' : 'transform opacity-0 scale-95 pointer-events-none' "></div>
<state>
  • Simple Flight Picker: "When a user clicks the button, add some classes to the hidden flight picker div, and remove them from other divs."
Adults
> 11 years
-
+
Children
2 to 11 years
-
+
Babies
2 years
-
+
Save

Learn Mini (in Three Steps)


1. Prefix your html attributes with js- to let them evaluate javascript

For example, for form inputs, use js-value to set an input's value.

<input type="text" js-value="navigator.userAgent" />

This will display this ⤵

  • To set an element's class, use the js-class attribute
  • To set an element's style, use the js-style attribute
  • And so on...

2. Use <state> to store state

You can declare your variables by making it an attribute of the <state> tag. Attributes declared in kebab-case will be automatically be available in its camelCase form.

<state first-name="Michael" last-name="Scott">
  <input type="text" js-value="firstName + ` ` +lastName" />
</state>

This will display this ⤵


3. Use events to respond to user interactions.

Mini extends the browser's native events with shorthand attributes like js-click, js-change, js-press, js-clickout and a few others. For example, you can use thejs-click attribute to respond to elements being clicked.

<state first-name="Michael" last-name="Scott">
  <button js-click="firstName = 'Pamela'" />
  <button js-click="lastName = 'Halpert'" />
  <input type="text" js-value="firstName + ` ` +lastName"  />
</state>

Combine these patterns 👆 for infinite possibilities

Being able to declare state with the <state> tag, update state in response to interactions, and mutate the dom depending on the state, unlocks a lot of UI patterns.


More Mini

Now that you've learned the basics, here are a few more tricks you can use.

Use js-text to set the inner text of an element

<span js-text="`My lucky number is: `+Math.floor(Math.random() * 100) + 1;" />

This will display:

Use js-change to monitor form inputs, and this.value to get their values

<state first-name>
  <input type="text" js-change="firstName = this.value" />
  <span js-text="`Your first name is: ` + firstName">
</state>
Your first name is:


Use event to get the current event

You can also access the current event with the event keyword.

<button js-click="console.log(event)">Click Me</button>

Use js-load to execute code when an element is loaded

Sometimes we want code to be executed as soon as the page, or a specific element on the page, is loaded.

<div js-load="console.log('I was loaded')"></div>

Use el. to scope state to a specific dom element

The benefit of scope is that you can have groups of dom elements that all share state. But sometimes your state only needs to exist on a single element. In this case you can use the el. prefix before your variables.

<button
  js-text="el.isHovered ? 'Hovering' : 'Hover over me!'"
  js-mouseenter="el.isHovered = true"
  js-mouseleave="el.isHovered = false"
></button>

It's Just Javascript

The basic premise of Mini is to let attributes execute javascript. This means you can do anything javascript can do, including, for example:

Basic, If Else statements

<state is-active="false">
  <p js-class="if (isActive) {
              return 'bg-red-900 text-white'
            } else {
              return 'text-gray-900'
            }"
  >
    Hello World
  </p>
  <button js-click="isActive = !isActive">
    Toggle Active
  </button>
</state>
Hello World

Nested Ternaries

<div
  js-class="(selectedTab === 'When' ? 'bg-white shadow-lg' : 'hover:bg-gray-300')
          (whenSelectedTab === 'Dates' ? 'hidden' : '')"
></div>