Skip to content

Commit f942c20

Browse files
committed
Merge branch 'unified-desktop-gui' into tgriesser/unify/cleanup-component-tests
* unified-desktop-gui: chore(launchpad): launchpad UI tweaks (#18369)
2 parents 065ecb4 + dfdc537 commit f942c20

22 files changed

+155
-167
lines changed

packages/frontend-shared/src/components/Button.vue

Lines changed: 10 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
11
<template>
22
<button
33
style="width: fit-content"
4-
class="flex items-center border rounded-sm gap-8px focus:border-indigo-600 focus:outline-transparent"
4+
class="flex items-center border rounded gap-8px hocus-default"
55
:class="classes"
66
>
77
<span
88
v-if="prefixIcon || $slots.prefix"
9-
:class="iconClasses"
10-
class="justify-self-start"
9+
class="justify-self-start flex items-center"
1110
>
1211
<slot name="prefix">
1312
<Icon
@@ -21,8 +20,7 @@
2120
</span>
2221
<span
2322
v-if="suffixIcon || $slots.suffix"
24-
:class="iconClasses"
25-
class="justify-self-end"
23+
class="justify-self-start flex items-center"
2624
>
2725
<slot name="suffix">
2826
<Icon
@@ -52,29 +50,23 @@ import { computed, useAttrs } from 'vue'
5250
import type { ButtonHTMLAttributes, FunctionalComponent, SVGAttributes } from 'vue'
5351
5452
const VariantClassesTable = {
55-
primary: 'border-indigo-600 bg-indigo-600 text-white',
56-
outline: 'border-gray-200 text-indigo-600 bg-white',
53+
primary: 'border-indigo-500 bg-indigo-600 text-white',
54+
outline: 'border-gray-100 text-indigo-600',
5755
link: 'border-transparent text-indigo-600',
5856
text: 'border-0',
5957
}
6058
6159
const SizeClassesTable = {
62-
sm: 'px-1 py-1 text-xs',
63-
md: 'px-2 py-1 text-sm',
64-
lg: 'px-4 py-2 text-sm',
65-
xl: 'px-6 py-3 text-lg',
66-
}
67-
68-
const IconClassesTable = {
69-
md: 'min-h-1.25em min-w-1.25em max-h-1.25em max-w-1.25em',
70-
lg: 'min-h-2em min-w-2em max-h-2em max-w-2em',
71-
xl: 'min-h-2.5em min-w-2.5em max-w-2.5em max-h-2.5em ',
60+
sm: 'px-6px py-2px text-14px',
61+
md: 'px-12px py-6px text-14px',
62+
lg: 'px-16px py-8px',
63+
'lg-wide': 'px-32px py-8px',
7264
}
7365
7466
const props = defineProps<{
7567
prefixIcon?: FunctionalComponent<SVGAttributes>
7668
suffixIcon?: FunctionalComponent<SVGAttributes>
77-
size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl'
69+
size?: 'sm' | 'md' | 'lg' | 'lg-wide'
7870
variant?: 'primary' | 'outline' | 'link' | 'text'
7971
prefixIconClass?: string
8072
suffixIconClass?: string
@@ -85,8 +77,6 @@ const attrs = useAttrs() as ButtonHTMLAttributes
8577
const variantClasses = VariantClassesTable[props.variant || 'primary']
8678
const sizeClasses = SizeClassesTable[props.size || 'md']
8779
88-
const iconClasses = ['flex', 'items-center', IconClassesTable[props.size || 'md']]
89-
9080
const classes = computed(() => {
9181
return [
9282
variantClasses,

packages/frontend-shared/src/components/CopyButton.vue

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,20 @@
44
<span
55
v-show="showCopied"
66
class="mx-3"
7+
role="status"
78
>{{ t('clipboard.copied') }}</span>
89
</transition>
910
<button
10-
class="bg-gray-50 px-3 py-1 rounded text-indigo-600"
11+
tabindex="1"
12+
class="bg-gray-50 text-14px px-2 py-1 rounded text-indigo-600 border-1 border-transparent hocus-default"
1113
@click="copyToClipboard"
1214
>
1315
{{ t('clipboard.copy') }}
1416
</button>
1517
</div>
1618
<textarea
1719
ref="textElement"
20+
tabindex="-1"
1821
:value="text"
1922
class="absolute -top-96"
2023
/>

packages/frontend-shared/src/components/Switch.spec.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,13 @@ describe('<Switch />', () => {
77

88
cy.mount(() => (
99
<div class="p-6">
10+
<label for="test-switch">Switch</label>
1011
<Switch
1112
// @ts-ignore
1213
value={valueRef.value}
1314
// @ts-ignore
1415
onUpdate={(newVal) => (valueRef.value = newVal)}
16+
name="test-switch"
1517
/>
1618
</div>
1719
))
Lines changed: 38 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,52 @@
11
<template>
22
<button
3-
class="rounded-md h-3 w-6 relative focus:outline-transparent"
4-
:class="value ? 'bg-green-600' : 'bg-gray-600'"
3+
:id="name"
4+
class="rounded-50px relative hocus-default border-transparent border-1"
5+
:class="[value ? 'bg-jade-400' : 'bg-gray-300', sizeClasses[size].container]"
6+
role="switch"
7+
:aria-checked="value"
58
@click="$emit('update', !value)"
69
>
710
<span
8-
class="absolute block toggle border border-1 border-gray-300 rounded-md bg-white"
9-
:class="value ? 'toggle-on' : ''"
11+
class="block toggle transform rounded-50px bg-white transition-transform duration-200 ease-out"
12+
:class="[{ [sizeClasses[size].translate]: value }, sizeClasses[size].indicator]"
1013
/>
1114
</button>
1215
</template>
1316

1417
<script lang="ts" setup>
15-
defineProps({
16-
value: {
17-
type: Boolean,
18-
default: false,
19-
},
20-
})
2118
22-
defineEmits(['update'])
23-
</script>
19+
withDefaults(defineProps<{
20+
value: boolean
21+
size?: 'sm' | 'md' | 'lg' | 'xl'
22+
name: string // required for an id so that an external <label> can be associated with the switch
23+
}>(), {
24+
value: false,
25+
size: 'lg',
26+
})
2427
25-
<style scoped>
26-
.toggle {
27-
left: 1px;
28-
top: 1px;
29-
height: 10px;
30-
width: 10px;
31-
transition: left 0.2s;
28+
const sizeClasses = {
29+
'sm': {
30+
container: 'w-16px h-10px',
31+
indicator: 'w-6px h-6px ml-2px',
32+
translate: 'translate-x-6px',
33+
},
34+
'md': {
35+
container: 'w-24px h-12px',
36+
indicator: 'w-8px h-8px ml-2px',
37+
translate: 'translate-x-12px',
38+
},
39+
'lg': {
40+
container: 'w-32px h-16px',
41+
indicator: 'w-12px h-12px ml-2px',
42+
translate: 'translate-x-14px',
43+
},
44+
'xl': {
45+
container: 'w-48px h-24px',
46+
indicator: 'w-16px h-16px ml-4px',
47+
translate: 'translate-x-24px',
48+
},
3249
}
3350
34-
.toggle-on {
35-
left: 13px;
36-
}
37-
</style>
51+
defineEmits(['update'])
52+
</script>

packages/frontend-shared/src/locales/en-US.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,9 @@
5858
},
5959
"openBrowser": {
6060
"launch": "Launch"
61+
},
62+
"configFile": {
63+
"createManually": "Create file manually"
6164
}
6265
},
6366
"globalPage": {

packages/frontend-shared/windi.config.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,10 @@ export default defineConfig({
2626
InteractionVariants,
2727
IconDuotoneColorsPlugin,
2828
],
29+
shortcuts: {
30+
'focus-default': 'focus:border focus:border-indigo-300 focus:ring-2 focus:ring-indigo-100 focus:outline-transparent transition transition-colors duration-100 disabled:hover:ring-0 disabled:hover:border-0',
31+
'hocus-default': 'hocus:border hover:border-indigo-100 focus:border-indigo-300 hocus:ring-2 hocus:ring-indigo-100 hocus:outline-transparent transition transition-colors duration-100 disabled:ring-0 disabled:border-0',
32+
},
2933
extract: {
3034
// accepts globs and file paths relative to project root
3135
include: ['index.html', '**/*.{vue,html,tsx}', '../frontend-shared/**/*.{vue,html,tsx}'],

packages/launchpad/src/components/select/SelectBundler.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
"
2424
:class="disabledClass
2525
+ (isOpen ? ' border-indigo-600' : ' border-gray-200')
26-
+ (props.disabled ? ' bg-gray-300 text-gray-600' : '')"
26+
+ (props.disabled ? ' bg-gray-100 text-gray-800' : '')"
2727
:disabled="props.disabled"
2828
@click="
2929
if (!props.disabled) {

packages/launchpad/src/components/select/SelectFramework.vue

Lines changed: 18 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -2,32 +2,23 @@
22
<div class="text-left relative">
33
<label
44
class="text-gray-800 text-sm my-3 block"
5-
:class="disabledClass"
6-
>{{
7-
props.name
8-
}}</label>
5+
:class="{ 'opacity-50': disabled }"
6+
>
7+
{{
8+
name
9+
}}
10+
</label>
911
<button
1012
v-click-outside="() => (isOpen = false)"
11-
class="
12-
h-10
13-
text-left
14-
flex
15-
justify-between
16-
items-center
17-
border-1
18-
px-2
19-
py-1
20-
rounded
21-
w-full
22-
focus:border-indigo-600 focus:outline-transparent
23-
"
13+
class="h-10 text-left flex justify-between items-center border-1 px-2 py-1 rounded w-full focus:border-indigo-600 focus:outline-transparent"
2414
data-cy="select-framework"
25-
:class="disabledClass
26-
+ (isOpen ? ' border-indigo-600' : ' border-gray-200')
27-
+ (props.disabled ? ' bg-gray-300 text-gray-600' : '')"
28-
:disabled="props.disabled"
15+
:class="
16+
[isOpen ? ' border-indigo-600' : ' border-gray-100',
17+
{ 'bg-gray-100 text-gray-800 opacity-50': disabled }]
18+
"
19+
:disabled="disabled"
2920
@click="
30-
if (!props.disabled) {
21+
if (!disabled) {
3122
isOpen = !isOpen;
3223
}
3324
"
@@ -37,35 +28,22 @@
3728
:src="FrameworkBundlerLogos[selectedOptionObject.type]"
3829
class="w-5 h-5 mr-3"
3930
>
40-
<span>
41-
{{ selectedOptionObject.name }}
42-
</span>
31+
<span>{{ selectedOptionObject.name }}</span>
4332
</template>
4433
<span
4534
v-else
4635
class="text-gray-400"
47-
>
48-
{{ props.placeholder }}
49-
</span>
36+
>{{ placeholder }}</span>
5037
<span class="flex-grow" />
5138
<i-fa-angle-down />
5239
</button>
5340
<ul
5441
v-if="isOpen"
55-
class="
56-
w-full
57-
absolute
58-
bg-white
59-
border-1 border-indigo-600 border-t-1 border-t-gray-100
60-
rounded-b
61-
flex flex-col
62-
gap-0
63-
z-10
64-
"
42+
class="w-full absolute bg-white border-1 border-indigo-600 border-t-1 border-t-gray-100 rounded-b flex flex-col gap-0 z-10"
6543
style="margin-top: -3px"
6644
>
6745
<li
68-
v-for="opt in props.options"
46+
v-for="opt in options"
6947
:key="opt.id"
7048
focus="1"
7149
class="cursor-pointer flex items-center py-1 px-2 hover:bg-gray-10"
@@ -75,9 +53,7 @@
7553
:src="FrameworkBundlerLogos[opt.type]"
7654
class="w-5 h-5 mr-3"
7755
>
78-
<span>
79-
{{ opt.name }}
80-
</span>
56+
<span>{{ opt.name }}</span>
8157
</li>
8258
</ul>
8359
</div>
@@ -121,5 +97,4 @@ const selectOption = (opt: FrontendFrameworkEnum) => {
12197
emit('select', opt)
12298
}
12399
124-
const disabledClass = computed(() => props.disabled ? 'opacity-50' : undefined)
125100
</script>

packages/launchpad/src/setup/ButtonBar.spec.tsx

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
import ButtonBar from './ButtonBar.vue'
2+
import { defaultMessages } from '@cy/i18n'
3+
4+
const { next: nextLabel, back: backLabel } = defaultMessages.setupPage.step
25

36
describe('<ButtonBar />', () => {
47
let nextFn: ReturnType<typeof cy.stub>
@@ -10,21 +13,21 @@ describe('<ButtonBar />', () => {
1013
})
1114

1215
it('playground', () => {
13-
cy.mount(() => <ButtonBar next="Next Step" back="Back" nextFn={nextFn} backFn={backFn} />)
16+
cy.mount(() => <ButtonBar next={nextLabel} back={backLabel} nextFn={nextFn} backFn={backFn} />)
1417
})
1518

1619
it('should trigger the next function', () => {
17-
cy.mount(() => <ButtonBar next="Next Step" back="Back" nextFn={nextFn} backFn={backFn} canNavigateForward={true} />)
18-
cy.contains('Next Step')
20+
cy.mount(() => <ButtonBar next={nextLabel} back={backLabel} nextFn={nextFn} backFn={backFn} canNavigateForward={true} />)
21+
cy.contains(nextLabel)
1922
.click()
2023
.then(() => {
2124
expect(nextFn).to.have.been.calledOnce
2225
})
2326
})
2427

2528
it('should trigger the back function', () => {
26-
cy.mount(() => <ButtonBar next="Next Step" back="Back" nextFn={nextFn} backFn={backFn} />)
27-
cy.contains('Back')
29+
cy.mount(() => <ButtonBar next={nextLabel} back={backLabel} nextFn={nextFn} backFn={backFn} />)
30+
cy.contains(backLabel)
2831
.click()
2932
.then(() => {
3033
expect(backFn).to.have.been.calledOnce
@@ -35,10 +38,10 @@ describe('<ButtonBar />', () => {
3538
const altFunction = cy.spy()
3639

3740
cy.mount(() => (
38-
<ButtonBar next="Next Step" back="Back" nextFn={nextFn} backFn={backFn} altFn={altFunction} alt="Install manually" />
41+
<ButtonBar next={nextLabel} back={backLabel} nextFn={nextFn} backFn={backFn} altFn={altFunction} alt="Install manually" />
3942
))
4043

41-
cy.contains('Install manually')
44+
cy.findAllByLabelText('Install manually')
4245
.click()
4346
.then(() => {
4447
expect(altFunction).to.have.been.calledOnce

packages/launchpad/src/setup/ButtonBar.vue

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,16 @@
11
<template>
2-
<div class="px-5 py-5 flex gap-3 bg-gray-50 border-t border-t-1 border-t-gray-200 rounded-b">
2+
<div class="px-5 py-5 flex gap-3 bg-gray-50 border-t border-t-1 border-t-gray-100 rounded-b">
33
<slot>
44
<Button
55
v-if="showNext"
6+
size="lg"
67
:disabled="!canNavigateForward"
78
@click="nextFn"
89
>
910
{{ next }}
1011
</Button>
1112
<Button
13+
size="lg"
1214
variant="outline"
1315
@click="backFn"
1416
>
@@ -20,10 +22,13 @@
2022
class="flex items-center px-3"
2123
>
2224
<label
25+
for="altFn"
2326
class="text-gray-500 px-3"
2427
@click="handleAlt"
2528
>{{ alt }}</label>
2629
<Switch
30+
size="lg"
31+
name="altFn"
2732
:value="altValue"
2833
@update="handleAlt"
2934
/>

0 commit comments

Comments
 (0)