Skip to content

Commit 87e460b

Browse files
authored
Merge pull request #1013 from Sysvale/feat/fluid-card
feat: adiciona comportamento fluido ao card e refatora para composition api
2 parents bb3f931 + 4c38657 commit 87e460b

File tree

2 files changed

+120
-105
lines changed

2 files changed

+120
-105
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.143.0",
3+
"version": "3.144.0",
44
"description": "A design system built by Sysvale, using storybook and Vue components",
55
"repository": {
66
"type": "git",

src/components/Card.vue

Lines changed: 119 additions & 104 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
<!-- eslint-disable vue/multi-word-component-names -->
22
<template>
3-
<cds-box
3+
<CdsBox
44
padding="0"
55
:clickable="clickable"
6-
@boxClick="handleClick"
6+
:fluid="fluid"
7+
@box-click="handleClick"
78
>
89
<div class="card__extra-container">
910
<div class="card__extra">
@@ -12,7 +13,7 @@
1213
</div>
1314
</div>
1415

15-
<div :class="{'card--horizontal': this.horizontal}">
16+
<div :class="{'card--horizontal': horizontal}">
1617
<div
1718
v-if="hasSlot($slots, 'image')"
1819
>
@@ -24,9 +25,9 @@
2425
v-else-if="imageSrc"
2526
class="card__image"
2627
>
27-
<cds-image
28+
<CdsImage
2829
:src="imageSrc"
29-
:width="imageWidth"
30+
:width="imageWidthResolver"
3031
:height="imageHeight"
3132
:alt="imageAlt"
3233
/>
@@ -51,8 +52,10 @@
5152
<slot name="header" />
5253
</div>
5354

54-
<div v-else="title">
55-
<p class="card__header">{{ title }}</p>
55+
<div v-else>
56+
<p class="card__header">
57+
{{ title }}
58+
</p>
5659
</div>
5760

5861
<div
@@ -63,8 +66,10 @@
6366
<slot name="body" />
6467
</div>
6568

66-
<div v-else="content">
67-
<p class="card__body">{{ content }}</p>
69+
<div v-else>
70+
<p class="card__body">
71+
{{ content }}
72+
</p>
6873
</div>
6974

7075
<div
@@ -76,111 +81,121 @@
7681
</div>
7782
</div>
7883
</div>
79-
</cds-box>
84+
</CdsBox>
8085
</template>
8186

82-
<script>
87+
<script setup>
88+
import { computed, defineProps } from 'vue';
89+
import hasSlot from '../utils/methods/hasSlot';
8390
import CdsBox from './Box.vue';
8491
import CdsImage from './Image.vue';
8592
86-
import hasSlot from '../utils/methods/hasSlot';
87-
88-
export default {
89-
components: {
90-
CdsBox,
91-
CdsImage,
93+
const props = defineProps({
94+
/**
95+
* Especifica o título do card. Quando conteúdo é enviado para o slot `Header` o conteúdo dessa prop não é exibido.
96+
*/
97+
title: {
98+
type: String,
99+
default: '',
92100
},
93-
94-
props: {
95-
/**
96-
* Especifica o título do card. Quando conteúdo é enviado para o slot `Header` o conteúdo dessa prop não é exibido.
97-
*/
98-
title: {
99-
type: String,
100-
default: '',
101-
},
102-
/**
103-
* Especifica texto do Card. Quando conteúdo é enviado para o slot `Body` o conteúdo dessa prop não é exibido.
104-
*/
105-
content: {
106-
type: String,
107-
default: '',
108-
},
109-
/**
110-
* Caminho da imagem que vai ser renderizada. Quando conteúdo é enviado para o slot `Image` o conteúdo dessa prop não é exibido.
111-
*/
112-
imageSrc: {
113-
type: String,
114-
default: '',
115-
},
116-
/**
117-
* Descrição em texto da imagem.
118-
*/
119-
imageAlt: {
120-
type: String,
121-
default: 'imagem do card',
122-
},
123-
/**
124-
* Largura da imagem do card.
125-
*/
126-
imageWidth: {
127-
type: [String, Number],
128-
default: 300,
129-
},
130-
/**
131-
* Altura da imagem do card.
132-
*/
133-
imageHeight: {
134-
type: [String, Number],
135-
default: 180,
136-
},
137-
/**
138-
* Largura do conteúdo do card.
139-
*/
140-
bodyWidth: {
141-
type: [String, Number],
142-
default: 300,
143-
},
144-
/**
145-
* Torna o alinhamento do Card horizontal.
146-
*/
147-
horizontal: {
148-
type: Boolean,
149-
default: false,
150-
},
151-
/**
152-
* Ativa ou desativa o clique no componente
153-
*/
154-
clickable: {
155-
type: Boolean,
156-
default: false,
157-
},
101+
/**
102+
* Especifica texto do Card. Quando conteúdo é enviado para o slot `Body` o conteúdo dessa prop não é exibido.
103+
*/
104+
content: {
105+
type: String,
106+
default: '',
107+
},
108+
/**
109+
* Caminho da imagem que vai ser renderizada. Quando conteúdo é enviado para
110+
o slot `Image` o conteúdo dessa prop não é exibido.
111+
*/
112+
imageSrc: {
113+
type: String,
114+
default: '',
115+
},
116+
/**
117+
* Descrição em texto da imagem.
118+
*/
119+
imageAlt: {
120+
type: String,
121+
default: 'imagem do card',
122+
},
123+
/**
124+
* Largura da imagem do card. Tem comportamento sobrescrito quando o card é vertical
125+
e a prop `fluid` está ativa.
126+
*/
127+
imageWidth: {
128+
type: [String, Number],
129+
default: 300,
130+
},
131+
/**
132+
* Altura da imagem do card.
133+
*/
134+
imageHeight: {
135+
type: [String, Number],
136+
default: 180,
137+
},
138+
/**
139+
* Largura do conteúdo do card.
140+
*/
141+
bodyWidth: {
142+
type: [String, Number],
143+
default: 300,
144+
},
145+
/**
146+
* Torna o alinhamento do Card horizontal.
147+
*/
148+
horizontal: {
149+
type: Boolean,
150+
default: false,
158151
},
152+
/**
153+
* Ativa ou desativa o clique no componente
154+
*/
155+
clickable: {
156+
type: Boolean,
157+
default: false,
158+
},
159+
/**
160+
* Ativa ou desativa o comportamento fluido do Card
161+
*/
162+
fluid: {
163+
type: Boolean,
164+
default: false
165+
}
166+
})
159167
160-
computed: {
161-
imageWidthResolver() {
162-
return this.horizontal ? 'fit-content' : `${this.imageWidth}px`;
163-
},
168+
const emits = defineEmits([
169+
/**
170+
* Evento que indica se o card foi clicado.
171+
* @event cardClick
172+
* @type {Event}
173+
*/
174+
'cardClick'
175+
]);
164176
165-
bodyWidthResolver() {
166-
return `${this.bodyWidth}px`;
167-
},
168-
},
177+
const cardSpacerMaxWidthResolver = computed(() => {
178+
if (props.fluid) {
179+
return '100%';
180+
}
169181
170-
methods: {
171-
hasSlot,
182+
return props.horizontal ? 'fit-content' : `${props.imageWidth}px`;
183+
});
172184
173-
handleClick() {
174-
if (this.clickable) {
175-
/**
176-
* Evento que indica se o card foi clicado.
177-
* @event cardClick
178-
* @type {Event}
179-
*/
180-
this.$emit('cardClick', true);
181-
}
182-
},
183-
},
185+
const bodyWidthResolver = computed(() => {
186+
return `${props.bodyWidth}px`;
187+
})
188+
189+
const imageWidthResolver = computed(() => {
190+
if (props.fluid && !props.horizontal) return '100%';
191+
192+
return props.imageWidth
193+
})
194+
195+
function handleClick() {
196+
if (props.clickable) {
197+
emits('cardClick', true);
198+
}
184199
}
185200
</script>
186201

@@ -228,7 +243,7 @@ export default {
228243
229244
&__spacer {
230245
padding: tokens.pa(5);
231-
max-width: v-bind(imageWidthResolver);
246+
max-width: v-bind(cardSpacerMaxWidthResolver);
232247
}
233248
234249
&__footer {

0 commit comments

Comments
 (0)