@rancher/shell 2.0.0 → 2.0.2-rc.1

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 (154) hide show
  1. package/assets/translations/en-us.yaml +69 -29
  2. package/assets/translations/zh-hans.yaml +1 -0
  3. package/components/AlertTable.vue +17 -7
  4. package/components/AssignTo.vue +2 -0
  5. package/components/GrafanaDashboard.vue +6 -4
  6. package/components/PromptRemove.vue +1 -0
  7. package/components/Questions/index.vue +2 -2
  8. package/components/auth/RoleDetailEdit.vue +5 -4
  9. package/components/form/KeyValue.vue +1 -0
  10. package/components/form/Members/ClusterPermissionsEditor.vue +1 -1
  11. package/components/form/ProjectMemberEditor.vue +1 -1
  12. package/components/form/ResourceLabeledSelect.vue +11 -3
  13. package/components/form/Taints.vue +13 -7
  14. package/components/form/__tests__/Taints.test.ts +70 -0
  15. package/components/form/labeled-select-utils/labeled-select.utils.ts +1 -1
  16. package/components/nav/Header.vue +1 -1
  17. package/components/nav/TopLevelMenu.vue +1 -4
  18. package/config/pagination-table-headers.js +5 -4
  19. package/config/product/auth.js +1 -1
  20. package/config/roles.ts +34 -19
  21. package/config/router/navigation-guards/attempt-first-login.js +1 -1
  22. package/config/router/navigation-guards/authentication.js +1 -1
  23. package/config/router/navigation-guards/i18n.js +13 -0
  24. package/config/router/navigation-guards/index.js +3 -1
  25. package/config/router/navigation-guards/load-initial-settings.js +1 -1
  26. package/config/router/navigation-guards/runtime-extension-route.js +31 -0
  27. package/config/router/routes.js +10 -1
  28. package/config/uiplugins.js +130 -61
  29. package/core/plugin.ts +5 -0
  30. package/core/plugins.js +7 -1
  31. package/detail/__tests__/provisioning.cattle.io.cluster.test.ts +42 -0
  32. package/detail/provisioning.cattle.io.cluster.vue +4 -4
  33. package/dialog/DeactivateDriverDialog.vue +30 -11
  34. package/edit/auth/__tests__/oidc.test.ts +2 -2
  35. package/edit/provisioning.cattle.io.cluster/__tests__/Basics.test.ts +86 -13
  36. package/edit/provisioning.cattle.io.cluster/__tests__/DirectoryConfig.test.ts +3 -134
  37. package/edit/provisioning.cattle.io.cluster/__tests__/rke2.test.ts +209 -0
  38. package/edit/provisioning.cattle.io.cluster/index.vue +8 -4
  39. package/edit/provisioning.cattle.io.cluster/rke2.vue +115 -17
  40. package/edit/provisioning.cattle.io.cluster/tabs/AddOnAdditionalManifest.vue +50 -0
  41. package/edit/provisioning.cattle.io.cluster/tabs/AddOnConfig.vue +29 -64
  42. package/edit/provisioning.cattle.io.cluster/tabs/Basics.vue +42 -3
  43. package/edit/provisioning.cattle.io.cluster/tabs/DirectoryConfig.vue +22 -86
  44. package/edit/provisioning.cattle.io.cluster/tabs/registries/RegistryConfigs.vue +8 -2
  45. package/edit/provisioning.cattle.io.cluster/tabs/registries/__tests__/RegistryConfigs.test.ts +61 -0
  46. package/edit/token.vue +2 -1
  47. package/initialize/entry-helpers.js +4 -24
  48. package/list/management.cattle.io.feature.vue +4 -2
  49. package/middleware/authenticated.js +0 -19
  50. package/mixins/__tests__/chart.test.ts +4 -1
  51. package/mixins/auth-config.js +1 -1
  52. package/mixins/chart.js +30 -14
  53. package/models/__tests__/apps.deployment.test.ts +93 -0
  54. package/models/apps.deployment.js +18 -4
  55. package/models/driver.js +3 -2
  56. package/models/kontainerdriver.js +30 -13
  57. package/models/management.cattle.io.authconfig.js +2 -2
  58. package/models/management.cattle.io.cluster.js +2 -2
  59. package/models/management.cattle.io.user.js +3 -3
  60. package/models/nodedriver.js +35 -13
  61. package/models/provisioning.cattle.io.cluster.js +4 -0
  62. package/package.json +3 -2
  63. package/pages/404.vue +15 -0
  64. package/pages/auth/login.vue +4 -1
  65. package/pages/auth/setup.vue +4 -1
  66. package/pages/c/_cluster/apps/charts/install.vue +3 -2
  67. package/pages/c/_cluster/explorer/index.vue +5 -0
  68. package/pages/c/_cluster/manager/drivers/kontainerDriver/index.vue +0 -3
  69. package/pages/c/_cluster/manager/drivers/nodeDriver/index.vue +1 -4
  70. package/pages/c/_cluster/manager/jwt.authentication/index.vue +10 -4
  71. package/pages/c/_cluster/settings/performance.vue +2 -2
  72. package/pages/c/_cluster/uiplugins/InstallDialog.vue +2 -1
  73. package/pages/c/_cluster/uiplugins/PluginInfoPanel.vue +7 -10
  74. package/pages/c/_cluster/uiplugins/index.vue +24 -16
  75. package/pages/home.vue +1 -13
  76. package/plugins/dashboard-store/actions.js +1 -1
  77. package/plugins/dashboard-store/getters.js +1 -1
  78. package/plugins/steve/__tests__/getters.test.ts +5 -5
  79. package/plugins/steve/getters.js +6 -4
  80. package/plugins/steve/hybrid-class.js +1 -5
  81. package/promptRemove/pod.vue +15 -7
  82. package/scripts/extension/helm/charts/ui-plugin-server/Chart.yaml +1 -1
  83. package/scripts/publish-shell.sh +54 -55
  84. package/scripts/test-plugins-build.sh +45 -39
  85. package/shell/types/shell/index.d.ts +2 -0
  86. package/store/auth.js +1 -1
  87. package/store/index.js +1 -1
  88. package/store/type-map.js +4 -2
  89. package/types/store/pagination.types.ts +1 -1
  90. package/utils/__tests__/kontainer.test.ts +89 -1
  91. package/utils/auth.js +1 -1
  92. package/utils/cluster.js +9 -0
  93. package/utils/kontainer.ts +5 -1
  94. package/utils/settings.ts +3 -1
  95. package/utils/version.js +2 -1
  96. package/creators/app/app.package.json +0 -13
  97. package/creators/app/files/.eslintignore +0 -16
  98. package/creators/app/files/.eslintrc.js +0 -173
  99. package/creators/app/files/.gitignore +0 -70
  100. package/creators/app/files/.gitlab-ci.yml +0 -14
  101. package/creators/app/files/.vscode/settings.json +0 -21
  102. package/creators/app/files/babel.config.js +0 -1
  103. package/creators/app/files/tsconfig.json +0 -42
  104. package/creators/app/files/vue.config.js +0 -6
  105. package/creators/app/init +0 -120
  106. package/creators/app/package.json +0 -25
  107. package/creators/pkg/files/.github/workflows/build-extension-catalog.yml +0 -24
  108. package/creators/pkg/files/.github/workflows/build-extension-charts.yml +0 -22
  109. package/creators/pkg/files/babel.config.js +0 -1
  110. package/creators/pkg/files/index.ts +0 -14
  111. package/creators/pkg/files/tsconfig.json +0 -53
  112. package/creators/pkg/files/vue.config.js +0 -1
  113. package/creators/pkg/init +0 -286
  114. package/creators/pkg/package.json +0 -19
  115. package/creators/pkg/pkg.package.json +0 -21
  116. package/creators/pkg/vue-shim.ts +0 -4
  117. package/creators/update/init +0 -56
  118. package/creators/update/package.json +0 -20
  119. package/creators/update/upgrade +0 -56
  120. package/rancher-components/components/Accordion/Accordion.test.ts +0 -45
  121. package/rancher-components/components/Accordion/Accordion.vue +0 -86
  122. package/rancher-components/components/Accordion/index.ts +0 -1
  123. package/rancher-components/components/BadgeState/BadgeState.test.ts +0 -12
  124. package/rancher-components/components/BadgeState/BadgeState.vue +0 -111
  125. package/rancher-components/components/BadgeState/index.ts +0 -1
  126. package/rancher-components/components/Banner/Banner.test.ts +0 -59
  127. package/rancher-components/components/Banner/Banner.vue +0 -244
  128. package/rancher-components/components/Banner/index.ts +0 -1
  129. package/rancher-components/components/Card/Card.test.ts +0 -37
  130. package/rancher-components/components/Card/Card.vue +0 -167
  131. package/rancher-components/components/Card/index.ts +0 -1
  132. package/rancher-components/components/Form/Checkbox/Checkbox.test.ts +0 -68
  133. package/rancher-components/components/Form/Checkbox/Checkbox.vue +0 -421
  134. package/rancher-components/components/Form/Checkbox/index.ts +0 -1
  135. package/rancher-components/components/Form/LabeledInput/LabeledInput.test.ts +0 -40
  136. package/rancher-components/components/Form/LabeledInput/LabeledInput.vue +0 -402
  137. package/rancher-components/components/Form/LabeledInput/index.ts +0 -1
  138. package/rancher-components/components/Form/Radio/RadioButton.test.ts +0 -33
  139. package/rancher-components/components/Form/Radio/RadioButton.vue +0 -293
  140. package/rancher-components/components/Form/Radio/RadioGroup.test.ts +0 -30
  141. package/rancher-components/components/Form/Radio/RadioGroup.vue +0 -259
  142. package/rancher-components/components/Form/Radio/index.ts +0 -2
  143. package/rancher-components/components/Form/TextArea/TextAreaAutoGrow.vue +0 -172
  144. package/rancher-components/components/Form/TextArea/index.ts +0 -1
  145. package/rancher-components/components/Form/ToggleSwitch/ToggleSwitch.test.ts +0 -94
  146. package/rancher-components/components/Form/ToggleSwitch/ToggleSwitch.vue +0 -152
  147. package/rancher-components/components/Form/ToggleSwitch/index.ts +0 -1
  148. package/rancher-components/components/Form/index.ts +0 -5
  149. package/rancher-components/components/LabeledTooltip/LabeledTooltip.vue +0 -156
  150. package/rancher-components/components/LabeledTooltip/index.ts +0 -1
  151. package/rancher-components/components/StringList/StringList.test.ts +0 -754
  152. package/rancher-components/components/StringList/StringList.vue +0 -650
  153. package/rancher-components/components/StringList/index.ts +0 -1
  154. package/types/shell/index.d.ts +0 -4585
@@ -1,30 +0,0 @@
1
- import { mount } from '@vue/test-utils';
2
- import { RadioGroup } from './index';
3
-
4
- describe('component: RadioGroup', () => {
5
- describe('when disabled', () => {
6
- it.each([true, false])('should expose disabled slot prop for indexed slots for %p', (disabled) => {
7
- const wrapper = mount(RadioGroup, {
8
- propsData: {
9
- name: 'whatever',
10
- options: [{ label: 'whatever', value: 'whatever' }],
11
- disabled
12
- },
13
- scopedSlots: {
14
- 0(props: {isDisabled: boolean}) {
15
- return this.$createElement('input', {
16
- attrs: {
17
- id: 'test',
18
- disabled: props.isDisabled
19
- }
20
- });
21
- }
22
- }
23
- });
24
-
25
- const slot = wrapper.find('#test').element as HTMLInputElement;
26
-
27
- expect(slot.disabled).toBe(disabled);
28
- });
29
- });
30
- });
@@ -1,259 +0,0 @@
1
- <script lang="ts">
2
- import { PropType, defineComponent } from 'vue';
3
- import { _VIEW } from '@shell/config/query-params';
4
- import RadioButton from '@components/Form/Radio/RadioButton.vue';
5
-
6
- interface Option {
7
- value: unknown,
8
- label: string,
9
- description?: string,
10
- }
11
-
12
- export default defineComponent({
13
- components: { RadioButton },
14
- props: {
15
- /**
16
- * Name for the checkbox grouping, must be unique on page.
17
- */
18
- name: {
19
- type: String,
20
- required: true
21
- },
22
-
23
- /**
24
- * Options can be an array of {label, value}, or just values.
25
- */
26
- options: {
27
- type: Array as PropType<Option[] | string[]>,
28
- required: true
29
- },
30
-
31
- /**
32
- * If options are just values, then labels can be a corresponding display
33
- * value.
34
- */
35
- labels: {
36
- type: Array as PropType<string[]>,
37
- default: null
38
- },
39
-
40
- /**
41
- * The selected value.
42
- */
43
- value: {
44
- type: [Boolean, String, Object],
45
- default: null
46
- },
47
-
48
- /**
49
- * Disable the radio group.
50
- */
51
- disabled: {
52
- type: Boolean,
53
- default: false
54
- },
55
-
56
- /**
57
- * The radio group editing mode.
58
- * @values _EDIT, _VIEW
59
- */
60
- mode: {
61
- type: String,
62
- default: 'edit'
63
- },
64
-
65
- /**
66
- * Label for above the radios.
67
- */
68
- label: {
69
- type: String,
70
- default: null
71
- },
72
-
73
- /**
74
- * The i18n key to use for the radio group label.
75
- */
76
- labelKey: {
77
- type: String,
78
- default: null
79
- },
80
-
81
- /**
82
- * Radio group tooltip.
83
- */
84
- tooltip: {
85
- type: [String, Object],
86
- default: null
87
- },
88
-
89
- /**
90
- * The i18n key to use for the radio group tooltip.
91
- */
92
- tooltipKey: {
93
- type: String,
94
- default: null
95
- },
96
-
97
- /**
98
- * Show radio buttons in column or row.
99
- */
100
- row: {
101
- type: Boolean,
102
- default: false
103
- }
104
- },
105
-
106
- computed: {
107
- /**
108
- * Creates a collection of Options from the provided props.
109
- */
110
- normalizedOptions(): Option[] {
111
- const out: Option[] = [];
112
-
113
- for (let i = 0; i < this.options.length; i++) {
114
- const opt = this.options[i];
115
-
116
- if (typeof opt === 'object' && opt) {
117
- out.push(opt);
118
- } else if (this.labels) {
119
- out.push({
120
- label: this.labels[i],
121
- value: opt
122
- });
123
- } else {
124
- out.push({
125
- label: opt,
126
- value: opt
127
- });
128
- }
129
- }
130
-
131
- return out;
132
- },
133
-
134
- /**
135
- * Determines the view mode for the radio group.
136
- */
137
- isView(): boolean {
138
- return this.mode === _VIEW;
139
- },
140
-
141
- /**
142
- * Determines if the radio group is disabled.
143
- */
144
- isDisabled(): boolean {
145
- return (this.disabled || this.isView);
146
- }
147
- },
148
-
149
- methods: {
150
- /**
151
- * Keyboard left/right event listener to select next/previous option. Emits
152
- * the input event.
153
- */
154
- clickNext(direction: number): void {
155
- const opts = this.normalizedOptions;
156
- const selected = opts.find((x) => x.value === this.value);
157
- let newIndex = (selected ? opts.indexOf(selected) : -1) + direction;
158
-
159
- if (newIndex >= opts.length) {
160
- newIndex = opts.length - 1;
161
- } else if (newIndex < 0) {
162
- newIndex = 0;
163
- }
164
-
165
- this.$emit('input', opts[newIndex].value);
166
- }
167
- }
168
- });
169
- </script>
170
-
171
- <template>
172
- <div>
173
- <!-- Label -->
174
- <div
175
- v-if="label || labelKey || tooltip || tooltipKey || $slots.label"
176
- class="radio-group label"
177
- >
178
- <slot name="label">
179
- <h3>
180
- <t
181
- v-if="labelKey"
182
- :k="labelKey"
183
- />
184
- <template v-else-if="label">
185
- {{ label }}
186
- </template>
187
- <i
188
- v-if="tooltipKey"
189
- v-clean-tooltip="t(tooltipKey)"
190
- class="icon icon-info icon-lg"
191
- />
192
- <i
193
- v-else-if="tooltip"
194
- v-clean-tooltip="tooltip"
195
- class="icon icon-info icon-lg"
196
- />
197
- </h3>
198
- </slot>
199
- </div>
200
-
201
- <!-- Group -->
202
- <div
203
- class="radio-group"
204
- :class="{'row':row}"
205
- tabindex="0"
206
- @keyup.down.stop="clickNext(1)"
207
- @keyup.up.stop="clickNext(-1)"
208
- >
209
- <div
210
- v-for="(option, i) in normalizedOptions"
211
- :key="name+'-'+i"
212
- >
213
- <slot
214
- :listeners="$listeners"
215
- :option="option"
216
- :is-disabled="isDisabled"
217
- :name="i"
218
- >
219
- <!-- Default input -->
220
- <RadioButton
221
- :key="name+'-'+i"
222
- :name="name"
223
- :value="value"
224
- :label="option.label"
225
- :description="option.description"
226
- :val="option.value"
227
- :disabled="isDisabled"
228
- :mode="mode"
229
- v-on="$listeners"
230
- />
231
- </slot>
232
- </div>
233
- </div>
234
- </div>
235
- </template>
236
-
237
- <style lang='scss'>
238
- .radio-group {
239
- &:focus {
240
- border:none;
241
- outline:none;
242
- }
243
-
244
- h3 {
245
- position: relative;
246
- }
247
-
248
- &.row {
249
- display: flex;
250
- .radio-container {
251
- margin-right: 10px;
252
- }
253
- }
254
-
255
- .label{
256
- font-size: 14px !important;
257
- }
258
- }
259
- </style>
@@ -1,2 +0,0 @@
1
- export { default as RadioButton } from './RadioButton.vue';
2
- export { default as RadioGroup } from './RadioGroup.vue';
@@ -1,172 +0,0 @@
1
- <script lang="ts">
2
- import { defineComponent } from 'vue';
3
- import debounce from 'lodash/debounce';
4
- import { _EDIT, _VIEW } from '@shell/config/query-params';
5
-
6
- declare module 'vue/types/vue' {
7
- /* eslint-disable no-unused-vars */
8
- interface Vue {
9
- queueResize(): void;
10
- }
11
- }
12
-
13
- export default defineComponent({
14
- inheritAttrs: false,
15
-
16
- props: {
17
- /**
18
- * Sets the edit mode for Text Area.
19
- * @values _EDIT, _VIEW
20
- */
21
- mode: {
22
- type: String,
23
- default: _EDIT
24
- },
25
-
26
- /**
27
- * Sets the Minimum height for Text Area. Prevents the height from becoming
28
- * smaller than the value specified in minHeight.
29
- */
30
- minHeight: {
31
- type: Number,
32
- default: 25
33
- },
34
-
35
- /**
36
- * Sets the maximum height for Text Area. Prevents the height from becoming
37
- * larger than the value specified in maxHeight.
38
- */
39
- maxHeight: {
40
- type: Number,
41
- default: 200
42
- },
43
-
44
- /**
45
- * Text that appears in the Text Area when it has no value set.
46
- */
47
- placeholder: {
48
- type: String,
49
- default: ''
50
- },
51
-
52
- /**
53
- * Specifies whether Text Area is subject to spell checking by the
54
- * underlying browser/OS.
55
- */
56
- spellcheck: {
57
- type: Boolean,
58
- default: true
59
- },
60
-
61
- /**
62
- * Disables the Text Area.
63
- */
64
- disabled: {
65
- type: Boolean,
66
- default: false
67
- }
68
- },
69
-
70
- data() {
71
- return {
72
- curHeight: this.minHeight,
73
- overflow: 'hidden'
74
- };
75
- },
76
-
77
- computed: {
78
- /**
79
- * Determines if the Text Area should be disabled.
80
- */
81
- isDisabled(): boolean {
82
- return this.disabled || this.mode === _VIEW;
83
- },
84
-
85
- /**
86
- * Sets the height to one-line for SSR pageload so that it's already right
87
- * (unless the input is long)
88
- */
89
- style(): string {
90
- return `height: ${ this.curHeight }px; overflow: ${ this.overflow };`;
91
- }
92
- },
93
-
94
- watch: {
95
- $attrs: {
96
- deep: true,
97
- handler() {
98
- this.queueResize();
99
- }
100
- }
101
- },
102
-
103
- created() {
104
- this.queueResize = debounce(this.autoSize, 100);
105
- },
106
-
107
- mounted() {
108
- (this.$refs.ta as HTMLElement).style.height = `${ this.curHeight }px`;
109
- this.$nextTick(() => {
110
- this.autoSize();
111
- });
112
- },
113
-
114
- methods: {
115
- /**
116
- * Emits the input event and resizes the Text Area.
117
- */
118
- onInput(event: Event): void {
119
- const val = (event?.target as HTMLInputElement)?.value;
120
-
121
- this.$emit('input', val);
122
- this.queueResize();
123
- },
124
-
125
- /**
126
- * Gives focus to the Text Area.
127
- */
128
- focus(): void {
129
- (this.$refs?.ta as HTMLElement).focus();
130
- },
131
-
132
- /**
133
- * Sets the overflowY and height of the Text Area based on the content
134
- * entered (calculated via scroll height).
135
- */
136
- autoSize(): void {
137
- const el = this.$refs.ta as HTMLElement;
138
-
139
- if (!el) {
140
- return;
141
- }
142
-
143
- el.style.height = '1px';
144
-
145
- const border = parseInt(getComputedStyle(el).getPropertyValue('borderTopWidth'), 10) || 0 + parseInt(getComputedStyle(el).getPropertyValue('borderBottomWidth'), 10) || 0;
146
- const neu = Math.max(this.minHeight, Math.min(el.scrollHeight + border, this.maxHeight));
147
-
148
- el.style.overflowY = el.scrollHeight > neu ? 'auto' : 'hidden';
149
- el.style.height = `${ neu }px`;
150
-
151
- this.curHeight = neu;
152
- }
153
- }
154
- });
155
- </script>
156
-
157
- <template>
158
- <textarea
159
- ref="ta"
160
- :data-testid="$attrs['data-testid'] ? $attrs['data-testid'] : 'text-area-auto-grow'"
161
- :disabled="isDisabled"
162
- :style="style"
163
- :placeholder="placeholder"
164
- class="no-resize no-ease"
165
- v-bind="$attrs"
166
- :spellcheck="spellcheck"
167
- @paste="$emit('paste', $event)"
168
- @input="onInput($event)"
169
- @focus="$emit('focus', $event)"
170
- @blur="$emit('blur', $event)"
171
- />
172
- </template>
@@ -1 +0,0 @@
1
- export { default as TextAreaAutoGrow } from './TextAreaAutoGrow.vue';
@@ -1,94 +0,0 @@
1
- import { shallowMount, Wrapper } from '@vue/test-utils';
2
- import { ToggleSwitch } from './index';
3
-
4
- describe('toggleSwitch.vue', () => {
5
- it('renders falsy by default', () => {
6
- const wrapper = shallowMount(ToggleSwitch);
7
-
8
- const toggleInput = wrapper.find('input[type="checkbox"]').element as HTMLInputElement;
9
-
10
- expect(toggleInput.checked).toBeFalsy();
11
- });
12
-
13
- it('renders a true value', () => {
14
- const wrapper = shallowMount(
15
- ToggleSwitch,
16
- { propsData: { value: true } });
17
-
18
- const toggleInput = wrapper.find('input[type="checkbox"]').element as HTMLInputElement;
19
-
20
- expect(toggleInput.checked).toBe(true);
21
- });
22
-
23
- it('updates from falsy to truthy when props change', async() => {
24
- const wrapper = shallowMount(ToggleSwitch);
25
-
26
- const toggleInput = wrapper.find('input[type="checkbox"]').element as HTMLInputElement;
27
-
28
- expect(toggleInput.checked).toBe(false);
29
-
30
- await wrapper.setProps({ value: true });
31
-
32
- expect(toggleInput.checked).toBe(true);
33
- });
34
-
35
- it('emits an input event with a true value', async() => {
36
- const wrapper: Wrapper<InstanceType<typeof ToggleSwitch>> = shallowMount(ToggleSwitch);
37
-
38
- wrapper.vm.toggle(true);
39
-
40
- await wrapper.vm.$nextTick();
41
-
42
- expect(wrapper.emitted().input?.length).toBe(1);
43
- expect(wrapper.emitted().input?.[0][0]).toBe(true);
44
- });
45
-
46
- it('emits an input event with a false value', async() => {
47
- const wrapper: Wrapper<InstanceType<typeof ToggleSwitch>> = shallowMount(
48
- ToggleSwitch,
49
- { propsData: { value: true } }
50
- );
51
-
52
- wrapper.vm.toggle(false);
53
-
54
- await wrapper.vm.$nextTick();
55
-
56
- expect(wrapper.emitted().input?.length).toBe(1);
57
- expect(wrapper.emitted().input?.[0][0]).toBe(false);
58
- });
59
-
60
- it('emits an input event with a custom onValue', async() => {
61
- const onValue = 'THE TRUTH';
62
-
63
- const wrapper: Wrapper<InstanceType<typeof ToggleSwitch>> = shallowMount(
64
- ToggleSwitch,
65
- { propsData: { onValue } });
66
-
67
- wrapper.vm.toggle(true);
68
-
69
- await wrapper.vm.$nextTick();
70
-
71
- expect(wrapper.emitted().input?.length).toBe(1);
72
- expect(wrapper.emitted().input?.[0][0]).toBe(onValue);
73
- });
74
-
75
- it('emits an input event with a custom offValue', async() => {
76
- const offValue = 'NOT THE TRUTH';
77
-
78
- const wrapper: Wrapper<InstanceType<typeof ToggleSwitch>> = shallowMount(
79
- ToggleSwitch,
80
- {
81
- propsData: {
82
- value: true,
83
- offValue,
84
- }
85
- });
86
-
87
- wrapper.vm.toggle(false);
88
-
89
- await wrapper.vm.$nextTick();
90
-
91
- expect(wrapper.emitted().input?.length).toBe(1);
92
- expect(wrapper.emitted().input?.[0][0]).toBe(offValue);
93
- });
94
- });
@@ -1,152 +0,0 @@
1
- <script lang="ts">
2
- import { defineComponent } from 'vue';
3
-
4
- type StateType = boolean | 'true' | 'false' | undefined;
5
-
6
- export default defineComponent({
7
- props: {
8
- value: {
9
- type: [Boolean, String, Number],
10
- default: false
11
- },
12
-
13
- offValue: {
14
- type: [Boolean, String, Number],
15
- default: false,
16
- },
17
-
18
- onValue: {
19
- type: [Boolean, String, Number],
20
- default: true,
21
- },
22
-
23
- offLabel: {
24
- type: String,
25
- default: '',
26
- },
27
-
28
- onLabel: {
29
- type: String,
30
- default: '',
31
- },
32
- },
33
- data() {
34
- return { state: false as StateType };
35
- },
36
-
37
- watch: {
38
- value: {
39
- handler() {
40
- this.state = this.value === this.onValue;
41
- },
42
- immediate: true
43
- }
44
- },
45
-
46
- methods: {
47
- toggle(neu: StateType | null) {
48
- this.state = neu === null ? !this.state : neu;
49
- this.$emit('input', this.state ? this.onValue : this.offValue);
50
- }
51
- }
52
- });
53
- </script>
54
-
55
- <template>
56
- <span class="toggle-container">
57
- <span
58
- class="label no-select hand"
59
- :class="{ active: !state}"
60
- @click="toggle(false)"
61
- >{{ offLabel }}</span>
62
- <label class="switch hand">
63
- <input
64
- type="checkbox"
65
- :checked="state"
66
- @input="toggle(null)"
67
- >
68
- <span class="slider round" />
69
- </label>
70
- <span
71
- class="label no-select hand"
72
- :class="{ active: state}"
73
- @click="toggle(true)"
74
- >{{ onLabel }}</span>
75
- </span>
76
- </template>
77
-
78
- <style lang="scss" scoped>
79
- $toggle-height: 16px;
80
-
81
- .toggle-container {
82
- align-items: center;
83
- display: flex;
84
-
85
- span:first-child {
86
- padding-right: 6px;
87
- }
88
- span:last-child {
89
- padding-left: 6px;
90
- }
91
- }
92
- /* The switch - the box around the slider */
93
- .switch {
94
- position: relative;
95
- display: inline-block;
96
- width: 48px;
97
- height: $toggle-height + 8px;
98
- }
99
-
100
- /* Hide default HTML checkbox */
101
- .switch input {
102
- opacity: 0;
103
- width: 0;
104
- height: 0;
105
- }
106
-
107
- /* The slider */
108
- .slider {
109
- position: absolute;
110
- cursor: pointer;
111
- top: 0;
112
- left: 0;
113
- right: 0;
114
- bottom: 0;
115
- background-color: var(--checkbox-disabled-bg);
116
- -webkit-transition: .4s;
117
- transition: .4s;
118
- }
119
-
120
- .slider:before {
121
- position: absolute;
122
- content: "";
123
- height: $toggle-height;
124
- width: $toggle-height;
125
- left: 4px;
126
- bottom: 4px;
127
- background-color: var(--checkbox-tick);
128
- -webkit-transition: .4s;
129
- transition: .4s;
130
- }
131
-
132
- input:checked + .slider {
133
- background-color: var(--checkbox-ticked-bg);
134
- }
135
-
136
- input:focus + .slider {
137
- box-shadow: 0 0 1px var(--checkbox-ticked-bg);
138
- }
139
-
140
- input:checked + .slider:before {
141
- transform: translateX(24px);
142
- }
143
-
144
- /* Rounded sliders */
145
- .slider.round {
146
- border-radius: 34px;
147
- }
148
-
149
- .slider.round:before {
150
- border-radius: 50%;
151
- }
152
- </style>
@@ -1 +0,0 @@
1
- export { default as ToggleSwitch } from './ToggleSwitch.vue';