Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(kcard): component reskin [KHCP-8971] #1804

Merged
merged 22 commits into from
Dec 5, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
6addadc
chore(sandbox): setup component sandbox [KHCP-8971]
portikM Oct 31, 2023
5369c37
feat(kcard): reskin component [KHCP-8971]
portikM Oct 31, 2023
f11bfff
test(kcard): update component tests [KHCP-8971]
portikM Oct 31, 2023
92c5926
fix(kcard): deprecate body slot instead of removing [KHCP-8971]
portikM Oct 31, 2023
09dc8a2
test(kcatalog): fix component tests [KHCP-8971]
portikM Oct 31, 2023
f5cac37
docs(kcard): update component docs [KHCP-8971]
portikM Oct 31, 2023
c93204f
fix(kcard): deprecate body prop instead of removing [KHCP-8971]
portikM Oct 31, 2023
a94b057
fix(kcard): address PR feedback [KHCP-8971]
portikM Nov 1, 2023
e5b901b
fix(kcard): address PR feedback [KHCP-8971]
portikM Nov 1, 2023
5de65ea
test(kcard): fix component tests [KHCP-8971]
portikM Nov 1, 2023
d12fab5
fix(kcard): address PR feedback [KHCP-8971]
portikM Nov 1, 2023
60ef18b
chore(sandbox): rebase [KHCP-8971]
portikM Nov 6, 2023
3bb80ff
fix(sandbox): rebase [KHCP-8971]
portikM Nov 6, 2023
70f0e98
fix: address PR feedback
portikM Nov 30, 2023
9caeccc
fix(kcard): address PR feedback [KHCP-8971]
portikM Nov 30, 2023
a257ce7
fix(mixins): address PR feedback [KHCP-8971]
portikM Nov 30, 2023
ae86f68
fix(kcard): card content full height [KHCP-8971]
portikM Dec 1, 2023
26905ee
fix(kcard): card content display [KHCP-8971]
portikM Dec 1, 2023
7401a9a
fix(kcard): card actions alignment [KHCP-8971]
portikM Dec 4, 2023
c2d6cd5
fix(sandbox): minor fix [KHCP-8971]
portikM Dec 4, 2023
2b166a2
fix(kslideout): fix kcard style overrides [KHCP-8971]
portikM Dec 4, 2023
b4c8a7b
fix(kslideout): fix style overrides [KHCP-8971]
portikM Dec 4, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
354 changes: 131 additions & 223 deletions docs/components/card.md

Large diffs are not rendered by default.

16 changes: 12 additions & 4 deletions docs/components/collapse.md
Original file line number Diff line number Diff line change
Expand Up @@ -166,9 +166,13 @@ To set the default state (collapsed or expanded) without binding to v-model you
</div>
</template>
<template #visible-content>
<KCard body="I am content that is always visible" />
<KCard>
I am content that is always visible
</KCard>
</template>
<KCard body="I am only visible when expanded" />
<KCard>
I am only visible when expanded
</KCard>
</KCollapse>
</template>
</KCard>
Expand All @@ -182,10 +186,14 @@ To set the default state (collapsed or expanded) without binding to v-model you
</div>
</template>
<template #visible-content>
<KCard body="I am content that is always visible" />
<KCard>
I am content that is always visible
</KCard>
</template>

<KCard body="I am only visible when expanded" />
<KCard>
I am only visible when expanded
</KCard>
</KCollapse>
```

Expand Down
33 changes: 33 additions & 0 deletions docs/guide/migrating-to-version-9.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,39 @@ Kongponents styles are no longer designed to be utilized standalone, separately

### KCard

#### Props

* `testMode` prop has been removed
* `body` prop has been removed. Use `default` slot instead
* `borderVariant` prop has been removed. KCard has a border by default
* `hasHover` prop has been removed
* `hasShadow` prop has been removed. KCard does not have a box-shadow by default
* `status` prop has been removed

#### Slots

* `statusHat` slot has been removed
* `body` slot has been removed. Use the `default` slot instead
* `notifications` slot has been removed

#### Structure

* `kong-card` class has been changed to `k-card`
* `hover` class has been removed
* `kcard-shadow` class has been removed
* `k-card-header` class has been changed to `card-header`
* `has-status` class has been removed
* `k-card-status-hat` class has been removed
* `k-card-title` class has been changed to `card-title`
* `k-card-actions` class has been changed to `card-actions`
* `k-card-content` class has been changed to `card-content`
* `k-card-body` class has been removed
* `k-card-notifications` class has been removed

#### Constants, Types & Interfaces

* `BorderVariantsArray` constant has been removed
* `BorderVariant` type has been removed

### KCatalog

Expand Down
1 change: 1 addition & 0 deletions sandbox/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ app.component('SandboxLayout', SandboxLayout)
const sandboxAppLinks: SandboxNavigationItem[] = ([
{ name: 'KAlert', to: { name: 'alert' } },
{ name: 'KButton', to: { name: 'button' } },
{ name: 'KCard', to: { name: 'card' } },
{ name: 'KCatalog', to: { name: 'catalog' } },
{ name: 'KCheckbox', to: { name: 'checkbox' } },
{ name: 'KDropdown', to: { name: 'dropdown' } },
Expand Down
128 changes: 128 additions & 0 deletions sandbox/pages/SandboxCard.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
<template>
<SandboxLayout
:links="inject('app-links', [])"
title="KCard"
>
<div class="kcard-sandbox">
<SandboxTitleComponent
title="KCard"
>
<template #description>
<KExternalLink href="https://www.figma.com/file/Yze0SWXl5nKjR0rFdilljK/Components?type=design&node-id=1152%3A19831&mode=dev">
Figma
</KExternalLink>
</template>
</SandboxTitleComponent>

<!-- Props -->
<SandboxTitleComponent
is-subtitle
title="Props"
/>
<SandboxSectionComponent title="title">
<KCard title="Card title">
Card content slot
</KCard>
</SandboxSectionComponent>

<!-- Slots -->
<SandboxTitleComponent
is-subtitle
title="Props"
/>
<SandboxSectionComponent title="title & content & actions & footer">
<div>
<KCard>
<template #title>
Card title
</template>
<template #actions>
<KDropdown
:items="[
{ label: 'Home', to: { name: 'home' } },
{ label: 'KDropdown', to: { name: 'dropdown' } },
{ label: 'Stay', to: { name: 'card' } }
]"
>
<KButton
appearance="tertiary"
class="icon-button"
size="small"
>
<MoreIcon />
</KButton>
</KDropdown>
</template>
<div>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt <em>ut labore</em> et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. <b>Excepteur sint occaecat cupidatat non proident</b>, sunt in culpa qui officia deserunt mollit anim id est laborum.</div>
<template #footer>
<KBadge appearance="success">
Published
</KBadge>
<KBadge>2 versions</KBadge>
</template>
</KCard>
</div>
<div class="limit-width">
<KCard>
<template #title>
Example of very long card title that should not be truncated with ellipsis and should wrap to the next line even if it is too long
</template>
<template #actions>
<KDropdown
:items="[
{ label: 'Home', to: { name: 'home' } },
{ label: 'KDropdown', to: { name: 'dropdown' } },
{ label: 'Stay', to: { name: 'card' } }
]"
>
<KButton
appearance="tertiary"
class="icon-button"
size="small"
>
<MoreIcon />
</KButton>
</KDropdown>
</template>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
<template #footer>
<CheckIcon
:color="KUI_COLOR_TEXT_SUCCESS"
:size="KUI_ICON_SIZE_40"
/>
Approved
</template>
</KCard>
</div>
</SandboxSectionComponent>
</div>
</SandboxLayout>
</template>

<script setup lang="ts">
import { inject } from 'vue'
import SandboxTitleComponent from '../components/SandboxTitleComponent.vue'
import SandboxSectionComponent from '../components/SandboxSectionComponent.vue'
import { MoreIcon, CheckIcon } from '@kong/icons'
import { KUI_COLOR_TEXT_SUCCESS, KUI_ICON_SIZE_40 } from '@kong/design-tokens'
</script>

<style scoped lang="scss">
.kcard-sandbox {
.horizontal-spacing {
display: flex;
gap: $kui-space-50;
}

.limit-width {
/* stylelint-disable-next-line @kong/design-tokens/use-proper-token */
max-width: $kui-breakpoint-mobile;
}

.footer-content {
color: $kui-color-text-success;
display: flex;
gap: $kui-space-30;
}
}
</style>
6 changes: 6 additions & 0 deletions sandbox/router/sandbox-routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,12 @@ const componentRoutes: RouteRecordRaw[] = [
meta: { title: 'Button Sandbox' },
component: () => import('../pages/SandboxButton.vue'),
},
{
path: '/card',
name: 'card',
meta: { title: 'Card Sandbox' },
component: () => import('../pages/SandboxCard.vue'),
},
{
path: '/catalog',
name: 'catalog',
Expand Down
91 changes: 23 additions & 68 deletions src/components/KCard/KCard.cy.ts
Original file line number Diff line number Diff line change
@@ -1,92 +1,47 @@
import { mount } from 'cypress/vue'
import KCard from '@/components/KCard/KCard.vue'
import { h } from 'vue'

/**
* ALL TESTS MUST USE testMode: true
* We generate unique IDs for reference by aria properties. Test mode strips these out
* allowing for successful snapshot verification.
* props: {
* testMode: true
* }
*/
describe('KCard', () => {
adamdehaven marked this conversation as resolved.
Show resolved Hide resolved
it('renders slots when passed', () => {
const cardStatusHat = 'Card Status Hat'
const cardTitle = 'Card Title'
const cardActions = 'Card Actions'
const cardBody = 'Card Body'
const cardNotifications = 'Card Notifications'
it('renders empty card element when no props or slots are passed', () => {
mount(KCard)

mount(KCard, {
props: {
testMode: true,
},
slots: {
statusHat: () => h('span', {}, cardStatusHat),
title: () => h('span', {}, cardTitle),
actions: () => h('span', {}, cardActions),
body: () => h('span', {}, cardBody),
notifications: () => h('span', {}, cardNotifications),
},
})

cy.get('.k-card-status-hat').should('contain.text', cardStatusHat)
cy.get('.k-card-title').should('contain.text', cardTitle)
cy.get('.k-card-actions').should('contain.text', cardActions)
cy.get('.k-card-body').should('contain.text', cardBody)
cy.get('.k-card-notifications').should('contain.text', cardNotifications)
cy.get('.k-card').should('be.visible')
cy.get('.k-card').find('card-header').should('not.exist')
cy.get('.k-card').find('card-content').should('not.exist')
cy.get('.k-card').find('card-footer').should('not.exist')
})

it('renders proper content when using props', () => {
const cardStatus = 'Card Status'
const cardTitle = 'Card Title'
const cardBody = 'Card Body'
it('renders title prop when passed', () => {
const titleProp = 'Title prop'

mount(KCard, {
props: {
testMode: true,
status: cardStatus,
title: cardTitle,
body: cardBody,
title: titleProp,
},
})

cy.get('.k-card-status-hat').should('have.text', cardStatus)
cy.get('.k-card-title').should('have.text', cardTitle)
cy.get('.k-card-body').should('have.text', cardBody)
cy.get('.k-card').find('.card-title').should('contain', titleProp)
})

it('has border class when passed', () => {
mount(KCard, {
props: {
testMode: true,
hasBorder: true,
},
})

cy.get('.kong-card').should('have.class', 'border')
})
it('renders slots when passed', () => {
const titleProp = 'Test title'
const titleText = 'I am the title'

it('has hover class when passed', () => {
mount(KCard, {
props: {
testMode: true,
hasHover: true,
title: titleProp,
},
})

cy.get('.kong-card').should('have.class', 'hover')
})

it('has shadow class when passed', () => {
mount(KCard, {
props: {
testMode: true,
hasShadow: true,
slots: {
title: `<span data-testid="card-title">${titleText}</span>`,
actions: '<span data-testid="card-actions">Card actions</span>',
default: '<span data-testid="card-content">Card content</span>',
footer: '<span data-testid="card-footer">Card footer</span>',
},
})

cy.get('.kong-card').should('have.class', 'kcard-shadow')
cy.get('.k-card').find('.card-title').get('[data-testid="card-title"]').should('contain', titleText)
cy.get('.k-card').find('.card-actions').get('[data-testid="card-actions"]').should('be.visible')
cy.get('.k-card').find('.card-content').get('[data-testid="card-content"]').should('be.visible')
cy.get('.k-card').find('.card-footer').get('[data-testid="card-footer"]').should('be.visible')
})
})
Loading
Loading