npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@htmlbricks/hb-calendar-events

v0.76.5

Published

Classic month grid (7-day week header and variable rows) with selectable cells, “today” styling, and event chips inside each day. Supports adjacent-month padding cells, Italian holidays, JSON `events`, and the same navigation/selection events as the appoi

Downloads

8,178

Readme

hb-calendar-events (calendar-events)

Category: calendar · Tags: calendar · Package: @htmlbricks/hb-calendar-events

Summary

hb-calendar-events is a Bulma-styled month calendar rendered as a full-width table: a localized weekday header (short names, order Monday → Sunday), a variable number of week rows, and per-day cells that can show muted “padding” days from the previous/next month. Users can change the visible month, select a day (current month or padding cells), and click small event chips mapped from a JSON events list. The component dispatches changeCalendarDate, changeSelectedDate, and calendarEventClick on the host for integration with host apps or sibling calendars.


Behavior

  • Visible month is anchored by the date prop: internally, month/year are derived from that value. The default is the first day of the current month (dayjs().startOf("month")).
  • Header (month title + prev/next controls) is shown unless disable_header is enabled. Prev/next call changeMonth(±1), update date, and dispatch changeCalendarDate with { date } (a Date for the new month anchor).
  • Weekday labels use Intl.DateTimeFormat with weekday: "short" and the browser’s primary language (navigator.languages[0], falling back to "en"). Column order is fixed in markup as Mon–Sat from startOf("week") + 1..6 days and Sunday in the last column (startOf("week")).
  • Grid size: rows = ceil((daysInMonth + dayOfWeekOfMonthStart) / 7) where dayOfWeek follows dayjs’s day() (0 = Sunday … 6 = Saturday). The first row mixes previous-month padding cells and current-month days; the last row mixes current-month days and next-month padding cells; middle rows are only current month.
  • Day selection: clicking a <td> (cell) sets selected to the logical calendar date for that cell and dispatches changeSelectedDate with { selectedDate }. Padding cells select dates in the adjacent month (previous or next), not only the visible month.
  • Events: optional events array is filtered per month for the visible month, previous month, and next month so padding cells can still show chips for events that fall on those dates. For each day, chips match events whose calendar day (DD) equals the cell’s day number in the month that cell represents (current, previous, or next). Each chip is a <button>; its click handler dispatches calendarEventClick with { eventId } (the event’s id string). Chip onclick does not stop propagation; hosts that also listen on the cell should account for possible bubbling if they attach listeners outside the shadow root.
  • IEvent.link and IEvent.icon exist in typings but are not used in the current template (no link or icon rendering).
  • date-holidays: the module is imported and new Holidays("IT") is constructed, but no holiday data is read or displayed in the current markup—do not rely on Italian public holidays in the UI until that logic is wired.

disable_header coercion

Inside $effect, if disable_header is a string, it is treated as true when (case-insensitive) "true" or "yes", or when the string is empty ""; otherwise false. From HTML attributes, expect the usual string forms your custom-element layer maps to this prop.

events and selected coercion

  • If events is a string, it is JSON.parsed into an array (invalid JSON will throw at runtime).
  • If selected is a string, it is parsed with dayjs(selected).toDate() (pass a value dayjs understands, e.g. ISO 8601).

Graphics and layout

  • Structure: Optional header div (part="calendar-header") plus a single <table class="table is-fullwidth hb-calendar-table"> with <thead> (weekdays) and <tbody> (day rows).
  • Table: width: 100%, height: 100%, table-layout: fixed, min-height: 34.375rem, border-collapse: collapse. Each day cell has vertical-align: baseline, a 1px border using --hb-calendar-cell-border, and row height split evenly via inline style="height: {100/rows}%;" on <td>.
  • Header (when enabled): flex row with spacing (is-flex, is-justify-content-space-between, etc.), default month + year text in a title-sized span, and default small light buttons ˂ / ˃ for prev/next unless slots override.
  • Cells: day number in a .cell-date div; padding days use .cell-date-muted. Today adds .cell-today (accent color + bold). Selected adds .cell-selected (background). Hover on any <td> uses --hb-calendar-hover.
  • Event chips: .cell-event buttons, full width of the cell, stacked; default background --hb-calendar-event-button-color and text --bulma-white-bis. If event.color is set, inline background-color (and transparent border) override the default chip background.

Logic (implementation notes)

| Concern | Implementation | |--------|------------------| | Month navigation | changeMonth mutates date, then dispatch("changeCalendarDate", { date }). | | Event lists | $derived filters: monthsEvent, previousMonthEvents, nextMonthEvents by M + YYYY of f.date. | | Cell click vs chip | Cell onclickselectDay(...); chip onclickcalendarEventClick({ eventId }). | | id prop | Normalized in $effect to "" when falsy; used as a conventional element id hook if your layer sets it. |

Note: The $effect block contains if (typeof date === "string") dayjs(date).startOf("month").toDate(); without assigning the result to date. Prefer supplying date as a Date (or rely on your framework’s property deserialization) for a predictable visible month.


Custom element tag

hb-calendar-events

Properties / attributes (snake_case)

From types/webcomponent.type.d.ts. In plain HTML, attributes are strings; booleans are typically yes / no in this project’s web-component conventions—and this component’s $effect accepts string forms for disable_header as described above. events should be a JSON string representing an array of event objects.

| Name | Type (authoring) | Role | |------|------------------|------| | id | string (optional) | Optional identifier; coerced to "" when missing in $effect. | | date | Date (optional) | Month anchor; default start of current month. Prefer a real Date instance. | | events | IEvent[] or JSON string | Events to show as chips; optional. Parsed from string when needed. | | selected | Date or parseable string (optional) | Highlights the matching day (including padding months). | | disable_header | boolean or string (optional) | When true, the entire header block (nav + slots) is omitted. |

IEvent shape (each item in events)

| Field | Required | Notes | |-------|----------|--------| | date | yes | Event occurrence; matched by month/year/day for chip placement. | | label | yes | Chip button text. | | id | yes | Passed back as eventId in calendarEventClick. | | link | no | Typing only; not rendered. | | icon | no | Typing only; not rendered. | | color | no | If set, applied as inline background-color on the chip. |


Events (host CustomEvent)

All dispatched on the custom element host via new CustomEvent(name, { detail }), so by default they do not bubble and are not composed through the shadow boundary—listen on the hb-calendar-events element itself.

| Event name | detail (TypeScript) | When | |------------|------------------------|------| | calendarEventClick | { eventId: string } | User activates an event chip (ideventId). | | changeCalendarDate | { date: Date } | Visible month changes (prev/next). | | changeSelectedDate | { selectedDate: Date } | User selects a day cell (any row, including padding). |


CSS custom properties

Documented in extra/docs.ts (styleSetup.vars); defaults in styles/webcomponent.scss fall back to Bulma tokens.

| Variable | Role | |----------|------| | --hb-calendar-event-button-color | Default background for event chips (default: --bulma-link). | | --hb-calendar-cell-border | 1px cell border color (default: --bulma-border). | | --hb-calendar-hover | <td> hover background (default: --bulma-background-lighter). | | --hb-calendar-selected | Selected cell background (default: --bulma-info). | | --hb-calendar-today | “Today” day number color (default: --bulma-primary). | | --bulma-radius | Chip border radius (docs default 0.375rem; SCSS fallback 0.25rem). | | --bulma-white-bis | Chip text on default chip background. | | --bulma-text-weak | Muted weekday header tone. |


CSS parts (::part)

| Part | Target | |------|--------| | calendar-header | Outer header strip (month navigation area). | | calendar-current-time-header | Inner span wrapping the default month/year line (and calendar_month slot). | | cell | Each day <td> in the grid (current, padding, selected, today). |


Slots

Names and descriptions match extra/docs.ts (htmlSlots).

| Slot | Purpose | |------|---------| | header | Wraps default header content: replace entire header row layout while keeping the outer calendar-header part on the parent when disable_header is false. | | calendar_month | Replace the default month name + year text inside the title span. | | header_month_icon_prev | Replace default previous month control (default: small ˂ button). | | header_month_icon_next | Replace default next month control (default: small ˃ button). |


Typings

Authoring types for consumers and wrappers live in:

src/wc/calendar-events/types/webcomponent.type.d.ts

  • IEvent — one calendar entry (date, label, id, optional link/icon/color).
  • Component — props: id, date, events, selected, disable_header.
  • Events — maps custom event names to their detail shapes: calendarEventClick, changeCalendarDate, changeSelectedDate.

After a full web-component build, generated DOM / Svelte element typings may also list this tag under types/html-elements.d.ts and types/svelte-elements.d.ts in the package output.


Minimal example

<hb-calendar-events
  events='[{"id":"launch","label":"Launch","date":"2026-03-15T10:00:00.000Z"}]'
></hb-calendar-events>

With explicit month anchor, selection, no header, and a listener (vanilla JS):

<hb-calendar-events
  id="cal-1"
  disable_header="yes"
  date="2026-03-01T00:00:00.000Z"
  selected="2026-03-15T00:00:00.000Z"
  events='[{"id":"a","label":"Ship","date":"2026-03-15T12:00:00.000Z","color":"#2574fc"}]'
></hb-calendar-events>

<script>
  const el = document.getElementById("cal-1");
  el.addEventListener("changeSelectedDate", (e) => {
    console.log("selected", e.detail.selectedDate);
  });
  el.addEventListener("calendarEventClick", (e) => {
    console.log("event", e.detail.eventId);
  });
</script>

Adjust attribute serialization (yes/no, JSON escaping) to match how your custom element layer maps host attributes to component props.