From 11e7348a2ae312ef90719b364d5fbec2c7fbfd5c Mon Sep 17 00:00:00 2001 From: Michal Szajter Date: Wed, 27 Jan 2021 16:43:50 +0100 Subject: [PATCH 1/2] feat: vue 3 compatibility migration --- src/component.js | 8 ++++---- src/index.js | 10 +++------- 2 files changed, 7 insertions(+), 11 deletions(-) diff --git a/src/component.js b/src/component.js index e674570..4ea3e3c 100644 --- a/src/component.js +++ b/src/component.js @@ -1,5 +1,6 @@ //@flow +import { h } from 'vue'; import moment from 'moment'; import Pikaday from 'pikaday'; import isDate from 'lodash/isDate'; @@ -74,10 +75,9 @@ export default { return Object.assign({}, this.defaultOptions, this.options); } }, - render(h: Function): Object { + render(): Object { return h('input', { - attrs: this.elementAttributes, - on: this.$listeners, + ...this.elementAttributes, value: this.inputValue(this.value) }, this.$slots.default); }, @@ -94,7 +94,7 @@ export default { this.change(value); }); }, - beforeDestroy() { + beforeUnmount() { this.destroy(); }, watch: { diff --git a/src/index.js b/src/index.js index 04b9c18..71067e5 100644 --- a/src/index.js +++ b/src/index.js @@ -2,14 +2,10 @@ import VuePikaday from './component'; import { VuePikadayVisible } from './directives'; const VuePikadayPlugin = { - install(Vue) { - Vue.component(VuePikaday.name, VuePikaday); - Vue.directive('p-visible', VuePikadayVisible); + install(app) { + app.component(VuePikaday.name, VuePikaday); + app.directive('p-visible', VuePikadayVisible); } }; -if (typeof window !== 'undefined' && window.Vue) { - window.Vue.use(VuePikadayPlugin); -} - export default VuePikadayPlugin; From e0922b250ba08b84f92450cf7ae868a82d59940a Mon Sep 17 00:00:00 2001 From: Michal Szajter Date: Thu, 28 Jan 2021 10:16:40 +0100 Subject: [PATCH 2/2] feat: vue 3 compatibility migration --- package.json | 2 +- rollup.config.js | 3 ++- src/component.js | 65 ++++++++++++++++++++++++++--------------------- src/directives.js | 22 ---------------- src/index.js | 2 -- yarn.lock | 18 ++++++------- 6 files changed, 48 insertions(+), 64 deletions(-) delete mode 100644 src/directives.js diff --git a/package.json b/package.json index 87ceb3d..915a5be 100644 --- a/package.json +++ b/package.json @@ -54,7 +54,7 @@ "peerDependencies": { "moment": "^2.24.0", "pikaday": "^1.8.0", - "vue": "^2.6.10" + "vue": "^3.0.5" }, "devDependencies": { "@babel/core": "^7.9.0", diff --git a/rollup.config.js b/rollup.config.js index 30c6635..cf961c1 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -74,7 +74,8 @@ export default [ sourcemap: true, globals: { moment: 'moment', - pikaday: 'Pikaday' + pikaday: 'Pikaday', + vue: 'vue' }, } }, diff --git a/src/component.js b/src/component.js index 4ea3e3c..d02f7b9 100644 --- a/src/component.js +++ b/src/component.js @@ -8,32 +8,33 @@ import isString from 'lodash/isString'; import 'pikaday/css/pikaday.css'; -function isEvent(value) { - return value instanceof Event || (value && value.constructor && value.constructor.name === 'Event'); +function isEvent(modelValue) { + return modelValue instanceof Event || (modelValue && modelValue.constructor && modelValue.constructor.name === 'Event'); } export default { name: 'vue-pikaday', inheritAttrs: false, + emits: ['update:modelValue', 'update:inputValue', 'update:visible'], props: { - value: { - validator(value: typeof undefined | null | Date | Event | string): boolean { + modelValue: { + validator(modelValue: typeof undefined | null | Date | Event | string): boolean { const allowedTypes: Array = [undefined, null]; - if (isEvent(value)) { + if (isEvent(modelValue)) { return true; } - if (isDate(value)) { + if (isDate(modelValue)) { return true; } - if(isString(value) && moment(value).isValid()) { + if(isString(modelValue) && moment(modelValue).isValid()) { return true; } for (const type of allowedTypes) { - const allowed: boolean = value === type || typeof value === type; + const allowed: boolean = modelValue === type || typeof modelValue === type; if (allowed) { return true; @@ -44,6 +45,10 @@ export default { }, required: true }, + visible: { + type: Boolean, + default: false + }, options: { required: false, default() { @@ -58,7 +63,6 @@ export default { }, data() { return { - visible: false, elAttrs: { type: 'text' }, @@ -73,25 +77,35 @@ export default { }, mergedOptions() { return Object.assign({}, this.defaultOptions, this.options); + }, + inputValue(): string | null { + if (!this.isModelValueValid) { + return null; + } + const inputValue: moment = moment(this.modelValue); + return inputValue.isValid() ? inputValue.format(this.mergedOptions.format) : null; + }, + isModelValueValid() { + return isDate(this.modelValue); } }, render(): Object { return h('input', { ...this.elementAttributes, - value: this.inputValue(this.value) + modelValue: this.inputValue }, this.$slots.default); }, mounted() { this.create(); - this.$watch('value', (value: typeof undefined | null | Date) => { - if (!isDate(value)) { - value = null; + this.$watch('modelValue', (modelValue: typeof undefined | null | Date) => { + if (!this.isModelValueValid) { + modelValue = null; } if (!this.visible) { - this.pikaday.setDate(value, true); + this.pikaday.setDate(modelValue, true); } - this.change(value); + this.change(modelValue); }); }, beforeUnmount() { @@ -117,7 +131,7 @@ export default { let defaultValue: typeof undefined | null | Date = this.value; - if (!this.value && this.autoDefault) { + if (!this.modelValue && this.autoDefault) { defaultValue = moment().toDate(); this.change(defaultValue); } @@ -137,29 +151,22 @@ export default { this.destroy(); this.create(); }, - change(value: typeof undefined | null | Date) { - this.$emit('input', value); - this.$emit('input-value', this.inputValue(value)); - }, - inputValue(value: typeof undefined | null | Date): string | null { - if (!isDate(value)) { - return null; - } - const inputValue: moment = moment(value); - return inputValue.isValid() ? inputValue.format(this.mergedOptions.format) : null; + change(modelValue: typeof undefined | null | Date) { + this.$emit('update:modelValue', modelValue); + this.$emit('update:inputValue', this.inputValue); }, onSelect() { this.change(this.pikaday.getDate()); }, onOpen() { - this.visible = true; + this.$emit('update:visible', true); }, onClose() { - if (!isDate(this.value)) { + if (!this.isModelValueValid) { this.pikaday.setDate(null, true); this.change(null); } - this.visible = false; + this.$emit('update:visible', false); }, show() { this.pikaday.show(); diff --git a/src/directives.js b/src/directives.js deleted file mode 100644 index d2ee7a2..0000000 --- a/src/directives.js +++ /dev/null @@ -1,22 +0,0 @@ -//@flow - -import _debounce from 'lodash/debounce'; - -function changeState(state: boolean, target: Object, expression: string, instance: Object | null = null) { - target[expression] = state; - instance = instance || target; - state ? instance.show() : instance.hide(); -} - -export const VuePikadayVisible = { - inserted(el: Object, binding: Object, VNode: Object) { - const instance: Object = VNode.componentInstance; - - instance.onOpen = () => _debounce(() => changeState(true, VNode.context, binding.expression, instance), 100); - - instance.onClose = _debounce(() => changeState(false, VNode.context, binding.expression, instance), 100); - }, - update(el: Object, binding: Object, VNode: Object) { - _debounce(() => changeState(binding.value, VNode.componentInstance, binding.expression), 100)(); - } -}; diff --git a/src/index.js b/src/index.js index 71067e5..3112314 100644 --- a/src/index.js +++ b/src/index.js @@ -1,10 +1,8 @@ import VuePikaday from './component'; -import { VuePikadayVisible } from './directives'; const VuePikadayPlugin = { install(app) { app.component(VuePikaday.name, VuePikaday); - app.directive('p-visible', VuePikadayVisible); } }; diff --git a/yarn.lock b/yarn.lock index 9a63170..caf861c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3915,19 +3915,19 @@ caniuse-api@^3.0.0: lodash.uniq "^4.5.0" caniuse-lite@^1.0.0, caniuse-lite@^1.0.30000792, caniuse-lite@^1.0.30000989: - version "1.0.30000997" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000997.tgz#ba44a606804f8680894b7042612c2c7f65685b7e" - integrity sha512-BQLFPIdj2ntgBNWp9Q64LGUIEmvhKkzzHhUHR3CD5A9Lb7ZKF20/+sgadhFap69lk5XmK1fTUleDclaRFvgVUA== + version "1.0.30001180" + resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001180.tgz" + integrity sha512-n8JVqXuZMVSPKiPiypjFtDTXc4jWIdjxull0f92WLo7e1MSi3uJ3NvveakSh/aCl1QKFAvIz3vIj0v+0K+FrXw== caniuse-lite@^1.0.30001035: - version "1.0.30001038" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001038.tgz#44da3cbca2ab6cb6aa83d1be5d324e17f141caff" - integrity sha512-zii9quPo96XfOiRD4TrfYGs+QsGZpb2cGiMAzPjtf/hpFgB6zCPZgJb7I1+EATeMw/o+lG8FyRAnI+CWStHcaQ== + version "1.0.30001180" + resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001180.tgz" + integrity sha512-n8JVqXuZMVSPKiPiypjFtDTXc4jWIdjxull0f92WLo7e1MSi3uJ3NvveakSh/aCl1QKFAvIz3vIj0v+0K+FrXw== caniuse-lite@^1.0.30001039, caniuse-lite@^1.0.30001043: - version "1.0.30001048" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001048.tgz#4bb4f1bc2eb304e5e1154da80b93dee3f1cf447e" - integrity sha512-g1iSHKVxornw0K8LG9LLdf+Fxnv7T1Z+mMsf0/YYLclQX4Cd522Ap0Lrw6NFqHgezit78dtyWxzlV2Xfc7vgRg== + version "1.0.30001180" + resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001180.tgz" + integrity sha512-n8JVqXuZMVSPKiPiypjFtDTXc4jWIdjxull0f92WLo7e1MSi3uJ3NvveakSh/aCl1QKFAvIz3vIj0v+0K+FrXw== capture-stack-trace@^1.0.0: version "1.0.1"