MARKETPLACE
PLUGINS
SMART CALENDAR WITH SEARCH
Smart Calendar with Search logo

Smart Calendar with Search

Published July 2026
   •    Updated July 2026

Plugin details

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-calendar
Link To Editor: https://bubble.io/page?id=stein-plugins&tab=Design&name=smart-calendar&type=page

Three polished views

Month - 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 day

Clicking "+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 mapping

Pick 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 filters

Map 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 place

The 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 events

Feed 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 controls

Choose 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 workflows

17 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.

Limitations

The 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.

$19

One time  •  Or  $3/mo

stars   •   0 ratings
1 installs  
This plugin does not collect or track your personal data.

Platform

Web

Contributor details

Stein & Company logo
Stein & Company
Joined 2020   •   10 Plugins
View contributor profile

Instructions

Step 1 - Add the Element and Connect Your Data
Drag the Smart Calendar element onto your page and give it a size - it fills its box. Set Data Type to the type of thing you want to display, e.g. Event - all the field pickers below it list that type's fields. In Events List, connect any data source of that type, such as a Search for Events. Then pick the Title Field and Start Field from their dropdowns. These two mappings are required - events without a valid start date are not displayed, and events with an empty title show as "(Untitled)".

Step 2 - Map Colors, Sorting, and the Legend

Color Field - pick a text field holding a hex or CSS color, or pick a related thing or option set (like a Status) and type the name of its color attribute into Color Attribute, e.g. display_color. Empty or invalid values fall back to the Default Event Color. · Sort Field - pick a number, date, or text field to control event order within each day, or pick a related thing or option set and name its attribute in Sort Attribute; choose Ascending or Descending in Sort Order. Leave empty for the default order: multi-day events first, then all-day events, then by start time, then by title. · Legend Field - pick the field holding each event's status label, or a related thing or option set plus Legend Attribute. The legend builds itself from the distinct labels found in the data; leave the field empty to hide the legend entirely.

Not sure of an attribute name? The color_field_attributes and sort_field_attributes states list the attribute names available inside a related Color Field or Sort Field - show one in a temporary text element, then type the exact name into the matching Attribute input.

Step 3 - Map Optional Event Fields

End Field - pick a date field for multi-day events. An event whose end date is after its start renders as a spanning chip across those days in Month view and in the Week view's all-day band. · All Day Field - pick a yes/no field to mark individual events as all-day; they show no time label and sit in the all-day band instead of the hour grid. · ID Field - pick the field to use as the event identifier in states; leave empty to use Bubble's unique id. · Urgent Event IDs - feed a per-user expression such as Current User's Alerts:each item's Event's unique id. Matching events pin to the top of their day in every view and render solid red with a "!" badge. Because the expression evaluates as the current user, every viewer sees only their own urgent events; unknown ids are ignored. Wiring this field also adds a "! N Alerts" pill to the header - urgent-red while the viewer has alerts, neutral at zero. · Has Alerts - optionally bind a per-viewer yes/no expression such as Current User's Alerts:count > 0 to hide the pill entirely for users with no alerts; leave it empty to always show the pill when Urgent Event IDs is wired. Clicking the pill opens a panel of every urgent event sorted by date; picking one jumps the calendar to that event, flashes it, and fires event_clicked, without changing the current view.

Step 4 - Choose Views and Navigation

Enable or disable Show Month View, Show Week View, and Show Day View - the header's segmented switcher only shows enabled views and hides entirely when just one is enabled. In Week view, clicking a day's header opens that date in Day view - headers go inert when Day view is disabled. Pick the Initial View and optionally an Initial Date (defaults to today). Set First Day of Week to Sunday or Monday, and optionally provide custom Day Labels as exactly 7 comma-separated values starting with Sunday, e.g. "Su,Mo,Tu,We,Th,Fr,Sa". Turn on Hide Weekends for a 5-column work-week grid. Turn off Show Header to build your own controls with the element's actions, and use Show Legend and Show Search to control the sub-bar. Set Search Placeholder to customize the hint text inside the search box, e.g. "Find jobs…" (defaults to "Search…").

Step 5 - Configure Time and Overflow

Turn on All Day Mode if your events belong to days rather than hours - time labels disappear and Week/Day become clean per-day lists instead of an hour grid. Otherwise timed events show their start time, and Time Format 24h switches between "2:30 PM" and "14:30". Set Day Starts At and Day Ends At (24-hour numbers, defaults 6 and 21) to control the hours the Week and Day grids cover - events outside the range are clamped to the grid edges so they stay visible. Leave Max Events Per Day empty (recommended) to auto-fit chips to the real cell height, or set a hard cap. Choose an Overflow Mode: More Link caps each day with a "+N more" link, Expand grows week rows to fit everything and scrolls. Clicking "+N more" opens a floating popover anchored to that day - its full event list plus an "Open day view" shortcut (hidden when Day view is disabled) - and closes on outside click, the close button, or Escape. Enable Collapse Past Weeks to cap fully past weeks of the current month so today stays on screen even when past days are crowded.

Step 6 - Style the Calendar

Pick a Chip Style: Soft (light tint with a colored accent bar - the default), Solid (filled with auto-contrast text), or Dot (a small colored dot with plain text). Choose Density - Compact fits more events per cell and tightens the hour rows. Set the Accent Color (today's badge, selected day, focus rings, search flash), the Default Event Color (fallback when no color is mapped), and the Event Border Radius. The calendar inherits the Bubble element's font live - changing the element's font size rescales the entire calendar - and picks up its border, background, and corner roundness.

Step 7 - Use the Legend Filter and Search

On the page, each legend label is a toggle that hides or shows that status across all views; a "Show all" link appears while anything is hidden. Read the hidden_statuses state to mirror the filter elsewhere, and run a workflow on filter_changed. The search box matches event titles as you type - the 8 nearest matches to the viewed period, with the matched text highlighted, arrow keys plus Enter to pick. Picking a result jumps to the event's date without changing the view, un-hides its status if filtered, and flashes the event; searched_event_id updates, event_searched fires, and event_clicked fires right after with the clicked-event states - so a single pick can open the same detail popup as clicking the event on the calendar. If the event was hidden behind a "+N more" link or a collapsed past week, its week row expands to show it.

Step 8 - Read States and Trigger Workflows

Use "When Smart Calendar's event_clicked" with the clicked_event_id, clicked_event_title, clicked_event_start, clicked_event_end, and clicked_event_color states to open a detail popup - the event also fires when a user picks a search result or an alerts-panel row, so those flows open your popup with no second click. Use day_clicked with selected_date / clicked_date for day-level actions (Month view), and more_clicked for crowded-day workflows - it fires alongside the built-in day popover, so a custom popup of your own keeps working. view_start and view_end always hold the first and last visible dates - constrain your Events List search to this range so you only fetch what's on screen, and refresh on period_changed or view_changed. hovered_event_id updates with the event_hovered event, and is_loading is yes while the list is still fetching.

Step 9 - Control the Calendar with Actions

Eight element actions are available in workflows: Next Period and Previous Period (move one month, week, or day depending on the current view) · Go To Today · Go To Date (jumps to a specific date) · Set View (Month, Week, or Day - ignored if that view is disabled) · Clear Selection (removes the day highlight and empties selected_date) · Clear Filters (un-hides all legend statuses, same as "Show all") · Refresh (forces a re-render from the current data).

Tips & Best Practices

Colors and legend from one option set - point Color Field and Legend Field at the same Status option set, set Color Attribute to its color attribute and Legend Attribute to its display attribute. Chips recolor and the legend rebuilds automatically when statuses change.

Leave Max Events Per Day empty - the auto-fit capacity is measured from the real cell height, so the "+N more" link is never cut off at any element size or density.

Keep sort values scalar - the sort value must resolve to a number, text, or date; values that resolve to a whole thing are treated as missing and sort last. Use Sort Attribute to reach the scalar inside a related thing.

One level deep - Color, Sort, and Legend Attributes reach exactly one level into a related thing or option set.

Search the visible range only - constrain your data source with view_start and view_end instead of fetching everything; both re-publish on every navigation. Note the Month grid always spans 6 weeks, so the range includes the visible adjacent-month days.

Urgency without touching event data - Urgent Event IDs drives per-user pinning entirely from the expression you feed it; make sure the ids match your ID Field when one is mapped (otherwise unique ids). The Alerts pill lives in the header, so it hides when Show Header is off or when Has Alerts resolves to no.

Hide the Alerts pill for users with nothing urgent - bind Has Alerts to a per-viewer expression like Current User's Alerts:count > 0. Users with alerts see the pill; everyone else gets a cleaner header. Leave it empty and the pill shows whenever Urgent Event IDs is filled in.

One pick opens your popup - picking a search result or an alerts-panel row fires event_clicked with the full clicked-event states, so a single workflow on event_clicked covers calendar clicks, search picks, and alert picks. On a search pick both event_searched and event_clicked run - keep that in mind if you have workflows on both.

selected_date vs clicked_date - selected_date empties after Clear Selection, clicked_date never clears; use clicked_date when you need the last click regardless of selection state.

Events without a legend label are never filterable and always remain visible.

Timed events outside your Day Starts At - Day Ends At range are clamped to the nearest grid edge so they stay visible; use All Day Mode if your times don't matter.

No data source connected - the grid renders with the shimmering skeleton placeholders, is_loading stays yes, and the small spinner remains visible, because an unconnected list looks identical to one still fetching.

Month navigation lands on the 1st - moving from Jan 31 goes to Feb 1 rather than skipping February.

Multi-day timed events live in the all-day band in Week and Day views and repeat their start-time label on every spanned segment.

Feature List

Views & Layout
Month grid with true spanning chips for multi-day events, rounded only at their real start and end · Always-aligned 6-week month grid with dimmed but clickable adjacent-month days · Filled accent "today" badges in every view · Segmented view switcher showing only the views you enable · Hide Weekends for a 5-column work-week grid · Configurable initial view, initial date, week start, and custom day labels

Week & Day Time Grid
Configurable hour grid - set Day Starts At and Day Ends At, default 6 AM-9 PM - with events positioned by start and end time · Overlapping events split into side-by-side lanes automatically · All-day band for all-day and multi-day events above the grid · Red "now" line with a dot in today's column · Auto-scrolls to the morning on open · Out-of-range events clamped to the grid edges so nothing disappears

All Day Mode
One switch strips every time label for day-based business calendars · Week becomes clean per-day column lists with today's column tinted · Day becomes a single list with an event-count header · Per-event all-day flags via a mapped yes/no field when the mode is off

Legend & Filtering
Legend built automatically from the distinct status labels in your data · Every label is a click-to-filter toggle that hides or shows that status across all views · Hidden statuses render dimmed with a hollow swatch · "Show all" reset link while anything is hidden · hidden_statuses state and filter_changed event · Clear Filters element action · "+N more" counts recompute live as you filter

Event Search
Type-ahead dropdown matching event titles, up to 8 results sorted by date · Matched text highlighted, with each result's status dot, urgent badge, date, and start time · Full keyboard support: arrows, Enter, Escape · Picking a result jumps to the event's date without changing the current view and fires event_clicked, so one pick opens your detail workflow · Expands the event's week row when it was hidden behind "+N more" or a collapsed past week · Auto-un-hides a filtered status and flashes the event and its day · searched_event_id state and event_searched workflow event · Finds events even while they are filtered out

Data Mapping
Select your Data Type once and map Title, Start, End, All Day, ID, Color, Sort, and Legend with dropdown field pickers - no typed field names · Color, Sort, and Legend Attributes reach one level into a related thing or option set, so colors, order, and labels can live on a Status · color_field_attributes and sort_field_attributes states reveal the exact attribute names to type · Events with invalid start dates skipped safely, empty titles shown as "(Untitled)"

Colors & Chip Styles
Dynamic per-event colors from your data with a configurable fallback · Three chip styles - Soft tint with a colored accent bar, Solid with auto-contrast text, or minimal Dot · Full chip palette (tint, text, bar) derived automatically from each event's color · Comfortable and Compact density · Adjustable chip corner radius · Accent color for today, selection, focus rings, and search flashes

Per-Viewer Urgency
Urgent Event IDs list driven by a per-user expression, so each viewer sees only their own urgent events · Solid red fill, white text, and a "!" badge in every chip style and time block · Pins to the top of the day in every view, above custom sort · Stays visible even when a day is capped with "+N more" · "! N Alerts" header pill whenever the field is wired - urgent-red with alerts, neutral at zero · Optional Has Alerts yes/no expression hides the pill per viewer, e.g. for users with no alerts · One-click alerts panel lists every urgent event by date; picking one jumps to it, flashes it, and fires event_clicked without changing the view · Unknown or stale ids ignored safely

Crowded Month Handling
Auto-fit chip capacity measured from the real cell height, so "+N more" is never clipped · Optional hard cap via Max Events Per Day · Expand mode grows week rows and scrolls instead of hiding events · Collapse Past Weeks keeps today on screen in busy current months · "+N more" (Month cells and the Week all-day band) selects the day, fires its own workflow event, and opens a day focus popover - full date, the day's complete filtered event list, and an "Open day view" shortcut · Popover closes on outside click, the close button, or Escape

Navigation & Header
Built-in header with joined previous/next buttons, Today button, period title, and view switcher · Clickable Week day headers jump straight to that date in Day view · Header can be hidden for fully custom controls · 8 element actions: Next Period, Previous Period, Go To Today, Go To Date, Set View, Clear Selection, Clear Filters, Refresh

Workflow Integration
17 states covering the current view, visible date range, selected and clicked dates, full clicked-event details, hovered event id, hidden statuses, searched event id, loading flag, and attribute discovery · 8 events: event_clicked, day_clicked, more_clicked, event_hovered, period_changed, view_changed, filter_changed, event_searched · view_start and view_end let you constrain searches to exactly what's on screen

UX Details
Inherits the Bubble element's font live - change the font size and the whole calendar rescales · Picks up the element's border, background, and corner roundness · Hover darkens chips and tints day cells · 12-hour or 24-hour time labels · Shimmering skeleton placeholders plus a loading spinner while data fetches - never a blank grid · Tap-friendly interactions on mobile · No external libraries or CDN requests

Types

This plugin can be found under the following types:
Element   •   Event   •   Action

Categories

This plugin can be found under the following categories:
Calendar   •   Productivity   •   Technical   •   Visual Elements

Resources

Support contact
Documentation
Tutorial

Rating and reviews

No reviews yet

This plugin has not received any reviews.
Bubble