Skip to content

Commit

Permalink
chore(lib): update Datetimepicker
Browse files Browse the repository at this point in the history
- `Datetimepicker` migrates to Vue 3. Changes sufficient to render the
  documentation page of `Datetimepicker` are made.
- In `src/components/datetimepicker/Datetimepicker.vue`,
    - `v-model` binding conforms to Vue 3,
        - `value` prop --> `modelValue`
        - `input` event --> `update:modelValue`
    - `value` binding of `b-input` is replaced with `model-value`.
    - Events to be emitted are listed in `emits`.
    - `disabled` is replaced with a new computed value
      `disabledOrUndefined` that takes `true` or `undefined`. This is
      introduced because setting a boolean attribute `false` does not
      remove it on Vue 3, and `null` or `undefined` has to be given to
      remove it.
- In `src/components/timepicker/Timepicker.vue`, manually fixes the
  following ESLint errors,
    - `.native` is removed from `v-on` because Vue 3 no longer supports
      it.
    - Explicitly returns `undefined` from the computed property
      `nativeStep`.
- Common,
    - Automatic ESLint fix is applied.
  • Loading branch information
kikuomax committed Jul 7, 2023
1 parent c99a8dd commit c3b8668
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 43 deletions.
64 changes: 43 additions & 21 deletions src/components/datetimepicker/Datetimepicker.vue
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
:placeholder="placeholder"
:horizontal-time-picker="horizontalTimePicker"
:range="false"
:disabled="disabled"
:disabled="disabledOrUndefined"
:mobile-native="isMobileNative"
:locale="locale"
:focusable="focusable"
Expand All @@ -36,11 +36,13 @@
@active-change="onActiveChange"
@icon-right-click="$emit('icon-right-click')"
@change-month="$emit('change-month', $event)"
@change-year="$emit('change-year', $event)">
@change-year="$emit('change-year', $event)"
>
<nav class="level is-mobile">
<div
class="level-item has-text-centered"
v-if="$slots.left !== undefined">
v-if="$slots.left !== undefined"
>
<slot name="left" />
</div>
<div class="level-item has-text-centered">
Expand All @@ -53,15 +55,16 @@
:min-time="minTime"
:max-time="maxTime"
:size="timepickerSize"
:disabled="timepickerDisabled"
:disabled="timepickerDisabled || undefined"
:focusable="focusable"
:mobile-native="isMobileNative"
:locale="locale"
/>
</div>
<div
class="level-item has-text-centered"
v-if="$slots.right !== undefined">
v-if="$slots.right !== undefined"
>
<slot name="right" />
</div>
</nav>
Expand All @@ -71,7 +74,7 @@
ref="input"
type="datetime-local"
autocomplete="off"
:value="formatNative(computedValue)"
:model-value="formatNative(computedValue)"
:placeholder="placeholder"
:size="size"
:icon="icon"
Expand All @@ -80,13 +83,14 @@
:loading="loading"
:max="formatNative(maxDate)"
:min="formatNative(minDate)"
:disabled="disabled"
:disabled="disabledOrUndefined"
:readonly="false"
v-bind="$attrs"
:use-html5-validation="useHtml5Validation"
@change.native="onChangeNativePicker"
@change="onChangeNativePicker"
@focus="onFocus"
@blur="onBlur"/>
@blur="onBlur"
/>
</template>

<script>
Expand All @@ -108,7 +112,7 @@ export default {
mixins: [FormElementMixin],
inheritAttrs: false,
props: {
value: {
modelValue: {
type: Date
},
editable: {
Expand Down Expand Up @@ -173,9 +177,16 @@ export default {
},
appendToBody: Boolean
},
emits: [
'active-change',
'change-month',
'change-year',
'icon-right-click',
'update:modelValue'
],
data() {
return {
newValue: this.adjustValue(this.value)
newValue: this.adjustValue(this.modelValue)
}
},
computed: {
Expand Down Expand Up @@ -211,8 +222,8 @@ export default {
} else {
this.newValue = this.adjustValue(value)
}
var adjustedValue = this.adjustValue(this.newValue, true) // reverse adjust
this.$emit('input', adjustedValue)
const adjustedValue = this.adjustValue(this.newValue, true) // reverse adjust
this.$emit('update:modelValue', adjustedValue)
}
},
localeOptions() {
Expand Down Expand Up @@ -270,6 +281,7 @@ export default {
adjMinDatetime.getDate() === this.newValue.getDate()) {
return adjMinDatetime
}
return undefined
},
maxTime() {
if (!this.maxDatetime || (this.newValue === null || typeof this.newValue === 'undefined')) {
Expand All @@ -281,26 +293,36 @@ export default {
adjMaxDatetime.getDate() === this.newValue.getDate()) {
return adjMaxDatetime
}
return undefined
},
datepickerSize() {
return this.datepicker && this.datepicker.size
? this.datepicker.size : this.size
? this.datepicker.size
: this.size
},
timepickerSize() {
return this.timepicker && this.timepicker.size
? this.timepicker.size : this.size
? this.timepicker.size
: this.size
},
timepickerDisabled() {
return this.timepicker && this.timepicker.disabled
? this.timepicker.disabled : this.disabled
? this.timepicker.disabled
: this.disabled
},
disabledOrUndefined() {
// On Vue 3, setting a boolean attribute `false` does not remove it,
// `null` or `undefined` has to be given to remove it.
return this.disabled || undefined
}
},
watch: {
value() {
this.newValue = this.adjustValue(this.value)
modelValue() {
this.newValue = this.adjustValue(this.modelValue)
},
tzOffset() {
this.newValue = this.adjustValue(this.value)
this.newValue = this.adjustValue(this.modelValue)
}
},
methods: {
Expand Down Expand Up @@ -331,7 +353,7 @@ export default {
return config.defaultDatetimeParser(date)
} else {
if (this.dtf.formatToParts && typeof this.dtf.formatToParts === 'function') {
let dayPeriods = [AM, PM, AM.toLowerCase(), PM.toLowerCase()]
const dayPeriods = [AM, PM, AM.toLowerCase(), PM.toLowerCase()]
if (this.$refs.timepicker) {
dayPeriods.push(this.$refs.timepicker.amString)
dayPeriods.push(this.$refs.timepicker.pmString)
Expand All @@ -340,7 +362,7 @@ export default {
const formatRegex = parts.map((part, idx) => {
if (part.type === 'literal') {
if (idx + 1 < parts.length && parts[idx + 1].type === 'hour') {
return `[^\\d]+`
return '[^\\d]+'
}
return part.value.replace(/ /g, '\\s?')
} else if (part.type === 'dayPeriod') {
Expand Down
61 changes: 39 additions & 22 deletions src/components/timepicker/Timepicker.vue
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
:mobile-modal="mobileModal"
:append-to-body="appendToBody"
append-to-body-copy-parent
@active-change="onActiveChange">
@active-change="onActiveChange"
>
<template #trigger v-if="!inline">
<slot name="trigger">
<b-input
Expand All @@ -26,79 +27,90 @@
:rounded="rounded"
v-bind="$attrs"
:use-html5-validation="useHtml5Validation"
@keyup.native.enter="toggle(true)"
@change.native="onChange($event.target.value)"
@focus="handleOnFocus"/>
@keyup.enter="toggle(true)"
@change="onChange($event.target.value)"
@focus="handleOnFocus"
/>
</slot>
</template>

<b-dropdown-item
:disabled="disabled"
:focusable="focusable"
custom>
custom
>
<b-field grouped position="is-centered">
<b-select
v-model="hoursSelected"
@change.native="onHoursChange($event.target.value)"
@change="onHoursChange($event.target.value)"
:disabled="disabled"
placeholder="00">
placeholder="00"
>
<option
v-for="hour in hours"
:value="hour.value"
:key="hour.value"
:disabled="isHourDisabled(hour.value)">
:disabled="isHourDisabled(hour.value)"
>
{{ hour.label }}
</option>
</b-select>
<span class="control is-colon">{{ hourLiteral }}</span>
<b-select
v-model="minutesSelected"
@change.native="onMinutesChange($event.target.value)"
@change="onMinutesChange($event.target.value)"
:disabled="disabled"
placeholder="00">
placeholder="00"
>
<option
v-for="minute in minutes"
:value="minute.value"
:key="minute.value"
:disabled="isMinuteDisabled(minute.value)">
:disabled="isMinuteDisabled(minute.value)"
>
{{ minute.label }}
</option>
</b-select>
<template v-if="enableSeconds">
<span class="control is-colon">{{ minuteLiteral }}</span>
<b-select
v-model="secondsSelected"
@change.native="onSecondsChange($event.target.value)"
@change="onSecondsChange($event.target.value)"
:disabled="disabled"
placeholder="00">
placeholder="00"
>
<option
v-for="second in seconds"
:value="second.value"
:key="second.value"
:disabled="isSecondDisabled(second.value)">
:disabled="isSecondDisabled(second.value)"
>
{{ second.label }}
</option>
</b-select>
<span class="control is-colon">{{ secondLiteral }}</span>
</template>
<b-select
v-model="meridienSelected"
@change.native="onMeridienChange($event.target.value)"
@change="onMeridienChange($event.target.value)"
v-if="!isHourFormat24"
:disabled="disabled">
:disabled="disabled"
>
<option
v-for="meridien in meridiens"
:value="meridien"
:key="meridien">
:key="meridien"
>
{{ meridien }}
</option>
</b-select>
</b-field>

<footer
v-if="$slots.default !== undefined && $slots.default.length"
class="timepicker-footer">
<slot/>
class="timepicker-footer"
>
<slot />
</footer>
</b-dropdown-item>
</b-dropdown>
Expand All @@ -122,9 +134,10 @@
:readonly="false"
v-bind="$attrs"
:use-html5-validation="useHtml5Validation"
@change.native="onChange($event.target.value)"
@change="onChange($event.target.value)"
@focus="handleOnFocus"
@blur="onBlur() && checkHtml5Validity()"/>
@blur="onBlur() && checkHtml5Validity()"
/>
</div>
</template>

Expand Down Expand Up @@ -156,7 +169,11 @@ export default {
},
computed: {
nativeStep() {
if (this.enableSeconds) return '1'
if (this.enableSeconds) {
return '1'
} else {
return undefined
}
}
}
}
Expand Down

0 comments on commit c3b8668

Please sign in to comment.