-
Notifications
You must be signed in to change notification settings - Fork 10
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(entities-shared): create shared empty state component [KHCP-14355]
- Loading branch information
Showing
9 changed files
with
344 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
77 changes: 77 additions & 0 deletions
77
packages/entities/entities-shared/docs/entity-empty-state.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
# EntityEmptyState.vue | ||
|
||
An empty state component that displays title, description, and optionally pricing, action button, learn more, and a set of features cards. Used for engaging and onboarding new users with rich information and context. | ||
|
||
- [Requirements](#requirements) | ||
- [Usage](#usage) | ||
- [Install](#install) | ||
- [Props](#props) | ||
- [Usage example](#usage-example) | ||
- [TypeScript interfaces](#typescript-interfaces) | ||
|
||
## Requirements | ||
|
||
- `vue` must be initialized in the host application | ||
- `@kong/kongponents` must be added as a `dependency` in the host application, globally available via the Vue Plugin installation, and the package's style imports must be added in the app entry file. [See here for instructions on installing Kongponents](https://kongponents.konghq.com/#globally-install-all-kongponents). | ||
|
||
## Usage | ||
|
||
### Install | ||
|
||
[See instructions for installing the `@kong-ui-public/entities-shared` package.](../README.md#install) | ||
|
||
### Props | ||
|
||
#### `title` | ||
|
||
- type: `String` | ||
- required: `true` | ||
|
||
Title for the empty state. | ||
|
||
#### `description` | ||
|
||
- type: `String` | ||
- default: `''` | ||
|
||
Description for the empty state. | ||
|
||
#### `pricing` | ||
|
||
- type: `String` | ||
- default: `` | ||
|
||
If provided, will display pricing information for transparency. | ||
|
||
#### `actionButtonText` | ||
|
||
- type: `String` | ||
- default: `` | ||
|
||
If provided, a CTA button will show with text and icon typically, for creating an entity. | ||
|
||
#### `learnMoreLink` | ||
|
||
- type: `String` | ||
- default: `` | ||
|
||
If provided, will link to the Learning Hub link for the entity. | ||
|
||
#### `features` | ||
|
||
- type: `Array` | ||
- default: `[]` | ||
|
||
If provided, will display card for each feature of that entity, along with an icon, a tilte and a short description. | ||
|
||
### Usage example | ||
|
||
Please refer to the [sandbox](../src/components/entity-empty-state/EntityEmptyState.vue). | ||
|
||
## TypeScript interfaces | ||
|
||
TypeScript interfaces [are available here](https://github.com/Kong/public-ui-components/blob/main/packages/entities/entities-shared/src/types/entity-empty-state.ts) and can be directly imported into your host application. The following type interfaces are available for import: | ||
|
||
```ts | ||
import type { EmptyStateFeature } from '@kong-ui-public/entities-shared' | ||
``` |
43 changes: 43 additions & 0 deletions
43
packages/entities/entities-shared/sandbox/pages/EntityEmptyStatePage.vue
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
<template> | ||
<div class="sandbox-container"> | ||
<main> | ||
<h3>Entity empty state</h3> | ||
<EntityEmptyState | ||
action-button-text="Create a gateway" | ||
description="Lorem ipsum dolor sit amet consectetur adipisicing elit. Id quidem aperiam similique vitae beatae. Repellat quam voluptas vitae, maxime consequuntur praesentium suscipit. Numquam aliquid nulla vel esse accusantium reiciendis error?" | ||
:features="features" | ||
title="Gateway Manager" | ||
> | ||
<template #icon> | ||
<RuntimesIcon /> | ||
</template> | ||
</EntityEmptyState> | ||
</main> | ||
</div> | ||
</template> | ||
|
||
<script setup lang="ts"> | ||
import { EntityEmptyState } from '../../src' | ||
import { RuntimesIcon } from '@kong/icons' | ||
const features = [ | ||
{ | ||
icon: RuntimesIcon, | ||
title: 'First', | ||
description: 'Lorem ipsum dolor sit amet consectetur adipisicing elit. Id quidem aperiam similique vitae beatae', | ||
}, | ||
{ | ||
icon: RuntimesIcon, | ||
title: 'Second', | ||
description: 'Lorem ipsum dolor sit amet consectetur adipisicing elit. Id quidem aperiam similique vitae beatae', | ||
}, { | ||
icon: RuntimesIcon, | ||
title: 'Third ', | ||
description: 'Lorem ipsum dolor sit amet consectetur adipisicing elit. Id quidem aperiam similique vitae beatae', | ||
}, { | ||
icon: RuntimesIcon, | ||
title: 'Fourth', | ||
description: 'Lorem ipsum dolor sit amet consectetur adipisicing elit. Id quidem aperiam similique vitae beatae', | ||
}, | ||
] | ||
</script> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
204 changes: 204 additions & 0 deletions
204
packages/entities/entities-shared/src/components/entity-empty-state/EntityEmptyState.vue
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,204 @@ | ||
<template> | ||
<div class="kong-ui-public-entity-empty-state"> | ||
<div | ||
v-if="$slots.icon" | ||
class="entity-empty-state-icon" | ||
> | ||
<slot name="icon" /> | ||
</div> | ||
<div | ||
v-else | ||
class="entity-empty-state-image" | ||
> | ||
<slot name="image" /> | ||
</div> | ||
<div class="entity-empty-state-content"> | ||
<div | ||
v-if="title || $slots.title" | ||
class="entity-empty-state-title" | ||
> | ||
<div :title="title"> | ||
{{ title }} | ||
</div> | ||
<span | ||
v-if="$slots['title-after']" | ||
> | ||
<slot | ||
name="title-after" | ||
/> | ||
</span> | ||
</div> | ||
<div | ||
v-if="description || $slots.default" | ||
class="entity-empty-state-description" | ||
> | ||
<slot name="default"> | ||
<p> | ||
{{ description }} | ||
</p> | ||
</slot> | ||
</div> | ||
<div | ||
v-if="pricing" | ||
class="entity-empty-state-pricing" | ||
> | ||
<p> | ||
<b>{{ t('emptyState.pricingTitle') }}</b> {{ pricing }} | ||
</p> | ||
</div> | ||
</div> | ||
<div | ||
v-if="$slots.message" | ||
class="entity-empty-state-message" | ||
> | ||
<slot name="message" /> | ||
</div> | ||
</div> | ||
<div | ||
v-if="(actionButtonText) || $slots.action" | ||
class="entity-empty-state-action" | ||
> | ||
<KButton | ||
appearance="primary" | ||
@click="$emit('click-action')" | ||
> | ||
{{ actionButtonText }} | ||
</KButton> | ||
<KButton | ||
v-if="learnMoreLink" | ||
appearance="secondary" | ||
:to="learnMoreLink" | ||
> | ||
<BookIcon decorative /> | ||
{{ t('emptyState.learnMore') }} | ||
</KButton> | ||
</div> | ||
<div class="entity-empty-state-card-container"> | ||
<template | ||
v-for="feature in features" | ||
:key="feature" | ||
> | ||
<KCard | ||
class="entity-empty-state-card" | ||
:title="feature.title" | ||
> | ||
<template #title> | ||
<component | ||
:is="feature.iconVariant" | ||
:color="`var(--kui-color-text-neutral-stronger, ${KUI_COLOR_TEXT_NEUTRAL_STRONGER})`" | ||
:size="KUI_ICON_SIZE_30" | ||
/> | ||
<div>{{ feature.title }}</div> | ||
</template> | ||
<template #default> | ||
{{ feature.description }} | ||
</template> | ||
</KCard> | ||
</template> | ||
</div> | ||
</template> | ||
|
||
<script lang="ts" setup> | ||
import { type PropType } from 'vue' | ||
import KButton from '@kong/kongponents' | ||
import composables from '../../composables' | ||
import type { EmptyStateFeature } from 'src/types/entity-empty-state' | ||
import { KUI_ICON_SIZE_30, KUI_COLOR_TEXT_NEUTRAL_STRONGER } from '@kong/design-tokens' | ||
defineProps({ | ||
title: { | ||
type: String, | ||
required: true, | ||
}, | ||
description: { | ||
type: String, | ||
required: true, | ||
}, | ||
pricing: { | ||
type: String, | ||
default: '', | ||
}, | ||
actionButtonText: { | ||
type: String, | ||
default: '', | ||
}, | ||
learnMoreLink: { | ||
type: String, | ||
default: '', | ||
}, | ||
features: { | ||
type: Array as PropType<EmptyStateFeature[]>, | ||
default: () => [], | ||
}, | ||
}) | ||
defineEmits(['click-action']) | ||
const { i18n: { t } } = composables.useI18n() | ||
</script> | ||
|
||
<style lang="scss" scoped> | ||
.kong-ui-public-entity-empty-state { | ||
align-items: center; | ||
background-color: var(--kui-color-background, $kui-color-background); | ||
box-sizing: border-box; | ||
display: flex; | ||
flex-direction: column; | ||
font-family: var(--kui-font-family-text, $kui-font-family-text); | ||
gap: var(--kui-space-60, $kui-space-60); | ||
padding: var(--kui-space-130, $kui-space-150) var(--kui-space-130, $kui-space-150); | ||
width: 100%; | ||
.entity-empty-state-icon { | ||
:deep() { | ||
height: var(--kui-icon-size-50, $kui-icon-size-50) !important; | ||
width: var(--kui-icon-size-50, $kui-icon-size-50) !important; | ||
} | ||
} | ||
.entity-empty-state-content { | ||
align-items: center; | ||
display: flex; | ||
flex-direction: column; | ||
gap: var(--kui-space-40, $kui-space-40); | ||
text-align: center; | ||
width: 100%; | ||
.entity-empty-state-title { | ||
color: var(--kui-color-text, $kui-color-text); | ||
font-size: var(--kui-font-size-70, $kui-font-size-70); | ||
font-weight: var(--kui-font-weight-bold, $kui-font-weight-bold); | ||
line-height: var(--kui-line-height-60, $kui-line-height-60); | ||
} | ||
} | ||
.entity-empty-state-description { | ||
color: var(--kui-color-text-neutral-strong, $kui-color-text-neutral-strong); | ||
font-size: var(--kui-font-size-30, $kui-font-size-30); | ||
font-weight: var(--kui-font-weight-regular, $kui-font-weight-regular); | ||
line-height: var(--kui-line-height-30, $kui-line-height-30); | ||
max-width: 640px; // limit width so the description stays readable if it is too long | ||
p { | ||
margin: var(--kui-space-0, $kui-space-0); | ||
} | ||
} | ||
.entity-empty-state-action { | ||
align-items: center; | ||
display: flex; | ||
gap: var(--kui-space-50, $kui-space-50); | ||
} | ||
.entity-empty-state-card-container { | ||
display: grid !important; | ||
gap: var(--kui-space-60, $kui-space-60); | ||
grid-template-columns: auto auto !important; | ||
.entity-empty-state-card { | ||
color: var(--kui-color-text-neutral-weak, $kui-color-text-neutral-weak); | ||
margin-bottom: $kui-space-40; | ||
} | ||
} | ||
} | ||
</style> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
5 changes: 5 additions & 0 deletions
5
packages/entities/entities-shared/src/types/entity-empty-state.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
export interface EmptyStateFeature { | ||
iconVariant: string, | ||
title: string, | ||
description: string | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters