calendarslider

package
v0.6.15 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 5, 2026 License: MIT Imports: 11 Imported by: 0

README

CalendarSlider

Declarative, JavaScript-free month calendar: one month visible at a time, sliding to its neighbors, with holidays, occupation percentage, today marker, and single-day selection — all signal-driven.

Features

  • One month on screen at a time, starting at Start (default: today's month) and sliding forward through up to NumMonths (max 12) consecutive months. ‹ › are <button>s; a small click handler (slideToMonth) jumps the scroll-snap strip to the neighbouring month card with ScrollIntoView, and the browser's scroll-snap animates it. They are deliberately not <a href="#cs-m-...">: an anchor mutates location.hash, which a hash-routed shell (platformd) reads as a route change, blanking the view. No rebuild, no JS.
  • Week starts Monday; Sunday and holidays render red (Danger), matching the original component. Each month carries its own weekday header and a month name label below it, like the original's footer-title-month.
  • Occupation days (Occupation []OccupationDay) are selectable and show a N% bar (data-use) plus title="N%"; values clamp to 0–100.
  • Today's date is marked with a Today style and title="Hoy".
  • Selected day is a *dom.SignalString (YYYY-MM-DD) written by the host or by clicking a bookable day; the DOM patches in place via BindState(widget.Selected, ...) — no full re-render.
  • OnSelect callback fired on click, in addition to the signal.
  • Accessible: role=grid/row/gridcell/columnheader, aria-selected, aria-hidden filler cells, labeled navigation buttons.
  • Light/dark out of the box: every color comes from theme tokens (light-dark()-aware), so the calendar follows whatever data-theme the app sets — pair it with tinywasm/components/themetoggle for a user-facing switch.
  • Mobile-aware: the single-month-at-a-time layout already fits a phone; the only device-specific rule grows the day cell to a more comfortable touch target — no JS, pure On(css.Mobile, ...).

Usage

import "github.com/tinywasm/components/calendarslider"

cal := &calendarslider.CalendarSlider{
    Start:     "2026-08", // first month of the strip (defaults to today's month)
    NumMonths: 3,         // how many months forward from Start are slidable (max 12)
    Holidays:   []calendarslider.Holiday{{Date: "2026-08-15", Name: "Asunción de la Virgen"}},
    Occupation: []calendarslider.OccupationDay{{Date: "2026-08-11", Percent: 60}},
    OnSelect: func(date string) {
        fmt.Printf("selected: %s\n", date)
    },
}
cal.Init(dom.NewCtx(...))
dom.Render("app", cal.Render())

// Host-driven selection:
cal.Selected.Set("2026-08-11")

API

CalendarSlider Struct
  • Start string: Month key YYYY-MM, the first (leftmost) month of the strip; empty means the current month. There is nothing to slide to before Start — like the original, this is built for booking forward, not browsing past months.
  • NumMonths int: How many consecutive months forward from Start are slidable (default 3, max 12).
  • Holidays []Holiday: {Date, Name string}; Date is YYYY-MM-DD, shown as the day's title and rendered red. Slice, not a map — TinyGo.
  • Occupation []OccupationDay: {Date string; Percent int}; Percent clamps to 0–100. A date's presence in the list makes that day selectable. Slice, not a map — TinyGo.
  • Selected *dom.SignalString: Two-way selection signal (YYYY-MM-DD); write it to select programmatically.
  • OnSelect func(date string): Callback fired when a bookable day is clicked.
Signals
  • Init seeds Selected with dom.NewString("") when nil — safe to use before any interaction.

Screenshots

The web/ demo (Start: "2026-08", the same sample holidays/occupation shown in Usage, plus themetoggle) in all four combinations of theme and viewport:

Light Dark
Light, desktop Dark, desktop
Light, mobile Dark, mobile

Documentation

Overview

Package calendarslider ports the legacy "calendar normal" widget — a single-month view with holidays, occupation percentages and day selection, sliding between neighboring months — to the tinywasm construction harness: pure Go, zero JavaScript. The old infinite slider (JS that animated margin-left and recycled DOM nodes) becomes a bounded, pre-rendered strip of up to maxMonths months. The ‹ › controls are <button>s; a small click handler (slideToMonth) jumps the scroll-snap strip to the neighbouring month card with ScrollIntoView, and the browser's scroll-snap animates it. They are deliberately not <a href="#cs-m-...">: an anchor mutates location.hash, which a hash-routed shell (platformd) reads as a route change, blanking the view.

Index

Constants

View Source
const (
	PartWeekday         = widget.Part("weekday")
	PartWeekRow         = widget.Part("week-row")
	PartStrip           = widget.Part("strip")
	PartMonth           = widget.Part("month")
	PartMonthName       = widget.Part("month-name")
	PartDay             = widget.Part("day")
	PartDayNum          = widget.Part("day-num")
	PartDayStack        = widget.Part("day-stack")
	PartDayUse          = widget.Part("day-use")
	PartDaySelectable   = widget.Part("day-selectable")
	PartDayOff          = widget.Part("day-off")
	PartDayRed          = widget.Part("day-red")
	PartDayToday        = widget.Part("day-today")
	PartPrev            = widget.Part("prev")
	PartNext            = widget.Part("next")
	PartMonthNav        = widget.Part("month-nav")
	PartCollapsed       = widget.Part("collapsed")
	PartCollapsedToggle = widget.Part("collapsed-toggle")
	PartCollapsedCap    = widget.Part("collapsed-cap")
	PartCollapsedIcon   = widget.Part("collapsed-icon")
	PartCollapsedText   = widget.Part("collapsed-text")
)
View Source
const NameCalendarSlider = widget.Name("calendarslider")

NameCalendarSlider is the widget identity.

Variables

This section is empty.

Functions

This section is empty.

Types

type CalendarSlider

type CalendarSlider struct {
	Element // value embed — NEVER pointer (TinyGo heap constraint)

	// Start es el primer mes de la tira, formato "YYYY-MM"; vacío = el mes
	// actual (zona local). Hacia atrás de Start no hay nada que deslizar —
	// igual que el calendario original, pensado para reservar hacia
	// adelante, no para consultar meses pasados.
	Start string
	// NumMonths es cuántos meses hay para deslizar hacia adelante desde
	// Start; 0 = 3, tope maxMonths (12).
	NumMonths int
	// Holidays lista los feriados del calendario. Slice, no map — TinyGo.
	Holidays []Holiday
	// Occupation lista el porcentaje de ocupación por fecha. Slice, no map —
	// TinyGo.
	Occupation []OccupationDay
	// Selected es la fecha "YYYY-MM-DD" seleccionada, o "". Señal pública:
	// el host puede leerla y escribirla.
	Selected *SignalString
	// OnSelect se invoca al hacer clic en un día ocupable, con "YYYY-MM-DD".
	OnSelect func(date string)
	// contains filtered or unexported fields
}

CalendarSlider muestra un mes a la vez, empezando en Start, con feriados, porcentaje de ocupación, marcador de hoy y selección de día; ‹ › deslizan hacia los meses vecinos. Los días con ocupación son los únicos seleccionables — el resto se muestra como día inactivo, igual que el calendario "normal" original.

func (*CalendarSlider) IconSvg added in v0.6.15

func (c *CalendarSlider) IconSvg() *sprite.Sprite

IconSvg ships the collapsed chip's calendar glyph. FontAwesome Free 6 "calendar-day" (solid), viewBox 0 0 448 512.

func (*CalendarSlider) Init

func (c *CalendarSlider) Init(_ Ctx)

func (*CalendarSlider) OnFilterChange added in v0.6.8

func (c *CalendarSlider) OnFilterChange(fn func(term string))

OnFilterChange implements widget.Filterable: it registers the sink called with the picked day ("YYYY-MM-DD") on every day selection. The signature is fixed by widget.Filterable — do not add a parameter, do not rename.

func (*CalendarSlider) Render

func (c *CalendarSlider) Render() *Element

Render arma la tira completa de meses de una sola vez, Start primero — sin señal, sin reconstrucción: el slide entre ellos lo hace el scroll-snap del navegador, disparado por los enlaces ‹ › de cada mes hacia el vecino. Al no reconstruirse nunca, el mes inicial es siempre el primer hijo de la tira — la posición de scroll 0 — sin necesitar desplazar el scroll por WASM al montar.

La navegación es un bucle: el ‹ del primer mes apunta al último y el › del último apunta al primero, igual que el deslizador infinito original — la alternativa (sin bucle) obliga a recorrer los N meses en orden para volver al principio.

func (*CalendarSlider) RenderCSS

func (c *CalendarSlider) RenderCSS() *css.Stylesheet

RenderCSS describe el aspecto del calendario con los tokens del tema. La puesta en escena es fiel al calendario original: un mes a la vez, centrado en la página (Center), con las secciones vecinas fuera de vista en una tira de scroll-snap (ScrollRow) — cada mes ocupa el 100% de la tira, así que solo uno es visible; el hoy se rellena con el color primario y las flechas ‹ › son una fila compacta centrada bajo el nombre del mes (PartMonthNav), idéntica en desktop y táctil. Es estática a propósito: sin reveal en hover/foco — volver las flechas absolutas las hacía desaparecer bajo el puntero, y ocultar la fila con foco cancelaba los toques en mobile (el mes no avanzaba). Cada mes lleva sus propias flechas — apuntan al vecino, así que cada sección es su propia ancla (Anchor). El chip colapsado es una barra de ancho completo bajo la tira, en flujo normal: visible siempre como toggle de plegado, sin flotar ni tapar nada en ningún estado.

El mismo diseño de un mes a la vez ya funciona en mobile sin reglas aparte; solo el tamaño de la celda del día crece para un objetivo táctil más cómodo.

func (*CalendarSlider) WidgetKind

func (c *CalendarSlider) WidgetKind() widget.Kind

func (*CalendarSlider) WidgetName

func (c *CalendarSlider) WidgetName() widget.Name

type Holiday

type Holiday struct {
	Date string // "YYYY-MM-DD"
	Name string
}

Holiday es un feriado del calendario.

type OccupationDay

type OccupationDay struct {
	Date    string // "YYYY-MM-DD"
	Percent int
}

OccupationDay es el porcentaje de ocupación (0..100) de una fecha; su sola presencia en la lista hace el día seleccionable.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL