Events & Downloads
Data-driven widgets as a native HTML alternative to iframe embedding (e.g. an external calendar or file-browser widget) - searchable, themeable via CSS, no cross-origin/height problem. Visually/token-compatible with Web Awesome, but not a <wa-*> custom element - plain vanilla JS + native ncss classes, works even without Web Awesome on the page. All three files are opt-in.
Setup
<script src="js/ics.js" defer></script> <!-- only needed for data-ics -->
<script src="js/events.js" defer></script>
<script src="js/downloads.js" defer></script>
events.js - four views, one engine
ONE load/render engine instead of four separate components - calendar, calendar list, event list, and single event are all the same normalized event data type, just displayed differently.
<div class="ncss-events" data-view="month" data-src="events.json"></div>
<div class="ncss-events" data-view="agenda" data-ics="calendar.ics" data-limit="8"></div>
<div class="ncss-events" data-view="list" data-src="events.json" data-limit="6"></div>
<div class="ncss-events" data-view="single" data-src="events.json" data-event-id="evt-3"></div>
data-view | Display |
|---|---|
month | Month grid (<table>), events shown as dots on the day, clicking a day opens it as a .ncss-modal |
agenda | Upcoming events, grouped by month - "calendar list" |
list | Events as a card grid (.ncss-card) |
single | One featured event (data-event-id, or the next upcoming one if omitted) |
Further attributes: data-limit (max. number of events in agenda/list), data-month (starting month for the month view, "YYYY-MM"), data-window-months (how far ahead an unbounded ICS RRULE without COUNT/UNTIL is expanded, default 18), data-week-start (first weekday in the month grid, 0=Sunday..6=Saturday - defaults based on lang: Monday for de, Sunday for en).
Data source
Two options, both resulting in the same internal event data type:
data-src: a JSON array, each element{id?, title, start, end?, allDay?, location?, description?, url?}-start/endas an ISO 8601 string ("2026-09-01"for all-day,"2026-09-01T09:00"with a time, no timezone suffix means local wall-clock time).data-ics: an.icsfile (Google/Outlook/Apple calendar export), parsed byjs/ics.js- its own dependency-free RFC 5545 parser rather than an npm package.
ICS coverage: VEVENT (UID/SUMMARY/DTSTART/DTEND/LOCATION/DESCRIPTION/URL), line unfolding, value escaping, all-day events, UTC times. RRULE subset: FREQ=DAILY/WEEKLY/MONTHLY/YEARLY, INTERVAL, COUNT, UNTIL, BYDAY (simple weekday list), EXDATE - covers the vast majority of real-world recurring events.
Not covered: TZID timezone conversion (times without a Z suffix are taken as local wall-clock time), BYMONTHDAY/BYSETPOS/BYWEEKNO, RECURRENCE-ID exceptions beyond EXDATE - see Known Limitations.
downloads.js
A file download list from JSON.
<div class="ncss-downloads" data-src="downloads.json"></div>
A JSON array, each element {title, url, size?, type?, description?} - type (the file extension without a dot, e.g. "pdf") is derived from the url's extension if omitted, and size (bytes) is simply not shown if omitted.
Live demo with all four views + downloads + sample data (JSON and .ics): demo/widgets.html.