@rancher/shell 0.3.23 → 0.3.24
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.
- package/assets/styles/base/_variables.scss +1 -0
- package/assets/styles/themes/_dark.scss +1 -0
- package/assets/styles/themes/_light.scss +6 -5
- package/assets/translations/en-us.yaml +15 -10
- package/assets/translations/zh-hans.yaml +1 -1
- package/components/ClusterProviderIconMenu.vue +161 -0
- package/components/Loading.vue +1 -1
- package/components/SideNav.vue +1 -1
- package/components/form/SelectOrCreateAuthSecret.vue +7 -0
- package/components/nav/Group.vue +54 -24
- package/components/nav/Header.vue +1 -1
- package/components/nav/TopLevelMenu.vue +469 -294
- package/components/nav/Type.vue +31 -5
- package/creators/pkg/init +2 -2
- package/edit/fleet.cattle.io.gitrepo.vue +43 -15
- package/edit/logging.banzaicloud.io.output/index.vue +7 -0
- package/edit/provisioning.cattle.io.cluster/CustomCommand.vue +3 -8
- package/edit/provisioning.cattle.io.cluster/rke2.vue +108 -33
- package/edit/workload/storage/ContainerMountPaths.vue +7 -5
- package/initialize/App.js +2 -0
- package/initialize/client.js +63 -51
- package/initialize/index.js +2 -0
- package/layouts/default.vue +8 -0
- package/machine-config/amazonec2.vue +1 -0
- package/mixins/fetch.client.js +3 -3
- package/package.json +1 -1
- package/pages/__tests__/prefs.test.ts +1 -1
- package/pages/c/_cluster/explorer/ConfigBadge.vue +1 -0
- package/pages/prefs.vue +3 -13
- package/plugins/dashboard-store/resource-class.js +1 -1
- package/public/index.html +4 -2
- package/rancher-components/BadgeState/BadgeState.vue +5 -1
- package/rancher-components/Banner/Banner.test.ts +51 -1
- package/rancher-components/Banner/Banner.vue +134 -53
- package/rancher-components/Card/Card.test.ts +37 -0
- package/rancher-components/Card/Card.vue +24 -7
- package/rancher-components/Form/Checkbox/Checkbox.test.ts +20 -29
- package/rancher-components/Form/Checkbox/Checkbox.vue +45 -20
- package/rancher-components/Form/LabeledInput/LabeledInput.test.ts +2 -8
- package/rancher-components/Form/LabeledInput/LabeledInput.vue +30 -10
- package/rancher-components/Form/Radio/RadioButton.test.ts +35 -0
- package/rancher-components/Form/Radio/RadioButton.vue +30 -13
- package/rancher-components/Form/Radio/RadioGroup.vue +26 -7
- package/rancher-components/Form/TextArea/TextAreaAutoGrow.vue +7 -6
- package/rancher-components/Form/ToggleSwitch/ToggleSwitch.test.ts +25 -38
- package/rancher-components/Form/ToggleSwitch/ToggleSwitch.vue +23 -11
- package/rancher-components/LabeledTooltip/LabeledTooltip.vue +19 -5
- package/rancher-components/StringList/StringList.test.ts +453 -49
- package/rancher-components/StringList/StringList.vue +92 -58
- package/scripts/extension/parse-tag-name +0 -0
- package/store/prefs.js +3 -4
- package/store/type-map.js +2 -16
- package/types/shell/index.d.ts +13 -10
- package/utils/__tests__/sort.test.ts +61 -0
- package/utils/string.js +12 -0
- package/vue.config.js +1 -4
- package/yarn-error.log +200 -0
|
@@ -2,8 +2,11 @@
|
|
|
2
2
|
import Vue, { PropType } from 'vue';
|
|
3
3
|
import { _EDIT, _VIEW } from '@shell/config/query-params';
|
|
4
4
|
import { addObject, removeObject } from '@shell/utils/array';
|
|
5
|
+
import cloneDeep from 'lodash/cloneDeep';
|
|
5
6
|
|
|
6
7
|
export default Vue.extend({
|
|
8
|
+
name: 'Checkbox',
|
|
9
|
+
|
|
7
10
|
props: {
|
|
8
11
|
/**
|
|
9
12
|
* The checkbox value.
|
|
@@ -46,8 +49,8 @@ export default Vue.extend({
|
|
|
46
49
|
},
|
|
47
50
|
|
|
48
51
|
/**
|
|
49
|
-
* Display an indeterminate state. Useful for cases where a checkbox might
|
|
50
|
-
* be the parent to child checkboxes, and we need to show that a subset of
|
|
52
|
+
* Display an indeterminate state. Useful for cases where a checkbox might
|
|
53
|
+
* be the parent to child checkboxes, and we need to show that a subset of
|
|
51
54
|
* children are checked.
|
|
52
55
|
*/
|
|
53
56
|
indeterminate: {
|
|
@@ -110,22 +113,22 @@ export default Vue.extend({
|
|
|
110
113
|
primary: {
|
|
111
114
|
type: Boolean,
|
|
112
115
|
default: false
|
|
113
|
-
},
|
|
116
|
+
},
|
|
114
117
|
},
|
|
115
118
|
|
|
116
119
|
computed: {
|
|
117
120
|
/**
|
|
118
121
|
* Determines if the checkbox is disabled.
|
|
119
|
-
* @returns boolean: True when the disabled prop is true or when mode is
|
|
122
|
+
* @returns boolean: True when the disabled prop is true or when mode is
|
|
120
123
|
* View.
|
|
121
124
|
*/
|
|
122
125
|
isDisabled(): boolean {
|
|
123
126
|
return (this.disabled || this.mode === _VIEW);
|
|
124
127
|
},
|
|
125
128
|
/**
|
|
126
|
-
* Determines if the checkbox is checked when using custom values or
|
|
129
|
+
* Determines if the checkbox is checked when using custom values or
|
|
127
130
|
* multiple values.
|
|
128
|
-
* @returns boolean: True when at least one value is true in a collection or
|
|
131
|
+
* @returns boolean: True when at least one value is true in a collection or
|
|
129
132
|
* when value matches `this.valueWhenTrue`.
|
|
130
133
|
*/
|
|
131
134
|
isChecked(): boolean {
|
|
@@ -162,13 +165,15 @@ export default Vue.extend({
|
|
|
162
165
|
const click = new CustomEvent('click', customEvent);
|
|
163
166
|
|
|
164
167
|
// Flip the value
|
|
165
|
-
|
|
168
|
+
const value = cloneDeep(this.value);
|
|
169
|
+
|
|
170
|
+
if (this.isMulti(value)) {
|
|
166
171
|
if (this.isChecked) {
|
|
167
|
-
removeObject(
|
|
172
|
+
removeObject(value, this.valueWhenTrue);
|
|
168
173
|
} else {
|
|
169
|
-
addObject(
|
|
174
|
+
addObject(value, this.valueWhenTrue);
|
|
170
175
|
}
|
|
171
|
-
this.$emit('input',
|
|
176
|
+
this.$emit('input', value);
|
|
172
177
|
} else if (this.isString(this.valueWhenTrue)) {
|
|
173
178
|
if (this.isChecked) {
|
|
174
179
|
this.$emit('input', null);
|
|
@@ -176,7 +181,7 @@ export default Vue.extend({
|
|
|
176
181
|
this.$emit('input', this.valueWhenTrue);
|
|
177
182
|
}
|
|
178
183
|
} else {
|
|
179
|
-
this.$emit('input', !
|
|
184
|
+
this.$emit('input', !value);
|
|
180
185
|
this.$el.dispatchEvent(click);
|
|
181
186
|
}
|
|
182
187
|
},
|
|
@@ -197,14 +202,17 @@ export default Vue.extend({
|
|
|
197
202
|
* @param value A collection of values for the checkbox.
|
|
198
203
|
*/
|
|
199
204
|
findTrueValues(value: boolean[]): boolean {
|
|
200
|
-
return value.find(v => v === this.valueWhenTrue) || false;
|
|
205
|
+
return value.find((v) => v === this.valueWhenTrue) || false;
|
|
201
206
|
}
|
|
202
207
|
}
|
|
203
208
|
});
|
|
204
209
|
</script>
|
|
205
210
|
|
|
206
211
|
<template>
|
|
207
|
-
<div
|
|
212
|
+
<div
|
|
213
|
+
class="checkbox-outer-container"
|
|
214
|
+
data-checkbox-ctrl
|
|
215
|
+
>
|
|
208
216
|
<label
|
|
209
217
|
class="checkbox-container"
|
|
210
218
|
:class="{ 'disabled': isDisabled}"
|
|
@@ -214,14 +222,13 @@ export default Vue.extend({
|
|
|
214
222
|
@click="clicked($event)"
|
|
215
223
|
>
|
|
216
224
|
<input
|
|
217
|
-
v-model="value"
|
|
218
225
|
:checked="isChecked"
|
|
219
226
|
:value="valueWhenTrue"
|
|
220
227
|
type="checkbox"
|
|
221
228
|
:tabindex="-1"
|
|
222
229
|
:name="id"
|
|
223
230
|
@click.stop.prevent
|
|
224
|
-
|
|
231
|
+
>
|
|
225
232
|
<span
|
|
226
233
|
class="checkbox-custom"
|
|
227
234
|
:class="{indeterminate: indeterminate}"
|
|
@@ -236,15 +243,33 @@ export default Vue.extend({
|
|
|
236
243
|
:class="{ 'checkbox-primary': primary }"
|
|
237
244
|
>
|
|
238
245
|
<slot name="label">
|
|
239
|
-
<t
|
|
246
|
+
<t
|
|
247
|
+
v-if="labelKey"
|
|
248
|
+
:k="labelKey"
|
|
249
|
+
:raw="true"
|
|
250
|
+
/>
|
|
240
251
|
<template v-else-if="label">{{ label }}</template>
|
|
241
|
-
<i
|
|
242
|
-
|
|
252
|
+
<i
|
|
253
|
+
v-if="tooltipKey"
|
|
254
|
+
v-clean-tooltip="t(tooltipKey)"
|
|
255
|
+
class="checkbox-info icon icon-info icon-lg"
|
|
256
|
+
/>
|
|
257
|
+
<i
|
|
258
|
+
v-else-if="tooltip"
|
|
259
|
+
v-clean-tooltip="tooltip"
|
|
260
|
+
class="checkbox-info icon icon-info icon-lg"
|
|
261
|
+
/>
|
|
243
262
|
</slot>
|
|
244
263
|
</span>
|
|
245
264
|
</label>
|
|
246
|
-
<div
|
|
247
|
-
|
|
265
|
+
<div
|
|
266
|
+
v-if="descriptionKey || description"
|
|
267
|
+
class="checkbox-outer-container-description"
|
|
268
|
+
>
|
|
269
|
+
<t
|
|
270
|
+
v-if="descriptionKey"
|
|
271
|
+
:k="descriptionKey"
|
|
272
|
+
/>
|
|
248
273
|
<template v-else-if="description">
|
|
249
274
|
{{ description }}
|
|
250
275
|
</template>
|
|
@@ -6,15 +6,9 @@ describe('component: LabeledInput', () => {
|
|
|
6
6
|
it('should emit input only once', () => {
|
|
7
7
|
const value = '2';
|
|
8
8
|
const delay = 1;
|
|
9
|
-
const wrapper = mount(LabeledInput, {
|
|
9
|
+
const wrapper = mount(LabeledInput, {
|
|
10
10
|
propsData: { delay },
|
|
11
|
-
mocks:
|
|
12
|
-
$store: {
|
|
13
|
-
getters: {
|
|
14
|
-
'i18n/t': jest.fn()
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
}
|
|
11
|
+
mocks: { $store: { getters: { 'i18n/t': jest.fn() } } }
|
|
18
12
|
});
|
|
19
13
|
|
|
20
14
|
jest.useFakeTimers();
|
|
@@ -27,7 +27,7 @@ export default (
|
|
|
27
27
|
|
|
28
28
|
/**
|
|
29
29
|
* The status class of the Labeled Input and tooltip.
|
|
30
|
-
* @values info, success, warning, error
|
|
30
|
+
* @values info, success, warning, error
|
|
31
31
|
*/
|
|
32
32
|
status: {
|
|
33
33
|
type: String,
|
|
@@ -59,7 +59,7 @@ export default (
|
|
|
59
59
|
},
|
|
60
60
|
|
|
61
61
|
/**
|
|
62
|
-
* Disables the password manager prompt to save the contents of the Labeled
|
|
62
|
+
* Disables the password manager prompt to save the contents of the Labeled
|
|
63
63
|
* Input.
|
|
64
64
|
*/
|
|
65
65
|
ignorePasswordManagers: {
|
|
@@ -124,7 +124,7 @@ export default (
|
|
|
124
124
|
|
|
125
125
|
tooltipValue(): string | undefined {
|
|
126
126
|
if (this.hasTooltip) {
|
|
127
|
-
return this.tooltipKey ? this.t(this.tooltipKey) : this.tooltip
|
|
127
|
+
return this.tooltipKey ? this.t(this.tooltipKey) : this.tooltip;
|
|
128
128
|
}
|
|
129
129
|
|
|
130
130
|
return undefined;
|
|
@@ -207,7 +207,14 @@ export default (
|
|
|
207
207
|
},
|
|
208
208
|
|
|
209
209
|
/**
|
|
210
|
-
* Emit on input
|
|
210
|
+
* Emit on input change
|
|
211
|
+
*/
|
|
212
|
+
onChange(event: Event): void {
|
|
213
|
+
this.$emit('change', event);
|
|
214
|
+
},
|
|
215
|
+
|
|
216
|
+
/**
|
|
217
|
+
* Emit on input with delay. Note: Arrow function is avoided due context
|
|
211
218
|
* binding.
|
|
212
219
|
*/
|
|
213
220
|
delayInput(value: string): void {
|
|
@@ -223,7 +230,7 @@ export default (
|
|
|
223
230
|
},
|
|
224
231
|
|
|
225
232
|
/**
|
|
226
|
-
* Handles the behavior of the Labeled Input when blurred and emits the blur
|
|
233
|
+
* Handles the behavior of the Labeled Input when blurred and emits the blur
|
|
227
234
|
* event.
|
|
228
235
|
* @see labeled-form-element.ts mixin for onBlurLabeled()
|
|
229
236
|
*/
|
|
@@ -253,10 +260,16 @@ export default (
|
|
|
253
260
|
>
|
|
254
261
|
<slot name="label">
|
|
255
262
|
<label v-if="hasLabel">
|
|
256
|
-
<t
|
|
263
|
+
<t
|
|
264
|
+
v-if="labelKey"
|
|
265
|
+
:k="labelKey"
|
|
266
|
+
/>
|
|
257
267
|
<template v-else-if="label">{{ label }}</template>
|
|
258
268
|
|
|
259
|
-
<span
|
|
269
|
+
<span
|
|
270
|
+
v-if="requiredField"
|
|
271
|
+
class="required"
|
|
272
|
+
>*</span>
|
|
260
273
|
</label>
|
|
261
274
|
</slot>
|
|
262
275
|
|
|
@@ -293,7 +306,8 @@ export default (
|
|
|
293
306
|
@input="onInput($event.target.value)"
|
|
294
307
|
@focus="onFocus"
|
|
295
308
|
@blur="onBlur"
|
|
296
|
-
|
|
309
|
+
@change="onChange"
|
|
310
|
+
>
|
|
297
311
|
</slot>
|
|
298
312
|
|
|
299
313
|
<slot name="suffix" />
|
|
@@ -308,8 +322,14 @@ export default (
|
|
|
308
322
|
:hover="hoverTooltip"
|
|
309
323
|
:value="validationMessage"
|
|
310
324
|
/>
|
|
311
|
-
<label
|
|
312
|
-
|
|
325
|
+
<label
|
|
326
|
+
v-if="cronHint"
|
|
327
|
+
class="cron-label"
|
|
328
|
+
>{{ cronHint }}</label>
|
|
329
|
+
<label
|
|
330
|
+
v-if="subLabel"
|
|
331
|
+
class="sub-label"
|
|
332
|
+
>{{ subLabel }}</label>
|
|
313
333
|
</div>
|
|
314
334
|
</template>
|
|
315
335
|
<style scoped lang="scss">
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { shallowMount } from '@vue/test-utils';
|
|
2
|
+
import { RadioButton } from './index';
|
|
3
|
+
import { cleanHtmlDirective } from '@shell/plugins/clean-html-directive';
|
|
4
|
+
|
|
5
|
+
describe('radioButton.vue', () => {
|
|
6
|
+
it('renders label slot contents', () => {
|
|
7
|
+
const wrapper = shallowMount(RadioButton, { slots: { label: 'Test Label' }, propsData: { val: {}, value: {} } });
|
|
8
|
+
|
|
9
|
+
expect(wrapper.find('.radio-label').text()).toBe('Test Label');
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
it('renders label prop contents', () => {
|
|
13
|
+
const wrapper = shallowMount(
|
|
14
|
+
RadioButton,
|
|
15
|
+
{
|
|
16
|
+
directives: { cleanHtmlDirective },
|
|
17
|
+
propsData: {
|
|
18
|
+
label: 'Test Label', val: {}, value: {}
|
|
19
|
+
}
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
expect(wrapper.find('.radio-label').text()).toBe('Test Label');
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
it('renders slot contents when both slot and label prop are provided', () => {
|
|
26
|
+
const wrapper = shallowMount(RadioButton, {
|
|
27
|
+
slots: { label: 'Test Label - Slot' },
|
|
28
|
+
propsData: {
|
|
29
|
+
label: 'Test Label - Props', val: {}, value: {}
|
|
30
|
+
},
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
expect(wrapper.find('.radio-label').text()).toBe('Test Label - Slot');
|
|
34
|
+
});
|
|
35
|
+
});
|
|
@@ -12,25 +12,25 @@ export default Vue.extend({
|
|
|
12
12
|
default: ''
|
|
13
13
|
},
|
|
14
14
|
|
|
15
|
-
/**
|
|
15
|
+
/**
|
|
16
16
|
* The value for this option.
|
|
17
|
-
*/
|
|
17
|
+
*/
|
|
18
18
|
val: {
|
|
19
19
|
required: true,
|
|
20
|
-
validator:
|
|
20
|
+
validator: () => true
|
|
21
21
|
},
|
|
22
22
|
|
|
23
|
-
/**
|
|
23
|
+
/**
|
|
24
24
|
* The selected value.
|
|
25
|
-
*/
|
|
25
|
+
*/
|
|
26
26
|
value: {
|
|
27
27
|
required: true,
|
|
28
|
-
validator:
|
|
28
|
+
validator: () => true
|
|
29
29
|
},
|
|
30
30
|
|
|
31
31
|
/**
|
|
32
32
|
* The label shown next to the radio.
|
|
33
|
-
*/
|
|
33
|
+
*/
|
|
34
34
|
label: {
|
|
35
35
|
type: String,
|
|
36
36
|
default: ''
|
|
@@ -96,6 +96,10 @@ export default Vue.extend({
|
|
|
96
96
|
hasDescriptionSlot(): boolean {
|
|
97
97
|
return !!this.$slots.description;
|
|
98
98
|
},
|
|
99
|
+
|
|
100
|
+
hasLabelSlot(): boolean {
|
|
101
|
+
return !!this.$slots.label || !!this.$scopedSlots.label;
|
|
102
|
+
}
|
|
99
103
|
},
|
|
100
104
|
|
|
101
105
|
watch: {
|
|
@@ -138,7 +142,7 @@ export default Vue.extend({
|
|
|
138
142
|
type="radio"
|
|
139
143
|
:tabindex="-1"
|
|
140
144
|
@click.stop.prevent
|
|
141
|
-
|
|
145
|
+
>
|
|
142
146
|
<span
|
|
143
147
|
ref="custom"
|
|
144
148
|
:class="[ isDisabled ? 'text-muted' : '', 'radio-custom']"
|
|
@@ -149,15 +153,28 @@ export default Vue.extend({
|
|
|
149
153
|
/>
|
|
150
154
|
<div class="labeling">
|
|
151
155
|
<label
|
|
152
|
-
v-if="label"
|
|
153
156
|
:class="[ muteLabel ? 'text-muted' : '', 'radio-label', 'm-0']"
|
|
154
157
|
:for="name"
|
|
155
|
-
v-html="label"
|
|
156
158
|
>
|
|
157
|
-
<slot
|
|
159
|
+
<slot
|
|
160
|
+
v-if="hasLabelSlot"
|
|
161
|
+
name="label"
|
|
162
|
+
>
|
|
163
|
+
<!-- slot content -->
|
|
164
|
+
</slot>
|
|
165
|
+
<span
|
|
166
|
+
v-else-if="label"
|
|
167
|
+
v-clean-html="label"
|
|
168
|
+
/>
|
|
158
169
|
</label>
|
|
159
|
-
<div
|
|
160
|
-
|
|
170
|
+
<div
|
|
171
|
+
v-if="descriptionKey || description"
|
|
172
|
+
class="radio-button-outer-container-description"
|
|
173
|
+
>
|
|
174
|
+
<t
|
|
175
|
+
v-if="descriptionKey"
|
|
176
|
+
:k="descriptionKey"
|
|
177
|
+
/>
|
|
161
178
|
<template v-else-if="description">
|
|
162
179
|
{{ description }}
|
|
163
180
|
</template>
|
|
@@ -28,7 +28,7 @@ export default Vue.extend({
|
|
|
28
28
|
},
|
|
29
29
|
|
|
30
30
|
/**
|
|
31
|
-
* If options are just values, then labels can be a corresponding display
|
|
31
|
+
* If options are just values, then labels can be a corresponding display
|
|
32
32
|
* value.
|
|
33
33
|
*/
|
|
34
34
|
labels: {
|
|
@@ -152,7 +152,7 @@ export default Vue.extend({
|
|
|
152
152
|
*/
|
|
153
153
|
clickNext(direction: number): void {
|
|
154
154
|
const opts = this.normalizedOptions;
|
|
155
|
-
const selected = opts.find(x => x.value === this.value);
|
|
155
|
+
const selected = opts.find((x) => x.value === this.value);
|
|
156
156
|
let newIndex = (selected ? opts.indexOf(selected) : -1) + direction;
|
|
157
157
|
|
|
158
158
|
if (newIndex >= opts.length) {
|
|
@@ -169,15 +169,29 @@ export default Vue.extend({
|
|
|
169
169
|
|
|
170
170
|
<template>
|
|
171
171
|
<div>
|
|
172
|
-
<div
|
|
172
|
+
<div
|
|
173
|
+
v-if="label || labelKey || tooltip || tooltipKey || $slots.label"
|
|
174
|
+
class="radio-group label"
|
|
175
|
+
>
|
|
173
176
|
<slot name="label">
|
|
174
177
|
<h3>
|
|
175
|
-
<t
|
|
178
|
+
<t
|
|
179
|
+
v-if="labelKey"
|
|
180
|
+
:k="labelKey"
|
|
181
|
+
/>
|
|
176
182
|
<template v-else-if="label">
|
|
177
183
|
{{ label }}
|
|
178
184
|
</template>
|
|
179
|
-
<i
|
|
180
|
-
|
|
185
|
+
<i
|
|
186
|
+
v-if="tooltipKey"
|
|
187
|
+
v-clean-tooltip="t(tooltipKey)"
|
|
188
|
+
class="icon icon-info icon-lg"
|
|
189
|
+
/>
|
|
190
|
+
<i
|
|
191
|
+
v-else-if="tooltip"
|
|
192
|
+
v-clean-tooltip="tooltip"
|
|
193
|
+
class="icon icon-info icon-lg"
|
|
194
|
+
/>
|
|
181
195
|
</h3>
|
|
182
196
|
</slot>
|
|
183
197
|
</div>
|
|
@@ -192,7 +206,12 @@ export default Vue.extend({
|
|
|
192
206
|
v-for="(option, i) in normalizedOptions"
|
|
193
207
|
:key="name+'-'+i"
|
|
194
208
|
>
|
|
195
|
-
<slot
|
|
209
|
+
<slot
|
|
210
|
+
:listeners="$listeners"
|
|
211
|
+
:option="option"
|
|
212
|
+
:is-disabled="isDisabled"
|
|
213
|
+
:name="i"
|
|
214
|
+
>
|
|
196
215
|
<RadioButton
|
|
197
216
|
:key="name+'-'+i"
|
|
198
217
|
:name="name"
|
|
@@ -24,14 +24,14 @@ export default Vue.extend({
|
|
|
24
24
|
},
|
|
25
25
|
|
|
26
26
|
/**
|
|
27
|
-
* Sets the Minimum height for Text Area. Prevents the height from becoming
|
|
27
|
+
* Sets the Minimum height for Text Area. Prevents the height from becoming
|
|
28
28
|
* smaller than the value specified in minHeight.
|
|
29
29
|
*/
|
|
30
30
|
minHeight: {
|
|
31
31
|
type: Number,
|
|
32
32
|
default: 25
|
|
33
33
|
},
|
|
34
|
-
|
|
34
|
+
|
|
35
35
|
/**
|
|
36
36
|
* Sets the maximum height for Text Area. Prevents the height from becoming
|
|
37
37
|
* larger than the value specified in maxHeight.
|
|
@@ -50,7 +50,7 @@ export default Vue.extend({
|
|
|
50
50
|
},
|
|
51
51
|
|
|
52
52
|
/**
|
|
53
|
-
* Specifies whether Text Area is subject to spell checking by the
|
|
53
|
+
* Specifies whether Text Area is subject to spell checking by the
|
|
54
54
|
* underlying browser/OS.
|
|
55
55
|
*/
|
|
56
56
|
spellcheck: {
|
|
@@ -83,7 +83,7 @@ export default Vue.extend({
|
|
|
83
83
|
},
|
|
84
84
|
|
|
85
85
|
/**
|
|
86
|
-
* Sets the height to one-line for SSR pageload so that it's already right
|
|
86
|
+
* Sets the height to one-line for SSR pageload so that it's already right
|
|
87
87
|
* (unless the input is long)
|
|
88
88
|
*/
|
|
89
89
|
style(): string {
|
|
@@ -112,7 +112,7 @@ export default Vue.extend({
|
|
|
112
112
|
},
|
|
113
113
|
|
|
114
114
|
methods: {
|
|
115
|
-
/**
|
|
115
|
+
/**
|
|
116
116
|
* Emits the input event and resizes the Text Area.
|
|
117
117
|
*/
|
|
118
118
|
onInput(val: string): void {
|
|
@@ -128,7 +128,7 @@ export default Vue.extend({
|
|
|
128
128
|
},
|
|
129
129
|
|
|
130
130
|
/**
|
|
131
|
-
* Sets the overflowY and height of the Text Area based on the content
|
|
131
|
+
* Sets the overflowY and height of the Text Area based on the content
|
|
132
132
|
* entered (calculated via scroll height).
|
|
133
133
|
*/
|
|
134
134
|
autoSize(): void {
|
|
@@ -155,6 +155,7 @@ export default Vue.extend({
|
|
|
155
155
|
<template>
|
|
156
156
|
<textarea
|
|
157
157
|
ref="ta"
|
|
158
|
+
data-testid="text-area-auto-grow"
|
|
158
159
|
:disabled="isDisabled"
|
|
159
160
|
:style="style"
|
|
160
161
|
:placeholder="placeholder"
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { shallowMount } from '@vue/test-utils';
|
|
1
|
+
import { shallowMount, Wrapper } from '@vue/test-utils';
|
|
2
2
|
import { ToggleSwitch } from './index';
|
|
3
3
|
|
|
4
|
-
describe('
|
|
4
|
+
describe('toggleSwitch.vue', () => {
|
|
5
5
|
it('renders falsy by default', () => {
|
|
6
6
|
const wrapper = shallowMount(ToggleSwitch);
|
|
7
7
|
|
|
8
|
-
const toggleInput = wrapper.find('input[type="checkbox"]').element as HTMLInputElement
|
|
8
|
+
const toggleInput = wrapper.find('input[type="checkbox"]').element as HTMLInputElement;
|
|
9
9
|
|
|
10
10
|
expect(toggleInput.checked).toBeFalsy();
|
|
11
11
|
});
|
|
@@ -13,71 +13,58 @@ describe('ToggleSwitch.vue', () => {
|
|
|
13
13
|
it('renders a true value', () => {
|
|
14
14
|
const wrapper = shallowMount(
|
|
15
15
|
ToggleSwitch,
|
|
16
|
-
{
|
|
17
|
-
propsData: {
|
|
18
|
-
value: true
|
|
19
|
-
}
|
|
20
|
-
});
|
|
16
|
+
{ propsData: { value: true } });
|
|
21
17
|
|
|
22
|
-
const toggleInput = wrapper.find('input[type="checkbox"]').element as HTMLInputElement
|
|
18
|
+
const toggleInput = wrapper.find('input[type="checkbox"]').element as HTMLInputElement;
|
|
23
19
|
|
|
24
20
|
expect(toggleInput.checked).toBe(true);
|
|
25
21
|
});
|
|
26
22
|
|
|
27
|
-
it('updates from falsy to truthy when props change', async
|
|
23
|
+
it('updates from falsy to truthy when props change', async() => {
|
|
28
24
|
const wrapper = shallowMount(ToggleSwitch);
|
|
29
|
-
|
|
30
|
-
const toggleInput = wrapper.find('input[type="checkbox"]').element as HTMLInputElement
|
|
25
|
+
|
|
26
|
+
const toggleInput = wrapper.find('input[type="checkbox"]').element as HTMLInputElement;
|
|
31
27
|
|
|
32
28
|
expect(toggleInput.checked).toBe(false);
|
|
33
29
|
|
|
34
30
|
await wrapper.setProps({ value: true });
|
|
35
|
-
|
|
31
|
+
|
|
36
32
|
expect(toggleInput.checked).toBe(true);
|
|
37
33
|
});
|
|
38
34
|
|
|
39
|
-
it('emits an input event with a true value', async
|
|
40
|
-
const wrapper = shallowMount(ToggleSwitch);
|
|
35
|
+
it('emits an input event with a true value', async() => {
|
|
36
|
+
const wrapper: Wrapper<InstanceType<typeof ToggleSwitch>> = shallowMount(ToggleSwitch);
|
|
41
37
|
|
|
42
|
-
|
|
38
|
+
wrapper.vm.toggle(true);
|
|
43
39
|
|
|
44
40
|
await wrapper.vm.$nextTick();
|
|
45
41
|
|
|
46
42
|
expect(wrapper.emitted().input?.length).toBe(1);
|
|
47
43
|
expect(wrapper.emitted().input?.[0][0]).toBe(true);
|
|
48
|
-
|
|
49
44
|
});
|
|
50
45
|
|
|
51
|
-
it('emits an input event with a false value', async
|
|
52
|
-
const wrapper = shallowMount(
|
|
46
|
+
it('emits an input event with a false value', async() => {
|
|
47
|
+
const wrapper: Wrapper<InstanceType<typeof ToggleSwitch>> = shallowMount(
|
|
53
48
|
ToggleSwitch,
|
|
54
|
-
{
|
|
55
|
-
propsData: {
|
|
56
|
-
value: true
|
|
57
|
-
}
|
|
58
|
-
}
|
|
49
|
+
{ propsData: { value: true } }
|
|
59
50
|
);
|
|
60
51
|
|
|
61
|
-
|
|
52
|
+
wrapper.vm.toggle(false);
|
|
62
53
|
|
|
63
54
|
await wrapper.vm.$nextTick();
|
|
64
55
|
|
|
65
56
|
expect(wrapper.emitted().input?.length).toBe(1);
|
|
66
57
|
expect(wrapper.emitted().input?.[0][0]).toBe(false);
|
|
67
|
-
})
|
|
58
|
+
});
|
|
68
59
|
|
|
69
|
-
it('emits an input event with a custom onValue', async
|
|
60
|
+
it('emits an input event with a custom onValue', async() => {
|
|
70
61
|
const onValue = 'THE TRUTH';
|
|
71
62
|
|
|
72
|
-
const wrapper = shallowMount(
|
|
63
|
+
const wrapper: Wrapper<InstanceType<typeof ToggleSwitch>> = shallowMount(
|
|
73
64
|
ToggleSwitch,
|
|
74
|
-
{
|
|
75
|
-
propsData: {
|
|
76
|
-
onValue,
|
|
77
|
-
}
|
|
78
|
-
});
|
|
65
|
+
{ propsData: { onValue } });
|
|
79
66
|
|
|
80
|
-
|
|
67
|
+
wrapper.vm.toggle(true);
|
|
81
68
|
|
|
82
69
|
await wrapper.vm.$nextTick();
|
|
83
70
|
|
|
@@ -85,10 +72,10 @@ describe('ToggleSwitch.vue', () => {
|
|
|
85
72
|
expect(wrapper.emitted().input?.[0][0]).toBe(onValue);
|
|
86
73
|
});
|
|
87
74
|
|
|
88
|
-
it('emits an input event with a custom offValue', async
|
|
75
|
+
it('emits an input event with a custom offValue', async() => {
|
|
89
76
|
const offValue = 'NOT THE TRUTH';
|
|
90
77
|
|
|
91
|
-
const wrapper = shallowMount(
|
|
78
|
+
const wrapper: Wrapper<InstanceType<typeof ToggleSwitch>> = shallowMount(
|
|
92
79
|
ToggleSwitch,
|
|
93
80
|
{
|
|
94
81
|
propsData: {
|
|
@@ -97,11 +84,11 @@ describe('ToggleSwitch.vue', () => {
|
|
|
97
84
|
}
|
|
98
85
|
});
|
|
99
86
|
|
|
100
|
-
|
|
87
|
+
wrapper.vm.toggle(false);
|
|
101
88
|
|
|
102
89
|
await wrapper.vm.$nextTick();
|
|
103
90
|
|
|
104
91
|
expect(wrapper.emitted().input?.length).toBe(1);
|
|
105
92
|
expect(wrapper.emitted().input?.[0][0]).toBe(offValue);
|
|
106
|
-
})
|
|
93
|
+
});
|
|
107
94
|
});
|