Mini lets you add interactivity to your web apps without leaving your HTML.
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>
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.
<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>
js-
to let them evaluate javascriptFor example, for form inputs, use js-value
to set an input's value
.
<input type="text" js-value="navigator.userAgent" />
This will display this ⤵
class
, use the js-class
attributestyle
, use the js-style
attribute<state>
to store stateYou 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 ⤵
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>
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.
Now that you've learned the basics, here are a few more tricks you can 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:
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>
event
to get the current eventYou can also access the current event with the event
keyword.
<button js-click="console.log(event)">Click Me</button>
js-load
to execute code when an element is loadedSometimes 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>
el.
to scope state to a specific dom elementThe 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>
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>
Nested Ternaries
<div
js-class="(selectedTab === 'When' ? 'bg-white shadow-lg' : 'hover:bg-gray-300')
(whenSelectedTab === 'Dates' ? 'hidden' : '')"
></div>