Skip to content

Commit 76ea135

Browse files
jvictordev1jvictordev1
andauthored
fix: corrige visibilidade do spinner de carregamento e refatora para composition API (#1030)
#### Por favor, verifique se o seu pull request está de acordo com o checklist abaixo: - [x] A implementação feita possui testes (Caso haja um motivo para não haver testes/haver apenas testes de snapshot, descrever abaixo) - [x] A documentação no mdx foi feita ou atualizada, caso necessário - [x] O eslint passou localmente ### 1 - Resumo Corrige visibilidade do spinner no CdsButton quando o mesmo possui a prop `secondary` ou `ghost` ativas. ### 2 - Tipo de pull request - [ ] 🧱 Novo componente - [ ] ✨ Nova feature ou melhoria - [X] 🐛 Fix - [ ] 👨‍💻 Refatoração - [ ] 📝 Documentação - [ ] 🎨 Estilo - [ ] 🤖 Build ou CI/CD ### 3 - Esse PR fecha alguma issue? Favor referenciá-la #1027 ### 4 - Quais são os passos para avaliar o pull request? - Rode os testes com `npm run test` e verifique o sucesso - Rode a documentação com `npm run docs:dev` - Acesse o componente `Button` e ative a prop `loading`, verificando a visibilidade do spinner quando as props `secondary` e `ghost` estão ativadas/desativadas - Verifique a alteração da cor do spinner ao alterar a prop `variant` quando o botão está com a prop `secondary` ou `ghost` está ativa ### 5 - Imagem ou exemplo de uso: <img width="1046" height="728" alt="image" src="https://github.com/user-attachments/assets/f47e5fff-9c46-499a-bdb5-d5db31a8d827" /> ### 6 - Esse pull request adiciona _breaking changes_? - [ ] Sim - [X] Não --------- Co-authored-by: jvictordev1 <jvictordev1@gmail.com>
1 parent 79e1478 commit 76ea135

File tree

2 files changed

+137
-156
lines changed

2 files changed

+137
-156
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@sysvale/cuida",
3-
"version": "3.149.0",
3+
"version": "3.149.1",
44
"description": "A design system built by Sysvale, using storybook and Vue components",
55
"repository": {
66
"type": "git",

src/components/Button.vue

Lines changed: 136 additions & 155 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
>
99
<CdsSpinner
1010
v-if="loading"
11-
variant="white"
11+
:variant="computedSpinnerVariant"
1212
size="sm"
1313
class="button__prepend"
1414
/>
@@ -33,169 +33,150 @@
3333
</button>
3434
</template>
3535

36-
<script>
37-
import CdsSpinner from '../components/Spinner.vue';
38-
import Cdstip from '../utils/directives/cdstip';
36+
<script setup>
37+
import { computed } from 'vue';
3938
import hasSlot from '../utils/methods/hasSlot';
4039
41-
export default {
42-
name: 'CdsButton',
43-
directives: {
44-
cdstip: Cdstip,
40+
defineOptions({ name: 'CdsButton' });
41+
42+
const predefinedColors = [
43+
'green',
44+
'teal',
45+
'turquoise',
46+
'blue',
47+
'indigo',
48+
'violet',
49+
'pink',
50+
'red',
51+
'orange',
52+
'amber',
53+
'dark',
54+
];
55+
const predefinedSizes = ['sm', 'md', 'lg'];
56+
57+
const props = defineProps({
58+
/**
59+
* A variante de cor. São 10 variantes:
60+
* @values green, teal, blue, indigo, violet, pink, red, orange, amber, dark
61+
*/
62+
variant: {
63+
type: String,
64+
default: 'green',
4565
},
46-
47-
components: {
48-
CdsSpinner,
66+
/**
67+
* Especifica o tamanho do botão. São 3 tamanhos implementados:
68+
* @values 'sm', 'md', 'lg'
69+
*/
70+
size: {
71+
type: String,
72+
default: 'md',
4973
},
50-
51-
props: {
52-
/**
53-
* A variante de cor. São 10 variantes:
54-
* @values green, teal, blue, indigo, violet, pink, red, orange, amber, dark
55-
*/
56-
variant: {
57-
type: String,
58-
default: 'green',
59-
},
60-
/**
61-
* Especifica o tamanho do botão. São 3 tamanhos implementados:
62-
* @values 'sm', 'md', 'lg'
63-
*/
64-
size: {
65-
type: String,
66-
default: 'md',
67-
},
68-
/**
69-
* Quando true, torna a largura do botão fluida
70-
*/
71-
block: {
72-
type: Boolean,
73-
default: false,
74-
},
75-
/**
76-
* Especifica o texto a ser apresentado no corpo do botão.
77-
* Este texto será exibido apenas se o slot default não for utilizado.
78-
*/
79-
text: {
80-
type: String,
81-
default: 'Click here',
82-
},
83-
/**
84-
* Controla a disponibilidade do Botão.
85-
*/
86-
disabled: {
87-
type: Boolean,
88-
default: false,
89-
},
90-
/**
91-
* Texto a ser exibido como tooltip com o hover do botão quando a prop disabled estiver ativa.
92-
*/
93-
tooltipText: {
94-
type: String,
95-
default: null,
96-
},
97-
/**
98-
* Especifica se a versão do Botão é a secundária.
99-
*/
100-
secondary: {
101-
type: Boolean,
102-
default: false,
103-
},
104-
/**
105-
* Especifica se a versão do Botão é a secundária.
106-
*/
107-
loading: {
108-
type: Boolean,
109-
default: false,
110-
},
111-
/**
112-
* Especifica se o componente deve ser exibido na sua versão ghost.
113-
*/
114-
ghost: {
115-
type: Boolean,
116-
default: false,
117-
},
74+
/**
75+
* Quando true, torna a largura do botão fluida
76+
*/
77+
block: {
78+
type: Boolean,
79+
default: false,
11880
},
119-
120-
data() {
121-
return {
122-
predefinedColors: [
123-
'green',
124-
'teal',
125-
'turquoise',
126-
'blue',
127-
'indigo',
128-
'violet',
129-
'pink',
130-
'red',
131-
'orange',
132-
'amber',
133-
'dark',
134-
],
135-
predefinedSizes: [
136-
'sm',
137-
'md',
138-
'lg',
139-
],
140-
};
81+
/**
82+
* Especifica o texto a ser apresentado no corpo do botão.
83+
* Este texto será exibido apenas se o slot default não for utilizado.
84+
*/
85+
text: {
86+
type: String,
87+
default: 'Click here',
14188
},
142-
143-
computed: {
144-
widthResolver() {
145-
return this.block ? '100%' : 'max-content';
146-
},
147-
148-
tooltipDisabled() {
149-
return this.disabled && this.tooltipText !== '' ? this.tooltipText : null;
150-
},
151-
152-
predefinedColor() {
153-
if (this.ghost) {
154-
return 'button--ghost';
155-
}
156-
157-
if (this.secondary) {
158-
return 'button--secondary';
159-
}
160-
161-
if (this.predefinedColors.indexOf(this.variant) > -1) {
162-
return `button--${this.variant}`;
163-
}
164-
165-
return 'button--green';
166-
},
167-
168-
predefinedSize() {
169-
if (this.predefinedSizes.indexOf(this.size) > -1) {
170-
return `button-size--${this.size}`;
171-
}
172-
return 'button-size--md';
173-
},
174-
175-
computedStyle() {
176-
const disabled = this.disabled ? '--disabled' : '--active';
177-
178-
return `${this.predefinedColor}${disabled} ${this.predefinedSize}`;
179-
},
89+
/**
90+
* Controla a disponibilidade do Botão.
91+
*/
92+
disabled: {
93+
type: Boolean,
94+
default: false,
18095
},
96+
/**
97+
* Texto a ser exibido como tooltip com o hover do botão quando a prop disabled estiver ativa.
98+
*/
99+
tooltipText: {
100+
type: String,
101+
default: null,
102+
},
103+
/**
104+
* Especifica se a versão do Botão é a secundária.
105+
*/
106+
secondary: {
107+
type: Boolean,
108+
default: false,
109+
},
110+
/**
111+
* Especifica se o botão deve mostrar spinner de carregamento.
112+
* Caso o botão seja do tipo ghost ou secondary a variante do spinner é a mesma passada na prop variant.
113+
*/
114+
loading: {
115+
type: Boolean,
116+
default: false,
117+
},
118+
/**
119+
* Especifica se o componente deve ser exibido na sua versão ghost.
120+
*/
121+
ghost: {
122+
type: Boolean,
123+
default: false,
124+
},
125+
});
126+
127+
const emits = defineEmits([
128+
/**
129+
* Evento que indica que o Botão foi clicado
130+
* @event button-click
131+
* @type {Event}
132+
*/
133+
'button-click',
134+
]);
135+
136+
const widthResolver = computed(() => {
137+
return props.block ? '100%' : 'max-content';
138+
});
139+
const tooltipDisabled = computed(() => {
140+
return props.disabled && props.tooltipText !== '' ? props.tooltipText : null;
141+
});
142+
const predefinedColor = computed(() => {
143+
if (props.ghost) {
144+
return 'button--ghost';
145+
}
181146
182-
methods: {
183-
hasSlot,
147+
if (props.secondary) {
148+
return 'button--secondary';
149+
}
184150
185-
clickHandler() {
186-
if (this.disabled) {
187-
return;
188-
}
189-
/**
190-
* Evento que indica que o Botão foi clicado
191-
* @event button-click
192-
* @type {Event}
193-
*/
194-
this.$emit('button-click', true);
195-
},
196-
},
197-
};
151+
if (predefinedColors.indexOf(props.variant) > -1) {
152+
return `button--${props.variant}`;
153+
}
154+
155+
return 'button--green';
156+
});
157+
const predefinedSize = computed(() => {
158+
if (predefinedSizes.indexOf(props.size) > -1) {
159+
return `button-size--${props.size}`;
160+
}
161+
return 'button-size--md';
162+
});
163+
const computedStyle = computed(() => {
164+
const disabled = props.disabled ? '--disabled' : '--active';
165+
166+
return `${predefinedColor.value}${disabled} ${predefinedSize.value}`;
167+
});
168+
const computedSpinnerVariant = computed(() => {
169+
return props.secondary || props.ghost ? props.variant : 'white';
170+
});
171+
172+
function clickHandler() {
173+
if (props.disabled) {
174+
return;
175+
}
176+
emits('button-click', true);
177+
}
198178
</script>
179+
199180
<style lang="scss" scoped>
200181
@use 'sass:color';
201182
@use '../assets/sass/tokens/index' as tokens;
@@ -207,7 +188,7 @@ export default {
207188
color: tokens.$n-700;
208189
border: 1px solid tokens.$n-50 !important;
209190
outline: none !important;
210-
191+
211192
&:hover {
212193
@extend .button--secondary--active;
213194
background-color: tokens.$n-20;

0 commit comments

Comments
 (0)