From a7cc37c3237a96bdc972bf960beed5a3b1d888e4 Mon Sep 17 00:00:00 2001 From: "kai.arrowood" Date: Thu, 13 Jul 2023 10:39:57 -0400 Subject: [PATCH 01/25] feat(pageheader): new component [khcp-7898] --- packages/core/app-layout/docs/page-header.md | 47 ++++++++ .../sandbox/components/NavLinks.vue | 3 + packages/core/app-layout/sandbox/index.ts | 5 + .../app-layout/sandbox/pages/PageHeader.vue | 66 ++++++++++ .../components/pageHeader/PageHeader.cy.ts | 74 ++++++++++++ .../src/components/pageHeader/PageHeader.vue | 113 ++++++++++++++++++ packages/core/app-layout/src/index.ts | 12 +- pnpm-lock.yaml | 1 + 8 files changed, 316 insertions(+), 5 deletions(-) create mode 100644 packages/core/app-layout/docs/page-header.md create mode 100644 packages/core/app-layout/sandbox/pages/PageHeader.vue create mode 100644 packages/core/app-layout/src/components/pageHeader/PageHeader.cy.ts create mode 100644 packages/core/app-layout/src/components/pageHeader/PageHeader.vue diff --git a/packages/core/app-layout/docs/page-header.md b/packages/core/app-layout/docs/page-header.md new file mode 100644 index 0000000000..6557871651 --- /dev/null +++ b/packages/core/app-layout/docs/page-header.md @@ -0,0 +1,47 @@ +# PageHeader.vue + +A Kong UI dynamic page header component. + +- [Features](#features) +- [Requirements](#requirements) +- [Usage](#usage) + - [Install](#install) + - [Props](#props) + - [Slots](#slots) + +## Features + +- Reactive updates based on `prop` value changes :rocket: +- Slottable areas for displaying custom content, icons, etc. + +## Requirements + +- `vue` must be initialized in the host application +- `@kong/kongponents` must be available as a `dependency` in the host application, along with the package's style imports. [See here for instructions on installing Kongponents](https://kongponents.konghq.com/#globally-install-all-kongponents). Specifically, the following Kongponents must be available: + - `KBreadcrumb` + +## Usage + +### Install + +[See instructions for installing the `@kong-ui-public/app-layout` package.](../README.md#install) + +### Props + +#### `title` + +- type: `String` +- required: `false` +- default: `''` + +The title text of the page. + +### Slots + +#### `center` + +The main slot to use for navbar content if you don't need a left/center/right navbar layout. + +--- + +[← Back to `@kong-ui-public/app-layout` docs](../README.md) diff --git a/packages/core/app-layout/sandbox/components/NavLinks.vue b/packages/core/app-layout/sandbox/components/NavLinks.vue index bf02be2bd5..0248f20bec 100644 --- a/packages/core/app-layout/sandbox/components/NavLinks.vue +++ b/packages/core/app-layout/sandbox/components/NavLinks.vue @@ -12,5 +12,8 @@ KM Example + + PageHeader + diff --git a/packages/core/app-layout/sandbox/index.ts b/packages/core/app-layout/sandbox/index.ts index 3ec532d923..c5d79218da 100644 --- a/packages/core/app-layout/sandbox/index.ts +++ b/packages/core/app-layout/sandbox/index.ts @@ -28,6 +28,11 @@ const router = createRouter({ name: 'kong-manager-example', component: () => import('./pages/KongManagerLayoutExample.vue'), }, + { + path: '/page-header', + name: 'page-header', + component: () => import('./pages/PageHeader.vue'), + }, ], }) diff --git a/packages/core/app-layout/sandbox/pages/PageHeader.vue b/packages/core/app-layout/sandbox/pages/PageHeader.vue new file mode 100644 index 0000000000..3e41313cbe --- /dev/null +++ b/packages/core/app-layout/sandbox/pages/PageHeader.vue @@ -0,0 +1,66 @@ + + + + + diff --git a/packages/core/app-layout/src/components/pageHeader/PageHeader.cy.ts b/packages/core/app-layout/src/components/pageHeader/PageHeader.cy.ts new file mode 100644 index 0000000000..8471eb03ea --- /dev/null +++ b/packages/core/app-layout/src/components/pageHeader/PageHeader.cy.ts @@ -0,0 +1,74 @@ +// Cypress component test spec file + +import PageHeader from './PageHeader.vue' + +describe('', () => { + it('should correctly render content when using props', () => { + const title = 'Cats are Cool' + const breadcrumbTitle = 'Home' + + cy.mount(PageHeader, { + props: { + title, + breadcrumbs: [{ + key: 'home', + to: { name: 'home' }, + text: breadcrumbTitle, + icon: 'kong', + }], + }, + }) + + cy.get('.kong-ui-page-header').should('exist') + cy.getTestId('page-breadcrumbs').should('be.visible') + cy.get('.k-breadcrumb-text').should('contain.text', breadcrumbTitle) + cy.getTestId('page-title-text').should('be.visible') + cy.getTestId('page-title-text').should('contain.text', title) + }) + + it('should correctly render content when use slots', () => { + const title = 'Cats are Cool' + const breadcrumbText = 'breadcrumbs-are-cool' + const iconText = 'title-icons-are-cool' + const badgeText = 'title-badges-are-cool' + const actionsText = 'actions-are-cool' + + cy.mount(PageHeader, { + slots: { + breadcrumbs: breadcrumbText, + default: title, + 'title-icon': iconText, + 'title-badge': badgeText, + actions: actionsText, + }, + }) + + cy.get('.kong-ui-page-header').should('exist') + cy.getTestId('page-breadcrumbs').should('be.visible') + cy.getTestId('page-breadcrumbs').should('contain.text', breadcrumbText) + cy.getTestId('page-title-icon').should('be.visible') + cy.getTestId('page-title-icon').should('contain.text', iconText) + cy.getTestId('page-title-text').should('be.visible') + cy.getTestId('page-title-text').should('contain.text', title) + cy.getTestId('page-title-badge').should('be.visible') + cy.getTestId('page-title-badge').should('contain.text', badgeText) + cy.getTestId('page-actions').should('be.visible') + cy.getTestId('page-actions').should('contain.text', actionsText) + }) + + it('should not render empty slots', () => { + const title = 'Cats are Cool' + + cy.mount(PageHeader, { + props: { + title, + }, + }) + + cy.get('.kong-ui-page-header').should('exist') + cy.getTestId('page-breadcrumbs').should('not.exist') + cy.getTestId('page-title-icon').should('not.exist') + cy.getTestId('page-title-badge').should('not.exist') + cy.getTestId('page-actions').should('not.exist') + }) +}) diff --git a/packages/core/app-layout/src/components/pageHeader/PageHeader.vue b/packages/core/app-layout/src/components/pageHeader/PageHeader.vue new file mode 100644 index 0000000000..21e76cf2c3 --- /dev/null +++ b/packages/core/app-layout/src/components/pageHeader/PageHeader.vue @@ -0,0 +1,113 @@ + + + + + diff --git a/packages/core/app-layout/src/index.ts b/packages/core/app-layout/src/index.ts index a61ae6de82..20a497b010 100644 --- a/packages/core/app-layout/src/index.ts +++ b/packages/core/app-layout/src/index.ts @@ -1,11 +1,12 @@ import type { App } from 'vue' + +import AccountDropdown from './components/navbar/AccountDropdown.vue' +import AppError from './components/errors/AppError.vue' import AppLayout from './components/AppLayout.vue' import AppNavbar from './components/navbar/AppNavbar.vue' -import AccountDropdown from './components/navbar/AccountDropdown.vue' - import AppSidebar from './components/sidebar/AppSidebar.vue' +import PageHeader from './components/pageHeader/PageHeader.vue' import SidebarToggle from './components/sidebar/SidebarToggle.vue' -import AppError from './components/errors/AppError.vue' // Export Vue plugin as the default export default { @@ -18,12 +19,13 @@ export default { // Export individual Components export { + AccountDropdown, + AppError, AppLayout, AppNavbar, AppSidebar, + PageHeader, SidebarToggle, - AppError, - AccountDropdown, } export * from './types' diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 4318f53551..fffa1fc2cc 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1536,6 +1536,7 @@ packages: transitivePeerDependencies: - '@popperjs/core' - debug + dev: true /@kong/swagger-ui-kong-theme-universal@4.2.6(react-dom@17.0.2)(react@17.0.2)(vue-router@4.2.4)(vue@3.3.4): resolution: {integrity: sha512-ZZtnsER3yHFnzjy5OO3jYgeY3ZCuhQP6IFqwq2vUj9HntyJUBOBUxvTJ9YJoQHz2wMVuatdUJHadQcUVS/Cktw==} From 0f52572adf980b8656428f74ac0c791298d22f2a Mon Sep 17 00:00:00 2001 From: "kai.arrowood" Date: Thu, 13 Jul 2023 10:41:00 -0400 Subject: [PATCH 02/25] fix(*): lint --- .../core/app-layout/src/components/pageHeader/PageHeader.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/core/app-layout/src/components/pageHeader/PageHeader.vue b/packages/core/app-layout/src/components/pageHeader/PageHeader.vue index 21e76cf2c3..75236ba172 100644 --- a/packages/core/app-layout/src/components/pageHeader/PageHeader.vue +++ b/packages/core/app-layout/src/components/pageHeader/PageHeader.vue @@ -84,8 +84,8 @@ const dataTestId = computed((): string => props.title ? `page-title-${props.titl justify-content: space-between; .page-title-wrapper { - display: flex; align-items: baseline; + display: flex; .page-title-icon { margin-right: var(--spacing-xs, 4px); From 5a7eaad027e1067ea6a584d2d6fff64ceed7d396 Mon Sep 17 00:00:00 2001 From: "kai.arrowood" Date: Thu, 13 Jul 2023 11:42:05 -0400 Subject: [PATCH 03/25] fix(*): adam feedback --- packages/core/app-layout/docs/page-header.md | 28 ++++- .../{PageHeader.vue => PageHeaderPage.vue} | 10 +- .../components/pageHeader/AppPageHeader.cy.ts | 73 +++++++++++ .../components/pageHeader/AppPageHeader.vue | 113 ++++++++++++++++++ .../components/pageHeader/PageHeader.cy.ts | 74 ------------ .../src/components/pageHeader/PageHeader.vue | 113 ------------------ 6 files changed, 218 insertions(+), 193 deletions(-) rename packages/core/app-layout/sandbox/pages/{PageHeader.vue => PageHeaderPage.vue} (85%) create mode 100644 packages/core/app-layout/src/components/pageHeader/AppPageHeader.cy.ts create mode 100644 packages/core/app-layout/src/components/pageHeader/AppPageHeader.vue delete mode 100644 packages/core/app-layout/src/components/pageHeader/PageHeader.cy.ts delete mode 100644 packages/core/app-layout/src/components/pageHeader/PageHeader.vue diff --git a/packages/core/app-layout/docs/page-header.md b/packages/core/app-layout/docs/page-header.md index 6557871651..bf12b4dc60 100644 --- a/packages/core/app-layout/docs/page-header.md +++ b/packages/core/app-layout/docs/page-header.md @@ -1,4 +1,4 @@ -# PageHeader.vue +# AppPageHeader.vue A Kong UI dynamic page header component. @@ -31,16 +31,36 @@ A Kong UI dynamic page header component. #### `title` - type: `String` -- required: `false` +- required: `true` - default: `''` The title text of the page. +#### `breadcrumbs` + +- type: Array as PropType +- required: `false` +- default: `[]` + +Breadcrumb object to be passed into `KBreadcrumb`. + ### Slots -#### `center` +#### `icon` + +Content displayed right before the title text, typically an icon. + +#### `badge` + +Content displayed right after the title text, typically a badge. + +#### `actions` + +Content displayed opposite the title, typically an action menu. + +#### `below` -The main slot to use for navbar content if you don't need a left/center/right navbar layout. +Content displayed directly below the title. --- diff --git a/packages/core/app-layout/sandbox/pages/PageHeader.vue b/packages/core/app-layout/sandbox/pages/PageHeaderPage.vue similarity index 85% rename from packages/core/app-layout/sandbox/pages/PageHeader.vue rename to packages/core/app-layout/sandbox/pages/PageHeaderPage.vue index 3e41313cbe..5ce50a5eeb 100644 --- a/packages/core/app-layout/sandbox/pages/PageHeader.vue +++ b/packages/core/app-layout/sandbox/pages/PageHeaderPage.vue @@ -4,14 +4,14 @@ :breadcrumbs="breadcrumbs" title="Cats are Cool" > - From fe958097bf8b7d97e52320d05a73af6565994174 Mon Sep 17 00:00:00 2001 From: "kai.arrowood" Date: Tue, 25 Jul 2023 17:36:35 -0400 Subject: [PATCH 16/25] fix(*): revert token usage --- .../components/pageHeader/AppPageHeader.vue | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/packages/core/app-layout/src/components/pageHeader/AppPageHeader.vue b/packages/core/app-layout/src/components/pageHeader/AppPageHeader.vue index 3a30d486af..7309b234e7 100644 --- a/packages/core/app-layout/src/components/pageHeader/AppPageHeader.vue +++ b/packages/core/app-layout/src/components/pageHeader/AppPageHeader.vue @@ -77,13 +77,13 @@ const hasBreadcrumbs = computed((): boolean => !!props.breadcrumbs?.length) From b3b1f19f1ae73b3146c49775e1d40e05b2251772 Mon Sep 17 00:00:00 2001 From: "kai.arrowood" Date: Tue, 25 Jul 2023 18:30:37 -0400 Subject: [PATCH 17/25] fix(*): mobile view --- .../src/components/pageHeader/AppPageHeader.vue | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/packages/core/app-layout/src/components/pageHeader/AppPageHeader.vue b/packages/core/app-layout/src/components/pageHeader/AppPageHeader.vue index 7309b234e7..a57bd54953 100644 --- a/packages/core/app-layout/src/components/pageHeader/AppPageHeader.vue +++ b/packages/core/app-layout/src/components/pageHeader/AppPageHeader.vue @@ -121,5 +121,15 @@ const hasBreadcrumbs = computed((): boolean => !!props.breadcrumbs?.length) :deep(.k-breadcrumbs) { margin-bottom: $kui-space-0; } + + @media (max-width: $kui-breakpoint-mobile) { + .page-header-title-section { + flex-wrap: wrap; + } + + .page-header-section-below { + margin-top: $kui-space-40; + } + } } From b67014818e4482c5b0e4b65ffb2e801e8e45e6ad Mon Sep 17 00:00:00 2001 From: "kai.arrowood" Date: Wed, 26 Jul 2023 12:07:30 -0400 Subject: [PATCH 18/25] fix(*): pr feedback --- .../components/pageHeader/AppPageHeader.vue | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/packages/core/app-layout/src/components/pageHeader/AppPageHeader.vue b/packages/core/app-layout/src/components/pageHeader/AppPageHeader.vue index a57bd54953..d4d0940e0c 100644 --- a/packages/core/app-layout/src/components/pageHeader/AppPageHeader.vue +++ b/packages/core/app-layout/src/components/pageHeader/AppPageHeader.vue @@ -9,6 +9,12 @@ + @@ -72,6 +78,10 @@ const props = defineProps({ }) const hasBreadcrumbs = computed((): boolean => !!props.breadcrumbs?.length) +const getBreadcrumbKey = (item: BreadcrumbItem, idx: number): string => { return item.key || `breadcrumb-${idx}` } +const breadcrumbIconSlots = computed((): string[] => { + return props.breadcrumbs.map((item, idx) => getBreadcrumbKey(item, idx) + '-icon') || [] +})