Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,13 @@
"svelte": "src/main.js",
"version": "12.0.1",
"license": "MIT",
"exports": {
".": {
"svelte": "./src/main.js",
"default": "./src/main.js"
},
"./*": "./*"
},
"scripts": {
"dev": "snowpack dev",
"build": "snowpack build",
Expand All @@ -13,7 +20,7 @@
"dependencies": {
"dayjs": "^1.10.7",
"es6-object-assign": "^1.1.0",
"svelte": "^3.24.0"
"svelte": "^3.24.0 || ^4.0.0"
},
"devDependencies": {
"@beyonk/eslint-config": "^4.2.0",
Expand Down
33 changes: 28 additions & 5 deletions src/App.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -59,13 +59,13 @@
<div class="row">
<aside>
<div class="menu-box">
<h4>Navigation</h4>
<h4>Navigation</h4>
<nav class="side-nav">
<ul>
<li><a href="/">Home</a></li>
<li><a href="/date-picker">Date Picker</a></li>
<li><a href="/range-picker">Range Picker</a></li>
</ul>
</ul>
</nav>
</div>
</aside>
Expand Down Expand Up @@ -272,7 +272,9 @@
format='ddd, DD MMM YYYY'
range={true}
time={true}
closeOnFocusLoss={false}
on:range-selected={e => {
console.log(e)
firedEvents = [
...firedEvents,
`Picked range ${e.detail.from} to ${e.detail.to}`
Expand All @@ -284,7 +286,18 @@
'Change fired'
]
}}
/>
let:selectedStart
let:selectedEnd
forceClose={forcedClose}
>
<div style="border: 1px solid black; padding: 10px; border-radius: 4px;">
<p>{selectedStart}</p>
<p>{selectedEnd}</p>
</div>
<div slot="beforeContents">
<h1>Before Contents Slot</h1>
</div>
</DatePicker>
</div>
<ul>
{#each firedEvents as fired}
Expand All @@ -293,6 +306,9 @@
<li>Pick date to see events</li>
{/each}
</ul>
<div style="position: fixed; top: 0; right: 0;">
<button on:click={forceClose}>click to force closed</button>
</div>
</Route>
</Route>
</Route>
Expand All @@ -314,7 +330,7 @@
<div class="container">
<div class="row">
<div class="col-lg-12 center">

</div>
</div>
</div>
Expand All @@ -335,6 +351,13 @@
let firedEvents = []
let firedEventsValue = null
let customSelected = null

let forcedClose = false
async function forceClose () {
forcedClose = true
await new Promise((resolve) => setTimeout(resolve, 100))
forcedClose = false
}
</script>

<style>
Expand Down Expand Up @@ -446,4 +469,4 @@
background-position: 100%;
}
}
</style>
</style>
76 changes: 69 additions & 7 deletions src/components/DatePicker.svelte
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
<script>
import Popover from './Popover.svelte'
import { dayjs } from './lib/date-utils'
import { createEventDispatcher, getContext, setContext } from 'svelte'
import { CalendarStyle } from '../calendar-style'
import { contextKey, setup } from './lib/context'
import { createEventDispatcher, setContext, getContext } from 'svelte'
import { CalendarStyle } from '../calendar-style.js'
import { createViewContext } from './lib/view-context.js'
import { dayjs } from './lib/date-utils'
import { ensureFutureMonth } from './lib/date-manipulation'
import { createViewContext } from './lib/view-context'
import Popover from './Popover.svelte'
import Toolbar from './Toolbar.svelte'
import View from './view/View.svelte'

export let range = false
export let defaultRange = [ 1, 'month' ]
export let placeholder = 'Choose Date'
export let format = 'DD / MM / YYYY'
export let start = dayjs().subtract(1, 'year')
Expand All @@ -23,6 +25,7 @@
export let night = 19
export let minuteStep = 5
export let continueText = 'Continue'
export let forceClose = false

const dispatch = createEventDispatcher()

Expand All @@ -33,6 +36,7 @@
start: dayjs(start),
end: dayjs(end),
isRangePicker: range,
defaultRange,
isTimePicker: time,
closeOnFocusLoss,
format,
Expand All @@ -46,6 +50,8 @@
const {
selectedStartDate,
selectedEndDate,
leftCalendarDate,
rightCalendarDate,
isOpen,
isClosing,
highlighted,
Expand All @@ -66,7 +72,7 @@
highlighted.set($selectedStartDate)
dispatch('open')
}

function setRangeValue () {
selected = [ $selectedStartDate, $selectedEndDate ]
dispatch('range-selected', {
Expand Down Expand Up @@ -114,6 +120,59 @@
dispatch('change')
}
}

/**
* Allow external sources to update dates by binding to selected prop
* and updating with JS Date objects. Also update the calendar view
* to show the selected dates.
*/
$: {
if (config.isRangePicker && selected) {
if (selected[0] instanceof Date) {
const startDate = dayjs(selected[0])
selectedStartDate.set(startDate)
leftCalendarDate.set(startDate.startOf('month'))
}
if (selected[1] instanceof Date) {
const endDate = dayjs(selected[1])
selectedEndDate.set(endDate)
rightCalendarDate.set(ensureFutureMonth($leftCalendarDate, endDate).startOf('month'))
}
} else if (selected instanceof Date) {
const date = dayjs(selected)
selectedStartDate.set(date)
leftCalendarDate.set(date.startOf('month'))
}
}

/**
* Allow external sources to react to internal selections via event forwarding
*/
let selectedStart = null
$: {
if ($selectedStartDate) {
selectedStart = $selectedStartDate.toDate()
} else {
selectedStart = null
}
}
let selectedEnd = null
$: {
if ($selectedEndDate) {
selectedEnd = $selectedEndDate.toDate()
} else {
selectedEnd = null
}
}

/**
* Allow forceful closing from outside
*/
$: {
if ($isOpen && forceClose) {
close()
}
}
</script>

<style>
Expand Down Expand Up @@ -177,7 +236,7 @@
on:opened={initialisePicker}
on:closed={() => dispatch('close')}>
<div slot="trigger">
<slot formatted={$formatter}>
<slot formatted={$formatter} {selectedStart} {selectedEnd}>
{#if !trigger}
<button class="calendar-button" type="button">
{#if $isDateChosen}
Expand All @@ -189,6 +248,9 @@
{/if}
</slot>
</div>
<div slot="beforeContents">
<slot name="beforeContents" {selectedStart} {selectedEnd} />
</div>
<div class="contents" slot="contents" class:is-range-picker={config.isRangePicker}>
<div class="view">
<View
Expand Down
39 changes: 39 additions & 0 deletions src/components/DatePickerAsyncWrapper.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<script>
import { onMount } from 'svelte'
import DatePickerInner from './DatePicker.svelte'
import { setLoadingCursor } from './lib/context'

let ready = false

onMount(async () => {
await setLoadingCursor()
ready = true
})
</script>

{#if ready}
{#if $$slots.default}
<DatePickerInner {...$$restProps}
on:open
on:range-selected
on:date-selected
on:change
on:close
let:selectedStart
let:selectedEnd
>
<slot {selectedStart} {selectedEnd} />
<div slot="beforeContents" let:selectedStart let:selectedEnd>
<slot name="beforeContents" {selectedStart} {selectedEnd} />
</div>
</DatePickerInner>
{:else}
<DatePickerInner {...$$restProps}
on:open
on:range-selected
on:date-selected
on:change
on:close
/>
{/if}
{/if}
Loading