From a63121e947c802c95cb02f880129e7e5314438b6 Mon Sep 17 00:00:00 2001 From: Kai Arrowood Date: Mon, 18 Apr 2022 17:51:39 -0400 Subject: [PATCH] feat(kmodalfullscreen): vue 3 upgrade (#585) Port `KModalFullscreen` component. --- docs/.vuepress/config.ts | 1 + docs/components/modal-fullscreen.md | 432 ++++++++++++++++++ .../KModalFullscreen/KModalFullscreen.spec.ts | 92 ++++ .../KModalFullscreen/KModalFullscreen.vue | 357 +++++++++++++++ src/components/index.ts | 1 + 5 files changed, 883 insertions(+) create mode 100644 docs/components/modal-fullscreen.md create mode 100644 src/components/KModalFullscreen/KModalFullscreen.spec.ts create mode 100644 src/components/KModalFullscreen/KModalFullscreen.vue diff --git a/docs/.vuepress/config.ts b/docs/.vuepress/config.ts index c79078ac59..e28c685533 100644 --- a/docs/.vuepress/config.ts +++ b/docs/.vuepress/config.ts @@ -109,6 +109,7 @@ export default defineUserConfig({ '/components/label', '/components/menu', '/components/modal', + '/components/modal-fullscreen', '/components/pagination', '/components/popover', '/components/prompt', diff --git a/docs/components/modal-fullscreen.md b/docs/components/modal-fullscreen.md new file mode 100644 index 0000000000..83829df330 --- /dev/null +++ b/docs/components/modal-fullscreen.md @@ -0,0 +1,432 @@ +# Modal Fullscreen + +The **KModalFullscreen** component is used to show content in a full screen modal on top of existing UI. + +Open Modal + + +

Proin in magna quam. Sed congue diam nec libero pretium, at lobortis erat dapibus. Interdum et malesuada fames ac ante ipsum primis in faucibus. Suspendisse id gravida tellus. Quisque venenatis ligula lobortis dui viverra, sed pellentesque quam molestie. Nulla viverra vel nunc ut blandit. Donec eget luctus nisl, ut dapibus risus. Nulla eros diam, finibus eu dignissim id, vehicula eu odio. Sed egestas eu sem a vestibulum. In nisl mi, tincidunt ut mi eu, suscipit faucibus eros.

+

Curabitur semper vitae neque elementum imperdiet. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Morbi urna felis, feugiat vitae quam quis, rhoncus vestibulum est. Vivamus diam neque, dictum vel urna nec, faucibus aliquet ipsum. Integer sodales ornare purus, sit amet efficitur elit. Fusce feugiat pharetra mollis. Proin sit amet metus sed massa laoreet feugiat eu id enim. Duis egestas lectus in dapibus accumsan.

+

Maecenas rutrum molestie dolor, sit amet volutpat sapien tristique vitae. Nam tortor nulla, malesuada vel lacus ut, consectetur sagittis nisi. Vestibulum convallis rhoncus ipsum, vitae porta nulla pharetra quis. Nam tristique eget metus sit amet blandit. Suspendisse porta nunc ut dapibus finibus. In hac habitasse platea dictumst. Morbi vel lectus vulputate, cursus augue ultrices, vulputate massa. Pellentesque bibendum et augue et placerat. Duis a est et quam blandit ornare. Phasellus quis mi eget magna vehicula pharetra eu et nunc. In hac habitasse platea dictumst. Nam eleifend purus ante, in porta mauris vulputate eget. Nunc in nulla aliquet metus vehicula rhoncus.

+

Praesent fringilla sapien vitae faucibus vestibulum. Integer viverra hendrerit purus quis consequat. Phasellus dolor enim, interdum in faucibus ut, congue eu quam. Donec eu metus eget eros accumsan feugiat. Donec a magna posuere, sagittis eros ac, bibendum erat. Donec aliquet velit et nunc mattis tincidunt. Nam eu nibh nec purus pretium fermentum. Proin interdum nunc ac turpis blandit, sed malesuada lectus convallis. Morbi quis aliquet lorem, non ultrices quam. Aliquam et consectetur lorem. Nam ac nisl tellus. Duis id nunc lectus. Etiam semper auctor enim, id hendrerit nisl vulputate nec.

+

Nunc ante orci, tempus a fringilla quis, interdum et nisi. Nulla a dui ut leo scelerisque rhoncus. Suspendisse iaculis, orci quis congue sollicitudin, orci ligula tempus nisl, consequat elementum urna elit sit amet orci. Pellentesque in feugiat massa, ac dapibus nunc. Etiam dapibus vehicula elit, a sollicitudin nulla fringilla in. Pellentesque lobortis arcu lectus, sit amet fringilla quam pretium sit amet. Sed mi turpis, bibendum quis tincidunt vel, mattis finibus lorem. Ut imperdiet ultrices libero in dictum. Duis elementum imperdiet erat in feugiat. Nam tempor interdum tellus non auctor. Quisque sed sodales purus. Nunc eu est ac elit aliquet euismod. Fusce pellentesque, lorem sed elementum placerat, dolor felis scelerisque quam, ut placerat elit dolor sit amet dui.

+

Cras porttitor malesuada lorem vel malesuada. Fusce at hendrerit enim. Suspendisse potenti. Nullam interdum maximus dolor, et commodo urna imperdiet condimentum. Nunc hendrerit arcu eu libero sodales, sed auctor nibh sodales. Nunc mattis tortor eleifend, rutrum justo non, malesuada massa. Integer aliquet accumsan ex, et consequat urna egestas pretium.

+
+ +```vue +Open Modal + + +

{{ alotOfText }}

+
+ + +``` + +## Props + +### iconString + +Name of KIcon to be displayed in the header. + +### title + +Title displayed in header. This prop is required for accessibility purposes even if you are slotting the title. + +### bodyHeader + +Text to display for the title in the body section. + +### bodyHeaderDescription + +Text to display beneath the `bodyHeader` as a description. + +### isVisible + +Tells the component whether or not to render modal. + +### cancelButtonText + +Change the text content of the close/cancel button. + +### cancelButtonAppearance + +Sets the [appearance](/components/button.html#props) of the close/cancel button. + +### actionButtonText + +Change the text content of the save/proceed button. + +### actionButtonAppearance + +Change the [appearance](/components/button.html#props) of the save/proceed button. + +Open Modal + + +

Maecenas rutrum molestie dolor, sit amet volutpat sapien tristique vitae. Nam tortor nulla, malesuada vel lacus ut, consectetur sagittis nisi. Vestibulum convallis rhoncus ipsum, vitae porta nulla pharetra quis. Nam tristique eget metus sit amet blandit. Suspendisse porta nunc ut dapibus finibus. In hac habitasse platea dictumst. Morbi vel lectus vulputate, cursus augue ultrices, vulputate massa. Pellentesque bibendum et augue et placerat. Duis a est et quam blandit ornare. Phasellus quis mi eget magna vehicula pharetra eu et nunc. In hac habitasse platea dictumst. Nam eleifend purus ante, in porta mauris vulputate eget. Nunc in nulla aliquet metus vehicula rhoncus.

+

Praesent fringilla sapien vitae faucibus vestibulum. Integer viverra hendrerit purus quis consequat. Phasellus dolor enim, interdum in faucibus ut, congue eu quam. Donec eu metus eget eros accumsan feugiat. Donec a magna posuere, sagittis eros ac, bibendum erat. Donec aliquet velit et nunc mattis tincidunt. Nam eu nibh nec purus pretium fermentum. Proin interdum nunc ac turpis blandit, sed malesuada lectus convallis. Morbi quis aliquet lorem, non ultrices quam. Aliquam et consectetur lorem. Nam ac nisl tellus. Duis id nunc lectus. Etiam semper auctor enim, id hendrerit nisl vulputate nec.

+

Nunc ante orci, tempus a fringilla quis, interdum et nisi. Nulla a dui ut leo scelerisque rhoncus. Suspendisse iaculis, orci quis congue sollicitudin, orci ligula tempus nisl, consequat elementum urna elit sit amet orci. Pellentesque in feugiat massa, ac dapibus nunc. Etiam dapibus vehicula elit, a sollicitudin nulla fringilla in. Pellentesque lobortis arcu lectus, sit amet fringilla quam pretium sit amet. Sed mi turpis, bibendum quis tincidunt vel, mattis finibus lorem. Ut imperdiet ultrices libero in dictum. Duis elementum imperdiet erat in feugiat. Nam tempor interdum tellus non auctor. Quisque sed sodales purus. Nunc eu est ac elit aliquet euismod. Fusce pellentesque, lorem sed elementum placerat, dolor felis scelerisque quam, ut placerat elit dolor sit amet dui.

+
+ +```vue +Open Modal + + +

Maecenas rutrum molestie dolor, sit amet volutpat sapien tristique vitae. Nam tortor nulla, malesuada vel lacus ut, consectetur sagittis nisi. Vestibulum convallis rhoncus ipsum, vitae porta nulla pharetra quis. Nam tristique eget metus sit amet blandit. Suspendisse porta nunc ut dapibus finibus. In hac habitasse platea dictumst. Morbi vel lectus vulputate, cursus augue ultrices, vulputate massa. Pellentesque bibendum et augue et placerat. Duis a est et quam blandit ornare. Phasellus quis mi eget magna vehicula pharetra eu et nunc. In hac habitasse platea dictumst. Nam eleifend purus ante, in porta mauris vulputate eget. Nunc in nulla aliquet metus vehicula rhoncus.

+

Praesent fringilla sapien vitae faucibus vestibulum. Integer viverra hendrerit purus quis consequat. Phasellus dolor enim, interdum in faucibus ut, congue eu quam. Donec eu metus eget eros accumsan feugiat. Donec a magna posuere, sagittis eros ac, bibendum erat. Donec aliquet velit et nunc mattis tincidunt. Nam eu nibh nec purus pretium fermentum. Proin interdum nunc ac turpis blandit, sed malesuada lectus convallis. Morbi quis aliquet lorem, non ultrices quam. Aliquam et consectetur lorem. Nam ac nisl tellus. Duis id nunc lectus. Etiam semper auctor enim, id hendrerit nisl vulputate nec.

+

Nunc ante orci, tempus a fringilla quis, interdum et nisi. Nulla a dui ut leo scelerisque rhoncus. Suspendisse iaculis, orci quis congue sollicitudin, orci ligula tempus nisl, consequat elementum urna elit sit amet orci. Pellentesque in feugiat massa, ac dapibus nunc. Etiam dapibus vehicula elit, a sollicitudin nulla fringilla in. Pellentesque lobortis arcu lectus, sit amet fringilla quam pretium sit amet. Sed mi turpis, bibendum quis tincidunt vel, mattis finibus lorem. Ut imperdiet ultrices libero in dictum. Duis elementum imperdiet erat in feugiat. Nam tempor interdum tellus non auctor. Quisque sed sodales purus. Nunc eu est ac elit aliquet euismod. Fusce pellentesque, lorem sed elementum placerat, dolor felis scelerisque quam, ut placerat elit dolor sit amet dui.

+
+``` + +## Slots + +There are 6 designated slots you can use to display content in the fullscreen modal. + +- `default` - modal body content +- `header-icon` +- `header-content` - title text in the header +- `action-buttons` - contains action buttons which are right-aligned. If not used, provide default Cancel/Submit buttons +- `body-header` - title to display in the body section +- `body-header-description` - description text displayed beneath the `body-header` + +Open Fullscreen Modal + + + + + + + +

Security

+ +

Authentication

+ +
+ +```vue +Open Fullscreen Modal + + + + + + + +

Security

+ +

Authentication

+ +
+``` + +Open Form Modal + + + + + + +
+ +

+
+ + +
+

e.g., tag1, tag2, tag3

+
+ + +
+

+ + Config key in body + +

+ + Config key in header + +

+ + Config key in query + +

+ + Config hide credentials + +

+
+ + +
+

+ + Config run on preflight + +
+
+ +```vue +Open Form Modal + + + + + + +
+ +

+
+ + +
+

e.g., tag1, tag2, tag3

+
+ + +
+

+ + Config key in body + +

+ + Config key in header + +

+ + Config key in query + +

+ + Config hide credentials + +

+
+ + +
+

+ + Config run on preflight + +
+
+``` + +## Events + +- `@canceled` - Emitted when cancel/close button is clicked or the Escape key is pressed +- `@proceed` - Emitted when action button is clicked or the Enter key is pressed + +## Theming + +| Variable | Purpose +|:-------- |:------- +| `--KModalFullscreenMaxWidth` | Modal max width +| `--KModalFullscreenHeaderColor` | Header text color +| `--KModalFullscreenHeaderSize` | Header font size +| `--KModalFullscreenHeaderWeight` | Header font weight +| `--KModalFullscreenColor`| Main content text color +| `--KModalFullscreenFontSize`| Main content text size + +An Example of changing the the colors of KModalFullscreen might look like. +> Note: We are scoping the overrides to a wrapper in this example + +Open Modal + + + +```vue + +Open Modal + + + + +``` + + + + diff --git a/src/components/KModalFullscreen/KModalFullscreen.spec.ts b/src/components/KModalFullscreen/KModalFullscreen.spec.ts new file mode 100644 index 0000000000..d1a3968172 --- /dev/null +++ b/src/components/KModalFullscreen/KModalFullscreen.spec.ts @@ -0,0 +1,92 @@ +// Import types for custom commands +/// + +import { mount } from '@cypress/vue' +import { h } from 'vue' +import KModalFullscreen from '@/components/KModalFullscreen/KModalFullscreen.vue' + +describe('KModalFullscreen', () => { + it('renders proper content when using slots', () => { + const headerIcon = 'This is some header icon text' + const headerText = 'This is some header text' + const bodyHeader = 'This is some body header text' + const bodyHeaderDescription = 'This is some body header description text' + const bodyText = 'This is some body text' + + mount(KModalFullscreen, { + props: { + isVisible: true, + title: headerText, + }, + slots: { + 'header-icon': () => h('div', {}, headerIcon), + 'header-content': () => h('div', {}, headerText), + 'body-header': () => h('div', {}, bodyHeader), + 'body-header-description': () => h('div', {}, bodyHeaderDescription), + default: () => h('div', {}, bodyText), + }, + }) + + cy.get('.k-modal-fullscreen-title .header-icon').should('contain', headerIcon) + cy.get('.k-modal-fullscreen-header').should('contain', headerText) + cy.get('.k-modal-fullscreen-body-header .body-header').should('contain', bodyHeader) + cy.get('.k-modal-fullscreen-body-header .body-header-description').should('contain', bodyHeaderDescription) + cy.get('.k-modal-fullscreen-body').should('contain', bodyText) + }) + + it('renders proper content when using action-buttons slot', () => { + const actionButtonsText = 'This is some action buttons text' + + mount(KModalFullscreen, { + props: { + isVisible: true, + title: 'Test Me', + }, + slots: { + 'action-buttons': h('div', {}, actionButtonsText), + }, + }) + + cy.get('.k-modal-fullscreen-action').should('contain', actionButtonsText) + }) + + it('renders proper content when using props', () => { + const title = 'Sweet prop title' + const actionButtonText = 'Sweet prop actionButton' + const cancelButtonText = 'Sweet prop cancelButton' + const bodyHeader = 'Sweet prop bodyHeader' + const bodyHeaderDescription = 'Sweet prop bodyHeaderDescription' + + mount(KModalFullscreen, { + props: { + isVisible: true, + title, + actionButtonText, + cancelButtonText, + bodyHeader, + bodyHeaderDescription, + iconString: 'immunity', + }, + }) + + cy.get('.k-modal-fullscreen-title .header-icon .kong-icon-immunity').should('be.visible') + cy.get('.proceed-button').should('contain', actionButtonText) + cy.get('.cancel-button').should('contain', cancelButtonText) + cy.get('.k-modal-fullscreen-header').should('contain', title) + cy.get('.k-modal-fullscreen-body-header .body-header').should('contain', bodyHeader) + cy.get('.k-modal-fullscreen-body-header .body-header-description').should('contain', bodyHeaderDescription) + }) + + it('emits close when hitting escape', () => { + mount(KModalFullscreen, { + props: { + title: 'Test Me', + isVisible: true, + }, + }) + + cy.get('body').type('{esc}').then(() => { + cy.wrap(Cypress.vueWrapper.emitted()).should('have.property', 'canceled') + }) + }) +}) diff --git a/src/components/KModalFullscreen/KModalFullscreen.vue b/src/components/KModalFullscreen/KModalFullscreen.vue new file mode 100644 index 0000000000..b289a45564 --- /dev/null +++ b/src/components/KModalFullscreen/KModalFullscreen.vue @@ -0,0 +1,357 @@ + + + + + diff --git a/src/components/index.ts b/src/components/index.ts index da5518682a..93cd39669f 100644 --- a/src/components/index.ts +++ b/src/components/index.ts @@ -26,6 +26,7 @@ export { default as KLabel } from './KLabel/KLabel.vue' export { default as KMenu } from './KMenu/KMenu.vue' export { default as KMenuItem } from './KMenu/KMenuItem.vue' export { default as KModal } from './KModal/KModal.vue' +export { default as KModalFullscreen } from './KModalFullscreen/KModalFullscreen.vue' export { default as KPagination } from './KPagination/KPagination.vue' export { default as KPop } from './KPop/KPop.vue' export { default as KPrompt } from './KPrompt/KPrompt.vue'