@rancher/shell 0.3.21 → 0.3.23

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.
Files changed (60) hide show
  1. package/assets/translations/en-us.yaml +4 -0
  2. package/assets/translations/zh-hans.yaml +8 -1
  3. package/babel.config.js +3 -0
  4. package/cloud-credential/__tests__/azure.test.ts +53 -0
  5. package/cloud-credential/azure.vue +6 -0
  6. package/components/GrowlManager.vue +33 -30
  7. package/components/SortableTable/paging.js +10 -0
  8. package/components/form/GitPicker.vue +16 -0
  9. package/components/form/ResourceQuota/ProjectRow.vue +38 -15
  10. package/components/form/SelectOrCreateAuthSecret.vue +9 -3
  11. package/components/formatter/ClusterProvider.vue +9 -3
  12. package/components/formatter/__tests__/ClusterProvider.test.ts +5 -1
  13. package/components/nav/Header.vue +1 -0
  14. package/config/settings.ts +59 -2
  15. package/config/types.js +2 -0
  16. package/creators/pkg/files/.github/workflows/build-extension-catalog.yml +28 -0
  17. package/creators/pkg/files/.github/workflows/build-extension-charts.yml +26 -0
  18. package/creators/pkg/init +63 -4
  19. package/detail/provisioning.cattle.io.cluster.vue +4 -2
  20. package/edit/fleet.cattle.io.gitrepo.vue +1 -0
  21. package/edit/provisioning.cattle.io.cluster/rke2.vue +4 -4
  22. package/edit/resources.cattle.io.backup.vue +3 -1
  23. package/edit/resources.cattle.io.restore.vue +3 -1
  24. package/mixins/__tests__/chart.test.ts +40 -0
  25. package/mixins/chart.js +5 -0
  26. package/models/catalog.cattle.io.clusterrepo.js +6 -2
  27. package/models/fleet.cattle.io.cluster.js +10 -2
  28. package/package.json +1 -1
  29. package/pages/c/_cluster/gatekeeper/index.vue +10 -1
  30. package/plugins/steve/__tests__/header-warnings.spec.ts +238 -0
  31. package/plugins/steve/actions.js +4 -23
  32. package/plugins/steve/header-warnings.ts +91 -0
  33. package/promptRemove/management.cattle.io.project.vue +9 -6
  34. package/rancher-components/BadgeState/BadgeState.vue +1 -5
  35. package/rancher-components/Banner/Banner.test.ts +1 -51
  36. package/rancher-components/Banner/Banner.vue +53 -134
  37. package/rancher-components/Card/Card.vue +7 -24
  38. package/rancher-components/Form/Checkbox/Checkbox.test.ts +29 -20
  39. package/rancher-components/Form/Checkbox/Checkbox.vue +20 -45
  40. package/rancher-components/Form/LabeledInput/LabeledInput.test.ts +8 -2
  41. package/rancher-components/Form/LabeledInput/LabeledInput.vue +10 -22
  42. package/rancher-components/Form/Radio/RadioButton.vue +13 -30
  43. package/rancher-components/Form/Radio/RadioGroup.vue +7 -26
  44. package/rancher-components/Form/TextArea/TextAreaAutoGrow.vue +6 -7
  45. package/rancher-components/Form/ToggleSwitch/ToggleSwitch.test.ts +38 -25
  46. package/rancher-components/Form/ToggleSwitch/ToggleSwitch.vue +11 -23
  47. package/rancher-components/LabeledTooltip/LabeledTooltip.vue +5 -19
  48. package/rancher-components/StringList/StringList.test.ts +49 -453
  49. package/rancher-components/StringList/StringList.vue +58 -92
  50. package/scripts/extension/parse-tag-name +30 -0
  51. package/types/shell/index.d.ts +16 -9
  52. package/utils/__tests__/formatter.test.ts +77 -0
  53. package/utils/formatter.js +11 -0
  54. package/utils/settings.ts +2 -17
  55. package/vue-config-helper.js +135 -0
  56. package/vue.config.js +29 -141
  57. package/creators/pkg/files/.github/workflows/build-container.yml +0 -64
  58. package/creators/pkg/files/.github/workflows/build-extension.yml +0 -110
  59. package/rancher-components/Card/Card.test.ts +0 -37
  60. package/rancher-components/Form/Radio/RadioButton.test.ts +0 -31
@@ -2,11 +2,8 @@
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';
6
5
 
7
6
  export default Vue.extend({
8
- name: 'Checkbox',
9
-
10
7
  props: {
11
8
  /**
12
9
  * The checkbox value.
@@ -49,8 +46,8 @@ export default Vue.extend({
49
46
  },
50
47
 
51
48
  /**
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
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
54
51
  * children are checked.
55
52
  */
56
53
  indeterminate: {
@@ -113,22 +110,22 @@ export default Vue.extend({
113
110
  primary: {
114
111
  type: Boolean,
115
112
  default: false
116
- },
113
+ },
117
114
  },
118
115
 
119
116
  computed: {
120
117
  /**
121
118
  * Determines if the checkbox is disabled.
122
- * @returns boolean: True when the disabled prop is true or when mode is
119
+ * @returns boolean: True when the disabled prop is true or when mode is
123
120
  * View.
124
121
  */
125
122
  isDisabled(): boolean {
126
123
  return (this.disabled || this.mode === _VIEW);
127
124
  },
128
125
  /**
129
- * Determines if the checkbox is checked when using custom values or
126
+ * Determines if the checkbox is checked when using custom values or
130
127
  * multiple values.
131
- * @returns boolean: True when at least one value is true in a collection or
128
+ * @returns boolean: True when at least one value is true in a collection or
132
129
  * when value matches `this.valueWhenTrue`.
133
130
  */
134
131
  isChecked(): boolean {
@@ -165,15 +162,13 @@ export default Vue.extend({
165
162
  const click = new CustomEvent('click', customEvent);
166
163
 
167
164
  // Flip the value
168
- const value = cloneDeep(this.value);
169
-
170
- if (this.isMulti(value)) {
165
+ if (this.isMulti(this.value)) {
171
166
  if (this.isChecked) {
172
- removeObject(value, this.valueWhenTrue);
167
+ removeObject(this.value, this.valueWhenTrue);
173
168
  } else {
174
- addObject(value, this.valueWhenTrue);
169
+ addObject(this.value, this.valueWhenTrue);
175
170
  }
176
- this.$emit('input', value);
171
+ this.$emit('input', this.value);
177
172
  } else if (this.isString(this.valueWhenTrue)) {
178
173
  if (this.isChecked) {
179
174
  this.$emit('input', null);
@@ -181,7 +176,7 @@ export default Vue.extend({
181
176
  this.$emit('input', this.valueWhenTrue);
182
177
  }
183
178
  } else {
184
- this.$emit('input', !value);
179
+ this.$emit('input', !this.value);
185
180
  this.$el.dispatchEvent(click);
186
181
  }
187
182
  },
@@ -202,17 +197,14 @@ export default Vue.extend({
202
197
  * @param value A collection of values for the checkbox.
203
198
  */
204
199
  findTrueValues(value: boolean[]): boolean {
205
- return value.find((v) => v === this.valueWhenTrue) || false;
200
+ return value.find(v => v === this.valueWhenTrue) || false;
206
201
  }
207
202
  }
208
203
  });
209
204
  </script>
210
205
 
211
206
  <template>
212
- <div
213
- class="checkbox-outer-container"
214
- data-checkbox-ctrl
215
- >
207
+ <div class="checkbox-outer-container" data-checkbox-ctrl>
216
208
  <label
217
209
  class="checkbox-container"
218
210
  :class="{ 'disabled': isDisabled}"
@@ -222,13 +214,14 @@ export default Vue.extend({
222
214
  @click="clicked($event)"
223
215
  >
224
216
  <input
217
+ v-model="value"
225
218
  :checked="isChecked"
226
219
  :value="valueWhenTrue"
227
220
  type="checkbox"
228
221
  :tabindex="-1"
229
222
  :name="id"
230
223
  @click.stop.prevent
231
- >
224
+ />
232
225
  <span
233
226
  class="checkbox-custom"
234
227
  :class="{indeterminate: indeterminate}"
@@ -243,33 +236,15 @@ export default Vue.extend({
243
236
  :class="{ 'checkbox-primary': primary }"
244
237
  >
245
238
  <slot name="label">
246
- <t
247
- v-if="labelKey"
248
- :k="labelKey"
249
- :raw="true"
250
- />
239
+ <t v-if="labelKey" :k="labelKey" :raw="true" />
251
240
  <template v-else-if="label">{{ label }}</template>
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
- />
241
+ <i v-if="tooltipKey" v-tooltip="t(tooltipKey)" class="checkbox-info icon icon-info icon-lg" />
242
+ <i v-else-if="tooltip" v-tooltip="tooltip" class="checkbox-info icon icon-info icon-lg" />
262
243
  </slot>
263
244
  </span>
264
245
  </label>
265
- <div
266
- v-if="descriptionKey || description"
267
- class="checkbox-outer-container-description"
268
- >
269
- <t
270
- v-if="descriptionKey"
271
- :k="descriptionKey"
272
- />
246
+ <div v-if="descriptionKey || description" class="checkbox-outer-container-description">
247
+ <t v-if="descriptionKey" :k="descriptionKey" />
273
248
  <template v-else-if="description">
274
249
  {{ description }}
275
250
  </template>
@@ -6,9 +6,15 @@ 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: { $store: { getters: { 'i18n/t': jest.fn() } } }
11
+ mocks: {
12
+ $store: {
13
+ getters: {
14
+ 'i18n/t': jest.fn()
15
+ }
16
+ }
17
+ }
12
18
  });
13
19
 
14
20
  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,7 @@ export default (
207
207
  },
208
208
 
209
209
  /**
210
- * Emit on input with delay. Note: Arrow function is avoided due context
210
+ * Emit on input with delay. Note: Arrow function is avoided due context
211
211
  * binding.
212
212
  */
213
213
  delayInput(value: string): void {
@@ -223,7 +223,7 @@ export default (
223
223
  },
224
224
 
225
225
  /**
226
- * Handles the behavior of the Labeled Input when blurred and emits the blur
226
+ * Handles the behavior of the Labeled Input when blurred and emits the blur
227
227
  * event.
228
228
  * @see labeled-form-element.ts mixin for onBlurLabeled()
229
229
  */
@@ -253,16 +253,10 @@ export default (
253
253
  >
254
254
  <slot name="label">
255
255
  <label v-if="hasLabel">
256
- <t
257
- v-if="labelKey"
258
- :k="labelKey"
259
- />
256
+ <t v-if="labelKey" :k="labelKey" />
260
257
  <template v-else-if="label">{{ label }}</template>
261
258
 
262
- <span
263
- v-if="requiredField"
264
- class="required"
265
- >*</span>
259
+ <span v-if="requiredField" class="required">*</span>
266
260
  </label>
267
261
  </slot>
268
262
 
@@ -299,7 +293,7 @@ export default (
299
293
  @input="onInput($event.target.value)"
300
294
  @focus="onFocus"
301
295
  @blur="onBlur"
302
- >
296
+ />
303
297
  </slot>
304
298
 
305
299
  <slot name="suffix" />
@@ -314,14 +308,8 @@ export default (
314
308
  :hover="hoverTooltip"
315
309
  :value="validationMessage"
316
310
  />
317
- <label
318
- v-if="cronHint"
319
- class="cron-label"
320
- >{{ cronHint }}</label>
321
- <label
322
- v-if="subLabel"
323
- class="sub-label"
324
- >{{ subLabel }}</label>
311
+ <label v-if="cronHint" class="cron-label">{{ cronHint }}</label>
312
+ <label v-if="subLabel" class="sub-label">{{ subLabel }}</label>
325
313
  </div>
326
314
  </template>
327
315
  <style scoped lang="scss">
@@ -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: () => true
20
+ validator: x => true
21
21
  },
22
22
 
23
- /**
23
+ /**
24
24
  * The selected value.
25
- */
25
+ */
26
26
  value: {
27
27
  required: true,
28
- validator: () => true
28
+ validator: x => 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,10 +96,6 @@ 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
- }
103
99
  },
104
100
 
105
101
  watch: {
@@ -142,7 +138,7 @@ export default Vue.extend({
142
138
  type="radio"
143
139
  :tabindex="-1"
144
140
  @click.stop.prevent
145
- >
141
+ />
146
142
  <span
147
143
  ref="custom"
148
144
  :class="[ isDisabled ? 'text-muted' : '', 'radio-custom']"
@@ -153,28 +149,15 @@ export default Vue.extend({
153
149
  />
154
150
  <div class="labeling">
155
151
  <label
152
+ v-if="label"
156
153
  :class="[ muteLabel ? 'text-muted' : '', 'radio-label', 'm-0']"
157
154
  :for="name"
155
+ v-html="label"
158
156
  >
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
- />
157
+ <slot name="label">{{ label }}</slot>
169
158
  </label>
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
- />
159
+ <div v-if="descriptionKey || description" class="radio-button-outer-container-description">
160
+ <t v-if="descriptionKey" :k="descriptionKey" />
178
161
  <template v-else-if="description">
179
162
  {{ description }}
180
163
  </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,29 +169,15 @@ export default Vue.extend({
169
169
 
170
170
  <template>
171
171
  <div>
172
- <div
173
- v-if="label || labelKey || tooltip || tooltipKey || $slots.label"
174
- class="radio-group label"
175
- >
172
+ <div v-if="label || labelKey || tooltip || tooltipKey || $slots.label" class="radio-group label">
176
173
  <slot name="label">
177
174
  <h3>
178
- <t
179
- v-if="labelKey"
180
- :k="labelKey"
181
- />
175
+ <t v-if="labelKey" :k="labelKey" />
182
176
  <template v-else-if="label">
183
177
  {{ label }}
184
178
  </template>
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
- />
179
+ <i v-if="tooltipKey" v-tooltip="t(tooltipKey)" class="icon icon-info icon-lg" />
180
+ <i v-else-if="tooltip" v-tooltip="tooltip" class="icon icon-info icon-lg" />
195
181
  </h3>
196
182
  </slot>
197
183
  </div>
@@ -206,12 +192,7 @@ export default Vue.extend({
206
192
  v-for="(option, i) in normalizedOptions"
207
193
  :key="name+'-'+i"
208
194
  >
209
- <slot
210
- :listeners="$listeners"
211
- :option="option"
212
- :is-disabled="isDisabled"
213
- :name="i"
214
- >
195
+ <slot :listeners="$listeners" :option="option" :name="i">
215
196
  <RadioButton
216
197
  :key="name+'-'+i"
217
198
  :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,7 +155,6 @@ export default Vue.extend({
155
155
  <template>
156
156
  <textarea
157
157
  ref="ta"
158
- data-testid="text-area-auto-grow"
159
158
  :disabled="isDisabled"
160
159
  :style="style"
161
160
  :placeholder="placeholder"
@@ -1,11 +1,11 @@
1
- import { shallowMount, Wrapper } from '@vue/test-utils';
1
+ import { shallowMount } from '@vue/test-utils';
2
2
  import { ToggleSwitch } from './index';
3
3
 
4
- describe('toggleSwitch.vue', () => {
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,58 +13,71 @@ describe('toggleSwitch.vue', () => {
13
13
  it('renders a true value', () => {
14
14
  const wrapper = shallowMount(
15
15
  ToggleSwitch,
16
- { propsData: { value: true } });
16
+ {
17
+ propsData: {
18
+ value: true
19
+ }
20
+ });
17
21
 
18
- const toggleInput = wrapper.find('input[type="checkbox"]').element as HTMLInputElement;
22
+ const toggleInput = wrapper.find('input[type="checkbox"]').element as HTMLInputElement
19
23
 
20
24
  expect(toggleInput.checked).toBe(true);
21
25
  });
22
26
 
23
- it('updates from falsy to truthy when props change', async() => {
27
+ it('updates from falsy to truthy when props change', async () => {
24
28
  const wrapper = shallowMount(ToggleSwitch);
25
-
26
- const toggleInput = wrapper.find('input[type="checkbox"]').element as HTMLInputElement;
29
+
30
+ const toggleInput = wrapper.find('input[type="checkbox"]').element as HTMLInputElement
27
31
 
28
32
  expect(toggleInput.checked).toBe(false);
29
33
 
30
34
  await wrapper.setProps({ value: true });
31
-
35
+
32
36
  expect(toggleInput.checked).toBe(true);
33
37
  });
34
38
 
35
- it('emits an input event with a true value', async() => {
36
- const wrapper: Wrapper<InstanceType<typeof ToggleSwitch>> = shallowMount(ToggleSwitch);
39
+ it('emits an input event with a true value', async () => {
40
+ const wrapper = shallowMount(ToggleSwitch);
37
41
 
38
- wrapper.vm.toggle(true);
42
+ (wrapper.vm as any).toggle(true);
39
43
 
40
44
  await wrapper.vm.$nextTick();
41
45
 
42
46
  expect(wrapper.emitted().input?.length).toBe(1);
43
47
  expect(wrapper.emitted().input?.[0][0]).toBe(true);
48
+
44
49
  });
45
50
 
46
- it('emits an input event with a false value', async() => {
47
- const wrapper: Wrapper<InstanceType<typeof ToggleSwitch>> = shallowMount(
51
+ it('emits an input event with a false value', async () => {
52
+ const wrapper = shallowMount(
48
53
  ToggleSwitch,
49
- { propsData: { value: true } }
54
+ {
55
+ propsData: {
56
+ value: true
57
+ }
58
+ }
50
59
  );
51
60
 
52
- wrapper.vm.toggle(false);
61
+ (wrapper.vm as any).toggle(false);
53
62
 
54
63
  await wrapper.vm.$nextTick();
55
64
 
56
65
  expect(wrapper.emitted().input?.length).toBe(1);
57
66
  expect(wrapper.emitted().input?.[0][0]).toBe(false);
58
- });
67
+ })
59
68
 
60
- it('emits an input event with a custom onValue', async() => {
69
+ it('emits an input event with a custom onValue', async () => {
61
70
  const onValue = 'THE TRUTH';
62
71
 
63
- const wrapper: Wrapper<InstanceType<typeof ToggleSwitch>> = shallowMount(
72
+ const wrapper = shallowMount(
64
73
  ToggleSwitch,
65
- { propsData: { onValue } });
74
+ {
75
+ propsData: {
76
+ onValue,
77
+ }
78
+ });
66
79
 
67
- wrapper.vm.toggle(true);
80
+ (wrapper.vm as any).toggle(true);
68
81
 
69
82
  await wrapper.vm.$nextTick();
70
83
 
@@ -72,10 +85,10 @@ describe('toggleSwitch.vue', () => {
72
85
  expect(wrapper.emitted().input?.[0][0]).toBe(onValue);
73
86
  });
74
87
 
75
- it('emits an input event with a custom offValue', async() => {
88
+ it('emits an input event with a custom offValue', async () => {
76
89
  const offValue = 'NOT THE TRUTH';
77
90
 
78
- const wrapper: Wrapper<InstanceType<typeof ToggleSwitch>> = shallowMount(
91
+ const wrapper = shallowMount(
79
92
  ToggleSwitch,
80
93
  {
81
94
  propsData: {
@@ -84,11 +97,11 @@ describe('toggleSwitch.vue', () => {
84
97
  }
85
98
  });
86
99
 
87
- wrapper.vm.toggle(false);
100
+ (wrapper.vm as any).toggle(false);
88
101
 
89
102
  await wrapper.vm.$nextTick();
90
103
 
91
104
  expect(wrapper.emitted().input?.length).toBe(1);
92
105
  expect(wrapper.emitted().input?.[0][0]).toBe(offValue);
93
- });
106
+ })
94
107
  });
@@ -31,6 +31,13 @@ export default Vue.extend({
31
31
  return { state: false as boolean | string | number };
32
32
  },
33
33
 
34
+ methods: {
35
+ toggle(neu: boolean | string | number) {
36
+ this.state = neu === null ? !this.state : neu;
37
+ this.$emit('input', this.state ? this.onValue : this.offValue);
38
+ }
39
+ },
40
+
34
41
  watch: {
35
42
  value: {
36
43
  handler() {
@@ -38,37 +45,18 @@ export default Vue.extend({
38
45
  },
39
46
  immediate: true
40
47
  }
41
- },
42
-
43
- methods: {
44
- toggle(neu: boolean | string | number) {
45
- this.state = neu === null ? !this.state : neu;
46
- this.$emit('input', this.state ? this.onValue : this.offValue);
47
- }
48
48
  }
49
49
  });
50
50
  </script>
51
51
 
52
52
  <template>
53
53
  <span class="toggle-container">
54
- <span
55
- class="label no-select hand"
56
- :class="{ active: !state}"
57
- @click="toggle(false)"
58
- >{{ offLabel }}</span>
54
+ <span class="label no-select hand" :class="{ active: !state}" @click="toggle(false)">{{ offLabel }}</span>
59
55
  <label class="switch hand">
60
- <input
61
- type="checkbox"
62
- :checked="state"
63
- @input="toggle(null)"
64
- >
65
- <span class="slider round" />
56
+ <input type="checkbox" :checked="state" @input="toggle(null)">
57
+ <span class="slider round"></span>
66
58
  </label>
67
- <span
68
- class="label no-select hand"
69
- :class="{ active: state}"
70
- @click="toggle(true)"
71
- >{{ onLabel }}</span>
59
+ <span class="label no-select hand" :class="{ active: state}" @click="toggle(true)">{{ onLabel }}</span>
72
60
  </span>
73
61
  </template>
74
62