thepipster / uswds-vue

MIT License
4 stars 1 forks source link

Add the date picker component from USWDS #1

Open jcandan opened 2 years ago

jcandan commented 2 years ago

Problem/Motivation

While uswds-vue does supply a datetime-local input type, The Date Picker component from USWDS does a good job of presenting a consistent user experience across browsers.

Chrome on macOS: image

Safari on macOS: image

Proposed resolution

Add the Date Picker component.

image

jcandan commented 2 years ago

Attempts to just supply the component code from USWDS Date picker documentation doesn't seem to work.

No calendar button icon is shown: image

I imagine that, since the calendar icon isn't part of the component code, there must be Javascript handling this somewhere. But I have no console errors.

jcandan commented 2 years ago

This is likely related to the #4 (Javascript is not loading).

jcandan commented 2 years ago

Mentioned this issue in https://github.com/uswds/uswds/discussions/4677#discussioncomment-3349160.

jcandan commented 2 years ago

Once I got USWDS Javascript working via the fix in (https://github.com/thepipster/uswds-vue/issues/4) (Javascript is not loading), I found that Vuelidate wasn't playing nicely with the Date Picker's hidden input field.

For whatever reason, Vuelidate is looking at the hidden field's input event instead of the original <input> field.

I was able to use the following to trigger a Vue @input event:

// USWDS Date Picker adds a hidden input field not seen by Vuelidate.
// Trigger an "input" event on this hidden field when selecting a date fires a change.
const picker_internal = document.querySelector('.usa-date-picker__internal-input');
const picker_external = document.querySelector('.usa-date-picker__external-input');

picker_external.addEventListener('change', () => {
    picker_internal.dispatchEvent(new Event('input'));
});
jcandan commented 2 years ago

So, the above worked in console, but to make it work in Vue, I had to do the following:

<div class="usa-date-picker">
  <input
    ref="datepicker"
...
  mounted() {
    // USWDS Date Picker adds a hidden input field not seen by Vuelidate.
    // Trigger an "input" event on this hidden field when selecting a date fires a change.
    const pickerInternal = this.$refs.datepicker;
    pickerInternal.addEventListener('change', () => {
      pickerInternal.dispatchEvent(new Event('input'));
    });
  },