rjcc is a web calendar control written in the spirit of the suckless tools. That is to say: it has no dependencies, is reltively small (lines-of-code-wise) doesn't assume that it knows your page better than you.
This is not for if you've gone all-in on React. There are good calendar controls for React. Go use one. This is for when you just need a plain old calendar for an "old school" page (think: minimal JS), and you don't feel like dragging in a couple dozen layers of complexity just to make that happen.
Why: because while jQuery and friends do a great job of making things slightly easier to deal with the garbage that is your average browser's scripting environment, a project (i.e. your library's users) typically only uses one of those frameworks. In my case, I wasn't about to drag in another 100K or so of code just for a calendar, so I couldn't reasonably use anything that used a framework other than jQuery. There went half the contenders. I also didn't want to drag in the overengineered almost-round-wheel that is jQuery UI, so there went another half dozen. Finally, I wasn't about to fork a control just to get it working with a modern version of jQuery. Suddenly I was only left with a dozen or so options based on framework alone.
Why: I'm not really a big fan of CSS (I think it's another comically-defective web technology, although it too is improving slowly), but it's the best tool I've got for web page look and feel, and this thing had to look presentable.
So calendar controls which had tons of hard-coded styling (or which made too many assumptions about how elements would be styled) were disqualified. It's painful enough to deal with CSS on its own without having to also fight a bunch of goofy inline styling from some control at the same time. I'm also not gonna drag in a 5KB stylesheet and 20KB of images just for a 5KB calendar control, so ones that came with a ton of other resources were also skipped. This brought me down to a half-dozen or so total.
Why: Because UI interaction should be event-driven. This means that if you're building a date picker, the caller should be able to give you a callback to have invoked when the user picks a date. This callback should then receive the date that was selected. If I (the caller) have to do anything more than that just to figure out what the user picked, you're making me do too much and I'm going to skip your control and use something else. This took out a couple more candidates.
Why: Because I want the user to be able to select just a month/year or just a year. This wasn't a hard requirement as I figured I'd have to add it to the control anyways -- but the control had to at least not prove downright hostile to this sort of addition. Sadly, most did.
"Partial" dates are relatively uncommon in many "general audience" sites, but painfully-common in certain problem domains. Clinical data acquisition, for example, is rife with partial dates. Patients can't remember dates, records get lost, etc. So a control that assumes that anything date-like consists of a year, a month, and a day is not suitable.
Why: Because I'm not.
This is the one that took out all the rest of the candidates. Every single one of them assumed that I was going to be 1) displaying a calendar as a result of focusing/clicking on a text input and/or 2) taking the date that was selected and putting it into an input. Both assumptions were wrong.
I needed a control that could be used to populate an input, but a) could also be used independently b) rendered where I bloody well told it too, not just "near the input that I 'attached' it to" c) didn't mess with the input directly. I have my own event model that needs to be observed -- I don't want to fight with a third party UI component when it comes to manipulation of form controls. So yeah, from about fifty contenders to zero. (And that's leaving out things like documentation, licensing, etc.)
No options? Time to write one. This is my attempt at that.
First, flexibility. The caller determines where (or even if) the control is rendered. You can position it anywhere you'd like, use whatever mechanism you want to show/hide it, etc. You create the element that it renders to (although it does expect to own the entire contents of that element.) You can style it however you want (it has no default styling), and if the CSS class names bother you then you can change any of them. There are no "magic" class names or special stylesheets that you need to make it work. Make it look however you'd like. Go nuts. There is an example stylesheet in the tarball. You're welcome to ignore it.
Second, it has a sane event model. You can invoke the control however you'd like. If you're using jQuery or MooTools or something and want to have the calendar render when you focus on an input it's easy to do that -- but I'm not going to force you to. You have exactly one callback to deal with: when the user picks a date or partial date. You're in control of the display/hide logic, so you don't need to give RJCC callbacks for that. It doesn't know when it's visible or not, nor does it need to. So the event model is really damn simple: your callback handles an object that has year, month, and day properties. That's it.
Third, it (optionally) supports partial dates, specifically the selection of a month/year combo (with no day component) or the selection of a year only. If either of those are selected, your callback gets the selected components (year or year/month) and no date.
So those are the major features. The other ones, in no particular order are:
Month names are configurable on an instance-by-instance basis.
No notion of timezones. This is intentional: a calendar control with no notion of time which tries to handle timezones invariably makes life difficult. If you want it, feel free to add it, but you're probably better off handling this outside of the control.
No support for laughably-bad browsers (IE 6, et al.) Yes, this is a feature -- supporting the insane quirks of bad browsers has held back the world of web development for more than a decade. I don't go out of my way to break these browsers, but I haven't tried RJCC in anything older than IE 9, Firefox 17, and Chrome 31.x If you're using something else that's standards compliant, it'll work. If not, it will break. I will accept compatibility patches provided they're not too invasive. I will not accept compatibility patches for IE ≤ 8 because that's not a thing we should be doing anymore.
About 500 lines of actual code. And since there are no frameworks or other dependencies, you should be able to understand and customize it relatively easily.
Support for using it as an AMD module. If you're not using an AMD module loader, it simply creates a global constructor function (RJCC). It should be trivial to adapt to other module systems as well.
Available from this Gitlab repository