A somewhat working version
This commit is contained in:
		
							
								
								
									
										132
									
								
								package-lock.json
									
									
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										132
									
								
								package-lock.json
									
									
									
										generated
									
									
									
										Normal file
									
								
							@@ -0,0 +1,132 @@
 | 
			
		||||
{
 | 
			
		||||
  "name": "@tp/tp-date-input",
 | 
			
		||||
  "version": "0.0.1",
 | 
			
		||||
  "lockfileVersion": 2,
 | 
			
		||||
  "requires": true,
 | 
			
		||||
  "packages": {
 | 
			
		||||
    "": {
 | 
			
		||||
      "name": "@tp/tp-date-input",
 | 
			
		||||
      "version": "0.0.1",
 | 
			
		||||
      "license": "Apache-2.0",
 | 
			
		||||
      "dependencies": {
 | 
			
		||||
        "date-fns": "^2.28.0",
 | 
			
		||||
        "date-fns-tz": "^1.3.3",
 | 
			
		||||
        "lit": "^2.2.0"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/@lit/reactive-element": {
 | 
			
		||||
      "version": "1.3.1",
 | 
			
		||||
      "resolved": "https://verdaccio.codeblob.work/@lit%2freactive-element/-/reactive-element-1.3.1.tgz",
 | 
			
		||||
      "integrity": "sha512-nOJARIr3pReqK3hfFCSW2Zg/kFcFsSAlIE7z4a0C9D2dPrgD/YSn3ZP2ET/rxKB65SXyG7jJbkynBRm+tGlacw==",
 | 
			
		||||
      "license": "BSD-3-Clause"
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/@types/trusted-types": {
 | 
			
		||||
      "version": "2.0.2",
 | 
			
		||||
      "resolved": "https://verdaccio.codeblob.work/@types%2ftrusted-types/-/trusted-types-2.0.2.tgz",
 | 
			
		||||
      "integrity": "sha512-F5DIZ36YVLE+PN+Zwws4kJogq47hNgX3Nx6WyDJ3kcplxyke3XIzB8uK5n/Lpm1HBsbGzd6nmGehL8cPekP+Tg==",
 | 
			
		||||
      "license": "MIT"
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/date-fns": {
 | 
			
		||||
      "version": "2.28.0",
 | 
			
		||||
      "resolved": "https://verdaccio.codeblob.work/date-fns/-/date-fns-2.28.0.tgz",
 | 
			
		||||
      "integrity": "sha512-8d35hViGYx/QH0icHYCeLmsLmMUheMmTyV9Fcm6gvNwdw31yXXH+O85sOBJ+OLnLQMKZowvpKb6FgMIQjcpvQw==",
 | 
			
		||||
      "license": "MIT",
 | 
			
		||||
      "engines": {
 | 
			
		||||
        "node": ">=0.11"
 | 
			
		||||
      },
 | 
			
		||||
      "funding": {
 | 
			
		||||
        "type": "opencollective",
 | 
			
		||||
        "url": "https://opencollective.com/date-fns"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/date-fns-tz": {
 | 
			
		||||
      "version": "1.3.3",
 | 
			
		||||
      "resolved": "https://verdaccio.codeblob.work/date-fns-tz/-/date-fns-tz-1.3.3.tgz",
 | 
			
		||||
      "integrity": "sha512-Gks46gwbSauBQnV3Oofluj1wTm8J0tM7sbSJ9P+cJq/ZnTCpMohTKmmO5Tn+jQ7dyn0+b8G7cY4O2DZ5P/LXcA==",
 | 
			
		||||
      "license": "MIT",
 | 
			
		||||
      "peerDependencies": {
 | 
			
		||||
        "date-fns": ">=2.0.0"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/lit": {
 | 
			
		||||
      "version": "2.2.1",
 | 
			
		||||
      "resolved": "https://verdaccio.codeblob.work/lit/-/lit-2.2.1.tgz",
 | 
			
		||||
      "integrity": "sha512-dSe++R50JqrvNGXmI9OE13de1z5U/Y3J2dTm/9GC86vedI8ILoR8ZGnxfThFpvQ9m0lR0qRnIR4IiKj/jDCfYw==",
 | 
			
		||||
      "license": "BSD-3-Clause",
 | 
			
		||||
      "dependencies": {
 | 
			
		||||
        "@lit/reactive-element": "^1.3.0",
 | 
			
		||||
        "lit-element": "^3.2.0",
 | 
			
		||||
        "lit-html": "^2.2.0"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/lit-element": {
 | 
			
		||||
      "version": "3.2.0",
 | 
			
		||||
      "resolved": "https://verdaccio.codeblob.work/lit-element/-/lit-element-3.2.0.tgz",
 | 
			
		||||
      "integrity": "sha512-HbE7yt2SnUtg5DCrWt028oaU4D5F4k/1cntAFHTkzY8ZIa8N0Wmu92PxSxucsQSOXlODFrICkQ5x/tEshKi13g==",
 | 
			
		||||
      "license": "BSD-3-Clause",
 | 
			
		||||
      "dependencies": {
 | 
			
		||||
        "@lit/reactive-element": "^1.3.0",
 | 
			
		||||
        "lit-html": "^2.2.0"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/lit-html": {
 | 
			
		||||
      "version": "2.2.1",
 | 
			
		||||
      "resolved": "https://verdaccio.codeblob.work/lit-html/-/lit-html-2.2.1.tgz",
 | 
			
		||||
      "integrity": "sha512-AiJ/Rs0awjICs2FioTnHSh+Np5dhYSkyRczKy3wKjp8qjLhr1Ov+GiHrUQNdX8ou1LMuznpIME990AZsa/tR8g==",
 | 
			
		||||
      "license": "BSD-3-Clause",
 | 
			
		||||
      "dependencies": {
 | 
			
		||||
        "@types/trusted-types": "^2.0.2"
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  "dependencies": {
 | 
			
		||||
    "@lit/reactive-element": {
 | 
			
		||||
      "version": "1.3.1",
 | 
			
		||||
      "resolved": "https://verdaccio.codeblob.work/@lit%2freactive-element/-/reactive-element-1.3.1.tgz",
 | 
			
		||||
      "integrity": "sha512-nOJARIr3pReqK3hfFCSW2Zg/kFcFsSAlIE7z4a0C9D2dPrgD/YSn3ZP2ET/rxKB65SXyG7jJbkynBRm+tGlacw=="
 | 
			
		||||
    },
 | 
			
		||||
    "@types/trusted-types": {
 | 
			
		||||
      "version": "2.0.2",
 | 
			
		||||
      "resolved": "https://verdaccio.codeblob.work/@types%2ftrusted-types/-/trusted-types-2.0.2.tgz",
 | 
			
		||||
      "integrity": "sha512-F5DIZ36YVLE+PN+Zwws4kJogq47hNgX3Nx6WyDJ3kcplxyke3XIzB8uK5n/Lpm1HBsbGzd6nmGehL8cPekP+Tg=="
 | 
			
		||||
    },
 | 
			
		||||
    "date-fns": {
 | 
			
		||||
      "version": "2.28.0",
 | 
			
		||||
      "resolved": "https://verdaccio.codeblob.work/date-fns/-/date-fns-2.28.0.tgz",
 | 
			
		||||
      "integrity": "sha512-8d35hViGYx/QH0icHYCeLmsLmMUheMmTyV9Fcm6gvNwdw31yXXH+O85sOBJ+OLnLQMKZowvpKb6FgMIQjcpvQw=="
 | 
			
		||||
    },
 | 
			
		||||
    "date-fns-tz": {
 | 
			
		||||
      "version": "1.3.3",
 | 
			
		||||
      "resolved": "https://verdaccio.codeblob.work/date-fns-tz/-/date-fns-tz-1.3.3.tgz",
 | 
			
		||||
      "integrity": "sha512-Gks46gwbSauBQnV3Oofluj1wTm8J0tM7sbSJ9P+cJq/ZnTCpMohTKmmO5Tn+jQ7dyn0+b8G7cY4O2DZ5P/LXcA==",
 | 
			
		||||
      "requires": {}
 | 
			
		||||
    },
 | 
			
		||||
    "lit": {
 | 
			
		||||
      "version": "2.2.1",
 | 
			
		||||
      "resolved": "https://verdaccio.codeblob.work/lit/-/lit-2.2.1.tgz",
 | 
			
		||||
      "integrity": "sha512-dSe++R50JqrvNGXmI9OE13de1z5U/Y3J2dTm/9GC86vedI8ILoR8ZGnxfThFpvQ9m0lR0qRnIR4IiKj/jDCfYw==",
 | 
			
		||||
      "requires": {
 | 
			
		||||
        "@lit/reactive-element": "^1.3.0",
 | 
			
		||||
        "lit-element": "^3.2.0",
 | 
			
		||||
        "lit-html": "^2.2.0"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "lit-element": {
 | 
			
		||||
      "version": "3.2.0",
 | 
			
		||||
      "resolved": "https://verdaccio.codeblob.work/lit-element/-/lit-element-3.2.0.tgz",
 | 
			
		||||
      "integrity": "sha512-HbE7yt2SnUtg5DCrWt028oaU4D5F4k/1cntAFHTkzY8ZIa8N0Wmu92PxSxucsQSOXlODFrICkQ5x/tEshKi13g==",
 | 
			
		||||
      "requires": {
 | 
			
		||||
        "@lit/reactive-element": "^1.3.0",
 | 
			
		||||
        "lit-html": "^2.2.0"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "lit-html": {
 | 
			
		||||
      "version": "2.2.1",
 | 
			
		||||
      "resolved": "https://verdaccio.codeblob.work/lit-html/-/lit-html-2.2.1.tgz",
 | 
			
		||||
      "integrity": "sha512-AiJ/Rs0awjICs2FioTnHSh+Np5dhYSkyRczKy3wKjp8qjLhr1Ov+GiHrUQNdX8ou1LMuznpIME990AZsa/tR8g==",
 | 
			
		||||
      "requires": {
 | 
			
		||||
        "@types/trusted-types": "^2.0.2"
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										10
									
								
								package.json
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								package.json
									
									
									
									
									
								
							@@ -1,18 +1,20 @@
 | 
			
		||||
{
 | 
			
		||||
  "name": "@tp/tp-element",
 | 
			
		||||
  "version": "0.0.1",
 | 
			
		||||
  "name": "@tp/tp-date-input",
 | 
			
		||||
  "version": "0.1.0",
 | 
			
		||||
  "description": "",
 | 
			
		||||
  "main": "tp-element.js",
 | 
			
		||||
  "main": "tp-date-input.js",
 | 
			
		||||
  "scripts": {
 | 
			
		||||
    "test": "echo \"Error: no test specified\" && exit 1"
 | 
			
		||||
  },
 | 
			
		||||
  "repository": {
 | 
			
		||||
    "type": "git",
 | 
			
		||||
    "url": "https://gitea.codeblob.work/tp-elements/tp-element.git"
 | 
			
		||||
    "url": "https://gitea.codeblob.work/tp-elements/tp-date-input.git"
 | 
			
		||||
  },
 | 
			
		||||
  "author": "trading_peter",
 | 
			
		||||
  "license": "Apache-2.0",
 | 
			
		||||
  "dependencies": {
 | 
			
		||||
    "date-fns": "^2.28.0",
 | 
			
		||||
    "date-fns-tz": "^1.3.3",
 | 
			
		||||
    "lit": "^2.2.0"
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										428
									
								
								tp-date-input.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										428
									
								
								tp-date-input.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,428 @@
 | 
			
		||||
/**
 | 
			
		||||
@license
 | 
			
		||||
Copyright (c) 2022 trading_peter
 | 
			
		||||
This program is available under Apache License Version 2.0
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
import '@tp/tp-input/tp-input.js';
 | 
			
		||||
import { ControlState } from '@tp/helpers/control-state.js';
 | 
			
		||||
import { EventHelpers } from '@tp/helpers/event-helpers.js';
 | 
			
		||||
import { FormElement } from '@tp/helpers/form-element.js';
 | 
			
		||||
import { LitElement, html, css } from 'lit';
 | 
			
		||||
import { format, parse, parseISO, isAfter, isValid, endOfDay } from 'date-fns/esm';
 | 
			
		||||
 | 
			
		||||
class TpDateInput extends EventHelpers(ControlState(FormElement(LitElement))) {
 | 
			
		||||
  static get styles() {
 | 
			
		||||
    return [
 | 
			
		||||
      css`
 | 
			
		||||
        :host {
 | 
			
		||||
          display: block;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        .wrap {
 | 
			
		||||
          display: flex;
 | 
			
		||||
          flex-direction: column;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        .wrap > div {
 | 
			
		||||
          align-self: flex-end;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        tp-input {
 | 
			
		||||
          width: 30px;
 | 
			
		||||
          text-align: center;
 | 
			
		||||
          border: none;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        tp-input.bigger {
 | 
			
		||||
          width: 50px;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        .under {
 | 
			
		||||
          position: relative;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        .error-message {
 | 
			
		||||
          position: absolute;
 | 
			
		||||
          top: -5px;
 | 
			
		||||
          left: 0;
 | 
			
		||||
          font-size: 10px;
 | 
			
		||||
          color: var(--tp-input-text-color-invalid, #B71C1C);
 | 
			
		||||
          transition: opacity 0.3s;
 | 
			
		||||
          opacity: 0;
 | 
			
		||||
          will-change: opacity;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        :host([invalid]) .error-message {
 | 
			
		||||
          opacity: 1;
 | 
			
		||||
        }
 | 
			
		||||
      `
 | 
			
		||||
    ];
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  render() {
 | 
			
		||||
    const { _delemiter } = this;
 | 
			
		||||
 | 
			
		||||
    return html`
 | 
			
		||||
      <div class="wrap">
 | 
			
		||||
        <tp-input .value=${this._input0} @change=${this._inputChanged} .validator=${} allowed-pattern="[0-9]" .auto-validate=${autoValidate} .readonly=${readonly} .required=${required}>
 | 
			
		||||
          <input type="text" placeholder=${this._setPlaceholder(0)}>
 | 
			
		||||
        </tp-input>
 | 
			
		||||
        <div>${_delemiter}</div>
 | 
			
		||||
        <tp-input .value=${this._input1} @change=${this._inputChanged} .validator=${} allowed-pattern="[0-9]" .auto-validate=${autoValidate} .readonly=${readonly} .required=${required}>
 | 
			
		||||
          <input type="text" placeholder=${this._setPlaceholder(1)}>
 | 
			
		||||
        </tp-input>
 | 
			
		||||
        <div>${_delemiter}</div>
 | 
			
		||||
        <tp-input class="bigger" .value=${this._input2} @change=${this._inputChanged} .validator=${} allowed-pattern="[0-9]" .auto-validate=${autoValidate} .readonly=${readonly} .required=${required}>
 | 
			
		||||
          <input type="text" placeholder=${this._setPlaceholder(2)}>
 | 
			
		||||
        </tp-input>
 | 
			
		||||
      </div>
 | 
			
		||||
    `;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  static get properties() {
 | 
			
		||||
    return {
 | 
			
		||||
      // Format of the date.
 | 
			
		||||
      // Supports MM, dd and y. The order specifies how the input fields are labeled.
 | 
			
		||||
      // The delimiter is also taken from the supplied format.
 | 
			
		||||
      format: { type: String },
 | 
			
		||||
 | 
			
		||||
      // Date object with the currently selected date.
 | 
			
		||||
      date: { type: Object },
 | 
			
		||||
 | 
			
		||||
      // If true, let value default to the date of today.
 | 
			
		||||
      today: { type: Boolean },
 | 
			
		||||
 | 
			
		||||
      required: { type: Boolean },
 | 
			
		||||
 | 
			
		||||
      autoValidate: { type: Boolean },
 | 
			
		||||
 | 
			
		||||
      // If true, the entered date is invalid.
 | 
			
		||||
      invalid: { type: Boolean, reflect: true },
 | 
			
		||||
 | 
			
		||||
      // Error message to show if the date is invalid.
 | 
			
		||||
      errorMessage: { type: String },
 | 
			
		||||
 | 
			
		||||
      optional: { type: Boolean },
 | 
			
		||||
 | 
			
		||||
      // Range of years in the future that are selectable in the date-picker.
 | 
			
		||||
      maxYear: { type: Number },
 | 
			
		||||
 | 
			
		||||
      // Range of years in the past that are selectable in the date-picker.
 | 
			
		||||
      minYear: { type: Number },
 | 
			
		||||
 | 
			
		||||
      // Maximum date that can be selected. Everything after will be disabled.
 | 
			
		||||
      // Set it to `today` to automatically allow dates till today (inclusive).
 | 
			
		||||
      // Expects 'today' or a ISO Date string.
 | 
			
		||||
      maxDate: { type: String },
 | 
			
		||||
    };
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  constructor() {
 | 
			
		||||
    super();
 | 
			
		||||
    this.format = 'MM-dd-y';
 | 
			
		||||
    this.required = false;
 | 
			
		||||
    this.autoValidate = false;
 | 
			
		||||
    this.invalid = false;
 | 
			
		||||
    this.optional = false;
 | 
			
		||||
    this.maxYear = 10;
 | 
			
		||||
    this.minYear = 10;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  shouldUpdate(changes) {
 | 
			
		||||
    if (changes.has('format')) {
 | 
			
		||||
      this._formatChanged();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (changes.has('value')) {
 | 
			
		||||
      this._onValueChanged();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return true;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  firstUpdated() {
 | 
			
		||||
    this.listen(this, 'input', '_autoMoveCursor');
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
  * Returns current validation state of the control.
 | 
			
		||||
  */
 | 
			
		||||
  validate() {
 | 
			
		||||
    this.inputs[0].validate();
 | 
			
		||||
    this.inputs[1].validate();
 | 
			
		||||
    this.inputs[2].validate();
 | 
			
		||||
 | 
			
		||||
    if (this.optional && this.inputs[0].value === '' && this.inputs[1].value === '' && this.inputs[2].value === '') {
 | 
			
		||||
      this.invalid = false;
 | 
			
		||||
      return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const maxDate = this._getMaxDate(this.maxDate);
 | 
			
		||||
 | 
			
		||||
    if ((this.inputs[0].invalid || this.inputs[1].invalid || this.inputs[2].invalid) ||
 | 
			
		||||
      !this.dateValid(this.value, maxDate)) {
 | 
			
		||||
      this.invalid = true;
 | 
			
		||||
      return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    this.invalid = false;
 | 
			
		||||
    return true;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  focus() {
 | 
			
		||||
    this.inputs[0].select();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
  * Test is a date is selectable when considering all restricting options
 | 
			
		||||
  * of the control, like enabledDates, maxDate, ...
 | 
			
		||||
  */
 | 
			
		||||
  dateValid(date, maxDate, enabledDates) {
 | 
			
		||||
    date = this._toDate(date);
 | 
			
		||||
 | 
			
		||||
    if (isValid(date) === false) {
 | 
			
		||||
      return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    maxDate = maxDate || this.maxDate;
 | 
			
		||||
    enabledDates = enabledDates || [];
 | 
			
		||||
 | 
			
		||||
    if ((enabledDates.length > 0 && enabledDates.indexOf(date) === -1) ||
 | 
			
		||||
      (maxDate && isAfter(date, maxDate))) {
 | 
			
		||||
      return false;
 | 
			
		||||
    }
 | 
			
		||||
    return true;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
  * Reset the control if a parent era-form is reset.
 | 
			
		||||
  */
 | 
			
		||||
  reset() {
 | 
			
		||||
    this._input0 = '';
 | 
			
		||||
    this._input1 = '';
 | 
			
		||||
    this._input2 = '';
 | 
			
		||||
    this.shadowRoot.querySelectorAll('era-input').forEach(el => el.invalid = false);
 | 
			
		||||
    this.invalid = false;
 | 
			
		||||
    this.value = null;
 | 
			
		||||
 | 
			
		||||
    if (this.today) {
 | 
			
		||||
      this._setToday();
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  _inputChanged() {
 | 
			
		||||
    const i0 = this._input0;
 | 
			
		||||
    const i1 = this._input1;
 | 
			
		||||
    const i2 = this._input2;
 | 
			
		||||
 | 
			
		||||
    if (i0 === '' && i1 === '' && i2 === '' && this.optional) {
 | 
			
		||||
      this.date = null;
 | 
			
		||||
      this.value = null;
 | 
			
		||||
      this.invalid = false;
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (
 | 
			
		||||
      i0 === '' || i1 === '' || i2 === '' ||
 | 
			
		||||
      !this.inputs[0].validate() || !this.inputs[1].validate() || !this.inputs[2].validate()
 | 
			
		||||
    ) {
 | 
			
		||||
      if (this.focused) {
 | 
			
		||||
        this.date = null;
 | 
			
		||||
        this.value = null;
 | 
			
		||||
        if (this.autoValidate) {
 | 
			
		||||
          this.invalid = true;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const date = parse(i0 + '-' + i1 + '-' + i2, this._inputAssign.join('-'), new Date());
 | 
			
		||||
 | 
			
		||||
    if (isValid(date)) {
 | 
			
		||||
      this.inputs[0].invalid = false;
 | 
			
		||||
      this.inputs[1].invalid = false;
 | 
			
		||||
      this.inputs[2].invalid = false;
 | 
			
		||||
      this.date = date;
 | 
			
		||||
      this.value = date.toISOString();
 | 
			
		||||
      this.invalid = false;
 | 
			
		||||
    } else {
 | 
			
		||||
      this.inputs[0].invalid = true;
 | 
			
		||||
      this.inputs[1].invalid = true;
 | 
			
		||||
      this.inputs[2].invalid = true;
 | 
			
		||||
      this.date = null;
 | 
			
		||||
      this.value = null;
 | 
			
		||||
      if (this.autoValidate) {
 | 
			
		||||
        this.invalid = true;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  _setValidator(idx) {
 | 
			
		||||
    switch (this._inputAssign[idx]) {
 | 
			
		||||
      case 'dd':
 | 
			
		||||
        return this._validateDay;
 | 
			
		||||
      case 'MM':
 | 
			
		||||
        return this._validateMonth;
 | 
			
		||||
      case 'y':
 | 
			
		||||
        return this._validateYear;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  _validateDay(value) {
 | 
			
		||||
    if (typeof value !== 'string') {
 | 
			
		||||
      return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (/^[0-9]+$/.test(value) !== true) {
 | 
			
		||||
      return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    var v = parseInt(value, 10);
 | 
			
		||||
    return v >= 1 && v <= 31;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  _validateMonth(value) {
 | 
			
		||||
    if (typeof value !== 'string') {
 | 
			
		||||
      return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (/^[0-9]+$/.test(value) !== true) {
 | 
			
		||||
      return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    var v = parseInt(value, 10);
 | 
			
		||||
    return v >= 1 && v <= 12;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  _validateYear(value) {
 | 
			
		||||
    if (typeof value !== 'string') {
 | 
			
		||||
      return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (/^[0-9]+$/.test(value) !== true) {
 | 
			
		||||
      return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    var v = parseInt(value, 10);
 | 
			
		||||
    return v >= 1900;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  _setPlaceholder(idx) {
 | 
			
		||||
    switch (this._inputAssign[idx]) {
 | 
			
		||||
      case 'dd':
 | 
			
		||||
        return 'DD';
 | 
			
		||||
      case 'MM':
 | 
			
		||||
        return 'MM';
 | 
			
		||||
      case 'y':
 | 
			
		||||
        return 'YYYYY';
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  _formatChanged(format) {
 | 
			
		||||
    if (!format) return;
 | 
			
		||||
 | 
			
		||||
    let _realFormat = format;
 | 
			
		||||
 | 
			
		||||
    const types = ['MM', 'dd', 'y'];
 | 
			
		||||
    this._inputAssign = [];
 | 
			
		||||
 | 
			
		||||
    this._delimiter = this._determineDelimiter(_realFormat);
 | 
			
		||||
 | 
			
		||||
    const parts = _realFormat.split(this._delimiter);
 | 
			
		||||
    if (parts.length < 2) {
 | 
			
		||||
      console.warn(this.tagName + ': Unknown format. Fallback to format MM-dd-y');
 | 
			
		||||
      this.format = 'MM-dd-y';
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    for (let i = 0; i <= 2; ++i) {
 | 
			
		||||
      for (let a = 0, la = types.length; a < la; ++a) {
 | 
			
		||||
        if (types[a] === parts[i] || types[a] === parts[i].toLowerCase()) {
 | 
			
		||||
          parts[i] = parts[i] !== 'MM' ? parts[i].toLowerCase() : parts[i];
 | 
			
		||||
          this._inputAssign.push(parts[i]);
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (this.value) {
 | 
			
		||||
      this._onValueChanged();
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  _determineDelimiter(format) {
 | 
			
		||||
    if (format.indexOf('-') > -1) {
 | 
			
		||||
      return '-';
 | 
			
		||||
    }
 | 
			
		||||
    if (format.indexOf('/') > -1) {
 | 
			
		||||
      return '/';
 | 
			
		||||
    }
 | 
			
		||||
    if (format.indexOf('.') > -1) {
 | 
			
		||||
      return '.';
 | 
			
		||||
    }
 | 
			
		||||
    return '/';
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Reset invalid state if value was changed.
 | 
			
		||||
  // This clears up old invalid states if the value was changed programmatically.
 | 
			
		||||
  _onValueChanged() {
 | 
			
		||||
    // If the control is focused we ignore a programmatically set value because
 | 
			
		||||
    // the user may works with the element right now.
 | 
			
		||||
    if (this.focused) {
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    this.invalid = false;
 | 
			
		||||
 | 
			
		||||
    if (this.value === null || this.value === undefined || this.value === 'Invalid date') {
 | 
			
		||||
      this.date = null;
 | 
			
		||||
      this.value = null;
 | 
			
		||||
      this._input0 = '';
 | 
			
		||||
      this._input1 = '';
 | 
			
		||||
      this._input2 = '';
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const date = this._toDate(this.value);
 | 
			
		||||
    this._input0 = format(date, this._inputAssign[0]);
 | 
			
		||||
    this._input1 = format(date, this._inputAssign[1]);
 | 
			
		||||
    this._input2 = format(date, this._inputAssign[2]);
 | 
			
		||||
    this.date = date;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  _setToday() {
 | 
			
		||||
    if (this.today) {
 | 
			
		||||
      setTimeout(() => {
 | 
			
		||||
        if (!this.value) {
 | 
			
		||||
          this.value = new Date().toISOString();
 | 
			
		||||
        }
 | 
			
		||||
      });
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  _getMaxDate(maxDate) {
 | 
			
		||||
    if (typeof maxDate !== 'string') return null;
 | 
			
		||||
    if (maxDate.toLowerCase() === 'today') {
 | 
			
		||||
      return endOfDay(new Date());
 | 
			
		||||
    }
 | 
			
		||||
    return this._toDate(maxDate);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  _autoMoveCursor(e) {
 | 
			
		||||
    const target = e.composedPath().find(node => node.tagName === 'ERA-INPUT');
 | 
			
		||||
    const idx = Array.from(this.inputs).findIndex(node => node === target);
 | 
			
		||||
    if (target.value.length === 2 && idx < 2) {
 | 
			
		||||
      this.inputs[idx + 1].select();
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  _toDate(value) {
 | 
			
		||||
    if (typeof value === 'string') {
 | 
			
		||||
      return parseISO(value);
 | 
			
		||||
    } else {
 | 
			
		||||
      return value;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
window.customElements.define('tp-date-input', TpDateInput);
 | 
			
		||||
@@ -1,35 +0,0 @@
 | 
			
		||||
/**
 | 
			
		||||
@license
 | 
			
		||||
Copyright (c) 2022 trading_peter
 | 
			
		||||
This program is available under Apache License Version 2.0
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
import { LitElement, html, css } from 'lit';
 | 
			
		||||
 | 
			
		||||
class TpElement extends LitElement {
 | 
			
		||||
  static get styles() {
 | 
			
		||||
    return [
 | 
			
		||||
      css`
 | 
			
		||||
        :host {
 | 
			
		||||
          display: block;
 | 
			
		||||
        }
 | 
			
		||||
      `
 | 
			
		||||
    ];
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  render() {
 | 
			
		||||
    const { } = this;
 | 
			
		||||
 | 
			
		||||
    return html`
 | 
			
		||||
 | 
			
		||||
    `;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  static get properties() {
 | 
			
		||||
    return { };
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
window.customElements.define('tp-element', TpElement);
 | 
			
		||||
		Reference in New Issue
	
	Block a user