dashboard-shell-shell 1.0.111 → 1.0.113
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/.DS_Store +0 -0
- package/assets/icons/demo.css +539 -0
- package/assets/icons/demo_index.html +1131 -0
- package/assets/icons/iconfont.css +200 -0
- package/assets/icons/iconfont.js +1 -0
- package/assets/icons/iconfont.json +296 -0
- package/assets/icons/iconfont.ttf +0 -0
- package/assets/icons/iconfont.woff +0 -0
- package/assets/icons/iconfont.woff2 +0 -0
- package/assets/images/API.svg +3 -0
- package/assets/images/login/password.svg +20 -0
- package/assets/images/login/user.svg +6 -0
- package/assets/images/login-bg.png +0 -0
- package/assets/images/login-left.png +0 -0
- package/assets/images/login-logo.svg +19 -0
- package/assets/images/logo.png +0 -0
- package/assets/images/pl/harvester.png +0 -0
- package/assets/images/promp-yellow.svg +5 -0
- package/assets/images/user.png +0 -0
- package/assets/styles/all.scss +63 -0
- package/assets/styles/app.scss +2 -0
- package/assets/styles/base/_basic.scss +8 -2
- package/assets/styles/base/_helpers.scss +4 -0
- package/assets/styles/base/_typography.scss +2 -1
- package/assets/styles/base/_variables.scss +10 -2
- package/assets/styles/global/_button.scss +37 -25
- package/assets/styles/global/_columns.scss +3 -1
- package/assets/styles/global/_form.scss +45 -13
- package/assets/styles/global/_labeled-input.scss +50 -25
- package/assets/styles/global/_layout.scss +9 -3
- package/assets/styles/global/_select.scss +20 -13
- package/assets/styles/global/_table.scss +1 -1
- package/assets/styles/global/_tooltip.scss +47 -6
- package/assets/styles/themes/_dark.scss +1 -0
- package/assets/styles/themes/_light.scss +59 -46
- package/assets/styles/themes/_suse.scss +1 -0
- package/assets/styles/vendor/vue-select.scss +18 -7
- package/assets/translations/en-us.yaml +93 -12
- package/assets/translations/zh-hans.yaml +278 -141
- package/components/ActionDropdown.vue +1 -1
- package/components/ActionDropdownShell.vue +71 -0
- package/components/ActionMenu.vue +2 -2
- package/components/ActionMenuShell.vue +1 -0
- package/components/AppModal.vue +78 -6
- package/components/AssignTo.vue +25 -11
- package/components/AsyncButton.vue +24 -7
- package/components/BannerGraphic.vue +1 -0
- package/components/ButtonDropdown.vue +26 -4
- package/components/ButtonGroup.vue +4 -0
- package/components/ButtonMultiAction.vue +1 -0
- package/components/CommunityLinks.vue +3 -3
- package/components/ConsumptionGauge.vue +24 -5
- package/components/CopyToClipboardText.vue +2 -1
- package/components/CruResource.vue +12 -7
- package/components/CruResourceFooter.vue +2 -2
- package/components/DashboardOptions.vue +21 -15
- package/components/DetailText.vue +5 -0
- package/components/DisableAuthProviderModal.vue +1 -0
- package/components/DotState.vue +84 -0
- package/components/ExplorerMembers.vue +1 -1
- package/components/ExplorerProjectsNamespaces.vue +56 -14
- package/components/FixedBanner.vue +19 -12
- package/components/GlobalRoleBindings.vue +5 -1
- package/components/GrafanaDashboard.vue +4 -4
- package/components/GrowlManager.vue +4 -1
- package/components/HardwareResourceGauge.vue +39 -3
- package/components/InfoBox.vue +3 -3
- package/components/InputOrDisplay.vue +28 -2
- package/components/LabelValue.vue +16 -1
- package/components/LandingPagePreference.vue +5 -3
- package/components/LocaleSelector.vue +39 -93
- package/components/ModalManager.vue +55 -0
- package/components/ModalWithCard.vue +2 -0
- package/components/MoveModal.vue +1 -0
- package/components/PromptChangePassword.vue +1 -1
- package/components/PromptModal.vue +15 -2
- package/components/PromptRemove.vue +28 -8
- package/components/PromptRestore.vue +1 -0
- package/components/ResourceCancelModal.vue +1 -0
- package/components/ResourceDetail/Masthead.vue +188 -43
- package/components/ResourceDetail/__tests__/Masthead.test.ts +5 -1
- package/components/ResourceDetail/index.vue +49 -14
- package/components/ResourceList/Masthead.vue +80 -18
- package/components/ResourceTable.vue +60 -19
- package/components/SideNav.vue +32 -12
- package/components/SlideInPanelManager.vue +126 -0
- package/components/SortableTable/THead.vue +34 -5
- package/components/SortableTable/actions.js +1 -1
- package/components/SortableTable/index.vue +649 -142
- package/components/SortableTable/paging.js +36 -28
- package/components/SortableTable/selection.js +0 -11
- package/components/StatusBadge.vue +77 -0
- package/components/Tabbed/Tab.vue +3 -3
- package/components/Tabbed/index.vue +44 -26
- package/components/Wizard.vue +2 -2
- package/components/__tests__/AsyncButton.test.ts +2 -2
- package/components/__tests__/FixedBanner.test.ts +3 -3
- package/components/__tests__/ModalManager.spec.ts +176 -0
- package/components/__tests__/SlideInPanelManager.spec.ts +166 -0
- package/components/auth/Principal.vue +10 -3
- package/components/auth/__tests__/RoleDetailEdit.test.ts +3 -2
- package/components/form/ArrayList.vue +123 -85
- package/components/form/ArrayListGrouped.vue +10 -2
- package/components/form/Command.vue +6 -15
- package/components/form/EnvVars.vue +16 -8
- package/components/form/Footer.vue +8 -5
- package/components/form/HealthCheck.vue +3 -3
- package/components/form/HookOption.vue +11 -16
- package/components/form/KeyValue.vue +16 -7
- package/components/form/LabeledSelect.vue +59 -76
- package/components/form/LifecycleHooks.vue +3 -3
- package/components/form/MatchExpressions.vue +35 -12
- package/components/form/NameNsDescription.vue +147 -115
- package/components/form/Networking.vue +20 -12
- package/components/form/NodeAffinity.vue +31 -23
- package/components/form/NodeScheduling.vue +13 -3
- package/components/form/Password.vue +11 -5
- package/components/form/PodAffinity.vue +43 -44
- package/components/form/Probe.vue +68 -66
- package/components/form/ResourceQuota/Project.vue +5 -1
- package/components/form/ResourceSelector.vue +7 -9
- package/components/form/SSHKnownHosts/KnownHostsEditDialog.vue +6 -3
- package/components/form/SSHKnownHosts/__tests__/KnownHostsEditDialog.test.ts +12 -1
- package/components/form/SSHKnownHosts/index.vue +16 -2
- package/components/form/Security.vue +54 -56
- package/components/form/Select.vue +41 -7
- package/components/form/ShellInput.vue +5 -1
- package/components/form/Tolerations.vue +5 -1
- package/components/form/UnitInput.vue +2 -2
- package/components/form/ValueFromResource.vue +134 -121
- package/components/form/WorkloadPorts.vue +18 -18
- package/components/form/__tests__/ArrayList.test.ts +5 -2
- package/components/form/__tests__/MatchExpressions.test.ts +12 -12
- package/components/form/__tests__/NameNsDescription.test.ts +115 -14
- package/components/form/__tests__/Probe.test.ts +12 -8
- package/components/form/__tests__/SSHKnownHosts.test.ts +11 -0
- package/components/form/__tests__/Select.test.ts +37 -0
- package/components/form/__tests__/UnitInput.test.ts +4 -5
- package/components/formatter/BadgeStateFormatter.vue +8 -5
- package/components/formatter/InternalExternalIP.vue +2 -0
- package/components/formatter/SecretData.vue +20 -7
- package/components/nav/Favorite.vue +5 -1
- package/components/nav/Group.vue +60 -27
- package/components/nav/Header.vue +39 -13
- package/components/nav/Jump.vue +7 -0
- package/components/nav/NamespaceFilter.vue +14 -8
- package/components/nav/Pinned.vue +1 -1
- package/components/nav/TopLevelMenu.vue +5 -17
- package/components/nav/Type.vue +32 -35
- package/components/nav/__tests__/TopLevelMenu.test.ts +0 -40
- package/components/templates/blank.vue +4 -1
- package/components/templates/default.vue +8 -0
- package/components/templates/home.vue +10 -1
- package/components/templates/plain.vue +10 -1
- package/package.json +1 -1
- package/rancher-components/Banner/Banner.vue +6 -4
- package/rancher-components/Card/Card.vue +6 -4
- package/rancher-components/Form/Checkbox/Checkbox.vue +20 -1
- package/rancher-components/Form/LabeledInput/LabeledInput.vue +46 -5
- package/rancher-components/Form/Radio/RadioButton.vue +32 -8
- package/rancher-components/Form/Radio/RadioGroup.vue +31 -24
- package/rancher-components/Form/ToggleSwitch/ToggleSwitch.test.ts +17 -0
- package/rancher-components/Form/ToggleSwitch/ToggleSwitch.vue +8 -3
- package/rancher-components/LabeledTooltip/LabeledTooltip.vue +15 -3
- package/rancher-components/RcButton/RcButton.vue +1 -0
- package/rancher-components/RcButton/types.ts +1 -0
- package/rancher-components/RcDropdown/RcDropdown.vue +54 -15
- package/rancher-components/RcDropdown/RcDropdownItem.vue +5 -4
- package/rancher-components/RcDropdown/RcDropdownMenu.vue +11 -7
- package/rancher-components/RcDropdown/RcDropdownTrigger.vue +12 -2
- package/rancher-components/RcDropdown/useDropdownCollection.ts +8 -0
- package/rancher-components/RcDropdown/useDropdownContext.ts +9 -3
- package/rancher-components/StringList/StringList.vue +1 -1
- package/store/type-map.js +29 -2
- package/utils/error.js +30 -8
- package/utils/errorTranslate.json +916 -0
- package/vue.config.js +1 -1
- package/components/formatter/ExtensionCache.vue +0 -74
- package/components/formatter/Port.vue +0 -24
- package/components/formatter/SecretType.vue +0 -41
|
@@ -4,6 +4,7 @@ import TextAreaAutoGrow from '@components/Form/TextArea/TextAreaAutoGrow.vue';
|
|
|
4
4
|
import LabeledTooltip from '@components/LabeledTooltip/LabeledTooltip.vue';
|
|
5
5
|
import { escapeHtml, generateRandomAlphaString } from '@shell/utils/string';
|
|
6
6
|
import cronstrue from 'cronstrue';
|
|
7
|
+
import 'cronstrue/locales/zh_CN';
|
|
7
8
|
import { isValidCron } from 'cron-validator';
|
|
8
9
|
import { debounce } from 'lodash';
|
|
9
10
|
import { useLabeledFormElement, labeledFormElementProps } from '@shell/composables/useLabeledFormElement';
|
|
@@ -148,7 +149,8 @@ export default defineComponent({
|
|
|
148
149
|
return {
|
|
149
150
|
updated: false,
|
|
150
151
|
validationErrors: '',
|
|
151
|
-
inputId: `input-${ generateRandomAlphaString(12) }
|
|
152
|
+
inputId: `input-${ generateRandomAlphaString(12) }`,
|
|
153
|
+
describedById: `described-by-${ generateRandomAlphaString(12) }`
|
|
152
154
|
};
|
|
153
155
|
},
|
|
154
156
|
|
|
@@ -212,7 +214,8 @@ export default defineComponent({
|
|
|
212
214
|
}
|
|
213
215
|
|
|
214
216
|
try {
|
|
215
|
-
const hint = cronstrue.toString(this.value as string || '', { verbose: true });
|
|
217
|
+
// const hint = cronstrue.toString(this.value as string || '', { verbose: true });
|
|
218
|
+
const hint = cronstrue.toString(this.value as string || '', { locale: 'zh_CN' });
|
|
216
219
|
|
|
217
220
|
return hint;
|
|
218
221
|
} catch (e) {
|
|
@@ -333,6 +336,24 @@ export default defineComponent({
|
|
|
333
336
|
</script>
|
|
334
337
|
|
|
335
338
|
<template>
|
|
339
|
+
<div class="label-input-all">
|
|
340
|
+
<slot name="label">
|
|
341
|
+
<label
|
|
342
|
+
v-if="hasLabel"
|
|
343
|
+
:for="inputId"
|
|
344
|
+
>
|
|
345
|
+
<t
|
|
346
|
+
v-if="labelKey"
|
|
347
|
+
:k="labelKey"
|
|
348
|
+
/>
|
|
349
|
+
<template v-else-if="label">{{ label }}</template>
|
|
350
|
+
|
|
351
|
+
<span
|
|
352
|
+
v-if="requiredField"
|
|
353
|
+
class="required"
|
|
354
|
+
>*</span>
|
|
355
|
+
</label>
|
|
356
|
+
</slot>
|
|
336
357
|
<div
|
|
337
358
|
:class="{
|
|
338
359
|
'labeled-input': true,
|
|
@@ -347,7 +368,7 @@ export default defineComponent({
|
|
|
347
368
|
[className]: true
|
|
348
369
|
}"
|
|
349
370
|
>
|
|
350
|
-
<slot name="label">
|
|
371
|
+
<!-- <slot name="label">
|
|
351
372
|
<label
|
|
352
373
|
v-if="hasLabel"
|
|
353
374
|
:for="inputId"
|
|
@@ -363,7 +384,7 @@ export default defineComponent({
|
|
|
363
384
|
class="required"
|
|
364
385
|
>*</span>
|
|
365
386
|
</label>
|
|
366
|
-
</slot>
|
|
387
|
+
</slot> -->
|
|
367
388
|
|
|
368
389
|
<slot name="prefix" />
|
|
369
390
|
|
|
@@ -380,6 +401,7 @@ export default defineComponent({
|
|
|
380
401
|
:placeholder="_placeholder"
|
|
381
402
|
autocapitalize="off"
|
|
382
403
|
:class="{ conceal: type === 'multiline-password' }"
|
|
404
|
+
:aria-describedby="cronHint || subLabel ? describedById : undefined"
|
|
383
405
|
@update:value="onInput"
|
|
384
406
|
@focus="onFocus"
|
|
385
407
|
@blur="onBlur"
|
|
@@ -400,6 +422,7 @@ export default defineComponent({
|
|
|
400
422
|
autocomplete="off"
|
|
401
423
|
autocapitalize="off"
|
|
402
424
|
:data-lpignore="ignorePasswordManagers"
|
|
425
|
+
:aria-describedby="cronHint || subLabel ? describedById : undefined"
|
|
403
426
|
@input="onInput"
|
|
404
427
|
@focus="onFocus"
|
|
405
428
|
@blur="onBlur"
|
|
@@ -428,17 +451,20 @@ export default defineComponent({
|
|
|
428
451
|
>
|
|
429
452
|
<div
|
|
430
453
|
v-if="cronHint"
|
|
454
|
+
:id="describedById"
|
|
431
455
|
role="alert"
|
|
432
456
|
:aria-label="cronHint"
|
|
433
457
|
>
|
|
434
458
|
{{ cronHint }}
|
|
435
459
|
</div>
|
|
436
460
|
<div
|
|
437
|
-
v-if="subLabel"
|
|
461
|
+
v-else-if="subLabel"
|
|
462
|
+
:id="describedById"
|
|
438
463
|
v-clean-html="subLabel"
|
|
439
464
|
/>
|
|
440
465
|
</div>
|
|
441
466
|
</div>
|
|
467
|
+
</div>
|
|
442
468
|
</template>
|
|
443
469
|
<style scoped lang="scss">
|
|
444
470
|
.labeled-input.view {
|
|
@@ -461,6 +487,21 @@ export default defineComponent({
|
|
|
461
487
|
-moz-appearance: textfield;
|
|
462
488
|
}
|
|
463
489
|
}
|
|
490
|
+
.label-input-all{
|
|
491
|
+
display: flex;
|
|
492
|
+
label{
|
|
493
|
+
width: 160px;
|
|
494
|
+
line-height: 32px;
|
|
495
|
+
.required{
|
|
496
|
+
color: red;
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
.v-popper--has-tooltip INPUT, .v-popper--has-tooltip INPUT:hover, .v-popper--has-tooltip INPUT:focus{
|
|
502
|
+
padding: 0px 0px 0px 11px;
|
|
503
|
+
}
|
|
504
|
+
|
|
464
505
|
</style>
|
|
465
506
|
<style>
|
|
466
507
|
.validation-message {
|
|
@@ -251,15 +251,21 @@ $fontColor: var(--input-label);
|
|
|
251
251
|
cursor: not-allowed
|
|
252
252
|
}
|
|
253
253
|
|
|
254
|
-
|
|
255
|
-
height:
|
|
256
|
-
width:
|
|
257
|
-
min-height:
|
|
258
|
-
min-width:
|
|
254
|
+
.radio-custom {
|
|
255
|
+
height: 12px;
|
|
256
|
+
width: 12px;
|
|
257
|
+
min-height: 13px;
|
|
258
|
+
min-width: 13px;
|
|
259
259
|
background-color: var(--input-bg);
|
|
260
260
|
border-radius: 50%;
|
|
261
|
+
transition: all 0.3s ease-out;
|
|
261
262
|
border: 1.5px solid var(--border);
|
|
262
|
-
margin-top:
|
|
263
|
+
margin-top: 4px;
|
|
264
|
+
|
|
265
|
+
&:focus {
|
|
266
|
+
outline: none;
|
|
267
|
+
border-radius: 50%;
|
|
268
|
+
}
|
|
263
269
|
}
|
|
264
270
|
|
|
265
271
|
input {
|
|
@@ -268,13 +274,31 @@ $fontColor: var(--input-label);
|
|
|
268
274
|
|
|
269
275
|
.radio-custom {
|
|
270
276
|
&[aria-checked="true"] {
|
|
271
|
-
background-color:
|
|
277
|
+
background-color: #fff;
|
|
272
278
|
-webkit-transform: rotate(0deg) scale(1);
|
|
273
279
|
-ms-transform: rotate(0deg) scale(1);
|
|
274
280
|
transform: rotate(0deg) scale(1);
|
|
275
281
|
opacity:1;
|
|
276
282
|
border: 1.5px solid var(--primary);
|
|
283
|
+
display: flex;
|
|
284
|
+
align-items: center;
|
|
285
|
+
justify-content: center;
|
|
286
|
+
|
|
277
287
|
|
|
288
|
+
&::after {
|
|
289
|
+
background-color: var(--primary);
|
|
290
|
+
width: 7px;
|
|
291
|
+
height: 7px;
|
|
292
|
+
display: inline;
|
|
293
|
+
content: "";
|
|
294
|
+
/* position: absolute; */
|
|
295
|
+
/* top: 17%;
|
|
296
|
+
left: 19%;
|
|
297
|
+
margin-left: 0.4px; */
|
|
298
|
+
/* top: 1.5px;
|
|
299
|
+
left: 1.5px; */
|
|
300
|
+
border-radius: 50%;
|
|
301
|
+
}
|
|
278
302
|
// Ensure that checked radio buttons are muted but still visibly selected when muted
|
|
279
303
|
&.text-muted {
|
|
280
304
|
opacity: .25;
|
|
@@ -297,7 +321,7 @@ $fontColor: var(--input-label);
|
|
|
297
321
|
display: inline-flex;
|
|
298
322
|
flex-direction: column;
|
|
299
323
|
|
|
300
|
-
margin: 3px
|
|
324
|
+
margin: 3px 16px 0px 5px;
|
|
301
325
|
}
|
|
302
326
|
}
|
|
303
327
|
|
|
@@ -199,33 +199,35 @@ export default defineComponent({
|
|
|
199
199
|
</script>
|
|
200
200
|
|
|
201
201
|
<template>
|
|
202
|
-
<
|
|
202
|
+
<fieldset>
|
|
203
203
|
<!-- Label -->
|
|
204
204
|
<div
|
|
205
205
|
v-if="label || labelKey || tooltip || tooltipKey || $slots.label"
|
|
206
206
|
class="radio-group label"
|
|
207
207
|
>
|
|
208
|
-
<
|
|
209
|
-
<
|
|
210
|
-
<
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
208
|
+
<legend>
|
|
209
|
+
<slot name="label">
|
|
210
|
+
<span class="radio-group-title">
|
|
211
|
+
<t
|
|
212
|
+
v-if="labelKey"
|
|
213
|
+
:k="labelKey"
|
|
214
|
+
/>
|
|
215
|
+
<template v-else-if="label">
|
|
216
|
+
{{ label }}
|
|
217
|
+
</template>
|
|
218
|
+
<i
|
|
219
|
+
v-if="tooltipKey"
|
|
220
|
+
v-clean-tooltip="t(tooltipKey)"
|
|
221
|
+
class="icon icon-info icon-lg"
|
|
222
|
+
/>
|
|
223
|
+
<i
|
|
224
|
+
v-else-if="tooltip"
|
|
225
|
+
v-clean-tooltip="tooltip"
|
|
226
|
+
class="icon icon-info icon-lg"
|
|
227
|
+
/>
|
|
228
|
+
</span>
|
|
229
|
+
</slot>
|
|
230
|
+
</legend>
|
|
229
231
|
</div>
|
|
230
232
|
|
|
231
233
|
<!-- Group -->
|
|
@@ -266,7 +268,7 @@ export default defineComponent({
|
|
|
266
268
|
</slot>
|
|
267
269
|
</div>
|
|
268
270
|
</div>
|
|
269
|
-
</
|
|
271
|
+
</fieldset>
|
|
270
272
|
</template>
|
|
271
273
|
|
|
272
274
|
<style lang='scss'>
|
|
@@ -292,7 +294,12 @@ export default defineComponent({
|
|
|
292
294
|
}
|
|
293
295
|
|
|
294
296
|
.label{
|
|
295
|
-
font-size:
|
|
297
|
+
font-size: 12px !important;
|
|
296
298
|
}
|
|
297
299
|
}
|
|
300
|
+
.radio-group-title{
|
|
301
|
+
font-size: 14px;
|
|
302
|
+
margin-bottom: 15px;
|
|
303
|
+
display: inline-block;
|
|
304
|
+
}
|
|
298
305
|
</style>
|
|
@@ -91,4 +91,21 @@ describe('toggleSwitch.vue', () => {
|
|
|
91
91
|
expect(wrapper.emitted('update:value')).toHaveLength(1);
|
|
92
92
|
expect(wrapper.emitted('update:value')[0][0]).toBe(offValue);
|
|
93
93
|
});
|
|
94
|
+
|
|
95
|
+
it('adds focus class when input is focused', async() => {
|
|
96
|
+
const wrapper = shallowMount(ToggleSwitch);
|
|
97
|
+
|
|
98
|
+
await wrapper.find('input').trigger('focus');
|
|
99
|
+
|
|
100
|
+
expect(wrapper.find('.slider').classes()).toContain('focus');
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
it('removes focus class when input is blurred', async() => {
|
|
104
|
+
const wrapper = shallowMount(ToggleSwitch);
|
|
105
|
+
|
|
106
|
+
await wrapper.find('input').trigger('focus');
|
|
107
|
+
await wrapper.find('input').trigger('blur');
|
|
108
|
+
|
|
109
|
+
expect(wrapper.find('.slider').classes()).not.toContain('focus');
|
|
110
|
+
});
|
|
94
111
|
});
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
import { defineComponent, onMounted, onBeforeUnmount,
|
|
2
|
+
import { defineComponent, onMounted, onBeforeUnmount, ref } from 'vue';
|
|
3
3
|
|
|
4
4
|
type StateType = boolean | 'true' | 'false' | undefined;
|
|
5
5
|
|
|
@@ -34,7 +34,7 @@ export default defineComponent({
|
|
|
34
34
|
emits: ['update:value'],
|
|
35
35
|
|
|
36
36
|
setup() {
|
|
37
|
-
const switchChrome =
|
|
37
|
+
const switchChrome = ref<HTMLElement | null>(null);
|
|
38
38
|
const focus = () => {
|
|
39
39
|
switchChrome.value?.classList.add('focus');
|
|
40
40
|
};
|
|
@@ -43,7 +43,7 @@ export default defineComponent({
|
|
|
43
43
|
switchChrome.value?.classList.remove('focus');
|
|
44
44
|
};
|
|
45
45
|
|
|
46
|
-
const switchInput =
|
|
46
|
+
const switchInput = ref<HTMLInputElement | null>(null);
|
|
47
47
|
|
|
48
48
|
onMounted(() => {
|
|
49
49
|
switchInput.value?.addEventListener('focus', focus);
|
|
@@ -54,6 +54,11 @@ export default defineComponent({
|
|
|
54
54
|
switchInput.value?.removeEventListener('focus', focus);
|
|
55
55
|
switchInput.value?.removeEventListener('blur', blur);
|
|
56
56
|
});
|
|
57
|
+
|
|
58
|
+
return {
|
|
59
|
+
switchChrome,
|
|
60
|
+
switchInput,
|
|
61
|
+
};
|
|
57
62
|
},
|
|
58
63
|
|
|
59
64
|
data() {
|
|
@@ -26,7 +26,15 @@ export default defineComponent({
|
|
|
26
26
|
hover: {
|
|
27
27
|
type: Boolean,
|
|
28
28
|
default: true
|
|
29
|
-
}
|
|
29
|
+
},
|
|
30
|
+
/**
|
|
31
|
+
* Inherited global identifier prefix for tests
|
|
32
|
+
* Define a term based on the parent component to avoid conflicts on multiple components
|
|
33
|
+
*/
|
|
34
|
+
componentTestid: {
|
|
35
|
+
type: String,
|
|
36
|
+
default: 'labeledTooltip-info-icon'
|
|
37
|
+
},
|
|
30
38
|
},
|
|
31
39
|
computed: {
|
|
32
40
|
iconClass(): string {
|
|
@@ -64,6 +72,7 @@ export default defineComponent({
|
|
|
64
72
|
:class="{'hover':!value, [iconClass]: true}"
|
|
65
73
|
class="icon status-icon"
|
|
66
74
|
tabindex="0"
|
|
75
|
+
:data-testid="componentTestid"
|
|
67
76
|
/>
|
|
68
77
|
</template>
|
|
69
78
|
<template v-else>
|
|
@@ -99,9 +108,12 @@ export default defineComponent({
|
|
|
99
108
|
|
|
100
109
|
.status-icon {
|
|
101
110
|
position: absolute;
|
|
102
|
-
right:
|
|
111
|
+
right: 5px;
|
|
112
|
+
top: 10px;
|
|
113
|
+
z-index: 3;
|
|
114
|
+
/* right: 30px;
|
|
103
115
|
top: $input-padding-lg;
|
|
104
|
-
z-index: z-index(hoverOverContent);
|
|
116
|
+
z-index: z-index(hoverOverContent); */
|
|
105
117
|
}
|
|
106
118
|
|
|
107
119
|
@mixin tooltipColors($color) {
|
|
@@ -15,6 +15,7 @@ const buttonRoles: { role: keyof ButtonRoleProps, className: string }[] = [
|
|
|
15
15
|
{ role: 'secondary', className: 'role-secondary' },
|
|
16
16
|
{ role: 'tertiary', className: 'role-tertiary' },
|
|
17
17
|
{ role: 'link', className: 'role-link' },
|
|
18
|
+
{ role: 'multiAction', className: 'role-multi-action' },
|
|
18
19
|
{ role: 'ghost', className: 'role-ghost' },
|
|
19
20
|
];
|
|
20
21
|
|
|
@@ -20,13 +20,22 @@
|
|
|
20
20
|
* </template>
|
|
21
21
|
* </rc-dropdown>
|
|
22
22
|
*/
|
|
23
|
-
import {
|
|
23
|
+
import { ref } from 'vue';
|
|
24
24
|
import { useClickOutside } from '@shell/composables/useClickOutside';
|
|
25
25
|
import { useDropdownContext } from '@components/RcDropdown/useDropdownContext';
|
|
26
26
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
27
|
+
import type { Placement } from 'floating-vue';
|
|
28
|
+
|
|
29
|
+
withDefaults(
|
|
30
|
+
defineProps<{
|
|
31
|
+
// eslint-disable-next-line vue/require-default-prop
|
|
32
|
+
ariaLabel?: string;
|
|
33
|
+
// eslint-disable-next-line vue/require-default-prop
|
|
34
|
+
distance?: number;
|
|
35
|
+
placement?: Placement;
|
|
36
|
+
}>(),
|
|
37
|
+
{ placement: 'bottom-end' }
|
|
38
|
+
);
|
|
30
39
|
|
|
31
40
|
const emit = defineEmits(['update:open']);
|
|
32
41
|
|
|
@@ -42,14 +51,14 @@ const {
|
|
|
42
51
|
|
|
43
52
|
provideDropdownContext();
|
|
44
53
|
|
|
45
|
-
const popperContainer =
|
|
46
|
-
const dropdownTarget =
|
|
54
|
+
// const popperContainer = ref(null);
|
|
55
|
+
const dropdownTarget = ref(null);
|
|
47
56
|
|
|
48
57
|
useClickOutside(dropdownTarget, () => showMenu(false));
|
|
49
58
|
|
|
50
59
|
const applyShow = () => {
|
|
51
60
|
registerDropdownCollection(dropdownTarget.value);
|
|
52
|
-
setFocus();
|
|
61
|
+
setFocus('down');
|
|
53
62
|
};
|
|
54
63
|
|
|
55
64
|
</script>
|
|
@@ -60,15 +69,30 @@ const applyShow = () => {
|
|
|
60
69
|
:triggers="[]"
|
|
61
70
|
:shown="isMenuOpen"
|
|
62
71
|
:auto-hide="false"
|
|
63
|
-
|
|
64
|
-
:placement="
|
|
72
|
+
append-to-body
|
|
73
|
+
:placement="placement"
|
|
74
|
+
:distance="distance"
|
|
65
75
|
@apply-show="applyShow"
|
|
76
|
+
popper-class="custom-dropdown"
|
|
66
77
|
>
|
|
67
78
|
<slot name="default">
|
|
68
79
|
<!--Empty slot content Trigger-->
|
|
69
80
|
</slot>
|
|
70
81
|
|
|
71
82
|
<template #popper>
|
|
83
|
+
<!-- <div
|
|
84
|
+
ref="dropdownTarget"
|
|
85
|
+
class="dropdownTarget"
|
|
86
|
+
tabindex="-1"
|
|
87
|
+
role="menu"
|
|
88
|
+
aria-orientation="vertical"
|
|
89
|
+
dropdown-menu-collection
|
|
90
|
+
:aria-label="ariaLabel || 'Dropdown Menu'"
|
|
91
|
+
@keydown="handleKeydown"
|
|
92
|
+
@keydown.down.prevent="setFocus('down')"
|
|
93
|
+
@keydown.up.prevent="setFocus('up')"
|
|
94
|
+
|
|
95
|
+
> -->
|
|
72
96
|
<div
|
|
73
97
|
ref="dropdownTarget"
|
|
74
98
|
class="dropdownTarget"
|
|
@@ -78,7 +102,10 @@ const applyShow = () => {
|
|
|
78
102
|
dropdown-menu-collection
|
|
79
103
|
:aria-label="ariaLabel || 'Dropdown Menu'"
|
|
80
104
|
@keydown="handleKeydown"
|
|
81
|
-
@keydown.down="setFocus()"
|
|
105
|
+
@keydown.down.prevent="setFocus('down')"
|
|
106
|
+
@keydown.up.prevent="setFocus('up')"
|
|
107
|
+
@keydown.tab="showMenu(false)"
|
|
108
|
+
@keydown.escape="returnFocus"
|
|
82
109
|
>
|
|
83
110
|
<slot name="dropdownCollection">
|
|
84
111
|
<!--Empty slot content-->
|
|
@@ -86,14 +113,13 @@ const applyShow = () => {
|
|
|
86
113
|
</div>
|
|
87
114
|
</template>
|
|
88
115
|
</v-dropdown>
|
|
89
|
-
<div
|
|
116
|
+
<!-- <div
|
|
90
117
|
ref="popperContainer"
|
|
91
118
|
class="popperContainer"
|
|
92
119
|
@keydown.tab="showMenu(false)"
|
|
93
120
|
@keydown.escape="returnFocus"
|
|
94
121
|
>
|
|
95
|
-
|
|
96
|
-
</div>
|
|
122
|
+
</div> -->
|
|
97
123
|
</template>
|
|
98
124
|
|
|
99
125
|
<style lang="scss" scoped>
|
|
@@ -102,7 +128,8 @@ const applyShow = () => {
|
|
|
102
128
|
&:deep(.v-popper__popper) {
|
|
103
129
|
|
|
104
130
|
.v-popper__wrapper {
|
|
105
|
-
box-shadow:
|
|
131
|
+
box-shadow: 0 5px 20px var(--shadow);
|
|
132
|
+
/* box-shadow: 0px 6px 18px 0px rgba(0, 0, 0, 0.25), 0px 4px 10px 0px rgba(0, 0, 0, 0.15); */
|
|
106
133
|
border-radius: var(--border-radius-lg);
|
|
107
134
|
|
|
108
135
|
.v-popper__arrow-container {
|
|
@@ -110,7 +137,9 @@ const applyShow = () => {
|
|
|
110
137
|
}
|
|
111
138
|
|
|
112
139
|
.v-popper__inner {
|
|
113
|
-
padding: 10px 0 10px 0;
|
|
140
|
+
/* padding: 10px 0 10px 0; */
|
|
141
|
+
padding: 0px;
|
|
142
|
+
/* min-width: 145px; */
|
|
114
143
|
}
|
|
115
144
|
}
|
|
116
145
|
}
|
|
@@ -121,4 +150,14 @@ const applyShow = () => {
|
|
|
121
150
|
outline: none;
|
|
122
151
|
}
|
|
123
152
|
}
|
|
153
|
+
|
|
154
|
+
.custom-dropdown{
|
|
155
|
+
.v-popper__wrapper{
|
|
156
|
+
.v-popper__inner {
|
|
157
|
+
padding: 0px;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
124
162
|
</style>
|
|
163
|
+
|
|
@@ -83,7 +83,7 @@ const handleActivate = (e: KeyboardEvent) => {
|
|
|
83
83
|
:aria-disabled="disabled || false"
|
|
84
84
|
@click.stop="handleClick"
|
|
85
85
|
@keydown.enter.space="handleActivate"
|
|
86
|
-
@keydown.up.down.stop="handleKeydown"
|
|
86
|
+
@keydown.up.down.prevent.stop="handleKeydown"
|
|
87
87
|
>
|
|
88
88
|
<slot name="before">
|
|
89
89
|
<!--Empty slot content-->
|
|
@@ -99,9 +99,10 @@ const handleActivate = (e: KeyboardEvent) => {
|
|
|
99
99
|
display: flex;
|
|
100
100
|
gap: 8px;
|
|
101
101
|
align-items: center;
|
|
102
|
-
padding:
|
|
103
|
-
|
|
104
|
-
|
|
102
|
+
padding: 8px 10px;
|
|
103
|
+
min-width: 145px;
|
|
104
|
+
/* margin: 0 9px; */
|
|
105
|
+
/* border-radius: 4px; */
|
|
105
106
|
|
|
106
107
|
&:hover {
|
|
107
108
|
cursor: pointer;
|
|
@@ -8,8 +8,11 @@ import {
|
|
|
8
8
|
import { RcDropdownMenuComponentProps, DropdownOption } from './types';
|
|
9
9
|
import IconOrSvg from '@shell/components/IconOrSvg';
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
withDefaults(defineProps<RcDropdownMenuComponentProps>(), {
|
|
12
|
+
buttonRole: 'primary',
|
|
13
|
+
buttonSize: undefined,
|
|
14
|
+
isDetail: false,
|
|
15
|
+
});
|
|
13
16
|
|
|
14
17
|
const emit = defineEmits(['update:open', 'select']);
|
|
15
18
|
|
|
@@ -29,7 +32,8 @@ const hasOptions = (options: DropdownOption[]) => {
|
|
|
29
32
|
:data-testid="dataTestid"
|
|
30
33
|
:aria-label="buttonAriaLabel"
|
|
31
34
|
>
|
|
32
|
-
<i
|
|
35
|
+
<i style="font-style: normal;" v-if="buttonRole === 'link'">操作</i>
|
|
36
|
+
<i class="icon icon-actions" v-else/>
|
|
33
37
|
</rc-dropdown-trigger>
|
|
34
38
|
<template #dropdownCollection>
|
|
35
39
|
<template
|
|
@@ -40,7 +44,7 @@ const hasOptions = (options: DropdownOption[]) => {
|
|
|
40
44
|
v-if="!a.divider"
|
|
41
45
|
@click="(e: MouseEvent) => emit('select', e, a)"
|
|
42
46
|
>
|
|
43
|
-
<template #before>
|
|
47
|
+
<!-- <template #before>
|
|
44
48
|
<IconOrSvg
|
|
45
49
|
v-if="a.icon || a.svg"
|
|
46
50
|
:icon="a.icon"
|
|
@@ -48,12 +52,12 @@ const hasOptions = (options: DropdownOption[]) => {
|
|
|
48
52
|
class="icon"
|
|
49
53
|
color="header"
|
|
50
54
|
/>
|
|
51
|
-
</template>
|
|
55
|
+
</template> -->
|
|
52
56
|
{{ a.label }}
|
|
53
57
|
</rc-dropdown-item>
|
|
54
|
-
<rc-dropdown-separator
|
|
58
|
+
<!-- <rc-dropdown-separator
|
|
55
59
|
v-else
|
|
56
|
-
/>
|
|
60
|
+
/> -->
|
|
57
61
|
</template>
|
|
58
62
|
<rc-dropdown-item
|
|
59
63
|
v-if="!hasOptions(options)"
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* A button that opens a menu. Used in conjunction with `RcDropdown.vue`.
|
|
4
4
|
*/
|
|
5
|
-
import { inject, onMounted,
|
|
5
|
+
import { inject, onMounted, ref } from 'vue';
|
|
6
6
|
import { RcButton, RcButtonType } from '@components/RcButton';
|
|
7
7
|
import { DropdownContext, defaultContext } from './types';
|
|
8
8
|
|
|
@@ -13,7 +13,7 @@ const {
|
|
|
13
13
|
handleKeydown,
|
|
14
14
|
} = inject<DropdownContext>('dropdownContext') || defaultContext;
|
|
15
15
|
|
|
16
|
-
const dropdownTrigger =
|
|
16
|
+
const dropdownTrigger = ref<RcButtonType | null>(null);
|
|
17
17
|
|
|
18
18
|
onMounted(() => {
|
|
19
19
|
registerTrigger(dropdownTrigger.value);
|
|
@@ -35,8 +35,18 @@ defineExpose({ focus });
|
|
|
35
35
|
@keydown.enter.space="handleKeydown"
|
|
36
36
|
@click="showMenu(true)"
|
|
37
37
|
>
|
|
38
|
+
<template #before>
|
|
39
|
+
<slot name="before">
|
|
40
|
+
<!-- Empty Content -->
|
|
41
|
+
</slot>
|
|
42
|
+
</template>
|
|
38
43
|
<slot name="default">
|
|
39
44
|
<!--Empty slot content-->
|
|
40
45
|
</slot>
|
|
46
|
+
<template #after>
|
|
47
|
+
<slot name="after">
|
|
48
|
+
<!-- Empty Content -->
|
|
49
|
+
</slot>
|
|
50
|
+
</template>
|
|
41
51
|
</RcButton>
|
|
42
52
|
</template>
|
|
@@ -10,6 +10,7 @@ export const useDropdownCollection = () => {
|
|
|
10
10
|
const dropdownItems = ref<Element[]>([]);
|
|
11
11
|
const dropdownContainer = ref<HTMLElement | null>(null);
|
|
12
12
|
const firstDropdownItem = ref<HTMLElement | null>(null);
|
|
13
|
+
const lastDropdownItem = ref<HTMLElement | null>(null);
|
|
13
14
|
|
|
14
15
|
/**
|
|
15
16
|
* Registers the dropdown container and initializes dropdown items.
|
|
@@ -22,6 +23,12 @@ export const useDropdownCollection = () => {
|
|
|
22
23
|
if (dropdownItems.value[0] instanceof HTMLElement) {
|
|
23
24
|
firstDropdownItem.value = dropdownItems.value[0];
|
|
24
25
|
}
|
|
26
|
+
|
|
27
|
+
const lastItem = dropdownItems.value[dropdownItems.value.length - 1];
|
|
28
|
+
|
|
29
|
+
if (lastItem instanceof HTMLElement) {
|
|
30
|
+
lastDropdownItem.value = lastItem;
|
|
31
|
+
}
|
|
25
32
|
}
|
|
26
33
|
};
|
|
27
34
|
|
|
@@ -40,6 +47,7 @@ export const useDropdownCollection = () => {
|
|
|
40
47
|
return {
|
|
41
48
|
dropdownItems,
|
|
42
49
|
firstDropdownItem,
|
|
50
|
+
lastDropdownItem,
|
|
43
51
|
dropdownContainer,
|
|
44
52
|
registerDropdownCollection,
|
|
45
53
|
};
|