Datepicker — OutfitKit
Datepicker
Calendario popover. Cabecera con título y navegación, rejilla de días (con día seleccionado, hoy, fuera de mes y rango).
Convención de fechas: los títulos de sección y los chips de resumen usan DD/MM/YYYY (ej. 15/05/2026); la cabecera interna del calendario sigue la convención habitual de widgets (Mayo 2026).
Mes simple — 15/05/2026 seleccionado
Mayo 2026
L
M
X
J
V
S
D
Fecha seleccionada: 15/05/2026
<div class="dp-mes-simple" data-dp-year="2026" data-dp-month="5" data-dp-day="15">
<div class="datepicker">
<div class="datepicker-head">
<span class="title md">Mayo 2026</span>
<span class="datepicker-nav">
<button type="button" class="datepicker-nav-btn" aria-label="Anterior"><iconify-icon icon="lucide:chevron-left" width="16" height="16"></iconify-icon></button>
<button type="button" class="datepicker-nav-btn" aria-label="Siguiente"><iconify-icon icon="lucide:chevron-right" width="16" height="16"></iconify-icon></button>
</span>
</div>
<div class="datepicker-grid">
<div class="datepicker-dow">L</div><div class="datepicker-dow">M</div><div class="datepicker-dow">X</div><div class="datepicker-dow">J</div><div class="datepicker-dow">V</div><div class="datepicker-dow">S</div><div class="datepicker-dow">D</div>
</div>
<div class="datepicker-shortcuts">
<button type="button" class="datepicker-shortcut" data-dp-shortcut="today">Hoy</button>
<button type="button" class="datepicker-shortcut" data-dp-shortcut="yesterday">Ayer</button>
<button type="button" class="datepicker-shortcut" data-dp-shortcut="thisWeek">Esta semana</button>
<button type="button" class="datepicker-shortcut" data-dp-shortcut="thisMonth">Este mes</button>
</div>
</div>
<p class="dp-mes-simple-caption" style="margin-top:10px;font-size:13px;color:var(--ink-3);">
Fecha seleccionada: <strong class="dp-mes-simple-value">15/05/2026</strong>
</p>
</div>
{% from "datetime.jinja" import datetime %}
{% call datetime("Mayo 2026") %}
<div class="datepicker-grid">
<div class="datepicker-dow">L</div><div class="datepicker-dow">M</div><div class="datepicker-dow">X</div><div class="datepicker-dow">J</div><div class="datepicker-dow">V</div><div class="datepicker-dow">S</div><div class="datepicker-dow">D</div>
{# … rejilla de días generada por el cliente … #}
</div>
<div class="datepicker-shortcuts">
<button class="datepicker-shortcut">Hoy</button>
<button class="datepicker-shortcut">Ayer</button>
<button class="datepicker-shortcut">Esta semana</button>
<button class="datepicker-shortcut">Este mes</button>
</div>
{% endcall %}
<Datetime label="Mayo 2026">
<div class="datepicker-grid">…</div>
<div class="datepicker-shortcuts">
<button class="datepicker-shortcut">Hoy</button>
<button class="datepicker-shortcut">Ayer</button>
<button class="datepicker-shortcut">Esta semana</button>
<button class="datepicker-shortcut">Este mes</button>
</div>
</Datetime>
Install the Jinja addon and import the component:
pip install outfitkit
Then in your template:
{% from "<component>.jinja" import <component> %}
{{ <component>(...) }}
Or with JinjaX:
<Component ... />
Datastar — selección reactiva
Mayo 2026
L
M
X
J
V
S
D
Fecha: 15/05/2026
<div data-signals="{ pickedDay: 15 }" style="display:flex;gap:24px;align-items:flex-start;flex-wrap:wrap;">
<div class="datepicker">
<div class="datepicker-head">
<span class="title md">Mayo 2026</span>
<span class="datepicker-nav">
<button type="button" class="datepicker-nav-btn" aria-label="Anterior"><iconify-icon icon="lucide:chevron-left" width="16" height="16"></iconify-icon></button>
<button type="button" class="datepicker-nav-btn" aria-label="Siguiente"><iconify-icon icon="lucide:chevron-right" width="16" height="16"></iconify-icon></button>
</span>
</div>
<div class="datepicker-grid">
<div class="datepicker-dow">L</div><div class="datepicker-dow">M</div><div class="datepicker-dow">X</div><div class="datepicker-dow">J</div><div class="datepicker-dow">V</div><div class="datepicker-dow">S</div><div class="datepicker-dow">D</div>
<button class="datepicker-day datepicker-day--muted">27</button><button class="datepicker-day datepicker-day--muted">28</button><button class="datepicker-day datepicker-day--muted">29</button><button class="datepicker-day datepicker-day--muted">30</button>
<button class="datepicker-day"
data-attr-class="'datepicker-day' + ($pickedDay === 1 ? ' datepicker-day--selected' : '')"
data-on:click="$pickedDay = 1">1</button>
<button class="datepicker-day"
data-attr-class="'datepicker-day' + ($pickedDay === 2 ? ' datepicker-day--selected' : '')"
data-on:click="$pickedDay = 2">2</button>
<button class="datepicker-day"
data-attr-class="'datepicker-day' + ($pickedDay === 3 ? ' datepicker-day--selected' : '')"
data-on:click="$pickedDay = 3">3</button>
<button class="datepicker-day"
data-attr-class="'datepicker-day' + ($pickedDay === 4 ? ' datepicker-day--selected' : '')"
data-on:click="$pickedDay = 4">4</button>
<button class="datepicker-day"
data-attr-class="'datepicker-day' + ($pickedDay === 5 ? ' datepicker-day--selected' : '')"
data-on:click="$pickedDay = 5">5</button>
<button class="datepicker-day"
data-attr-class="'datepicker-day' + ($pickedDay === 6 ? ' datepicker-day--selected' : '')"
data-on:click="$pickedDay = 6">6</button>
<button class="datepicker-day"
data-attr-class="'datepicker-day' + ($pickedDay === 7 ? ' datepicker-day--selected' : '')"
data-on:click="$pickedDay = 7">7</button>
<button class="datepicker-day"
data-attr-class="'datepicker-day' + ($pickedDay === 8 ? ' datepicker-day--selected' : '')"
data-on:click="$pickedDay = 8">8</button>
<button class="datepicker-day"
data-attr-class="'datepicker-day' + ($pickedDay === 9 ? ' datepicker-day--selected' : '')"
data-on:click="$pickedDay = 9">9</button>
<button class="datepicker-day"
data-attr-class="'datepicker-day' + ($pickedDay === 10 ? ' datepicker-day--selected' : '')"
data-on:click="$pickedDay = 10">10</button>
<button class="datepicker-day"
data-attr-class="'datepicker-day' + ($pickedDay === 11 ? ' datepicker-day--selected' : '')"
data-on:click="$pickedDay = 11">11</button>
<button class="datepicker-day"
data-attr-class="'datepicker-day' + ($pickedDay === 12 ? ' datepicker-day--selected' : '')"
data-on:click="$pickedDay = 12">12</button>
<button class="datepicker-day"
data-attr-class="'datepicker-day' + ($pickedDay === 13 ? ' datepicker-day--selected' : '')"
data-on:click="$pickedDay = 13">13</button>
<button class="datepicker-day"
data-attr-class="'datepicker-day' + ($pickedDay === 14 ? ' datepicker-day--selected' : '')"
data-on:click="$pickedDay = 14">14</button>
<button class="datepicker-day"
data-attr-class="'datepicker-day' + ($pickedDay === 15 ? ' datepicker-day--selected' : '')"
data-on:click="$pickedDay = 15">15</button>
<button class="datepicker-day"
data-attr-class="'datepicker-day' + ($pickedDay === 16 ? ' datepicker-day--selected' : '')"
data-on:click="$pickedDay = 16">16</button>
<button class="datepicker-day"
data-attr-class="'datepicker-day' + ($pickedDay === 17 ? ' datepicker-day--selected' : '')"
data-on:click="$pickedDay = 17">17</button>
<button class="datepicker-day"
data-attr-class="'datepicker-day' + ($pickedDay === 18 ? ' datepicker-day--selected' : '')"
data-on:click="$pickedDay = 18">18</button>
<button class="datepicker-day"
data-attr-class="'datepicker-day' + ($pickedDay === 19 ? ' datepicker-day--selected' : '')"
data-on:click="$pickedDay = 19">19</button>
<button class="datepicker-day"
data-attr-class="'datepicker-day' + ($pickedDay === 20 ? ' datepicker-day--selected' : '')"
data-on:click="$pickedDay = 20">20</button>
<button class="datepicker-day"
data-attr-class="'datepicker-day' + ($pickedDay === 21 ? ' datepicker-day--selected' : '')"
data-on:click="$pickedDay = 21">21</button>
<button class="datepicker-day"
data-attr-class="'datepicker-day' + ($pickedDay === 22 ? ' datepicker-day--selected' : '')"
data-on:click="$pickedDay = 22">22</button>
<button class="datepicker-day"
data-attr-class="'datepicker-day' + ($pickedDay === 23 ? ' datepicker-day--selected' : '')"
data-on:click="$pickedDay = 23">23</button>
<button class="datepicker-day"
data-attr-class="'datepicker-day' + ($pickedDay === 24 ? ' datepicker-day--selected' : '')"
data-on:click="$pickedDay = 24">24</button>
<button class="datepicker-day"
data-attr-class="'datepicker-day' + ($pickedDay === 25 ? ' datepicker-day--selected' : '')"
data-on:click="$pickedDay = 25">25</button>
<button class="datepicker-day"
data-attr-class="'datepicker-day' + ($pickedDay === 26 ? ' datepicker-day--selected' : '')"
data-on:click="$pickedDay = 26">26</button>
<button class="datepicker-day"
data-attr-class="'datepicker-day' + ($pickedDay === 27 ? ' datepicker-day--selected' : '')"
data-on:click="$pickedDay = 27">27</button>
<button class="datepicker-day"
data-attr-class="'datepicker-day' + ($pickedDay === 28 ? ' datepicker-day--selected' : '')"
data-on:click="$pickedDay = 28">28</button>
<button class="datepicker-day"
data-attr-class="'datepicker-day' + ($pickedDay === 29 ? ' datepicker-day--selected' : '')"
data-on:click="$pickedDay = 29">29</button>
<button class="datepicker-day"
data-attr-class="'datepicker-day' + ($pickedDay === 30 ? ' datepicker-day--selected' : '')"
data-on:click="$pickedDay = 30">30</button>
<button class="datepicker-day"
data-attr-class="'datepicker-day' + ($pickedDay === 31 ? ' datepicker-day--selected' : '')"
data-on:click="$pickedDay = 31">31</button>
</div>
</div>
<div>
Fecha: <strong data-text="('0' + $pickedDay).slice(-2) + '/05/2026'">15/05/2026</strong>
</div>
</div>
{% from "datetime.jinja" import datetime %}
<div data-signals="{ pickedDay: 15 }" style="display:flex;gap:24px;align-items:flex-start;flex-wrap:wrap;">
{% call datetime("Mayo 2026") %}
<div class="datepicker-grid">
<div class="datepicker-dow">L</div><div class="datepicker-dow">M</div><div class="datepicker-dow">X</div><div class="datepicker-dow">J</div><div class="datepicker-dow">V</div><div class="datepicker-dow">S</div><div class="datepicker-dow">D</div>
{% for d in [27,28,29,30] %}<button class="datepicker-day datepicker-day--muted">{{ d }}</button>{% endfor %}
{% for d in range(1, 32) %}
<button class="datepicker-day"
data-attr-class="'datepicker-day' + ($pickedDay === {{ d }} ? ' datepicker-day--selected' : '')"
data-on:click="$pickedDay = {{ d }}">{{ d }}</button>
{% endfor %}
</div>
{% endcall %}
<div>
Fecha: <strong data-text="('0' + $pickedDay).slice(-2) + '/05/2026'">15/05/2026</strong>
</div>
</div>
<div data-signals="{ pickedDay: 15 }" style="display:flex;gap:24px;align-items:flex-start;flex-wrap:wrap;">
<Datetime label="Mayo 2026">
<div class="datepicker-grid">
<div class="datepicker-dow">L</div><div class="datepicker-dow">M</div><div class="datepicker-dow">X</div><div class="datepicker-dow">J</div><div class="datepicker-dow">V</div><div class="datepicker-dow">S</div><div class="datepicker-dow">D</div>
{% for d in [27,28,29,30] %}<button class="datepicker-day datepicker-day--muted">{{ d }}</button>{% endfor %}
{% for d in range(1, 32) %}
<button class="datepicker-day"
data-attr-class="'datepicker-day' + ($pickedDay === {{ d }} ? ' datepicker-day--selected' : '')"
data-on:click="$pickedDay = {{ d }}">{{ d }}</button>
{% endfor %}
</div>
</Datetime>
<div>
Fecha: <strong data-text="('0' + $pickedDay).slice(-2) + '/05/2026'">15/05/2026</strong>
</div>
</div>
Install the Jinja addon and import the component:
pip install outfitkit
Then in your template:
{% from "<component>.jinja" import <component> %}
{{ <component>(...) }}
Or with JinjaX:
<Component ... />
Rango — 07/05/2026 → 22/06/2026
Mayo 2026
L
M
X
J
V
S
D
Junio 2026
L
M
X
J
V
S
D
<div style="display:flex;gap:12px;flex-wrap:wrap;">
<div class="datepicker">
<div class="datepicker-head">
<span class="title md">Mayo 2026</span>
<span class="datepicker-nav">
<button type="button" class="datepicker-nav-btn" aria-label="Anterior"><iconify-icon icon="lucide:chevron-left" width="16" height="16"></iconify-icon></button>
<button type="button" class="datepicker-nav-btn" aria-label="Siguiente"><iconify-icon icon="lucide:chevron-right" width="16" height="16"></iconify-icon></button>
</span>
</div>
<div class="datepicker-grid">
<div class="datepicker-dow">L</div><div class="datepicker-dow">M</div><div class="datepicker-dow">X</div><div class="datepicker-dow">J</div><div class="datepicker-dow">V</div><div class="datepicker-dow">S</div><div class="datepicker-dow">D</div>
<button class="datepicker-day datepicker-day--muted">27</button><button class="datepicker-day datepicker-day--muted">28</button><button class="datepicker-day datepicker-day--muted">29</button><button class="datepicker-day datepicker-day--muted">30</button>
<button class="datepicker-day">1</button>
<button class="datepicker-day">2</button>
<button class="datepicker-day">3</button>
<button class="datepicker-day">4</button>
<button class="datepicker-day">5</button>
<button class="datepicker-day">6</button>
<button class="datepicker-day datepicker-day--selected datepicker-day--range-start">7</button>
<button class="datepicker-day datepicker-day--in-range">8</button>
<button class="datepicker-day datepicker-day--in-range">9</button>
<button class="datepicker-day datepicker-day--in-range">10</button>
<button class="datepicker-day datepicker-day--in-range">11</button>
<button class="datepicker-day datepicker-day--in-range">12</button>
<button class="datepicker-day datepicker-day--in-range">13</button>
<button class="datepicker-day datepicker-day--in-range">14</button>
<button class="datepicker-day datepicker-day--in-range">15</button>
<button class="datepicker-day datepicker-day--in-range">16</button>
<button class="datepicker-day datepicker-day--in-range">17</button>
<button class="datepicker-day datepicker-day--in-range">18</button>
<button class="datepicker-day datepicker-day--in-range">19</button>
<button class="datepicker-day datepicker-day--in-range">20</button>
<button class="datepicker-day datepicker-day--in-range">21</button>
<button class="datepicker-day datepicker-day--in-range">22</button>
<button class="datepicker-day datepicker-day--in-range">23</button>
<button class="datepicker-day datepicker-day--in-range">24</button>
<button class="datepicker-day datepicker-day--in-range">25</button>
<button class="datepicker-day datepicker-day--in-range">26</button>
<button class="datepicker-day datepicker-day--in-range">27</button>
<button class="datepicker-day datepicker-day--in-range">28</button>
<button class="datepicker-day datepicker-day--in-range">29</button>
<button class="datepicker-day datepicker-day--in-range">30</button>
<button class="datepicker-day datepicker-day--in-range">31</button>
</div>
</div>
<div class="datepicker">
<div class="datepicker-head">
<span class="title md">Junio 2026</span>
<span class="datepicker-nav">
<button type="button" class="datepicker-nav-btn" aria-label="Anterior"><iconify-icon icon="lucide:chevron-left" width="16" height="16"></iconify-icon></button>
<button type="button" class="datepicker-nav-btn" aria-label="Siguiente"><iconify-icon icon="lucide:chevron-right" width="16" height="16"></iconify-icon></button>
</span>
</div>
<div class="datepicker-grid">
<div class="datepicker-dow">L</div><div class="datepicker-dow">M</div><div class="datepicker-dow">X</div><div class="datepicker-dow">J</div><div class="datepicker-dow">V</div><div class="datepicker-dow">S</div><div class="datepicker-dow">D</div>
<button class="datepicker-day datepicker-day--in-range">1</button>
<button class="datepicker-day datepicker-day--in-range">2</button>
<button class="datepicker-day datepicker-day--in-range">3</button>
<button class="datepicker-day datepicker-day--in-range">4</button>
<button class="datepicker-day datepicker-day--in-range">5</button>
<button class="datepicker-day datepicker-day--in-range">6</button>
<button class="datepicker-day datepicker-day--in-range">7</button>
<button class="datepicker-day datepicker-day--in-range">8</button>
<button class="datepicker-day datepicker-day--in-range">9</button>
<button class="datepicker-day datepicker-day--in-range">10</button>
<button class="datepicker-day datepicker-day--in-range">11</button>
<button class="datepicker-day datepicker-day--in-range">12</button>
<button class="datepicker-day datepicker-day--in-range">13</button>
<button class="datepicker-day datepicker-day--in-range">14</button>
<button class="datepicker-day datepicker-day--in-range">15</button>
<button class="datepicker-day datepicker-day--in-range">16</button>
<button class="datepicker-day datepicker-day--in-range">17</button>
<button class="datepicker-day datepicker-day--in-range">18</button>
<button class="datepicker-day datepicker-day--in-range">19</button>
<button class="datepicker-day datepicker-day--in-range">20</button>
<button class="datepicker-day datepicker-day--in-range">21</button>
<button class="datepicker-day datepicker-day--selected datepicker-day--range-end">22</button>
<button class="datepicker-day">23</button>
<button class="datepicker-day">24</button>
<button class="datepicker-day">25</button>
<button class="datepicker-day">26</button>
<button class="datepicker-day">27</button>
<button class="datepicker-day">28</button>
<button class="datepicker-day">29</button>
<button class="datepicker-day">30</button>
</div>
</div>
</div>
{% from "datetime.jinja" import datetime %}
{# Dos meses lado a lado: la selección de rango se pinta sobre ambos calendarios. #}
<div style="display:flex;gap:12px;flex-wrap:wrap;">
{% call datetime("Mayo 2026") %}
<div class="datepicker-grid">
<div class="datepicker-dow">L</div><div class="datepicker-dow">M</div><div class="datepicker-dow">X</div><div class="datepicker-dow">J</div><div class="datepicker-dow">V</div><div class="datepicker-dow">S</div><div class="datepicker-dow">D</div>
{% for d in [27,28,29,30] %}<button class="datepicker-day datepicker-day--muted">{{ d }}</button>{% endfor %}
{% for d in range(1, 32) %}
{% if d == 7 %}<button class="datepicker-day datepicker-day--selected datepicker-day--range-start">{{ d }}</button>
{% elif d > 7 %}<button class="datepicker-day datepicker-day--in-range">{{ d }}</button>
{% else %}<button class="datepicker-day">{{ d }}</button>{% endif %}
{% endfor %}
</div>
{% endcall %}
{% call datetime("Junio 2026") %}
<div class="datepicker-grid">
<div class="datepicker-dow">L</div><div class="datepicker-dow">M</div><div class="datepicker-dow">X</div><div class="datepicker-dow">J</div><div class="datepicker-dow">V</div><div class="datepicker-dow">S</div><div class="datepicker-dow">D</div>
{% for d in range(1, 31) %}
{% if d == 22 %}<button class="datepicker-day datepicker-day--selected datepicker-day--range-end">{{ d }}</button>
{% elif d < 22 %}<button class="datepicker-day datepicker-day--in-range">{{ d }}</button>
{% else %}<button class="datepicker-day">{{ d }}</button>{% endif %}
{% endfor %}
</div>
{% endcall %}
</div>
<div style="display:flex;gap:12px;flex-wrap:wrap;">
<Datetime label="Mayo 2026">…</Datetime>
<Datetime label="Junio 2026">…</Datetime>
</div>
Install the Jinja addon and import the component:
pip install outfitkit
Then in your template:
{% from "<component>.jinja" import <component> %}
{{ <component>(...) }}
Or with JinjaX:
<Component ... />
API
| Prop | Tipo | Default | Descripción |
|---|---|---|---|
title | str | "" | Título de cabecera con flechas de navegación. Vacío oculta la cabecera. |
range | bool | false | Marca el componente como variante de rango (clase --range). Para layout dual de dos meses lado a lado, renderiza dos <Datepicker> en un wrapper flex y aplica --range-start / --in-range / --range-end a los días. |
attrs | dict | None | Atributos extra (data-signals, etc). |
Slot: la rejilla .datepicker-grid, accesos rápidos .datepicker-shortcuts y footer son markup libre dentro del macro.