-
-
Save mindplay-dk/d85fbf5427d5e4436fadc70ce46d9ac2 to your computer and use it in GitHub Desktop.
Svelte date-picker
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<script> | |
import DatePicker from "./DatePicker.svelte"; | |
let startDate = "2022-03-01"; | |
let endDate = "2022-03-03"; | |
const locale = { | |
en: { | |
days: "Su|Mo|Tu|We|Th|Fr|Sa".split("|"), | |
months: "Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec".split('|'), | |
start: 0, | |
}, | |
da: { | |
days: "Sø|Ma|Ti|On|To|Fr|Lø".split("|"), | |
months: "Jan|Feb|Mar|Apr|Maj|Jun|Jul|Aug|Sep|Okt|Nov|Dec".split('|'), | |
start: 1, | |
} | |
} | |
let culture = "en"; | |
</script> | |
<h1>DatePicker</h1> | |
<label> | |
Culture: | |
<select bind:value={culture}> | |
{#each Object.keys(locale) as lang} | |
<option value={lang}>{lang}</option> | |
{/each} | |
</select> | |
</label> | |
<h3>Start Date</h3> | |
<input type="text" bind:value={startDate}/> | |
<DatePicker bind:value={startDate} {...locale[culture]}/> | |
<h3>End Date</h3> | |
<input type="text" bind:value={endDate}/> | |
<DatePicker bind:value={endDate} {...locale[culture]}/> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<script context="module"> | |
export function iso(date) { | |
const pad = n => n < 10 ? "0" + n : n; | |
return date.getFullYear() + "-" + pad(date.getMonth()+1) + "-" + pad(date.getDate()); | |
} | |
</script> | |
<script> | |
export let value = iso(new Date()); | |
export let days = 'Su|Mo|Tu|We|Th|Fr|Sa'.split('|'); | |
export let months = 'Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec'.split('|'); | |
export let start = 0; // first day of the week (0 = Sunday, 1 = Monday) | |
export let offset = 0; // offset in months from currently selected date | |
let date = iso(new Date()); | |
$: acceptDate(value); | |
function acceptDate(value) { | |
const newDate = new Date(value); | |
if (!isNaN(newDate)) { | |
date = iso(newDate); | |
} | |
} | |
function go(direction) { | |
offset = offset + direction; | |
} | |
function selectDate(newValue) { | |
date = newValue; | |
value = newValue; | |
offset = 0; | |
} | |
$: viewDate = viewDateFrom(date, offset); | |
$: month = months[viewDate.getMonth()]; | |
$: year = viewDate.getFullYear(); | |
$: weeks = weeksFrom(viewDate, date, start); | |
function viewDateFrom(date, offset) { | |
var viewDate = new Date(date); | |
viewDate.setMonth(viewDate.getMonth() + offset); | |
return viewDate; | |
} | |
function weeksFrom(viewDate, date, start) { | |
var first = new Date(viewDate.getTime()); | |
first.setDate(1); | |
first.setDate(first.getDate() + ((start - first.getDay() - 7) % 7)); | |
var last = new Date(viewDate.getTime()); | |
last.setDate(new Date(viewDate.getFullYear(), viewDate.getMonth() + 1, 0).getDate()); | |
last.setDate(last.getDate() + ((start - last.getDay() + 6) % 7)); | |
var d = new Date(first.getTime()), | |
M = viewDate.getMonth(), | |
Y = viewDate.getFullYear(), | |
week = [], | |
weeks = [week]; | |
while (d.getTime() <= last.getTime()) { | |
var dd = d.getDate(), | |
mm = d.getMonth(), | |
yy = d.getFullYear(), | |
value = iso(d); | |
week.push({ | |
date: dd, | |
value, | |
class: [ | |
date === value ? "selected" : "", | |
mm == M ? "" : ((mm > M ? yy >= Y : yy > Y) ? "future" : "past") | |
].join(' ') | |
}); | |
d = new Date(d.getFullYear(), d.getMonth(), d.getDate() + 1); | |
if (d.getDay() === start) { | |
week = []; | |
weeks.push(week); | |
} | |
} | |
return weeks; | |
} | |
</script> | |
<table> | |
<tr> | |
<td class="btn" on:click={() => go(-1)}>◀</td> | |
<td colspan=5>{month} {year}</td> | |
<td class="btn" on:click={() => go(+1)}>▶</td> | |
</tr> | |
<tr> | |
{#each days as day} | |
<th>{day}</th> | |
{/each} | |
</tr> | |
{#each weeks as week} | |
<tr> | |
{#each week as day} | |
<td class="btn {day.class}" on:click={() => selectDate(day.value)}>{day.date}</td> | |
{/each} | |
</tr> | |
{/each} | |
</table> | |
<style> | |
td, th { | |
width: 28px; | |
text-align: center; | |
border-radius: 4px; | |
line-height: 24px; | |
margin: 0; | |
padding: 0; | |
} | |
td.past, td.future { | |
opacity: 0.5; | |
} | |
.btn { | |
cursor: pointer; | |
} | |
.btn:hover { | |
background: gray; | |
color: white; | |
} | |
td.selected { | |
color: #ffffff; | |
font-weight: bold; | |
background-color: #006dcc; | |
border-color: #002a80; | |
} | |
</style> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Recently updated to Svelte 3 - if you'd like to compare with an older version of Svelte, check here.