Skip to content

Commit 486d419

Browse files
committed
feat(vuetify): upgrade to vue3 and add CustomSelect
issue: #4 BREAKING CHANGE: no vue2 support
1 parent 2d33143 commit 486d419

File tree

13 files changed

+247
-99
lines changed

13 files changed

+247
-99
lines changed

core/dev/example-usage.vue

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,19 @@
11
<template>
22
<div id="app">
33
Cron: <input :value="value" @change="value = $event.target.value" type="text" />
4-
<VueCronCore :value="value" @update:value="value = $event" v-slot="{period, error, fields}">
4+
<VueCronCore v-model="value" v-slot="{period, error, fields}">
55
<div>
66
<span>
77
{{period.prefix}}:
8-
<select @input="period.events.input(JSON.parse($event.target.value))">
8+
<select @input="period.events['update:model-value'](JSON.parse($event.target.value).id)">
99
<option v-for="item in period.items" :key="item.text" :value="JSON.stringify(item)">{{item.text}}</option>
1010
</select>
1111
</span>
1212

1313
<template v-for="f in fields" :key="f.id">
1414
<span>
1515
{{f.prefix}}
16-
<select @input="f.events.input(getSelected($event.target))" multiple>
16+
<select @input="f.events['update:model-value'](getSelected($event.target))" multiple>
1717
<option v-for="item in f.items" :key="item.value" :value="item.value">{{item.text}}</option>
1818
</select>
1919
{{f.suffix}}

core/src/core.vue

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ const {Field} = types
1010
export default {
1111
name: "VueCronCore",
1212
props: {
13-
value: {
13+
modelValue: {
1414
type: String,
1515
default: '* * * * *'
1616
},
@@ -57,7 +57,7 @@ export default {
5757
default: true
5858
},
5959
},
60-
emits: ["update:value", "error"],
60+
emits: ["update:model-value", "error"],
6161
data(){
6262
6363
let selected = {}
@@ -74,7 +74,7 @@ export default {
7474
7575
computed: {
7676
splitValue(){
77-
return this.value.split(' ')
77+
return this.modelValue.split(' ')
7878
},
7979
fieldIndex(){
8080
return this.fields.reduce((acc, f, i) => {
@@ -145,10 +145,10 @@ export default {
145145
let values = this.selected[field.id]
146146
147147
let attrs = {
148-
value: values,
148+
modelValue: values,
149149
}
150150
let events = {
151-
input: ((fieldId) => (evt) => {
151+
'update:model-value': ((fieldId) => (evt) => {
152152
this.selected[fieldId] = evt
153153
})(field.id)
154154
}
@@ -170,10 +170,10 @@ export default {
170170
171171
period:{
172172
attrs:{
173-
value: this.selectedPeriod.id
173+
modelValue: this.selectedPeriod.id
174174
},
175175
events:{
176-
input: (periodId) => {
176+
'update:model-value': (periodId) => {
177177
let i = this.periodIndex[periodId] || 0
178178
this.selectedPeriod = this.periods[i]
179179
}
@@ -191,7 +191,7 @@ export default {
191191
},
192192
cronToSelected(value){
193193
if(!value){
194-
this.$emit('update:value', this.defaultValue())
194+
this.$emit('update:model-value', this.defaultValue())
195195
return
196196
}
197197
@@ -233,7 +233,7 @@ export default {
233233
strings.push(str.value)
234234
}
235235
this.error = ''
236-
this.$emit('update:value', strings.join(' '))
236+
this.$emit('update:model-value', strings.join(' '))
237237
},
238238
239239
sort(array){

core/test/core.test.js

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
1-
import { config, mount } from '@vue/test-utils'
1+
import { mount } from '@vue/test-utils'
22
import 'regenerator-runtime/runtime'
33
import VueCron from '../src/core.vue'
44

5-
config.renderStubDefaultSlot = true
6-
75
test('test VueCron', async () => {
86
// render the component
97
let onUpdateValue = jest.fn()

light/dev/example-usage.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<template>
22
<div>
3-
<VueCronEditor :value="value" @update:value="value = $event">
3+
<VueCronEditor v-model="value">
44
</VueCronEditor>
55
<div><br />cron expression: {{value}}</div>
66
</div>

light/src/CronEditor.vue

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11

22
<template>
3-
<CronCore v-bind="$attrs" @update:value="$emit('update:value', $event)" @error="$emit('error', $event)" v-slot="{fields, period}">
3+
<CronCore v-bind="$attrs" @update:model-value="$emit('update:model-value', $event)" @error="$emit('error', $event)" v-slot="{fields, period}">
44
<span class="vcron-editor">
55
<span>{{period.prefix}}</span>
66
<custom-select v-bind="period.attrs" v-on="period.events" :items="period.items" item-value="id" :cols="cols('period')" :width="width('period')" />
77
<span>{{period.suffix}}</span>
88

9-
109
<template v-for="f in fields" :key="f.id">
1110
<span>{{f.prefix}}</span>
1211
<custom-select v-bind="f.attrs" v-on="f.events" :items="f.items" :cols="cols(f.id)" :width="width(f.id)" multiple>{{f.selectedStr}}</custom-select>
@@ -48,6 +47,6 @@ export default {
4847
}
4948
}
5049
},
51-
emits:['update:value', 'error']
50+
emits:['update:model-value', 'error']
5251
}
5352
</script>

light/src/components/CustomSelect.vue

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ export default {
2929
type: Boolean,
3030
default: false
3131
},
32-
value: {
32+
modelValue: {
3333
type: [String, Array, Object],
3434
default(props){
3535
return props.multiple ? [] : null
@@ -60,6 +60,7 @@ export default {
6060
default: 'unset'
6161
}
6262
},
63+
emits: ['update:model-value'],
6364
data(){
6465
return {
6566
menu: false
@@ -79,7 +80,7 @@ export default {
7980
}
8081
},
8182
_value(){
82-
return (this.multiple) ? this.value : [this.value]
83+
return (this.multiple) ? this.modelValue : [this.modelValue]
8384
},
8485
selectedItems(){
8586
return this.items.filter((item) => {
@@ -127,10 +128,10 @@ export default {
127128
else{
128129
value.push(item)
129130
}
130-
this.$emit('input', (this.returnObject) ? value : value.map((item) => item[this.itemValue]))
131+
this.$emit('update:model-value', (this.returnObject) ? value : value.map((item) => item[this.itemValue]))
131132
}
132133
else {
133-
this.$emit('input', (this.returnObject) ? item : item[this.itemValue])
134+
this.$emit('update:model-value', (this.returnObject) ? item : item[this.itemValue])
134135
}
135136
}
136137
}

vuetify/build/rollup.config.js

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import commonjs from '@rollup/plugin-commonjs'; // Convert CommonJS modules to ES6
2+
import css from 'rollup-plugin-css-only';
23
import vue from 'rollup-plugin-vue'; // Handle .vue SFC files
3-
import buble from '@rollup/plugin-buble'; // Transpile/polyfill with reasonable browser support
4-
import css from 'rollup-plugin-css-only'
54
export default {
65
input: 'src/index.js', // Path relative to package.json
76
output: {
@@ -17,11 +16,5 @@ export default {
1716
compileTemplate: true, // Explicitly convert template to render function
1817
}),
1918
commonjs(),
20-
/*buble({
21-
objectAssign: 'Object.assign',
22-
transforms: {
23-
forOf: false
24-
}
25-
}), // Transpile to ES5*/
2619
],
2720
};

vuetify/dev/example-usage.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
<v-container>
44
<v-card>
55
<v-card-text>
6-
<v-text-field label="" :value="value" @change="value=$event"></v-text-field>
6+
<v-text-field label="" :value="value" @change="value=$event" density="compact"></v-text-field>
77
<VueCronEditor v-model="value">
88

99
</VueCronEditor>

vuetify/dev/serve.js

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,14 @@
1-
import Vue from 'vue'
1+
import '@mdi/font/css/materialdesignicons.css'
2+
import { createApp } from 'vue'
3+
import { createVuetify } from 'vuetify'
4+
import * as components from 'vuetify/components'
5+
import 'vuetify/styles'
26
import example from './example-usage.vue'
3-
import Vuetify from 'vuetify'
4-
import 'vuetify/dist/vuetify.min.css'
57

6-
Vue.use(Vuetify)
7-
const opts = {}
8-
const vuetify = new Vuetify(opts)
8+
const app = createApp(example)
9+
const vuetify = createVuetify({
10+
components: components
11+
})
12+
app.use(vuetify)
913

10-
Vue.config.productionTip = false
11-
12-
new Vue({
13-
render: h => h(example),
14-
vuetify
15-
}).$mount('#app')
14+
app.mount('#app')

vuetify/package.json

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,10 @@
2222
},
2323
"dependencies": {
2424
"@vue-js-cron/core": "2.1.1",
25-
"vuetify": "^2.4.6"
25+
"vuetify": "^3.0.0-beta.6"
2626
},
2727
"devDependencies": {
28-
"@vue/cli-service": "^4.5.15",
29-
"rollup-plugin-css-only": "^3.1.0"
28+
"@mdi/font": "^7.0.96"
3029
},
3130
"files": [
3231
"package.json",

vuetify/src/CronEditor.vue

Lines changed: 42 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,67 +1,63 @@
11

22
<template>
3-
<CronCore v-bind="$attrs" @input="$emit('input', $event)" @error="$emit('error', $event)">
4-
<template #default="{fields, period}">
5-
<v-row align="baseline" dense>
6-
<v-col v-if="period.prefix" class="flex-grow-0">{{period.prefix}}</v-col>
3+
<CronCore v-bind="$attrs" @update:model-value="$emit('update:model-value', $event)" @error="$emit('error', $event)" v-slot="{fields, period}">
4+
5+
<v-row align="baseline" dense>
6+
<v-col v-if="period.prefix" class="flex-grow-0">{{period.prefix}}</v-col>
7+
<v-col cols="auto">
8+
<custom-select v-bind="period.attrs" :items="period.items" v-on="period.events" item-value="id" :density="density" :variant="variant"></custom-select>
9+
</v-col>
10+
<v-col v-if="period.suffix" class="flex-grow-0">{{period.suffix}}</v-col>
11+
12+
13+
<template v-for="f in fields" :key="f.id">
14+
<v-col v-if="f.prefix" class="flex-grow-0">{{f.prefix}}</v-col>
715
<v-col cols="auto">
8-
<v-select class="fit" v-bind="period.attrs" :items="period.items" @input="period.events.input" item-value="id" dense></v-select>
16+
<custom-select v-bind="f.attrs" v-on="f.events" :selection="f.selectedStr" :cols="cols(f.id)" :items="f.items" multiple :density="density" :variant="variant" :close-on-content-click="false" clearable>
17+
</custom-select>
918
</v-col>
10-
<v-col v-if="period.suffix" class="flex-grow-0">{{period.suffix}}</v-col>
11-
12-
13-
<template v-for="f in fields">
14-
<v-col v-if="f.prefix" class="flex-grow-0" :key="f.id+'-prefix'">{{f.prefix}}</v-col>
15-
<v-col cols="auto" :key="f.id">
16-
<v-select class="fit" v-bind="f.attrs" v-on="f.events" :items="f.items" multiple dense :menu-props="{ auto: false, offsetY: true }">
17-
<template #prepend-inner>
18-
<div>{{f.selectedStr}}</div>
19-
</template>
20-
<template #selection>
21-
22-
</template>
23-
<template #item="{item, attrs}">
24-
<v-list-item-title v-bind="attrs">{{item.text}}</v-list-item-title>
25-
</template>
26-
</v-select>
27-
</v-col>
28-
<v-col v-if="f.suffix" class="flex-grow-0" :key="f.id+'-suffix'">{{f.suffix}}</v-col>
29-
</template>
30-
</v-row>
31-
32-
</template>
19+
<v-col v-if="f.suffix" class="flex-grow-0">{{f.suffix}}</v-col>
20+
</template>
21+
</v-row>
22+
3323
</CronCore>
3424
</template>
3525

3626
<script>
3727
import CronCore from '@vue-js-cron/core'
28+
import CustomSelect from './components/CustomSelect.vue'
3829
3930
export default {
4031
name: "VueCronEditor",
4132
components:{
4233
'CronCore': CronCore.component,
34+
CustomSelect
35+
},
36+
props: {
37+
variant: {
38+
type: String,
39+
default: 'elevated'
40+
},
41+
density: {
42+
type: String,
43+
default: 'default'
44+
},
45+
cols: {
46+
type: Function,
47+
default: (fieldId) => {
48+
49+
if(fieldId == 'minute') return 5
50+
else if (fieldId == 'hour') return 4
51+
else if (fieldId == 'day') return 4
52+
else return 1
53+
54+
}
55+
},
4356
},
57+
emits: ['update:model-value', 'error']
4458
}
4559
</script>
4660

4761
<style lang="css">
4862
49-
.v-select.fit {
50-
width: min-content;
51-
}
52-
.v-select.fit .v-select__selection--comma {
53-
text-overflow: unset;
54-
}
55-
.v-select.fit .v-input__prepend-inner {
56-
white-space: nowrap;
57-
align-items: center;
58-
59-
}
60-
.v-select.fit .v-input__prepend-inner div {
61-
min-height: 10px;
62-
line-height: 26px;
63-
}
64-
65-
66-
6763
</style>

0 commit comments

Comments
 (0)