js-kompo-utils 1.0.30 → 1.0.32
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -62,8 +62,11 @@ export default {
|
|
|
62
62
|
customTextInsertion(){ return this.$_config('customTextInsertion') },
|
|
63
63
|
},
|
|
64
64
|
methods: {
|
|
65
|
-
onReady(editor
|
|
66
|
-
el
|
|
65
|
+
onReady(editor) {
|
|
66
|
+
const el = editor.sourceElement
|
|
67
|
+
if (!el) return
|
|
68
|
+
|
|
69
|
+
el.ckInstance = editor
|
|
67
70
|
|
|
68
71
|
el.typeSimulated = async (text, options) => {
|
|
69
72
|
const {
|
|
@@ -93,13 +96,20 @@ export default {
|
|
|
93
96
|
}, 50 )
|
|
94
97
|
},
|
|
95
98
|
$_inputAction(){
|
|
99
|
+
// This override replaces Field.js's $_inputAction, so behaviors wired
|
|
100
|
+
// there must be re-triggered here. Whispers fire immediately (typing
|
|
101
|
+
// indicators can't wait for the value-commit debounce below).
|
|
102
|
+
if (this.$_config('socketWhisper') && this.$_triggerWhisper) {
|
|
103
|
+
this.$_triggerWhisper()
|
|
104
|
+
}
|
|
105
|
+
|
|
96
106
|
if(typeof window.KCK !== 'undefined') {
|
|
97
107
|
clearTimeout(window.KCK);
|
|
98
108
|
}
|
|
99
109
|
|
|
100
110
|
window.KCK = setTimeout(() => {
|
|
101
|
-
this.$_changeAction()
|
|
102
|
-
this.$emit('change', this.$_value)
|
|
111
|
+
this.$_changeAction()
|
|
112
|
+
this.$emit('change', this.$_value)
|
|
103
113
|
}, this.$_debounce || 1200);
|
|
104
114
|
},
|
|
105
115
|
/*$_inputAction: _.debounce(function () { //this works too but doesn't allow me to add this.$_debounce
|
|
@@ -190,16 +200,6 @@ export default {
|
|
|
190
200
|
this.focus()
|
|
191
201
|
},
|
|
192
202
|
created(){
|
|
193
|
-
const originalCreate = ClassicEditor.create;
|
|
194
|
-
const self = this;
|
|
195
|
-
ClassicEditor.create = function (element, config) {
|
|
196
|
-
return originalCreate.call(this, element, config).then(editor => {
|
|
197
|
-
element.ckeditorInstance = editor;
|
|
198
|
-
self.onReady(editor, element);
|
|
199
|
-
return editor;
|
|
200
|
-
});
|
|
201
|
-
};
|
|
202
|
-
|
|
203
203
|
let extraPlugins = [
|
|
204
204
|
Essentials,
|
|
205
205
|
Alignment,
|
package/package.json
CHANGED
|
@@ -1,125 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect } from 'vitest'
|
|
2
|
-
import VlMultiStateCheckbox from './VlMultiStateCheckbox.vue'
|
|
3
|
-
import { mountKompo } from './__test_helpers__/mountKompo'
|
|
4
|
-
|
|
5
|
-
const SINGLE = { mode: 'single', values: [1, 2, 3], colors: ['bg-r', 'bg-y', 'bg-g'] }
|
|
6
|
-
const SECTION = { mode: 'section', values: [1, 2, 3], colors: ['bg-r', 'bg-y', 'bg-g'] }
|
|
7
|
-
|
|
8
|
-
function mountMscb(config, value) {
|
|
9
|
-
return mountKompo(VlMultiStateCheckbox, { config, value })
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
describe('VlMultiStateCheckbox — single mode rendering', () => {
|
|
13
|
-
it('shows the color matching the current value', () => {
|
|
14
|
-
const w = mountMscb(SINGLE, 2)
|
|
15
|
-
expect(w.find('.vl-mscb__swatch').classes()).toContain('bg-y')
|
|
16
|
-
})
|
|
17
|
-
|
|
18
|
-
it('shows empty when value is null', () => {
|
|
19
|
-
const w = mountMscb(SINGLE, null)
|
|
20
|
-
expect(w.find('.vl-mscb__swatch').classes()).toContain('vl-mscb__swatch--empty')
|
|
21
|
-
})
|
|
22
|
-
|
|
23
|
-
it('shows empty when value is not in the values list', () => {
|
|
24
|
-
const w = mountMscb(SINGLE, 99)
|
|
25
|
-
expect(w.find('.vl-mscb__swatch').classes()).toContain('vl-mscb__swatch--empty')
|
|
26
|
-
})
|
|
27
|
-
})
|
|
28
|
-
|
|
29
|
-
describe('VlMultiStateCheckbox — single mode click', () => {
|
|
30
|
-
it.each([
|
|
31
|
-
[null, 1],
|
|
32
|
-
[1, 2],
|
|
33
|
-
[2, 3],
|
|
34
|
-
[3, null],
|
|
35
|
-
[99, 1],
|
|
36
|
-
])('cycles %s → %s', async (from, to) => {
|
|
37
|
-
const w = mountMscb(SINGLE, from)
|
|
38
|
-
await w.find('.vl-mscb').trigger('click')
|
|
39
|
-
expect(w.vm.component.value).toBe(to)
|
|
40
|
-
})
|
|
41
|
-
|
|
42
|
-
it('does not change value when readonly', async () => {
|
|
43
|
-
const w = mountMscb({ ...SINGLE, readonly: true }, 1)
|
|
44
|
-
await w.find('.vl-mscb').trigger('click')
|
|
45
|
-
expect(w.vm.component.value).toBe(1)
|
|
46
|
-
})
|
|
47
|
-
|
|
48
|
-
it.each(['keydown.enter', 'keydown.space'])('cycles via %s', async (key) => {
|
|
49
|
-
const w = mountMscb(SINGLE, null)
|
|
50
|
-
await w.find('.vl-mscb').trigger(key)
|
|
51
|
-
expect(w.vm.component.value).toBe(1)
|
|
52
|
-
})
|
|
53
|
-
})
|
|
54
|
-
|
|
55
|
-
describe('VlMultiStateCheckbox — section mode rendering', () => {
|
|
56
|
-
it('renders one bar per distinct active value (mixed)', () => {
|
|
57
|
-
const w = mountMscb(SECTION, [1, 2])
|
|
58
|
-
const bars = w.findAll('.vl-mscb__bar--visible')
|
|
59
|
-
expect(bars.length).toBe(2)
|
|
60
|
-
expect(bars.at(0).classes()).toContain('bg-r')
|
|
61
|
-
expect(bars.at(1).classes()).toContain('bg-y')
|
|
62
|
-
})
|
|
63
|
-
|
|
64
|
-
it('renders one bar when all entries share a value (uniform)', () => {
|
|
65
|
-
const w = mountMscb(SECTION, [2, 2, 2])
|
|
66
|
-
const bars = w.findAll('.vl-mscb__bar--visible')
|
|
67
|
-
expect(bars.length).toBe(1)
|
|
68
|
-
expect(bars.at(0).classes()).toContain('bg-y')
|
|
69
|
-
})
|
|
70
|
-
|
|
71
|
-
it.each([
|
|
72
|
-
['empty array', []],
|
|
73
|
-
['all-null', [null, null]],
|
|
74
|
-
['null value', null],
|
|
75
|
-
])('renders no bars when %s', (_label, value) => {
|
|
76
|
-
const w = mountMscb(SECTION, value)
|
|
77
|
-
expect(w.findAll('.vl-mscb__bar--visible').length).toBe(0)
|
|
78
|
-
})
|
|
79
|
-
|
|
80
|
-
it('skips entries not in the values whitelist', () => {
|
|
81
|
-
const w = mountMscb(SECTION, [1, 99, 2])
|
|
82
|
-
const bars = w.findAll('.vl-mscb__bar--visible')
|
|
83
|
-
expect(bars.length).toBe(2)
|
|
84
|
-
})
|
|
85
|
-
})
|
|
86
|
-
|
|
87
|
-
describe('VlMultiStateCheckbox — section mode click', () => {
|
|
88
|
-
it.each([
|
|
89
|
-
['uniform — advances from shared value', [2, 2], 3],
|
|
90
|
-
['uniform at last — cycles to null', [3, 3], null],
|
|
91
|
-
['mixed — starts at first state', [1, 2], 1],
|
|
92
|
-
['empty — starts at first state', [], 1],
|
|
93
|
-
])('%s', async (_label, value, expected) => {
|
|
94
|
-
const w = mountMscb(SECTION, value)
|
|
95
|
-
await w.find('.vl-mscb').trigger('click')
|
|
96
|
-
expect(w.vm.component.value).toBe(expected)
|
|
97
|
-
})
|
|
98
|
-
|
|
99
|
-
it('does not change value when readonly', async () => {
|
|
100
|
-
const w = mountMscb({ ...SECTION, readonly: true }, [1, 2])
|
|
101
|
-
await w.find('.vl-mscb').trigger('click')
|
|
102
|
-
expect(w.vm.component.value).toEqual([1, 2])
|
|
103
|
-
})
|
|
104
|
-
|
|
105
|
-
it('emits a scalar value, not an array', async () => {
|
|
106
|
-
const w = mountMscb(SECTION, [1, 1])
|
|
107
|
-
await w.find('.vl-mscb').trigger('click')
|
|
108
|
-
expect(Array.isArray(w.vm.component.value)).toBe(false)
|
|
109
|
-
expect(w.vm.component.value).toBe(2)
|
|
110
|
-
})
|
|
111
|
-
|
|
112
|
-
it('updates the visual to a uniform bar at the new target after click', async () => {
|
|
113
|
-
const w = mountMscb(SECTION, [1, 2]) // mixed — click resets to states[0]=1
|
|
114
|
-
await w.find('.vl-mscb').trigger('click')
|
|
115
|
-
const bars = w.findAll('.vl-mscb__bar--visible')
|
|
116
|
-
expect(bars.length).toBe(1)
|
|
117
|
-
expect(bars.at(0).classes()).toContain('bg-r')
|
|
118
|
-
})
|
|
119
|
-
|
|
120
|
-
it('renders no bars after a click that cycles past the last state to null', async () => {
|
|
121
|
-
const w = mountMscb(SECTION, [3, 3]) // uniform at last → click → null
|
|
122
|
-
await w.find('.vl-mscb').trigger('click')
|
|
123
|
-
expect(w.findAll('.vl-mscb__bar--visible').length).toBe(0)
|
|
124
|
-
})
|
|
125
|
-
})
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
import { mount } from '@vue/test-utils'
|
|
2
|
-
|
|
3
|
-
// Minimal stub for vl-form-field. Real impl is heavy and unrelated to the
|
|
4
|
-
// behaviour we're testing; we just need a transparent wrapper for the slot.
|
|
5
|
-
const VlFormFieldStub = {
|
|
6
|
-
props: ['component', 'errors'],
|
|
7
|
-
template: '<div class="vl-form-field-stub"><slot /></div>',
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* Mount a kompo Field-style Vue component with a synthesized vkompo blob.
|
|
12
|
-
* Use this for any component that mixes in `vue-kompo/js/form/mixins/Field`
|
|
13
|
-
* (or descendants of `BaseElement`) so tests don't have to hand-roll the
|
|
14
|
-
* shape every time.
|
|
15
|
-
*
|
|
16
|
-
* mountKompo(MyField, {
|
|
17
|
-
* config: { mode: 'single', values: [1,2], colors: ['a','b'] },
|
|
18
|
-
* value: null,
|
|
19
|
-
* })
|
|
20
|
-
*
|
|
21
|
-
* Reads `wrapper.vm.component.value` to observe value changes after click.
|
|
22
|
-
*/
|
|
23
|
-
export function mountKompo(component, { config = {}, value = null, name = 'test', label = null } = {}) {
|
|
24
|
-
return mount(component, {
|
|
25
|
-
propsData: {
|
|
26
|
-
vkompo: {
|
|
27
|
-
vueComponent: component.name || 'TestComponent',
|
|
28
|
-
config,
|
|
29
|
-
value,
|
|
30
|
-
name,
|
|
31
|
-
label,
|
|
32
|
-
_kid: 'k-test',
|
|
33
|
-
},
|
|
34
|
-
},
|
|
35
|
-
stubs: {
|
|
36
|
-
'vl-form-field': VlFormFieldStub,
|
|
37
|
-
},
|
|
38
|
-
})
|
|
39
|
-
}
|
package/components/test-setup.js
DELETED
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
// Test setup for components that use vue-kompo's Field mixin chain.
|
|
2
|
-
// The kompo runtime expects `_` (lodash) and `$kompo` to be available globally.
|
|
3
|
-
import _ from 'lodash'
|
|
4
|
-
import Vue from 'vue'
|
|
5
|
-
|
|
6
|
-
// Lodash is referenced as a bare global (`_`) inside vue-kompo mixins.
|
|
7
|
-
globalThis._ = _
|
|
8
|
-
// vue-kompo's KompoHelper module references `Vue` as a bare global at import time.
|
|
9
|
-
globalThis.Vue = Vue
|
|
10
|
-
|
|
11
|
-
// Stub the kompo bus that Field's $_changeAction reaches into.
|
|
12
|
-
// Tests don't exercise the real form/error pipeline, so the methods are no-ops.
|
|
13
|
-
Vue.prototype.$kompo = {
|
|
14
|
-
vlUpdateErrorState() {},
|
|
15
|
-
vlSubmit() {},
|
|
16
|
-
vlToggle() {},
|
|
17
|
-
vlEmitFrom() {},
|
|
18
|
-
vlHybridFilter() {},
|
|
19
|
-
vlJsInstantFilter() {},
|
|
20
|
-
vlSetFieldValue() {},
|
|
21
|
-
events: {
|
|
22
|
-
$on() {},
|
|
23
|
-
$off() {},
|
|
24
|
-
},
|
|
25
|
-
}
|