calendarslider

package
v0.5.7 Latest Latest
Warning

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

Go to latest
Published: Aug 12, 2026 License: MIT Imports: 8 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 plain same-page anchor links (<a href="#cs-m-...">) into the neighboring month — the browser's native scroll-snap does the sliding. No click handler, 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 links.
  • 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 plain same-page anchor links (<a href="#cs-m-...">) into the neighboring month, and the browser's native scroll-snap does the sliding — no click handler, no rebuild.

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")
)
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) Init

func (c *CalendarSlider) Init(_ Ctx)

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 tiras superpuestas en los bordes del mes (EdgeStrip), no ancladas a una esquina, para que cubran toda su altura como en el original. Cada mes lleva sus propias flechas — apuntan al vecino, así que solo hace falta ancla (Anchor) en la sección misma, no en la raíz.

PartMonth lleva PadInline: las flechas se posicionan contra su propio padding-box (position:absolute no ve el padding de un ancestro salvo el propio), así que ese padding es el gutter que evita que se superpongan con la columna de días más externa.

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