MinimalComps2 v1.5.0

minimalcomps

I know, I know, too many releases in too short a time. But I think this is the last minor release for a while. Pretty sure I’ve done most of what I really want to do with these for a v1. And I have no idea what v2 will look like. So from here on out it should be mostly patches with bug fixes and minor tweaks.

https://github.com/bit101/minimalcomps2/releases/tag/v1.5.0

What’s in it?

HSlider label positions

Up to now you could only change the position of the text label on an HSlider. Now you can put the value slider just about wherever you want it as well. Both can be placed top, left, right or bottom. There’s some logic in there to make sure they don’t overlap. A change on this one is that previously the value label would be to the right of the slider. Like this:

Old HSlider with value on right.

Now it defaults to on top. Like this:

New HSlider with value on top.

I think this looks a lot better, but it might mess things up for you. You can easily manually change it back to the right side.

ColorPicker with sliders

New color choosing sliders.

When you tab or click into the color picker’s input field, the panel will drop down, giving you RGB sliders to adjust your color. I like this SO much better. My favorite update for this release! You can make it drop up if you want, or turn this feature off altogether to just use the text field.

Dropdown drop up

You can now make the Dropdown component drop up if you don’t have room for it to drop down. This is not automatic. It’s a setting. Hey, these are minimal components.

VSlider swap labels

You can swap the position of the text and value labels on the VSlider, like you can on the Knob. Not a big deal, but someone might use it.

PlayButton component

Yup, a new component.

PlayButton

Functionally, this is the same as a Checkbox or Toggle. You click it to toggle it back and forth between two states (checked / not checked, toggled / not toggled, playing / not playing). But who wants to use a checkbox to start and stop an animation or audio?

Summary

That’s all folks. Like I said, I don’t anticipate a v1.6 for a while. But probably some v1.5.x patches here and there to fix bugs and give minor tweaks. Mostly I’m just going to be using them as much as I can in various experiments.

MinimalComps2 v1.4.0

minimalcomps

I gotta admin, I’m not crazy about how the 2 in MinimalComps2 works with the semantic versioning. Version 1.4 of version 2? Whatever.

Anyway… VERSION 1.4.0!!!

No new components this time, but some super useful features, as well as a bunch of bug fixes.

Defaults

There are some new defaults in the Defaults object. These are mostly useful if you are creating a bunch of components that need some specific property that is not settable in the constructor. Like HSlider’s text position. Rather than doing something like:

const hs1 = new HSlider(panel, x, y, "one", 0, 0, 100);
hs1.textPosition = "left";
const hs2 = new HSlider(panel, x, y, "two", 0, 0, 100);
hs2.textPosition = "left";
const hs3 = new HSlider(panel, x, y, "three", 0, 0, 100);
hs3.textPosition = "left";

You can do:

Defaults.hslider.textPosition = "left";
const hs1 = new HSlider(panel, x, y, "one", 0, 0, 100);
const hs2 = new HSlider(panel, x, y, "two", 0, 0, 100);
const hs3 = new HSlider(panel, x, y, "three", 0, 0, 100);

You can see all the properties that use this technique here.

Chainable setters

Another ease of use improvement. Basically, all settable properties now have a setter method that returns the current instance of the component. This lets you set a bunch of properties in a row and assign the result back to a variable that holds the instance. Especially useful for those properties that aren’t in the constructor, but some people don’t like the long constructors either. Along with this work, I made sure that just about all the constructor parameters are optional and have sensible defaults.

So now, if you want, you can do stuff like this:

const velSlider = new HSlider(panel)
  .setText("velocity")
  .move(x, y)
  .setSize(200, 30)
  .setHandleSize(30)
  .setMin(50)
  .setMax(200)
  .setValue(175)
  .setTextPosition("left")
  .setDecimals(2)
  .addHandler(handleSlider);

Maybe a little overboard with that example, but you get the idea.

Binding

Binding is one of my favorite features. It turns this:

new HSlider(panel, 20, 20, "velocity", 0, 0, 100, event => model.velocity = event.target.value;

to this:

new HSlider(panel, 20, 20, "velocity", 0, 0, 100)
  .bind(model, "velocity");

I wrote about this in a lot more detail here: https://www.minimalcomps2.com/docs/bind/ . So I’ll leave you with that.

Other stuff

I also upgraded the API docs a bit, both in style and content.

A bunch of bug fixes, more demos

Also, check my last few posts here for some more examples of the components in action.

I hope to get a showcase up eventually, linking to other real world uses of the library beyond my own. So if you do something with these, let me know!

MinimalComps2 v1.3.0

minimalcomps

I’m super excited to announce the latest official build of MinimalComps2. I’ve put a lot of work into these. Been seriously obsessed over them to be honest.

That’s a live demo, not a screenshot, so have a play around. The source for that demo is here. It includes instances of all 22 components in the set.

As you can see there have been several new components added since last week. I’m quite happy with all of them but I won’t go into detail about them here. Better to check the demos and docs, API documentation and source code.

For each new component I’ve made recently, I’ve made sure that:

  1. They are fully documented. I’m using jsdoc for this at the moment. I’ll probably do a bit of work on the documentation theme, but overall, I’m happy with it. In fact, ALL components are fully documented now, not just the new ones.
  2. They are fully unit tested. I actually wrote my own unit test framework. Silly I know, but I wanted it to work the way I wanted it to work. Other testing frameworks I was trying were too bloated and complex. I had a lot of fun writing this one. It’s a minimal unit testing framework, which is appropriate. Unit test frameworks are actually super simple. I think people tend to overengineer them and make them do too much. They start to morph more into integration test frameworks than purely unit testing. All the new components are fully tested. In all, nine out of the twenty two components are tested, so there’s more to do there. But that’s close to 300 individual assertions. Doing this has uncovered a lot of little bugs, so it’s been 110% worth it.
  3. Each new component has a live demo on the main site showing how it is used.

There is more work to be done on these, but I think I’m done with creating new components. Everything I added in this release was on the early list of components I wanted to create. That list is now officially empty. I’m sure I’ll have an idea or two later on, but I’m satisfied that the library fulfills its needs at this point.

The work going forward is mostly on wrapping up the unit testing, improving some standards and best practices throughout the code. I don’t feel like the code is too horrible, but there are places where I do one thing one way and a similar thing in a different way somewhere else. So getting some more consistency in there would be good. Raking the documentation over the coals too. Some of that was copied and pasted and I’m sure there are some minor errors here and there. And finally, doing more demos as examples of how to use different components.

I really hope people find these useful and hope to see some examples in the wild. If you use them, shoot me a link and I’ll share it around.

If you do find them useful and want to support the work in some way… buy me a beer/coffee/new car.

MinimalComps2

minimalcomps

Back in 2008, when Flash was still a thing, I created a set of UI controls called MinimalComps. A basic history of Flash UI controls starts with the ones that were included with Flash called “UIComponents” and later updated to “V2 Components”. Although most of the rest of the user interface world calls these things controls or ui elements or widgets, in Flash the name “components” caught on and stuck.

A lot of people created custom component sets. In 2004 I created a full featured set called “BitComponents” which I sold to a company called BeamJive. I always enjoyed making custom components, usually one off for specific needs, but in 2008, I set to work creating MinimalComps.

The idea behind MinimalComps was that they should be simple to create and use. Lots of people were doing Flash experiments and creating quick one-off apps and prototypes and proof-of-concept projects. Most existing component sets had all kinds of complicated styling and layout and data binding features which made them powerful, but gave them a bit of a learning curve. I wanted something where you could throw together a quick user interface without thinking much about it. One of the goals was to be able to create and configure most of the components in a single line of code. If you look at, say, a range slider type of component from that time, setting it up would go something like this:

var slider = new Slider();
slider.move(20, 20);
slider.value = 50;
slider.min = 0;
slider max = 100;
someParent.addChild(slider);
slider.addEventListener("change", someChangeHandler);

Up to seven lines of code to create a single slider. Some apps might have a dozen sliders. You’re getting up close to 100 lines of code just to create the sliders!

MinimalComps looked more like this:

var slider = new Slider(parent, 20, 20, 50, 0, 100, someChangeHandler);

With a signature something like:

new Slider(parent, x, y, value, min, max, handler);

I know that’s a lot of parameters, but when you’re making a lot of them, it become second nature and in the long run, 12 lines of code is better than 84 lines of code that does the same thing.

Here’s what they looked like, by the way:

MinimalComps

And that’s all they really looked like. I did later add a dark theme, but beyond that there was no theming, styling, not a whole lot of customization possible. In spite of those limitations, they became wildly popular in the Flash community. I think the height of it all was this Adidas ad/video that featured MinimalComps.

“Featured” is a stretch, but they did appear for maybe two seconds total. 🙂

Adidas and MinimalComps

Anyway, getting carried away with nostalgia. It was a good time. And then Flash died. Everyone moved to Processing or Unity3D or WebGL or, like me, just straight up JavaScript and Canvas.

I made multiple attempts to port MinimalComps to HTML, both via Canvas and HTML/CSS/JavaScript. But back in 2011, things were pretty rough in terms of the state of all of those technologies. It was just kind of painful and I gave up each time.

Jump to 2021 and things have changed. JavaScript has classes and all kinds of other very neat features. HTML has Web Components (there’s that word again) and the Shadow DOM, and CSS is … well, CSS is still CSS, but it’s probably improved somewhat. Long story short, it’s actually possible to build some pretty cool stuff now. Like MinimalComps2.

So here they are

Yeah, so MinimalComps2 is a thing now. I’ve been obsessed with it for the last several weeks. The Web Components / Shadow DOM technology has made this a lot easier. The goal was always to be able to just add a single library to your app and have all the components there. Not add multiple libraries plus CSS files, configure some kind of bundler, rely on some specific framework, etc. You can just throw the library in a script tag in your HTML file, or access it as a JS Module.

No complex layout system. Just give each component an x, y coordinate. Generally, you’ll first create a Panel component that serves as the parent and visually contains the rest of the UI, but it’s not required.

Oh, and here’s what they look like:

As you can see, I tried to stick to the original aesthetic (or lack thereof maybe). I did make some elements a bit larger (because of my eyes not being what they were 13 years ago?) but they can be made smaller if you’re into the whole barely visible thing.

Most of these components are brand new and 100% custom. Which is to say that the Button component is not a styled HTML button. Checkboxes, RadioButtons, Sliders, Dropdown, NumericStepper and ColorChooser are also built from the ground up. Why? Have you ever tried to do a custom style for a checkbox, radio button or range slider? And make it work on all platforms and browsers? It’s a CSS nightmare. I’m not saying it was easy to create these things from scratch rather than relying on existing elements, but it was a lot more fun and a lot less frustrating. And I could customize them in ways that would not really be possible across all platforms. For example, Firefox does not even support vertical range sliders. You have to hack it together with CSS rotation transforms. Same for reverse sliders where the max value is on the left or bottom and min is on the top or right. Not supported at all in HTML. Was very straightforward in a custom slider.

I was even able to implement focus indicators, tab navigation and keyboard activation for all the interactive components. I’m not saying they are fully accessible, but there is some progress there. They also work on the mobile browsers I’ve tried. It’s not a great experience on mobile to be honest, but basic functionality seems to be there.

More info

If you want to learn more about MinimalComps2, read the docs, see a bunch of live demos, head over to the minimalcomps2.com site!

And if you want to get the libraries themselves (one for global/script tag, one for JS modules) head over to the github repo: https://github.com/bit101/minimalcomps2

I’ll have more info here as things evolve. Hoping to get some small fraction of the excitement over these that the original version had!