UNPKG

@svelte-plugins/datepicker

Version:

A simple datepicker component designed for Svelte.

474 lines (400 loc) 22.3 kB
# @svelte-plugins/datepicker A simple datepicker component designed for Svelte. Try it in the [Svelte REPL](https://svelte.dev/repl/cae0ce6e92634878b6e1a587146decbd?version=4.2.7). ## Install ```bash # npm > npm install svelte @svelte-plugins/datepicker # pnpm > pnpm install svelte @svelte-plugins/datepicker # yarn > yarn add svelte @svelte-plugins/datepicker ``` ## Using the DatePicker component ```svelte <script> import { DatePicker } from "@svelte-plugins/datepicker"; import { format } from 'date-fns'; let startDate = new Date(); let dateFormat = 'MM/dd/yy'; let isOpen = false; const toggleDatePicker = () => (isOpen = !isOpen); const formatDate = (dateString) => { return dateString && format(new Date(dateString), dateFormat) || ''; }; let formattedStartDate = formatDate(startDate); const onChange = () => { startDate = new Date(formattedStartDate); }; $: formattedStartDate = formatDate(startDate); </script> <DatePicker bind:isOpen bind:startDate> <input type="text" placeholder="Select date" bind:value={formattedStartDate} on:click={toggleDatePicker} /> </DatePicker> <style> input[type="text"] { border: 1px solid #eee; border-radius: 4px; padding: 8px; } </style> ``` ## API ### Props | Prop | Description | Default | | :---------------- | :------------------------------------------------------------------------------------ | :-------------------------- | | startDate | The start date string or date object. | `object` (default: `null`) | endDate | The end date string or date object. | `object` (default: `null`) | startDateTime | The start date time string in 24 hour format. | `string` (default: `00:00`) | endDateTime | The end date time string in 24 hour format. | `string` (default: `00:00`) | defaultYear | The year you want to show as the default. | `number` (default: `2023`) | align | The edge alignment of the datepicker. | `string` (default: `left`) | enabledDates | An array of date strings to enable only. | `array` (default: [...]) | disabledDates | An array of date strings to disable. | `array` (default: [...]) | isRange | Changes the date picker into a range picker and allows start and end date selection. | `boolean` (default: `false`) | isMultipane | If true, two calendar months will be shown side-by-side instead of one. | `boolean` (default: `false`) | isOpen | If true, the picker will be shown without user interaction. | `boolean` (default: `false`) | showPresets | If true, the picker will show the preset ranges for selection. | `boolean` (default: `false`) | showPresetsOnly | If true, the picker will show only preset ranges. | `boolean` (default: `false`) | showYearControls | If true, the picker will hide the year navigation controls. | `boolean` (default: `false`) | showTimePicker | If true, the picker will show the time picker. | `boolean` (default: `false`) | enableFutureDates | If true, the picker will allow the user to select future dates. | `boolean` (default: `false`) | enablePastDates | If disabled, the picker will prevent the user from selecting anything prior to today. | `boolean` (default: `true`) | theme | The theme name that should be assigned to the theme data-attribute. | `string` (default: `''`) | presetRanges | The array of present configs to replace the default set with. | `array` (default: [...]) | includeFont | If false, the default Rubik font will not be loaded | `boolean` (default: `true`) ### Events | Prop | Description | Default | | :----------------- | :------------------------------------------------------------------------------------ | :-------------------------- | | onDateChange | Callback function to handle date change events. | `function` | onDayClick | Callback function to handle day click events. | `function` | onNavigationChange | Callback function to handle the navigation click event for months and years | `function` ## Theming You can customize DatePicker theme using several methods: - Assign a theme class name via the `theme` property that includes all of your CSS variables overrides - Define the overrides directly using the `style` property - Override the CSS variables globally DatePicker CSS variables: ```css /** * Common Variables */ --datepicker-border-color: #e8e9ea; --datepicker-border-radius-small: .125rem; --datepicker-border-radius-base: .25rem; --datepicker-border-radius-large: .5rem; --datepicker-border-radius-xlarge: .75rem; --datepicker-border-radius-xxlarge: 1rem; --datepicker-border-radius-xxxlarge: 1.125rem; --datepicker-state-active: #0087ff; --datepicker-state-hover: #e7f7fc; --datepicker-color: #21333d; --datepicker-font-family: 'Rubik', sans-serif; --datepicker-font-size-jumbo: 1.75rem; --datepicker-font-size-xxxlarge: 1.5rem; --datepicker-font-size-xxlarge: 1.375rem; --datepicker-font-size-xlarge: 1.25rem; --datepicker-font-size-large: 1.125rem; --datepicker-font-size-base: 14px; --datepicker-font-size-medium: 0.89rem; --datepicker-font-size-small: 0.75rem; --datepicker-font-size-xsmall: 0.625rem; --datepicker-font-size-xxsmall: 0.5rem; --datepicker-font-size-xxxsmall: 0.375rem; --datepicker-font-weight-thin: 100; --datepicker-font-weight-light: 300; --datepicker-font-weight-base: 400; --datepicker-font-weight-medium: 500; --datepicker-font-weight-bold: 700; --datepicker-font-weight-black: 900; --datepicker-spacing: 8px; --datepicker-margin-xsmall: calc(var(--datepicker-spacing) / 4); --datepicker-margin-small: calc(var(--datepicker-spacing) / 2); --datepicker-margin-base: var(--datepicker-spacing); --datepicker-margin-large: calc(var(--datepicker-spacing) * 2); --datepicker-margin-xlarge: calc(var(--datepicker-spacing) * 3); --datepicker-margin-xxlarge: calc(var(--datepicker-spacing) * 4); --datepicker-margin-xxxlarge: calc(var(--datepicker-spacing) * 5); --datepicker-margin-jumbo: calc(var(--datepicker-spacing) * 6); --datepicker-padding-xsmall: calc(var(--datepicker-spacing) / 4); --datepicker-padding-small: calc(var(--datepicker-spacing) / 2); --datepicker-padding-base: var(--datepicker-spacing); --datepicker-padding-large: calc(var(--datepicker-spacing) * 2); --datepicker-padding-xlarge: calc(var(--datepicker-spacing) * 3); --datepicker-padding-xxlarge: calc(var(--datepicker-spacing) * 4); --datepicker-padding-xxxlarge: calc(var(--datepicker-spacing) * 5); --datepicker-padding-jumbo: calc(var(--datepicker-spacing) * 6); /** * Container */ --datepicker-container-background: #fff; --datepicker-container-border: 1px solid var(--datepicker-border-color); --datepicker-container-border-radius: 12px; --datepicker-container-box-shadow: 0 1px 20px rgba(0, 0, 0, 0.1); --datepicker-container-font-family: var(--datepicker-font-family); --datepicker-container-left: 0; --datepicker-container-position: absolute; --datepicker-container-top: 105%; --datepicker-container-width: fit-content; --datepicker-container-zindex: 99; /** * Calendar */ --datepicker-calendar-border: 0; --datepicker-calendar-padding: var(--datepicker-padding-base) var(--datepicker-padding-large) var(--datepicker-padding-xlarge); --datepicker-calendar-position: relative; --datepicker-calendar-width: 310px; --datepicker-calendar-split-border: 1px solid var(--datepicker-border-color); /** * Calendar Header */ --datepicker-calendar-header-align-items: center; --datepicker-calendar-header-color: var(--datepicker-color); --datepicker-calendar-header-display: flex; --datepicker-calendar-header-font-size: var(--datepicker-font-size-large); --datepicker-calendar-header-justify-content: space-between; --datepicker-calendar-header-margin: 0 0 var(--datepicker-margin-xlarge) 0; --datepicker-calendar-header-padding: var(--datepicker-padding-large) var(--datepicker-padding-base); --datepicker-calendar-header-user-select: none; /** * Calendar Header Month Navigation */ --datepicker-calendar-header-month-nav-background: transparent; --datepicker-calendar-header-month-nav-background-hover: #f5f5f5; --datepicker-calendar-header-month-nav-border: 0; --datepicker-calendar-header-month-nav-cursor: pointer; --datepicker-calendar-header-month-nav-border-radius: 20px; --datepicker-calendar-header-month-nav-color: var(--datepicker-color); --datepicker-calendar-header-month-nav-cursor: pointer; --datepicker-calendar-header-month-nav-font-size: var(--datepicker-font-size-large); --datepicker-calendar-header-month-nav-height: 32px; --datepicker-calendar-header-month-nav-margin-left: -8px; --datepicker-calendar-header-month-nav-padding: var(--datepicker-padding-small); --datepicker-calendar-header-month-nav-text-align: center; --datepicker-calendar-header-month-nav-width: 32px; --datepicker-calendar-header-month-nav-icon-next-background: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAACXBIWXMAABYlAAAWJQFJUiTwAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAACLSURBVHgB7ZTLCYAwEERHbcASUpIlaAd2YDoxlmIX3ixFEwwYQQL5kCWwD94ph5mwywIMUzmLlYRBe1lXENBrT+oSgktwiepLNJ63EWkl3AOltBMCkHh/kEv5F9SCGN8IzKntEYfAdwQb0kYaHO4uoUJBBIdzOAoiKMMNQ47wDvEceA7Zrp3BMLVyA56LVFYQOkngAAAAAElFTkSuQmCC') no-repeat center center; --datepicker-calendar-header-month-nav-icon-next-background-size: 16px 16px; --datepicker-calendar-header-month-nav-icon-next-filter: invert(0); --datepicker-calendar-header-month-nav-icon-next-height: 16px; --datepicker-calendar-header-month-nav-icon-next-margin: auto; --datepicker-calendar-header-month-nav-icon-next-width: 16px; --datepicker-calendar-header-month-nav-icon-prev-background: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAACXBIWXMAABYlAAAWJQFJUiTwAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAACKSURBVHgB7ZbBDYAgDEW/xgEcgZHcQDYRJ5ER3EhHcAPtAQMHQwIiSNKXvAMH+CUNDQDDVM5kLMJCnsYBmXHDN1IgIxzO4QIZ+Ty8gT9cOuuZ3BHHQa4hGxTszVOpnoJaFMbXAk2OzvpNC+7zojYVewFcBBdRVRE9CqCR4EvWIR4JO5iC5jzD/IoLU/FXPXheCj0AAAAASUVORK5CYII=') no-repeat center center; --datepicker-calendar-header-month-nav-icon-prev-background-size: 16px 16px; --datepicker-calendar-header-month-nav-icon-prev-filter: invert(0); --datepicker-calendar-header-month-nav-icon-prev-height: 16px; --datepicker-calendar-header-month-nav-icon-prev-margin: auto; --datepicker-calendar-header-month-nav-icon-prev-width: 16px; /** * Calendar Header Text */ --datepicker-calendar-header-text-align-items: center; --datepicker-calendar-header-text-color: var(--datepicker-color); --datepicker-calendar-header-text-display: flex; --datepicker-calendar-header-text-font-size: inherit; --datepicker-calendar-header-text-font-weight: var(--datepicker-font-weight-medium); --datepicker-calendar-header-text-gap: 8px; /** * Calendar Header Year Navigation Container */ --datepicker-calendar-header-year-align-items: center; --datepicker-calendar-header-year-display: flex; --datepicker-calendar-header-year-flex-direction: column; --datepicker-calendar-header-year-margin: 0; /** * Calendar Header Year Navigation Controls */ --datepicker-calendar-header-year-nav-display: block; --datepicker-calendar-header-year-nav-color: var(--datepicker-color); --datepicker-calendar-header-year-nav-height: 12px; --datepicker-calendar-header-year-nav-line-height: 12px; --datepicker-calendar-header-year-nav-margin: -2px 0 0 0; --datepicker-calendar-header-year-nav-padding: 0; --datepicker-calendar-header-year-nav-width: 12px; --datepicker-calendar-header-year-nav-icon-font-size: 13px; --datepicker-calendar-header-year-nav-icon-next-background: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAACXBIWXMAABYlAAAWJQFJUiTwAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAABuSURBVHgB7c7BCYAwDIXhBy7gKB2hm9Vx3UJzqCASRWOTHvo+yDG8HyAiGt2Ef7LcLLeigyK31SsIdh4Pj9DGwyKu40u9kAht/OAe8TTuHvFm3C3iy3jziGQYv4vIMMjGcS0iwSjBWN/on4hoADu88UW4KXFVfgAAAABJRU5ErkJggg==') no-repeat center center; --datepicker-calendar-header-year-nav-icon-next-background-size: 12px 12px; --datepicker-calendar-header-year-nav-icon-next-display: block; --datepicker-calendar-header-year-nav-icon-next-filter: invert(0); --datepicker-calendar-header-year-nav-icon-next-height: 12px; --datepicker-calendar-header-year-nav-icon-next-width: 12px; --datepicker-calendar-header-year-nav-icon-prev-background: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAACXBIWXMAABYlAAAWJQFJUiTwAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAB3SURBVHgB7dTRCYAwDATQAxdwlI6QzZpx3UIrKJSC1aS2fngP7kvi3VcBIqK/m26+S8qcssBHWu5Dynokwi5m9wIHyX5gHRGL2wAndYwoyxWN1DDi9XLLiG7lT0Z0L6+NGFZ+NWJoeW2EYjD9svy0PzACIiJqsAHF2EaCcjFGaQAAAABJRU5ErkJggg==') no-repeat center center; --datepicker-calendar-header-year-nav-icon-prev-background-size: 12px 12px; --datepicker-calendar-header-year-nav-icon-prev-display: block; --datepicker-calendar-header-year-nav-icon-prev-filter: invert(0); --datepicker-calendar-header-year-nav-icon-prev-height: 12px; --datepicker-calendar-header-year-nav-icon-prev-width: 12px; /** * Presets */ --datepicker-presets-border: 1px solid var(--datepicker-border-color); --datepicker-presets-padding: 24px; --datepicker-presets-minwidth: 180px; --datepicker-presets-maxwidth: 200px; /** * Presets Button */ --datepicker-presets-button-background: transparent; --datepicker-presets-button-background-hover: var(--datepicker-state-hover); --datepicker-presets-button-background-active: var(--datepicker-state-active); --datepicker-presets-button-border: 0; --datepicker-presets-button-border-radius: 40px; --datepicker-presets-button-border-radius-active: 20px; --datepicker-presets-button-color: var(--datepicker-color); --datepicker-presets-button-color-active: #fff; --datepicker-presets-button-color-hover: var(--datepicker-color); --datepicker-presets-button-color-focus: var(--datepicker-color); --datepicker-presets-button-cursor: pointer; --datepicker-presets-button-cursor-active: default; --datepicker-presets-button-font-family: var(--datepicker-font-family); --datepicker-presets-button-font-size: var(--datepicker-font-size-base); --datepicker-presets-button-font-weight-active: var(--datepicker-font-weight-medium); --datepicker-presets-button-outline-focus: 5px auto -webkit-focus-ring-color; --datepicker-presets-button-margin: var(--datepicker-margin-small) 0; --datepicker-presets-button-padding: calc(var(--datepicker-padding-base) + 2px) var(--datepicker-padding-large); --datepicker-presets-button-text-align: left; --datepicker-presets-button-zindex-focus: 10; /** * Timepicker Container */ --datepicker-timepicker-container-align-items: center; --datepicker-timepicker-container-display: flex; --datepicker-timepicker-container-justify-content: space-around; --datepicker-timepicker-container-margin-bottom: var(--datepicker-margin-xlarge); /** * Timepicker Input */ --datepicker-timepicker-input-border: 1px solid var(--datepicker-border-color); --datepicker-timepicker-input-border-radius: var(--datepicker-border-radius-base); --datepicker-timepicker-input-display: block; --datepicker-timepicker-input-font-family: var(--datepicker-font-family); --datepicker-timepicker-input-margin: 0 auto; --datepicker-timepicker-input-padding: var(--datepicker-padding-small) var(--datepicker-padding-base); /** * Calendar DOW (Days of Week) */ --datepicker-calendar-dow-color: #8b9198; --datepicker-calendar-dow-font-size: var(--datepicker-font-size-base); --datepicker-calendar-dow-font-weight: var(--datepicker-font-weight-medium); --datepicker-calendar-dow-margin-bottom: var(--datepicker-margin-large); --datepicker-calendar-dow-text-align: center; /** * Calendar Month */ --datepicker-calendar-container-display: grid; --datepicker-calendar-container-grid-template-columns: repeat(7, 1fr); --datepicker-calendar-container-grid-gap: 0; --datepicker-calendar-container-width: fit-content; /** * Calendar Day Container */ --datepicker-calendar-day-container-appearance: none; --datepicker-calendar-day-container-background: inherit; --datepicker-calendar-day-container-border: 0; --datepicker-calendar-day-container-margin: 0; --datepicker-calendar-day-container-padding: 0; --datepicker-calendar-day-container-position: relative; --datepicker-calendar-day-container-text-align: center; /** * Calendar Day */ --datepicker-calendar-day-align-items: center; --datepicker-calendar-day-background-hover: #f5f5f5; --datepicker-calendar-day-border: 1px solid transparent; --datepicker-calendar-day-border: 1px solid transparent; --datepicker-calendar-day-border-radius: 100%; --datepicker-calendar-day-color: #232a32; --datepicker-calendar-day-color-disabled: #b9bdc1; --datepicker-calendar-day-color-hover: #232a32; --datepicker-calendar-day-cursor: pointer; --datepicker-calendar-day-cursor-disabled: default; --datepicker-calendar-day-display: flex; --datepicker-calendar-day-height: 40px; --datepicker-calendar-day-justify-content: center; --datepicker-calendar-day-font-family: var(--datepicker-font-family); --datepicker-calendar-day-font-size: var(--datepicker-font-size-base); --datepicker-calendar-day-margin-bottom: 1px; --datepicker-calendar-day-padding: var(--datepicker-padding-base); --datepicker-calendar-day-text-align: center; --datepicker-calendar-day-width: 40px; --datepicker-calendar-day-zindex-focus: 12; /** * Calendar Days Outside of Month */ --datepicker-calendar-day-other-border: 0; --datepicker-calendar-day-other-box-shadow: none; --datepicker-calendar-day-other-color: #d1d3d6; /** * Calendar Today */ --datepicker-calendar-today-background: transparent; --datepicker-calendar-today-border: 1px solid #232a32; --datepicker-calendar-today-cursor: default; --datepicker-calendar-today-font-weight: var(--datepicker-font-weight-bold); /** * Calendar Range */ --datepicker-calendar-range-background: var(--datepicker-state-hover); --datepicker-calendar-range-background-disabled: var(--datepicker-state-hover); --datepicker-calendar-range-border: 0; --datepicker-calendar-range-border-radius: 0; --datepicker-calendar-range-color: var(--datepicker-color); --datepicker-calendar-range-color-disabled: #ffc0b7; --datepicker-calendar-range-cursor: default; --datepicker-calendar-range-font-weight: var(--datepicker-font-weight-base); /** * Calendar Range Start & End */ --datepicker-calendar-range-start-box-shadow: inset -20px 0 0 var(--datepicker-state-hover); --datepicker-calendar-range-end-box-shadow: inset 20px 0 0 var(--datepicker-state-hover); --datepicker-calendar-range-start-box-shadow-selected: inset -20px 0 0 #eceff1; --datepicker-calendar-range-end-box-shadow-selected: inset 20px 0 0 #eceff1; --datepicker-calendar-range-start-end-background: #f5f5f5; --datepicker-calendar-range-start-end-color: #232a32; /** * Calendar Range Selected */ --datepicker-calendar-range-selected-background: var(--datepicker-state-active); --datepicker-calendar-range-selected-border-radius: 20px; --datepicker-calendar-range-selected-color: #fff; --datepicker-calendar-range-selected-font-weight: var(--datepicker-font-weight-medium); --datepicker-calendar-range-selected-start-border-radius: 20px; /** * Calendar Range Hover */ --datepicker-calendar-range-included-background: #eceff1; --datepicker-calendar-range-included-box-shadow: inset 20px 0 0 #eceff1; --datepicker-calendar-range-included-color: #232a32; --datepicker-calendar-range-included-font-weight: var(--datepicker-font-weight-base); --datepicker-calendar-range-included-height: var(--datepicker-calendar-day-height); ``` ### Using the theme property ```svelte <DatePicker ... theme="custom-datepicker">...</DatePicker> <style> :global(.datepicker[data-picker-theme="custom-datepicker"]) { --datepicker-container-background: #ff66ae; --datepicker-container-border: 1px solid #ff1683; --datepicker-calendar-header-text-color: #fff; --datepicker-calendar-dow-color: #fff; --datepicker-calendar-day-color: #fff; --datepicker-calendar-day-color-disabled: pink; --datepicker-calendar-range-selected-background: #ff1683; --datepicker-calendar-header-month-nav-background-hover: #ff1683; --datepicker-calendar-header-month-nav-icon-next-filter: invert(100); --datepicker-calendar-header-month-nav-icon-prev-filter: invert(100); --datepicker-calendar-header-year-nav-icon-next-filter: invert(100); --datepicker-calendar-header-year-nav-icon-prev-filter: invert(100); --datepicker-calendar-split-border: 1px solid pink; --datepicker-presets-border: 1px solid pink; --datepicker-presets-button-background-active: #ff1683; --datepicker-presets-button-color: #fff; --datepicker-presets-button-color-active: #fff; --datepicker-presets-button-color-hover: #333; --datepicker-presets-button-color-focus: #333; } </style> ``` ## Changelog [Changelog](CHANGELOG.md) ## License [MIT](LICENSE)