Outgrow Bubble's built-in calendar. Search built in - type-ahead search jumps to any event, even one buried behind a "+N more" link, and opens your detail popup in one pick. Alerts built in - a per-viewer Alerts pill pins each user's urgent items red at the top of their day. Your colors, your order - point the pickers at the Status option set you already have and chip colors and sort order come along for free. No color fields bolted onto your data type, no lookup workarounds. Sort by any field or option set attribute, filter by status with the clickable legend, and show Month, Week, or Day with true multi-day spanning chips and skeleton loading. No external libraries.
Link To Demo: https://stein-plugins.bubbleapps.io/version-test/smart-calendar/smart-calendarLink To Editor: https://bubble.io/page?id=stein-plugins&tab=Design&name=smart-calendar&type=pageThree polished viewsMonth - a 6-week grid where multi-day events render as continuous spanning chips across the days they cover, with rounded corners only at their true start and end and square edges where they continue into the next week. Today wears a filled accent badge, adjacent-month days are dimmed but clickable, and the "+N more" capacity is measured from the real cell height so the link is never clipped. ·
Week - a day header row, an all-day band (single-day all-day chips per column, multi-day events as spanning chips above), and a scrollable hour grid covering the hours you choose - default 6 AM to 9 PM - where overlapping events split into side-by-side lanes, a red "now" line marks the current time in today's column, and the grid auto-scrolls to the morning. ·
Day - the same hour grid for a single day, with an all-day section on top.
Turn on
All Day Mode for business calendars where events belong to a day, not an hour: all time labels disappear and Week/Day swap the hour grid for clean per-day lists.
Drill into any dayClicking "+N more" - in the Month grid or the Week view's all-day band - opens a floating popover anchored to that day: the full date, every event on that day (respecting the active legend filter, including the events hidden under the cap), and an "Open day view" footer that jumps straight to that date in Day view. It closes on outside click, the close button, or Escape - and the more_clicked workflow event still fires, so a custom popup you've built keeps working. Week day headers are clickable too: clicking one opens that date in Day view and fires view_changed.
Point-and-click data mappingPick your Data Type once and every mapping becomes a dropdown of that type's fields - Title, Start, and optionally End, All Day, ID, Color, Sort, and Legend. No typed field names, no typos. When Color, Sort, or Legend points at a related thing or option set (like a Status), type the name of the attribute inside it into Color Attribute, Sort Attribute, or Legend Attribute - e.g. display_color. Two helper states, color_field_attributes and sort_field_attributes, list the attribute names available inside a related field so you can discover the exact name to type.
A legend that filtersMap a Legend Field and the calendar builds a legend automatically from the distinct status labels found in your data, each with its group's color as a swatch. Every label is a toggle: clicking it hides or shows that status across all views and recomputes "+N more" counts live. Hidden statuses render dimmed with a hollow swatch, a "Show all" reset appears while anything is hidden, the hidden_statuses state lists what's filtered out, and filter_changed fires on every change. A Clear Filters action resets it from workflows.
Search that doesn't lose your placeThe built-in search box matches event titles as you type and shows the 8 matches closest to the period you are viewing, listed in date order - so when a project has dozens of releases with the same name, you see the ones around the month on screen instead of the oldest ones. Years appear on results outside the viewed year. Each result shows a status color dot, an urgent badge when applicable, the matched text highlighted, and the event's date and start time. Navigate with the arrow keys and Enter, or click a result. Picking one moves the calendar to the event's date
without changing the current view, un-hides its status if it was filtered out, flashes the event chip, and pulses its day - then publishes searched_event_id, fires event_searched, and fires event_clicked with the full clicked-event states, so picking a result counts as clicking the event and your detail popup opens in one tap. If the picked event was tucked behind a "+N more" link or inside a collapsed past week, its week row expands so the event is actually visible - and stays visible until you navigate away. Search even finds events currently hidden by the legend filter.
Per-viewer urgent eventsFeed Urgent Event IDs a dynamic expression like Current User's Alerts:each item's Event's unique id. Because the expression evaluates as whoever is viewing the page, every user sees only their own urgent items - no flags stored on the shared event type. Urgent events pin to the top of their day in every view (above your custom sort), render with a solid fill in your Urgent Color (default red), subtle hazard stripes, a white separator ring with a soft glow, and a "!" badge in every chip style - unmistakable even when your status palette uses a similar red, and stay visible even when a day is capped with "+N more". Stale or unknown ids are ignored safely. Wiring the field also adds a "! N Alerts" pill to the header - urgent-red while the viewer has alerts, neutral when they have none. The optional Has Alerts field controls whether the pill appears at all: bind a per-viewer expression like Current User's Alerts:count > 0 and users with no alerts never see it. Clicking the pill opens an "Urgent Alerts" panel listing every urgent event sorted by date; picking one jumps the calendar to that event, flashes it, and fires event_clicked with the clicked-event states - without changing the current view, and expanding the event's week row if it was hidden behind a "+N more" cap. Because the ids are per-viewer, each user sees only their own alert count and list.
Design controlsChoose a
Chip Style: Soft (a light tint of the event's color with darker text and a colored accent bar), Solid (filled with auto-contrast text), or Dot (minimal, a small colored dot with plain text). Pick Comfortable or Compact
Density, set the chip corner radius, the accent color, and the fallback event color. Per-event colors come from your data, and each chip's full palette - tint, text, bar - is derived automatically from that color. Hide weekends for a 5-column work week, collapse past weeks of the current month so today never gets pushed off screen, and the whole calendar inherits the Bubble element's font live - change the font size and everything rescales. And while your data source is still loading, the calendar shows a soft shimmering preview of ghost events instead of a blank grid - the real events swap in the moment they arrive.
Built for workflows17 exposed states cover the current view, the visible date range (view_start / view_end - perfect for constraining a search to what's on screen), the displayed title, the selected and clicked day, full details of the last clicked event (id, title, start, end, color), the hovered event id, the hidden legend statuses, the last searched event id, a loading flag, and the two attribute-discovery helper lists.
8 events fire on event click, day click, "+N more" click, event hover, period change, view change, filter change, and search pick.
8 element actions give you full control: Next Period, Previous Period, Go To Today, Go To Date, Set View, Clear Selection, Clear Filters, and Refresh. Hide the built-in header and drive the calendar entirely from your own buttons if you prefer.
LimitationsThe hour grid covers the range you set with Day Starts At and Day Ends At (default 6 AM to 9 PM); events outside it are clamped to the nearest edge so they stay visible. · Search matches event titles only. · No drag-and-drop or event resizing. · Recurring events are not expanded; your data source must contain each occurrence. · Dates are bucketed in the visitor's local timezone with no conversion. · Color, Sort, and Legend Attributes reach exactly one level into a related thing or option set. · Day cells are clickable in Month view; day_clicked does not fire from Week or Day views. · View and filter choices are not persisted across page loads. · Clicks trigger workflows - event creation and editing UI is yours to build.