-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix(app-layout): add collapsiblesection component [KHCP-14578] (#1888)
* fix(app-layout): add collapsiblesection component [KHCP-14578] * fix: stylelint:fix * fix: address pr feedback * fix: minor fix * fix: apply pr feedback Co-authored-by: Adam DeHaven <[email protected]> --------- Co-authored-by: Adam DeHaven <[email protected]>
- Loading branch information
1 parent
26bb869
commit 977c718
Showing
5 changed files
with
395 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
# PageInfoSection.vue | ||
|
||
A Kong UI simple optionally collapsible section component. | ||
|
||
- [Requirements](#requirements) | ||
- [Usage](#usage) | ||
- [Install](#install) | ||
- [Props](#props) | ||
- [Slots](#slots) | ||
|
||
## 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) | ||
|
||
## 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 section. | ||
|
||
#### `description` | ||
|
||
- type: `String` | ||
- required: `false` | ||
- default: `''` | ||
|
||
Descriptive text displayed below the `title` | ||
|
||
#### `collapsible` | ||
|
||
- type: `Boolean` | ||
- required: `false` | ||
- default: `true` | ||
|
||
Whether or not section should be collapsible. Collapsible section is rendered as a `details` element, while a non-collapsible is rendered as a `div`. | ||
|
||
#### `titleTag` | ||
|
||
- type: `String` | ||
- required: `false` | ||
- default: `'div'` | ||
|
||
HTML element you want title to be rendered as. Defaults to `div`. | ||
|
||
### Slots | ||
|
||
#### `header` | ||
|
||
Header content to be rendered in place of `title` and `description`. | ||
|
||
#### `default` | ||
|
||
Main content to be displayed in the section. | ||
|
||
#### `actions` | ||
|
||
Located to the right of the card title, the `actions` slot allows for slotting in any action elements. | ||
|
||
_Note:_ actions slot will be omitted when [`collapsible` prop](#collapsible) is `true` in order to leave room for caret icon. | ||
|
||
--- | ||
|
||
[← Back to `@kong-ui-public/app-layout` docs](../README.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 |
---|---|---|
|
@@ -108,8 +108,43 @@ | |
|
||
<p>This is the top.</p> | ||
|
||
<div class="collapsible-sections-container"> | ||
<PageInfoSection | ||
description="This is a collapsible section that's rendered collapsed by default. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua." | ||
title="Collapsible section" | ||
> | ||
Lorem ipsum dolor sit amet consectetur adipisicing elit. Id quidem aperiam similique vitae beatae. Repellat quam voluptas vitae, maxime consequuntur praesentium et suscipit. Numquam aliquid nulla vel esse accusantium reiciendis error? | ||
</PageInfoSection> | ||
|
||
<PageInfoSection | ||
description="This is a collapsible section that's rendered open by default. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua." | ||
open | ||
title="Collapsible section" | ||
title-tag="h2" | ||
> | ||
Lorem ipsum dolor sit amet consectetur adipisicing elit. Id quidem aperiam similique vitae beatae. Repellat quam voluptas vitae, maxime consequuntur praesentium et suscipit. Numquam aliquid nulla vel esse accusantium reiciendis error? | ||
</PageInfoSection> | ||
|
||
<KComponent | ||
v-slot="{ data }" | ||
:data="{ toggleModel: true }" | ||
> | ||
<PageInfoSection | ||
:collapsible="false" | ||
description="This is a non-collapsible section with a toggle in the header. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua." | ||
title="Non-collapsible section" | ||
> | ||
<template #actions> | ||
<KInputSwitch v-model="data.toggleModel" /> | ||
</template> | ||
|
||
Lorem ipsum dolor sit amet consectetur adipisicing elit. Id quidem aperiam similique vitae beatae. Repellat quam voluptas vitae, maxime consequuntur praesentium et suscipit. Numquam aliquid nulla vel esse accusantium reiciendis error? | ||
</PageInfoSection> | ||
</KComponent> | ||
</div> | ||
|
||
<p | ||
v-for="index in 9" | ||
v-for="index in 3" | ||
:key="index" | ||
> | ||
Lorem ipsum dolor sit amet consectetur adipisicing elit. Id quidem aperiam similique vitae beatae. Repellat quam voluptas vitae, maxime consequuntur praesentium et suscipit. Numquam aliquid nulla vel esse accusantium reiciendis error? | ||
|
@@ -129,6 +164,7 @@ import AppGruceLogo from '../components/icons/AppGruceLogo.vue' | |
import AppLogo from '../components/icons/AppLogo.vue' | ||
import { OverviewIcon, RuntimesIcon, ServiceHubIcon, MeshIcon, DevPortalIcon, BarChartIcon, PeopleIcon, CogIcon } from '@kong/icons' | ||
import { KUI_ICON_SIZE_40 } from '@kong/design-tokens' | ||
import PageInfoSection from '../../src/components/pageInfoSection/PageInfoSection.vue' | ||
const userNameAndEmail = ref<string>('Jackie Jiang\n[email protected]') | ||
|
@@ -384,4 +420,10 @@ const handleCloseAlert = (): void => { | |
display: flex; | ||
padding-left: 16px; | ||
} | ||
.collapsible-sections-container { | ||
display: flex; | ||
flex-direction: column; | ||
gap: $kui-space-50; | ||
} | ||
</style> |
105 changes: 105 additions & 0 deletions
105
packages/core/app-layout/src/components/pageInfoSection/PageInfoSection.cy.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,105 @@ | ||
import PageInfoSection from './PageInfoSection.vue' | ||
|
||
describe('<PageInfoSection />', () => { | ||
describe('as a collapsible section', () => { | ||
it('renders a collapsible section', () => { | ||
const title = 'Collapsible section' | ||
const description = 'This is a collapsible section.' | ||
|
||
cy.mount(PageInfoSection, { | ||
props: { | ||
title, | ||
description, | ||
collapsible: true, | ||
}, | ||
slots: { | ||
default: '<div data-testid="slotted-hidden-content">Content</div>', | ||
}, | ||
}) | ||
|
||
cy.getTestId('page-info-section').should('be.visible').and('not.have.attr', 'open') | ||
// verify correct HTML tag | ||
cy.getTestId('page-info-section').should('have.prop', 'tagName').and('eq', 'DETAILS') | ||
cy.getTestId('page-info-section').findTestId('slotted-hidden-content').should('not.be.visible') | ||
|
||
// verify correct content | ||
cy.getTestId('page-info-section-title').should('be.visible').and('have.text', title) | ||
cy.getTestId('page-info-section-description').should('be.visible').and('have.text', description) | ||
|
||
// verify correct HTML tag | ||
cy.getTestId('page-info-section-header').should('have.prop', 'tagName').and('eq', 'SUMMARY') | ||
cy.getTestId('page-info-section-header').find('.page-info-section-chevron-icon').should('be.visible') | ||
}) | ||
|
||
it('expands and collapses the section when clicking the header', () => { | ||
const slottedContentTestId = 'slotted-hidden-content' | ||
|
||
cy.mount(PageInfoSection, { | ||
props: { | ||
title: 'Collapsible section', | ||
collapsible: true, | ||
}, | ||
slots: { | ||
default: `<div data-testid="${slottedContentTestId}">Content</div>`, | ||
}, | ||
}) | ||
|
||
// expand the section | ||
cy.getTestId('page-info-section-header').click() | ||
|
||
cy.getTestId('page-info-section').should('have.attr', 'open') | ||
cy.getTestId(slottedContentTestId).should('be.visible') | ||
|
||
// collapse the section | ||
cy.getTestId('page-info-section-header').click() | ||
|
||
cy.getTestId('page-info-section').should('not.have.attr', 'open') | ||
cy.getTestId(slottedContentTestId).should('not.be.visible') | ||
}) | ||
}) | ||
|
||
describe('as a non-collapsible section', () => { | ||
it('renders a non-collapsible section', () => { | ||
const title = 'Non-collapsible section' | ||
const slottedContentTestId = 'slotted-always-visible-content' | ||
|
||
cy.mount(PageInfoSection, { | ||
props: { | ||
title, | ||
collapsible: false, | ||
}, | ||
slots: { | ||
default: `<div data-testid="${slottedContentTestId}">Content</div>`, | ||
}, | ||
}) | ||
|
||
cy.getTestId('page-info-section').as('details') | ||
cy.getTestId('page-info-section-header').as('summary') | ||
|
||
// verify correct HTML tag | ||
cy.getTestId('page-info-section').should('have.prop', 'tagName').and('eq', 'DIV') | ||
cy.getTestId('page-info-section').findTestId(slottedContentTestId).should('be.visible') | ||
|
||
cy.getTestId('page-info-section-header').should('be.visible').and('have.text', title) | ||
// verify correct HTML tag | ||
cy.getTestId('page-info-section-header').should('have.prop', 'tagName').and('eq', 'DIV') | ||
cy.getTestId('page-info-section-header').find('.page-info-section-chevron-icon').should('not.exist') | ||
}) | ||
|
||
it('renders actions slot', () => { | ||
const slottedActionsTestId = 'slotted-action-button' | ||
|
||
cy.mount(PageInfoSection, { | ||
props: { | ||
title: 'Non-collapsible section', | ||
collapsible: false, | ||
}, | ||
slots: { | ||
actions: `<button data-testid="${slottedActionsTestId}">Actions</button>`, | ||
}, | ||
}) | ||
|
||
cy.getTestId(slottedActionsTestId).should('be.visible') | ||
}) | ||
}) | ||
}) |
Oops, something went wrong.