Giter Club home page Giter Club logo

svelte-flatpickr's Introduction

svelte-flatpickr

Svelte component for flatpickr datetime picker.

Usage

Ideally, if you're using svelte already, configure your bundler to resolve the package's svelte field (or import from svelte-flatpickr/src/Flatpickr.svelte) and compile the template from within your own project. See sveltejs/svelte#604 for more information.

Don't forget to import flatpickr's stylesheets as well (flatpickr/dist/flatpickr.css, and optionally any theme stylesheets you want).

Versions

  • For Svelte v3 use v3.x.x
  • For Svelte v2.x use v1.x.x
  • For Svelte v1.x use v0.x.x

Flatpickr documentation

Example

See the test directory for a full working example.

<main>
    <form on:submit={handleSubmit}>
        <Flatpickr {options} bind:value bind:formattedValue on:change={handleChange} name="date" />

        <button type="submit">
            Submit
        </button>
    </form>
</main>

<script>
    import Flatpickr from 'svelte-flatpickr';
    import 'flatpickr/dist/flatpickr.css';

    let value, formattedValue;

    const options = {
        enableTime: true,
        onChange(selectedDates, dateStr) {
            console.log('flatpickr hook', selectedDates, dateStr);
        }
    };

    $: console.log({ value, formattedValue });

    function handleChange(event) {
        const [ selectedDates, dateStr ] = event.detail;
        console.log({ selectedDates, dateStr });
    }

    function handleSubmit(event) {
        event.preventDefault();

        console.log(event.target.elements['date'].value);
    }
</script>

The selected date(s) can be obtained using hooks or binding to value.

The format of the date expected can be controlled with the prop dateFormat, which will take a date format acceptable to Flatpickr.

The prop formattedValue can also be bound to, which contains the selected date(s)'s formatted string.

The props input and flatpickr (or fp) can also be bound to, which represent the underlying input element (unless using a custom external element as described below) and the flatpickr instance, respectively. Assigning to these will break the Flatpickr component, please don't.

Hooks

Hooks can be specified normally in the options object, or by listening to the svelte event.

When binding svelte handler, event.details will be [ selectedDates, dateStr, instance ] (see flatpickr events docs).

External Elements

As per the flatpickr documentation, it is also possible to wrap a custom element rather than have the component create the input for you. This allows for decoration of the control such as adding a clear button or similar.

You can add the custom element by wrapping it in the Flatpickr component, as it is the default slot. However, it is necessary to pass the selector for the custom element, as the element attribute to Flatpickr's options.

Specifying the selector for a custom element automatically adds the {wrap: true} option to flatpickr.

<Flatpickr
    options="{ flatpickrOptions }"
    bind:value="{date}"
    element="#my-picker"
>
    <div class="flatpickr" id="my-picker">
        <input type="text" placeholder="Select Date.." data-input />

        <a class="input-button" title="clear" data-clear>
            <i class="icon-close"></i>
        </a>
    </div>
</Flatpickr>

<script>
    import Flatpickr from 'svelte-flatpickr';

    import 'flatpickr/dist/flatpickr.css';
    import 'flatpickr/dist/themes/light.css';

    let date = null;
    const flatpickrOptions = {};
</script>

svelte-flatpickr's People

Contributors

alexander-mart avatar danhstevens avatar frederikhors avatar gregroyal avatar hjsung-brique avatar jacobmischka avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

svelte-flatpickr's Issues

A little issue with Svelte 5 typescript check

I'm trying it with Svelte 5 for the first time today and it works.

I'm having only a small issue:

<script lang="ts">
    export let selectedDateTime: string | Date | Date[] | null | undefined = undefined;
    // ...
</script>

<Flatpickr on:change bind:value={selectedDateTime}>
    <!-- ... -->
</Flatpickr>
Error: Object literal may only specify known properties, and 'children' does not exist in type 'WithBindings<SvelteFlatpickrProps & SvelteInputProps>'. (ts)

Can you help me understand?

Small error message when using 'mode: range' in options.

When adding mode: 'range' into my options for flatpickr I get this error message. It still works as expected, but it just throws this error message. Thanks for any input...

Type '{ mode: string; dateFormat: string; defaultDate: string; enableTime: boolean; onChange: (selectedDates: any, dateStr: any) => void; }' is not assignable to type 'Partial<BaseOptions>'.

const options = { mode: 'range', dateFormat: 'm/d/Y', defaultDate: '', enableTime: false, onChange: function (selectedDates, dateStr) { onDone(selectedDates[0], selectedDates[1], dateStr); }

Calling setDate before flatpickr is ready does not format date

$: if (fp) fp.setDate(value, false, dateFormat);

This line triggers as soon as fp is assigned a value but it does not guarantee Flatpickr is ready. As such when I give an initial value to the component it won't format the date and look like an ISO date.

Changing the code above to the following

  let ready = false;
  if (!props.onReady) {
    props.onReady = () => (ready = true);
  }

  $: if (fp && ready) {
    fp.setDate(new Date(value), false, dateFormat);
  }

You probably know a better way to implement this

Problem imports localization

Are used Svelte 2.16.1, Sapper 0.25, template rollup.

For named import import { Russian } from 'flatpicker'

<div>
  <Flatpickr
      {flatpickrOptions}
      bind:value="date"
      on:change
  />
</div>

<script>
  import {Russian} from "flatpickr/dist/l10n/ru.js";
  import 'flatpickr/dist/flatpickr.css';
  import 'flatpickr/dist/themes/light.css';


  export default {
    components: {
      Flatpickr: 'svelte-flatpickr',
    },
    data() {
      return {
        flatpickrOptions: {
          enableTime: true,
          locale: Russian,
        }
      }
    },
  }
</script>

compile error

(node:10484) UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'imports' of undefined
....
(node:10484) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 23)

For import by default everything is compiled, but the locale does not change.

rollup.config.js

import replace from 'rollup-plugin-replace';
import resolve from 'rollup-plugin-node-resolve';
import commonjs from 'rollup-plugin-commonjs';
import svelte from 'rollup-plugin-svelte';
import babel from 'rollup-plugin-babel';
import { terser } from 'rollup-plugin-terser';
import config from 'sapper/config/rollup.js';
import pkg from './package.json';

const sveltePreprocess = require('svelte-preprocess');

const mode = process.env.NODE_ENV;
const dev = mode === 'development';
const legacy = !!process.env.SAPPER_LEGACY_BUILD;

const options = {
  transformers: {
    postcss: true,
  },
};

const preprocess = sveltePreprocess(options);

/* eslint import/no-default-export: [0, "fs"] */
export default {
  client: {
    input: config.client.input(),
    output: config.client.output(),
    plugins: [
      replace({
        'process.browser': true,
        'process.env.NODE_ENV': JSON.stringify(mode),
      }),
      svelte({
        dev,
        hydratable: true,
        emitCss: true,
        preprocess: preprocess,
      }),
      resolve(),
      commonjs(),

      legacy &&
        babel({
          extensions: ['.js', '.html'],
          runtimeHelpers: true,
          exclude: ['node_modules/@babel/**'],
          presets: [
            [
              '@babel/preset-env',
              {
                targets: '> 0.25%, not dead',
              },
            ],
          ],
          plugins: [
            '@babel/plugin-syntax-dynamic-import',
            [
              '@babel/plugin-transform-runtime',
              {
                useESModules: true,
              },
            ],
          ],
        }),

      !dev &&
        terser({
          module: true,
        }),
    ],
  },

  server: {
    input: config.server.input(),
    output: config.server.output(),
    plugins: [
      replace({
        'process.browser': false,
        'process.env.NODE_ENV': JSON.stringify(mode),
      }),
      svelte({
        generate: 'ssr',
        dev,
        preprocess: preprocess,
      }),
      resolve(),
      commonjs(),
    ],
    external: Object.keys(pkg.dependencies).concat(
      require('module').builtinModules ||
      /* eslint node/no-deprecated-api: [error, {ignoreGlobalItems: ["process.binding"]}] */
        Object.keys(process.binding('natives')),
    ),
  },

  serviceworker: {
    input: config.serviceworker.input(),
    output: config.serviceworker.output(),
    plugins: [
      resolve(),
      replace({
        'process.browser': true,
        'process.env.NODE_ENV': JSON.stringify(mode),
      }),
      commonjs(),
      !dev && terser(),
    ],
  },
};

Cannot find module 'flatpickr/dist/theme/material_blue.css'

Hi,

I probably missed something but sveltekit doesn't see the css theme path.

// myfile.svelte
<script>
  import Flatpickr from "svelte-flatpickr";
  import "flatpickr/dist/flatpickr.css";
  import "flatpickr/dist/theme/material_blue.css";
...
Cannot find module 'flatpickr/dist/theme/material_blue.css' imported from '/Users/.../myfile.svelte'

Thx

Running jest : flatpickr is not a function

I've tried running tests on components that include this package but they end up failing.
At first I would get
TypeError: Flatpickr is not a constructor
then I added 'jest-svelte-resolver' to my jest.config.js which gave me
SyntaxError: Unexpected token '<'

So I added transformIgnorePatterns: ['node_modules/(?!svelte-flatpickr)/'], in the jest.config
and this is where I am stuck. I keep getting
TypeError: flatpickr is not a function

I've previously tried doing import * as Flatpickr from 'svelte-flatpickr';, that would bypass the test problems, but break the app.

jest.config.js

const { pathsToModuleNameMapper } = require('ts-jest/utils');
const { compilerOptions } = require('./tsconfig');

module.exports = {
  preset: 'ts-jest',
  resolver: 'jest-svelte-resolver',
  testEnvironment: 'node',
  transform: {
    '^.+\\.svelte$': [
      'svelte-jester',
      {
        preprocess: true
      }
    ],
    '^.+\\.ts$': 'ts-jest'
  },
  transformIgnorePatterns: ['node_modules/(?!svelte-flatpickr)/'],
  setupFilesAfterEnv: [
    '@testing-library/jest-dom/extend-expect',
    './setupTests.ts'
  ],
  moduleFileExtensions: ['js', 'ts', 'svelte'],
  modulePathIgnorePatterns: ['<rootDir>/cypress/'],
  moduleNameMapper: pathsToModuleNameMapper(compilerOptions.paths, {
    prefix: '<rootDir>'
  })
};

Has anyone been able to fix this issue?

I just found out another crazy issue!

I just found out another crazy issue!

REPL: https://svelte.dev/repl/c3a6591167c34bb48d28966fe83b22f2?version=3.59.1

If you click on the button "Toggle Flatpickr" the Flatpickr renders and works with date:

image

But if you use the mobile version of the browser and click the button two times to re-render it, it throws!

image

Uncaught (in promise) TypeError: Cannot set properties of undefined (setting 'tabIndex')
    at buildMonthSwitch (eval at handle_message (about:srcdoc:14:8), <anonymous>:1723:51)
    at jumpToDate (eval at handle_message (about:srcdoc:14:8), <anonymous>:1484:17)
    at Object.setDate (eval at handle_message (about:srcdoc:14:8), <anonymous>:2823:13)
    at $$self.$$.update (eval at handle_message (about:srcdoc:14:8), <anonymous>:3457:13)
    at update (eval at handle_message (about:srcdoc:14:8), <anonymous>:335:16)
    at flush (eval at handle_message (about:srcdoc:14:8), <anonymous>:299:21)

This happens in mobile only!

Why? What's the problem?

Missing `null` in value type

I have a small issue with this code:

<script lang="ts">
	import Flatpickr from 'svelte-flatpickr';

	export let selected_date_time: string | Date | Date[] | null | undefined = undefined;
</script>


<Flatpickr bind:value={selected_date_time}> <!-- here the error -->
  <!-- More code here -->
</Flatpickr>

error:

Type 'string | Date | Date[] | null | undefined' is not assignable to type 'string | Date | Date[] | undefined'.
  Type 'null' is not assignable to type 'string | Date | Date[] | undefined'.

I think because the type for value is only string | Date | Date[] | undefined, missing the null.

Can we add it too, please?

Or maybe I'm totally wrong.

Since update to 3.3.4 my own app does not build correctly anymore and Flatpickr is inserted as argument to my app

Hi all,
I have a weird issue and it took me some time to figure out, that this comes from the update from version <=3.3.2 to version 3.3.4.

My bundle.js is created with rollup. Everything worked perfectly fine and my bundle.js looked somewhat like this:

var app = (function () {
    'use strict';

    function noop$1() { }
    const identity = x => x;
    function assign(tar, src) {
        // @ts-ignore
        for (const k in src)
            tar[k] = src[k];
        return tar;
    }
.... // this goes on and on and on

    let app;
    requireI18n(() => {
    	app = new App({
    		target: document.body,
    	});
    });

    var app$1 = app;

    return app$1;

})();
//# sourceMappingURL=bundle.js.map

However, I now want to update to Svelte v4 and therefore updated to version 3.3.4, because you provide support for Svelte there. The problem that I than have is that my bundle.js is still built, but the Flatpickr kind of wrapps around my app/is inserted as argument to my app function:

var app = (function (Flatpickr) {
    'use strict';

    function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }

    var Flatpickr__default = /*#__PURE__*/_interopDefaultLegacy(Flatpickr);

    function noop$1() { }
    const identity = x => x;
    function assign(tar, src) {
        // @ts-ignore
        for (const k in src)
            tar[k] = src[k];
        return tar;
    }
....// this goes on and on and on

let app;
    requireI18n(() => {
    	app = new App({
    		target: document.body,
    	});
    });

    var app$1 = app;

    return app$1;

})(Flatpickr);
//# sourceMappingURL=bundle.js.map

This results in my app not working anymore (I will only see a white screen) and a hint showing up:

(!) Missing global variable name
Use output.globals to specify browser global variable names corresponding to external modules
svelte-flatpickr/src/Flatpickr.svelte (guessing 'Flatpickr')

Maybe someone of you has an idea, what exactly causes the issue (it must be something in the commits for version 3.3.4) and how to solve it, such that I can still build my app also with Svelte v4?

Cheers,
Jonas

How to use with Sapper and SSR?

Hi! I try to use in Sapper app and get this message:

is not a valid SSR component. You may need to review your build config to ensure that dependencies are compiled, rather than imported as pre-compiled modules

Are any options to use this great component with Sapper and SSR?

DOMException thrown on Android mobile Chrome

Thanks for your efforts to make this component available for Svelte.
It has been quiet useful to have a Date picker component with the support for date ranges.
Even though this picker works as expected on the Web browsers on desktops, its throwing an error which originates from Flatpickr component when we try to use it on smaller view ports such as Android mobile Chrome.
Here is the full error stack:

Uncaught (in promise) DOMException: Failed to read the 'cssRules' property from 'CSSStyleSheet': Cannot access rules
    at getDocumentStyleSheet (http://localhost:3000/node_modules/.vite/deps/chunk-EN7TYZOW.js?v=56d3d774:1874:18)
    at positionCalendar (http://localhost:3000/node_modules/.vite/deps/chunk-EN7TYZOW.js?v=56d3d774:1854:17)
    at Object.open (http://localhost:3000/node_modules/.vite/deps/chunk-EN7TYZOW.js?v=56d3d774:1655:7)
    at handleOpen (http://localhost:3000/src/components/DatePicker.svelte:445:19)
    at $$self.$$.update (http://localhost:3000/src/components/DatePicker.svelte:560:7)
    at update (http://localhost:3000/node_modules/.vite/deps/chunk-TVA3GBF4.js?v=56d3d774:1004:8)
    at flush (http://localhost:3000/node_modules/.vite/deps/chunk-TVA3GBF4.js?v=56d3d774:979:7)

Once this error is encountered the entire app is usable and forces user to reload.

What have I tried so far?

  • Made sure that import 'flatpickr/dist/flatpickr.css'; is in the main app.css file as well as tried to put that in the main +layout.svelte

Note: This error occurs only on Android mobile Chrome, not on iOS mobile browser (Safari)

Any suggestions or workarounds for this issue, is much appreciated. Thanks.

`this` has been rewritten to `undefined` compiling the bundle

Any idea what I did wrong?

$ npm run dev
....
bundles ./app-entries/development.js โ†’ public/js/development.js...
(!) `this` has been rewritten to `undefined`
https://rollupjs.org/guide/en/#error-this-is-undefined
node_modules/flatpickr/dist/esm/index.js
1: var __assign = (this && this.__assign) || function () {
                   ^
2:     __assign = Object.assign || function(t) {
3:         for (var s, i = 1, n = arguments.length; i < n; i++) {
...and 3 other occurrences

I tried to import in both ways but still gives the error.

// import Flatpickr from 'svelte-flatpickr';
// import Flatpickr from 'svelte-flatpickr/src/Flatpickr.svelte';

rollup.conf.js:

import path from 'path';

import svelte from 'rollup-plugin-svelte';
import alias from '@rollup/plugin-alias';
import resolve from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
import livereload from 'rollup-plugin-livereload';
import replace from '@rollup/plugin-replace';
import { config } from 'dotenv';
import { terser } from 'rollup-plugin-terser';
import { bundles } from './app-entries/bundles'

const
    production = !process.env.ROLLUP_WATCH,
    projectRootDir = path.resolve(__dirname),
    bundlesRootDir = path.resolve(projectRootDir, './public/js')

function serve() {
    let server;

    function toExit() {
        if (server) server.kill(0);
    }

    return {
        writeBundle() {
            if (server) return;
            server = require('child_process').spawn('npm', ['run', 'start', '--', '--dev'], {
                stdio: ['ignore', 'inherit', 'inherit'],
                shell: true
            });

            process.on('SIGTERM', toExit);
            process.on('exit', toExit);
        }
    };
}

const getPlugins = (bundle) => {
    return [
        alias({
            entries: [
                {
                    // No need for you to use this alias.
                    find: '~',
                    replacement: path.resolve(projectRootDir, './src')
                },
                {
                    find: '@',
                    replacement: path.resolve(projectRootDir, './src/components')
                },
                {
                    find: '$/data',
                    replacement: path.resolve(projectRootDir, './src/data')
                },
                {
                    find: '$/utils',
                    replacement: path.resolve(projectRootDir, './src/utils')
                },
                {
                    find: '$/services',
                    replacement: path.resolve(projectRootDir, './src/services')
                },
                {
                    find: '$/stores',
                    replacement: path.resolve(projectRootDir, './src/stores')
                },
            ]
        }),
        replace({
            preventAssignment: false,
            __app: JSON.stringify({
                config: {
                    isProduction: production,
                    containerId: bundle.containerId,
                    ...config().parsed // attached the .env config
                }
            }),
        }),

        svelte({
            emitCss: false,
            compilerOptions: {
                // enable run-time checks when not in production
                dev: !production,
            }
        }),

        // If you have external dependencies installed from
        // npm, you'll most likely need these plugins. In
        // some cases you'll need additional configuration -
        // consult the documentation for details:
        // https://github.com/rollup/plugins/tree/master/packages/commonjs
        resolve({
            browser: true,
            dedupe: ['svelte']
        }),
        commonjs(),

        // In dev mode, call `npm run start` once
        // the bundle has been generated
        !production && bundle.input === 'development' && serve(),

        // Watch the `public` directory and refresh the
        // browser on changes when not in production
        !production && livereload('public'),

        // If we're building for production (npm run build
        // instead of npm run dev), minify
        production && terser()
    ]
}

// Exported configuration object
export default Object.keys(bundles)
    .map((input) => ({
        input: `./app-entries/${input}.js`,
        output: {
            sourcemap: true,
            format: 'iife',
            name: 'app',
            file: `${bundlesRootDir}/${bundles[input].outputFileName}.js`
        },
        plugins: getPlugins({input, ...bundles[input]}),
        watch: {
            clearScreen: false,
        }
}))

Svelte version 3.47.0

Typescript types?

Why this error in a Svelte Typescript project?

Could not find a declaration file for module 'svelte-flatpickr'. 'C:/project/node_modules/svelte-flatpickr/dist/index.cjs.js' implicitly has an 'any' type.
  Try `npm i --save-dev @types/svelte-flatpickr` if it exists or add a new declaration (.d.ts) file containing `declare module 'svelte-flatpickr';` (ts)

ERROR: Uncaught RangeError: Maximum call stack size exceeded.

Whenever I use the time-picker in a component that I am importing, I get this error from Svelte Router. Pretty nasty one...here is a screenshot:
Screen Shot 2020-10-01 at 12 59 59 PM

Here is how I am using it in my component:
<Flatpickr options="{ timepickrOptions }" bind:value={values.time} element="#timePicker"> <div class="form-group col-sm-12 col-md-6" id="timePicker"> <input type="text" class="form-control timePickerSelect" placeholder="Choose a Time...*" data-input> </div> </Flatpickr>

It does not seem to happen if the Flatpickr component is added in the same file its being used in (hoping that makes sense). In my case, I have a form in a modal that is a separate component. Additionally, there does not seem to be a similar error with the date-picker.

Default selected date not working

Hello,

I am trying to set default selected date for the Datepicker but it is not working (Using Svelte). Anyone out there can you please help me. Thanks.
"Svelte Version": ^3.46.0
"svelte-flatpickr": "^3.2.6"

let datepickerOption = {
minDate: new Date().fp_incr(1),
time_24hr: true,
allowInput: true,
altInput: true,
altFormat: 'F j, Y',
dateFormat: 'Y-m-d',
default: '2022-10-31'
};

<Flatpickr
options={datepickerOption}
on:change={(e) => handleBookingDateChange(e, i)}
name="bookingDate"
dateFormat="F j, Y"
placeholder="Select Date"
id="bookingDate"
/>

moduleResolution: "bundler" support

I tried use svelte-flatpickr with tsconfig.json setting as below:

{
	"extends": "./.svelte-kit/tsconfig.json",
	"compilerOptions": {
		"allowJs": true,
		"checkJs": true,
		...
		"module": "ESNext",
		"moduleResolution": "Bundler",
		"types": ["vitest/globals"]
	}
}

When I import module as
import Flatpickr from 'svelte-flatpickr';
and executed npm run check, I see error :

Error: Cannot find module 'svelte-flatpickr' or its corresponding type declarations. (ts)
        import Flatpickr from 'svelte-flatpickr';

It was because "moduleResolution": "Bundler" option in tsconfig.json makes fail to find type definitions. (https://www.typescriptlang.org/docs/handbook/modules/theory.html#module-resolution)

I tried to fix package.json file of svelte-flatpickr module as below, and error resolved.

{
     ...
      "exports": {
		".": {
			"svelte": "./src/Flatpickr.svelte",
			"types": "./src/types.d.ts"
		}
	}
}

How about adding "types" field to svelte-flatpickr module's package.json file?

Can't get to work with custom element

I can't seem to get this package to work properly with any custom elements.

Even with a barebones implementation I get:

TypeError: Cannot read property 'nodeName' of null
Uncaught (in promise) TypeError: fp.setDate is not a function

Here is the implementation:

<script>
  import Flatpickr from 'svelte-flatpickr'
  import 'flatpickr/dist/flatpickr.css'
  import 'flatpickr/dist/themes/light.css'

  const flatpickrOptions = {
    enableTime: true,
    wrap: true,
    element: '#test',
    onChange: (selectedDates, dateStr, instance) => {
      console.log('Options onChange handler', selectedDates, dateStr)
    }
  }
  
  let date
</script>

<Flatpickr options={ flatpickrOptions } bind:value={ date } element='#test'>
  <input id='test' type='text' />
</Flatpickr>

Also, FYI, the example code in the repo does not work. It throws the following error:

Directive value must be a JavaScript expression enclosed in curly braces
29:     bind:value={date}
30:     placeholder="optional placeholder"
31:     on:change="handleChange(...event)" />
                   ^
32: </div>

Wrapping the expression in curly braces produces:

'event' is not defined
29:     bind:value={date}
30:     placeholder="optional placeholder"
31:     on:change="{ handleChange(...event) }" />
                                     ^
32: </div>

formattedValue not updating on AM/PM change

I have noticed that the flatpicker is not triggering the value or the formattedValue on change. Note the following minimum reproducable issue:

<script lang="ts">
    import Flatpickr from "svelte-flatpickr";

    let timeStart: string;
    let formattedTimeStart: string;
</script>

<Flatpickr
    id="flatpickr-time-start"
    class="form-control"
    name="time-start"
    bind:value={timeStart}
    bind:formattedValue={formattedTimeStart}
    options={{
        enableTime: true,
        noCalendar: true,
        dateFormat: "H:i:S",
        time_24hr: false,
        altFormat: "h:i K",
        altInput: true,
    }}
/>

<p style="margin-top: 100px;">Time Start: {timeStart}</p>
<p>Formatted Time Start: {formattedTimeStart}</p>   

When running this code, you'll note that if I use the keyboard to tab between the hours, minutes and AM/PM and update the AM/PM using the arrow keys up/down, the UI will update but the bound variables will not update consistently. When using the mouse to click the AM/PM button, it seems to work better.

It seems an intermittent issue because sometimes it does update, other times it doesn't. I have taken a screen recording demonstrating the issue.

https://www.loom.com/share/ec4d711a828c42988419ba573cdee8fa?sid=e7e753dd-0969-47ba-aa8a-30581539b894

Issues initially building css

First of all, thank you for your work on this. It's the best one out there for Svelte!

When I initially run yarn watch to build and watch file changes, it works. When I try to access a page that has svelte-flatpickr on it, the page fails to load and I see this error message:

Screen Shot 2019-10-04 at 11 23 28 AM

Essentially, the CSS is causing issues. I tried multiple routes such as adding the CSS imports to a <script context="module"><script>. Ultimately I copied the CSS from the files and added them to my public folder and then I can reference them like so:

<svelte:head>
  <link rel="stylesheet" href="/css/flatpickr/flatpickr.css" />
  <link rel="stylesheet" href="/css/flatpickr/light-theme.css" />
</svelte:head>

This obviously wouldn't help for future updates.

Flatpickr Date Picker Not Opening in SvelteKit 2

I was experiencing an issue with the Flatpickr date picker not opening in my SvelteKit 2 web app. After installing the library via npm, the date picker failed to open due to the Flatpickr CSS file not being automatically included in the project. I believe this is addressed somewhere but I just wanted to highlight a fix to the issue in-case anyone else ends up struggling with it in the future.

Environment

  • SvelteKit Version: 2
  • Svelte Version: 4.2.7
  • Flatpickr Version: Latest (installed via npm)

Solution

The issue was resolved by making the following changes:

Vite Configuration: Update vite.config.js to include this in the plugins array:

copy({
  targets: [
    {
      src: './node_modules/flatpickr/dist/flatpickr.css',
      dest: 'public/build'
    }
  ]
})

Top-Level Layout: Import the Flatpickr CSS file in the +layout.svelte page:

import "flatpickr/dist/flatpickr.css";

And there we go, the date picker should function correctly.

If this is something obvious or already detailed somewhere else, feel free to close or delete this issue. Just thought I'd share what I've learned from my 45 min struggle.

Happy coding!

Year not displaying

Before importing css, year is displaying and everything works. But as either flatpickr/dist/flatpickr.min.css or flatpickr/dist/flatpickr.css imported, the year part is just disappearing

Non-standard export of types

Hi! I wanted to use this library in Astro but I ran into issues. However, other Svelte libraries that use flatpickr, for example carbon-components-svelte work fine.

This is some feedback I got from people more knowledgable about types:

[svelte-flatpickr] is very weirdly packaged, it only has a single export using a non-standard export name and it declares its types using a fake module

I don't really know how we would support that without implementing Svelte's module resolution I assume. If the package just exposed the files normally, you could just import the Svelte components.

I tried fixing this to open a pull request but I couldn't quite get it to work locally and I don't have time to look into it more. I tried setting up a new project and following the instructions about packaging from the SvelteKit docs which gave me better types and made it work in Astro, but I couldn't figure out how to migrate this repository to the "correct" format without "starting from scratch".

I thought I'd leave an issue here to let you know that a more standard way of exporting the component and its types would be very helpful for Astro users and possibly others too!

Not working with range plugin

I am trying to implement a range picker, that will have the start date in one field and the end date in a separate field.

I have this prototype which is using the range plugin.

I have tried getting the same thing going in this repl but I seem to be hitting some limitations, or missing something essential...

Error when more than one Flatpickr on a page

If I have more than one <Flatpickr> on a page I get the error:

Uncaught (in promise) TypeError: selectedDates is undefined
getModeValue svelte-flatpickr.js:177

Versions:

flatpickr@^4.5.2:
  version "4.6.13"
  resolved "https://registry.npmjs.org/flatpickr/-/flatpickr-4.6.13.tgz"

svelte-flatpickr@^3.3.4:
  version "3.3.4"
  resolved "https://registry.npmjs.org/svelte-flatpickr/-/svelte-flatpickr-3.3.4.tgz"
  dependencies:
    flatpickr "^4.5.2"

I had to comment the usage of the second instance to get it to work:

https://github.com/stav/sveltekit-blog-app/blob/a8ca20bf2d72386af30efcec16f11fd8afad9dc8/src/routes/admin/jobs/form.svelte#L41

<FormField label="Beginning Date" name="beg_date">
  <DateField name="beg_date" value={formItem?.beg_date ?? ''} />
</FormField>

<!-- Uncaught (in promise) TypeError: selectedDates is undefined -->
<!-- <FormField label="Ending Date" name="end_date">
  <DateField name="end_date" value={formItem?.end_date ?? ''} />
</FormField> -->

Component is here: https://github.com/stav/sveltekit-blog-app/blob/a8ca20bf2d72386af30efcec16f11fd8afad9dc8/src/lib/date-field.svelte#L14

Am I missing a documented way to have multiple data input fields on the same page?

Can not bind formattedValue to a Svelte store

Hello!

I have a use case where I need to use two-way binding to bind formattedValue to a Svelte store. So that when the store is updated, the datepicker is also updated.

I would like to use it like outlined here: https://svelte.dev/tutorial/store-bindings

But the store doesn't update when I try to do bind:formattedValue={$myStore}.

Would it be possible to enable this behavior? If not, is there a workaround to achieve that?

"Error: Unexpected token" when building

Hello!
I'm getting this error with Node v16.14.0. Any idea where it could come from?
Thanks!

node_modules/svelte-flatpickr/src/Flatpickr.svelte (1:0)
1: <script>
   ^
2:   import { onMount, createEventDispatcher } from 'svelte';
3:   import flatpickr from 'flatpickr';
Error: Unexpected token (Note that you need plugins to import files that are not JavaScript)
    at error (/home/elkcloner/git/doctoctocbot/src/conversation/svelte/scroll/node_modules/rollup/dist/shared/rollup.js:160:30)
    at Module.error (/home/elkcloner/git/doctoctocbot/src/conversation/svelte/scroll/node_modules/rollup/dist/shared/rollup.js:12438:16)
    at Module.tryParse (/home/elkcloner/git/doctoctocbot/src/conversation/svelte/scroll/node_modules/rollup/dist/shared/rollup.js:12826:25)
    at Module.setSource (/home/elkcloner/git/doctoctocbot/src/conversation/svelte/scroll/node_modules/rollup/dist/shared/rollup.js:12729:24)
    at ModuleLoader.addModuleSource (/home/elkcloner/git/doctoctocbot/src/conversation/svelte/scroll/node_modules/rollup/dist/shared/rollup.js:22203:20)

Here is my package.json:

{
  "name": "svelte-app",
  "version": "1.0.0",
  "scripts": {
    "build": "rollup -c",
    "dev": "rollup -c -w",
    "start": "sirv public --no-clear"
  },
  "devDependencies": {
    "@rollup/plugin-alias": "^3.1.9",
    "@rollup/plugin-commonjs": "^17.0.0",
    "@rollup/plugin-json": "^4.1.0",
    "@rollup/plugin-node-resolve": "^11.0.0",
    "@rollup/plugin-replace": "^3.1.0",
    "@rollup/plugin-typescript": "^8.3.0",
    "@smui/chips": "^6.0.0-beta.14",
    "rollup": "^2.67.2",
    "rollup-plugin-copy": "^3.4.0",
    "rollup-plugin-css-only": "^3.1.0",
    "rollup-plugin-livereload": "^2.0.0",
    "rollup-plugin-postcss": "^4.0.2",
    "rollup-plugin-svelte": "^7.0.0",
    "rollup-plugin-terser": "^7.0.0",
    "svelte": "^3.46.4"
  },
  "dependencies": {
    "bootstrap": "^4.6.1",
    "date-fns": "^2.28.0",
    "dayjs": "^1.10.7",
    "flatpickr": "^4.6.9",
    "moment": "^2.29.1",
    "moment-timezone": "^0.5.34",
    "sirv": "^1.0.19",
    "sirv-cli": "^2.0.0",
    "svelte-flatpickr": "^3.2.6",
    "svelte-i18n": "^3.3.13"
  }
}

Despite this error message, my Datepickr component seems to be working fine...

Usage with Yarn v4 and PnP strategy

I'm trying to upgrade my app to Yarn v4 with zero-install and PnP strategy.
Previously with the node_modules linker it worked perfectly fine as it is.

With the upgrade now, the error I'm getting is the following:
Failed to resolve import "flatpickr/dist/flatpickr.css"

Tried with the newest released version of v.3.3.4 but no luck.

Any help regarding this?

Thanks

How do I use wrap: true?

Thanks for creating this library. I want Flatpickr to wrap a cancel icon inside the input. How do I do it? Thanks!

bind value formatting as per given dateFormat

I was expecting the bound variable to be formatted as per the dateFormat spec.

instead of the current implementation;

function updateValue(newValue) {
	value = (Array.isArray(newValue) && newValue.length === 1) ? newValue[0] : newValue;
}

I was expecting something along these lines;

function updateValue(newValue) {
	newValue = newValue.map((e) => fp.formatDate(new Date(e), dateFormat));
	value = (Array.isArray(newValue) && newValue.length === 1) ? newValue[0] : newValue;
}

This may be by design or I may have missed the proper way to achieve this, could you elaborate?

Why is this object re-assigned?

REPL: https://svelte.dev/repl/953050f84c9d4f528ecfaaaf50defbbf?version=3.55.1

Using the below code I found that the first team is re-assigned, the second nope (see the console).

Why?

I expect to not get re-assigned when the date is already present.

This may seem negligible, but when there are 30+ components on a page it is not at all (performances).

<script>
  import Flatpickr from './flatpickr.svelte';

  // this assigns team 2 times
  let team = {id: "1", start_date: new Date()};

  // this not
  // let team = {id: "1"};

  $: console.log("team assigned:", team);
</script>

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.