|
1 | 1 | <!-- eslint-disable vue/multi-word-component-names --> |
2 | 2 | <template> |
3 | | - <cds-box |
| 3 | + <CdsBox |
4 | 4 | padding="0" |
5 | 5 | :clickable="clickable" |
6 | | - @boxClick="handleClick" |
| 6 | + :fluid="fluid" |
| 7 | + @box-click="handleClick" |
7 | 8 | > |
8 | 9 | <div class="card__extra-container"> |
9 | 10 | <div class="card__extra"> |
|
12 | 13 | </div> |
13 | 14 | </div> |
14 | 15 |
|
15 | | - <div :class="{'card--horizontal': this.horizontal}"> |
| 16 | + <div :class="{'card--horizontal': horizontal}"> |
16 | 17 | <div |
17 | 18 | v-if="hasSlot($slots, 'image')" |
18 | 19 | > |
|
24 | 25 | v-else-if="imageSrc" |
25 | 26 | class="card__image" |
26 | 27 | > |
27 | | - <cds-image |
| 28 | + <CdsImage |
28 | 29 | :src="imageSrc" |
29 | | - :width="imageWidth" |
| 30 | + :width="imageWidthResolver" |
30 | 31 | :height="imageHeight" |
31 | 32 | :alt="imageAlt" |
32 | 33 | /> |
|
51 | 52 | <slot name="header" /> |
52 | 53 | </div> |
53 | 54 |
|
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> |
56 | 59 | </div> |
57 | 60 |
|
58 | 61 | <div |
|
63 | 66 | <slot name="body" /> |
64 | 67 | </div> |
65 | 68 |
|
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> |
68 | 73 | </div> |
69 | 74 |
|
70 | 75 | <div |
|
76 | 81 | </div> |
77 | 82 | </div> |
78 | 83 | </div> |
79 | | - </cds-box> |
| 84 | + </CdsBox> |
80 | 85 | </template> |
81 | 86 |
|
82 | | -<script> |
| 87 | +<script setup> |
| 88 | +import { computed, defineProps } from 'vue'; |
| 89 | +import hasSlot from '../utils/methods/hasSlot'; |
83 | 90 | import CdsBox from './Box.vue'; |
84 | 91 | import CdsImage from './Image.vue'; |
85 | 92 |
|
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: '', |
92 | 100 | }, |
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, |
158 | 151 | }, |
| 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 | +}) |
159 | 167 |
|
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 | +]); |
164 | 176 |
|
165 | | - bodyWidthResolver() { |
166 | | - return `${this.bodyWidth}px`; |
167 | | - }, |
168 | | - }, |
| 177 | +const cardSpacerMaxWidthResolver = computed(() => { |
| 178 | + if (props.fluid) { |
| 179 | + return '100%'; |
| 180 | + } |
169 | 181 |
|
170 | | - methods: { |
171 | | - hasSlot, |
| 182 | + return props.horizontal ? 'fit-content' : `${props.imageWidth}px`; |
| 183 | +}); |
172 | 184 |
|
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 | + } |
184 | 199 | } |
185 | 200 | </script> |
186 | 201 |
|
@@ -228,7 +243,7 @@ export default { |
228 | 243 | |
229 | 244 | &__spacer { |
230 | 245 | padding: tokens.pa(5); |
231 | | - max-width: v-bind(imageWidthResolver); |
| 246 | + max-width: v-bind(cardSpacerMaxWidthResolver); |
232 | 247 | } |
233 | 248 | |
234 | 249 | &__footer { |
|
0 commit comments