Skip to content

Commit

Permalink
feature(#788) : update KtCard component
Browse files Browse the repository at this point in the history
- added a div for image skeleton, header skeleton, and body skeleton
- added a class --is-clickable for clickable cards with its associated style
- created computed property hasActions that return true if 2 actions props are defined
- removed footer slot as we want only to have buttons in the footer (design is ok)
- added props: isImgLoading, isTextLoading, primaryActionLabel, secondaryActionLabel, dataTests ...
- added a size sm to skeleton size for rectangle
- updated documentation for KtCard
  • Loading branch information
RueRivoli committed Aug 4, 2023
1 parent d577c6d commit 2dd954e
Show file tree
Hide file tree
Showing 5 changed files with 105 additions and 13 deletions.
4 changes: 2 additions & 2 deletions packages/documentation/components/CodePreview.vue
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,12 @@ export default defineComponent({
padding-top: var(--unit-2);
&__switcher {
width: fit-content;
padding: var(--unit-1) var(--unit-2);
margin-bottom: var(--unit-3);
font-size: 12px;
color: var(--white);
background: rgba(0, 0, 0, 0.4);
width: fit-content;
margin-bottom: var(--unit-3);
&:hover {
cursor: pointer;
Expand Down
42 changes: 42 additions & 0 deletions packages/documentation/pages/usage/components/card.vue
Original file line number Diff line number Diff line change
@@ -1,7 +1,49 @@
<template>
<div>
<ComponentInfo v-bind="{ component }" />
<div class="card-view-example">
<KtCard
v-bind="{ imgPosition }"
imgUrl="https://picsum.photos/900/300"
primaryActionLabel="Confirm"
secondaryActionLabel="Cancel"
>
<h2 slot="card-header">Lorem Ipsum</h2>
<p slot="card-body">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus
consequat nisl at nisl condimentum vehicula.
</p>
</KtCard>
</div>
<br />

<div class="card-view-example-2">
<KtCard v-bind="{ imgPosition }" imgUrl="https://picsum.photos/900/300">
<h2 slot="card-header">Lorem Ipsum</h2>
<p slot="card-body">
Moebius ring by pmaegermanis licensed under CC BY 3.0 (Creative
Commons https://www.thingiverse.com/thing:1649028
</p>
</KtCard>
</div>
<br />
<div class="card-view-example-skeleton">
<KtCard
v-bind="{ imgPosition }"
imgUrl="https://picsum.photos/900/300"
:isImgLoading="true"
:isTextLoading="true"
primaryActionLabel="Confirm"
secondaryActionLabel="Cancel"
>
<h2 slot="card-header">Lorem Ipsum</h2>
<p slot="card-body">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus
consequat nisl at nisl condimentum vehicula.
</p>
</KtCard>
</div>
<br />
<div class="element-example">
<KtCard>
<div slot="card-header">
Expand Down
62 changes: 51 additions & 11 deletions packages/kotti-ui/source/kotti-card/KtCard.vue
Original file line number Diff line number Diff line change
@@ -1,36 +1,64 @@
<template>
<div :class="cardClass">
<div :class="cardClass" tabindex="0" @click.prevent="handleClick">
<div v-if="imgUrl" :class="imageRowClass">
<img class="kt-card__image-row__image" :src="imgUrl" />
<div v-if="isImgLoading" class="skeleton square md" />
<img v-else class="kt-card__image-row__image" :src="imgUrl" />
</div>
<div v-if="$slots['card-header']" class="kt-card__header">
<slot name="card-header" />
<div v-if="isTextLoading" class="skeleton rectangle md" />
<slot v-else name="card-header" />
</div>
<div v-if="$slots['card-body']" class="kt-card__body">
<slot name="card-body" />
<div v-if="isTextLoading" class="skeleton rectangle sm" />
<slot v-else name="card-body" />
</div>
<div v-if="$slots['card-footer']" class="kt-card__footer">
<slot name="card-footer" />
<div v-if="hasActions" class="kt-card__footer">
<div v-if="hasActions && !isTextLoading">
<KtButton
:data-test="secondaryActionDataTest"
:label="secondaryActionLabel"
type="text"
@click.prevent="$emit('clickOnSecondaryButton')"
/>
<KtButton
:data-test="primaryActionDataTest"
:label="primaryActionLabel"
type="primary"
@click.prevent="$emit('clickOnPrimaryButton')"
/>
</div>
</div>
</div>
</template>

<script lang="ts">
import { computed, defineComponent } from '@vue/composition-api'
import { KtButton } from '../kotti-button'
import { makeProps } from '../make-props'
import { KottiCard } from './types'
export default defineComponent<KottiCard.PropsInternal>({
name: 'KtCard',
components: { KtButton },
props: makeProps(KottiCard.propsSchema),
setup(props) {
setup(props, { emit }) {
const hasActions = computed(
() =>
props.primaryActionLabel != null && props.secondaryActionLabel != null,
)
return {
cardClass: computed(() => ({
'kt-card': true,
'kt-card--is-clickable': !hasActions.value,
[`kt-card--has-${props.imgPosition}-image`]: props.imgUrl,
})),
handleClick: () => {
if (!hasActions.value) emit('click')
},
hasActions,
imageRowClass: computed(() => ({
'kt-card__image-row': true,
[`kt-card__image-row--is-${props.imgPosition}`]: props.imgUrl,
Expand All @@ -48,18 +76,30 @@ export default defineComponent<KottiCard.PropsInternal>({
padding: var(--unit-4);
word-break: break-word;
background: var(--ui-background);
border: 1px solid var(--ui-02);
border-radius: var(--border-radius);
&--has-top-image {
padding-top: 0;
}
&--has-bottom-image {
padding-bottom: 0;
}
&--is-clickable {
&:hover {
cursor: pointer;
border: 1px solid var(--interactive-01-hover);
}
&:active {
border-color: var(--primary-90);
}
}
.skeleton {
margin: 0;
}
&__header {
order: 2;
.skeleton {
margin: 0 0 var(--unit-2) 0;
}
}
&__body {
Expand All @@ -74,7 +114,7 @@ export default defineComponent<KottiCard.PropsInternal>({
&__image-row {
&__image {
display: block;
max-width: 100%;
width: 100%;
}
margin: var(--unit-4) calc(-1 * var(--unit-4));
Expand Down
6 changes: 6 additions & 0 deletions packages/kotti-ui/source/kotti-card/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,12 @@ export namespace KottiCard {
export const propsSchema = z.object({
imgPosition: z.nativeEnum(ImagePosition).default(ImagePosition.TOP),
imgUrl: z.string().nullable().default(null),
isImgLoading: z.boolean().default(false),
isTextLoading: z.boolean().default(false),
primaryActionLabel: z.string().nullable().default(null),
primaryActionDataTest: z.string().optional(),
secondaryActionLabel: z.string().nullable().default(null),
secondaryActionDataTest: z.string().optional(),
})

export type Props = z.input<typeof propsSchema>
Expand Down
4 changes: 4 additions & 0 deletions packages/kotti-ui/source/kotti-style/_loadings.scss
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,10 @@
@include skeleton-style(1800px, 1200px);
height: 0.4rem;

&.sm {
height: 0.4rem;
}

&.md {
height: 0.8rem;
}
Expand Down

0 comments on commit 2dd954e

Please sign in to comment.