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(kslideout): update kslideout for vue 3 #571

Merged
merged 2 commits into from
Apr 11, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 4 additions & 0 deletions TEMP-MIGRATION-CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,3 +108,7 @@ export default defineConfig({
### KTabs

- `v-model` is now mapped to `modelValue` prop instead of `value`.

### KSlideout

- Changed `isVisible` class to `is-visible`
1 change: 1 addition & 0 deletions docs/.vuepress/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ export default defineUserConfig<DefaultThemeOptions, ViteBundlerOptions>({
'/components/radio',
'/components/select',
'/components/skeleton',
'/components/slideout',
'/components/table',
'/components/tabs',
'/components/textarea',
Expand Down
2 changes: 1 addition & 1 deletion docs/components/renderless/clipboard-provider.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# KClipboard
# KClipboardProvider

`<KClipboardProvider />` Provide clipboard functionality to components.

Expand Down
82 changes: 82 additions & 0 deletions docs/components/slideout.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
# Slideout

**KSlideout** - provides a container/wrapper to show content that may not always be important to show all of the time. It is a user-initiated component and should only show with a click.

Below we demonstrate wrapping `KSlideout` in the [`KToggle`](/components/renderless/toggle.html) component. This allows us to easily toggle the open state without needing to set a data prop in the parent component.

<KToggle v-slot="{ isToggled, toggle }">
<div>
<KButton @click="toggle">Toggle Panel</KButton>
<KSlideout :is-visible="isToggled.value" @close="toggle">
<div>
<h2>Not only can you put any html in here like the paragraph below but you can also use other components</h2>
<p>Anim officia eiusmod duis est consequat nulla tempor ad non magna Lorem ullamco nostrud amet. Occaecat voluptate dolor enim eiusmod do qui nulla pariatur enim. Et elit elit consequat do do duis enim est ullamco id sunt sunt amet eiusmod. Do minim mollit irure ea sunt officia minim sint eiusmod enim amet. Quis exercitation in ullamco quis aliqua.</p>
<p>Anim officia eiusmod duis est consequat nulla tempor ad non magna Lorem ullamco nostrud amet. Occaecat voluptate dolor enim eiusmod do qui nulla pariatur enim. Et elit elit consequat do do duis enim est ullamco id sunt sunt amet eiusmod. Do minim mollit irure ea sunt officia minim sint eiusmod enim amet. Quis exercitation in ullamco quis aliqua.</p>
<p>Anim officia eiusmod duis est consequat nulla tempor ad non magna Lorem ullamco nostrud amet. Occaecat voluptate dolor enim eiusmod do qui nulla pariatur enim. Et elit elit consequat do do duis enim est ullamco id sunt sunt amet eiusmod. Do minim mollit irure ea sunt officia minim sint eiusmod enim amet. Quis exercitation in ullamco quis aliqua.</p>
<p>Anim officia eiusmod duis est consequat nulla tempor ad non magna Lorem ullamco nostrud amet. Occaecat voluptate dolor enim eiusmod do qui nulla pariatur enim. Et elit elit consequat do do duis enim est ullamco id sunt sunt amet eiusmod. Do minim mollit irure ea sunt officia minim sint eiusmod enim amet. Quis exercitation in ullamco quis aliqua.</p>
<p>Anim officia eiusmod duis est consequat nulla tempor ad non magna Lorem ullamco nostrud amet. Occaecat voluptate dolor enim eiusmod do qui nulla pariatur enim. Et elit elit consequat do do duis enim est ullamco id sunt sunt amet eiusmod. Do minim mollit irure ea sunt officia minim sint eiusmod enim amet. Quis exercitation in ullamco quis aliqua.</p>
</div>
<KButton appearance="primary">Buttons</KButton>
<KCard class="mt-2">
<template v-slot:body>
Something in a KCard
</template>
</KCard>
<KAlert
appearance="info"
alert-message="Or even an alert!"
class="mt-2" />
</KSlideout>
</div>
</KToggle>

```vue
<KToggle v-slot="{ isToggled, toggle }">
<div>
<KButton @click="toggle">Toggle Panel</KButton>
<KSlideout :is-visible="isToggled.value" @close="toggle">
<div>
<h2>Not only can you put any html in here like the paragraph below but you can also use other components</h2>
<p>Anim officia eiusmod duis est consequat nulla tempor ad non magna Lorem ullamco nostrud amet. Occaecat voluptate dolor enim eiusmod do qui nulla pariatur enim. Et elit elit consequat do do duis enim est ullamco id sunt sunt amet eiusmod. Do minim mollit irure ea sunt officia minim sint eiusmod enim amet. Quis exercitation in ullamco quis aliqua.</p>
<p>Anim officia eiusmod duis est consequat nulla tempor ad non magna Lorem ullamco nostrud amet. Occaecat voluptate dolor enim eiusmod do qui nulla pariatur enim. Et elit elit consequat do do duis enim est ullamco id sunt sunt amet eiusmod. Do minim mollit irure ea sunt officia minim sint eiusmod enim amet. Quis exercitation in ullamco quis aliqua.</p>
<p>Anim officia eiusmod duis est consequat nulla tempor ad non magna Lorem ullamco nostrud amet. Occaecat voluptate dolor enim eiusmod do qui nulla pariatur enim. Et elit elit consequat do do duis enim est ullamco id sunt sunt amet eiusmod. Do minim mollit irure ea sunt officia minim sint eiusmod enim amet. Quis exercitation in ullamco quis aliqua.</p>
<p>Anim officia eiusmod duis est consequat nulla tempor ad non magna Lorem ullamco nostrud amet. Occaecat voluptate dolor enim eiusmod do qui nulla pariatur enim. Et elit elit consequat do do duis enim est ullamco id sunt sunt amet eiusmod. Do minim mollit irure ea sunt officia minim sint eiusmod enim amet. Quis exercitation in ullamco quis aliqua.</p>
<p>Anim officia eiusmod duis est consequat nulla tempor ad non magna Lorem ullamco nostrud amet. Occaecat voluptate dolor enim eiusmod do qui nulla pariatur enim. Et elit elit consequat do do duis enim est ullamco id sunt sunt amet eiusmod. Do minim mollit irure ea sunt officia minim sint eiusmod enim amet. Quis exercitation in ullamco quis aliqua.</p>
</div>
<KButton appearance="primary">Buttons</KButton>
<KCard class="mt-2">
<template v-slot:body>
Something in a KCard
</template>
</KCard>
<KAlert
appearance="info"
alert-message="Or even an alert!"
class="mt-2" />
</KSlideout>
</div>
</KToggle>
```

## Props

### isVisible

Tells the component whether or not to render the open panel.

## Slots

There is one default slot which is used to place content into the slideout panel.

```vue
<KSlideout :is-visible="isToggled" @close="toggle">
<div>
<h1>Default Slot</h1>
<p>Anything here will render in the panel</p>
</div>
</KSlideout>
```

## Events

- `@close` - Emitted when the close button is clicked, anything outside the panel is clicked, or the `esc` key is pressed.
4 changes: 4 additions & 0 deletions docs/components/tabs.md
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,10 @@ export default defineComponent({
</script>
```

## Events

- `@changed` - Emitted when the active tab is updated, and includes the new active `hash` value

## Usage

### Router Hash
Expand Down
13 changes: 8 additions & 5 deletions src/components/KIcon/KIcon.vue
Original file line number Diff line number Diff line change
Expand Up @@ -246,14 +246,17 @@ export default defineComponent({
visibility: hidden !important;
}
}

@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(1turn); }
}
</style>

<style lang="scss">
// @keyframes animations need to be un-scoped
.kong-icon {
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(1turn); }
}
}

// unscoped, so the svg <g> element can be accessed from the imported file
.kong-icon.kong-icon-spinner svg g {
transform-box: fill-box;
Expand Down
5 changes: 4 additions & 1 deletion src/components/KPop/KPop.vue
Original file line number Diff line number Diff line change
Expand Up @@ -589,8 +589,11 @@ export default defineComponent({
}
}
}
</style>

<style lang="scss">
// @keyframes animations need to be un-scoped

/** Animations */
$transition-speed: .3s !default;

@keyframes fadeIn {
Expand Down
19 changes: 13 additions & 6 deletions src/components/KSkeleton/KSkeletonBox.vue
Original file line number Diff line number Diff line change
Expand Up @@ -85,12 +85,19 @@ export default defineComponent({
}
}
}
@keyframes gradient {
0% {
background-position: 100% 50%;
}
100% {
background-position: 0% 50%;
</style>

<style lang="scss">
// @keyframes animations need to be un-scoped

.box {
@keyframes gradient {
0% {
background-position: 100% 50%;
}
100% {
background-position: 0% 50%;
}
}
}
</style>
49 changes: 49 additions & 0 deletions src/components/KSlideout/KSlideout.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// Import types for custom commands
/// <reference types="../../cypress/support" />

import { mount } from '@cypress/vue'
import KSlideout from '@/components/KSlideout/KSlideout.vue'
import { h } from 'vue'

describe('KSlideout', () => {
it('renders default slot', () => {
mount(KSlideout, {
props: {
isVisible: true,
},
slots: {
default: () => h('div', {}, [
h('h1', {}, 'What\'s up default slot'),
h('p', {}, 'Default slots are the easiest'),
]),
},
})

cy.get('h1').should('be.visible')
cy.get('p').should('be.visible')
})

it('emits close when panel-background is clicked', () => {
mount(KSlideout, {
props: {
isVisible: true,
},
})

cy.get('.panel-background').click({ force: true }).then(() => {
cy.wrap(Cypress.vueWrapper.emitted()).should('have.property', 'close')
})
})

it('emits close when esc key pressed', () => {
mount(KSlideout, {
props: {
isVisible: true,
},
})

cy.get('body').type('{esc}').then(() => {
cy.wrap(Cypress.vueWrapper.emitted()).should('have.property', 'close')
})
})
})
146 changes: 146 additions & 0 deletions src/components/KSlideout/KSlideout.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
<template>
<div class="k-slideout">
<transition name="fade">
<div
v-if="isVisible"
class="panel-background"
@click="event => handleClose(event, true)"
/>
</transition>
<transition
tag="div"
name="slide"
>
<div
v-if="isVisible"
:class="{ isVisible: 'is-visible' }"
class="panel"
>
<button
class="close-btn"
@click="event => handleClose(event, true)"
>
<KIcon
icon="close"
size="24"
view-box="0 0 24 24"
/>
</button>
<div class="content">
<KCard border-variant="noBorder">
<template #body>
<slot />
</template>
</KCard>
</div>
</div>
</transition>
</div>
</template>

<script lang="ts">
import { defineComponent, onMounted, onUnmounted } from 'vue'
import KCard from '@/components/KCard/KCard.vue'
import KIcon from '@/components/KIcon/KIcon.vue'

export default defineComponent({
name: 'KSlideout',
components: { KCard, KIcon },
props: {
isVisible: {
type: Boolean,
default: false,
},
},
emits: ['close'],
setup(props, { emit }) {
const handleClose = (e: any, forceClose = false): void => {
if ((props.isVisible && e.keyCode === 27) || forceClose) {
emit('close')
}
}

onMounted(() => {
document.addEventListener('keydown', handleClose)
})

onUnmounted(() => {
document.removeEventListener('keydown', handleClose)
})

return {
handleClose,
}
},
})
</script>

<style lang="scss" scoped>
@import '@/styles/variables';

.k-slideout {
--KCardPaddingY: 2rem;
--KCardPaddingX: 3rem;

.panel-background {
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
background: var(--black-45, color(black-45));
z-index: 9999;
}

.panel {
position: fixed;
top: 0;
right: 0;
height: 100vh;
width: 100%;
max-width: 500px;
background-color: var(--white, color(white));
z-index: 9999;

.close-btn {
position: absolute;
top: 1rem;
left: 1rem;
height: 16px;
width: 16px;
padding: 0;
border: none;
background: none;
cursor: pointer;
outline: inherit;
transition: 200ms ease;
}

.content {
height: 100%;
overflow: auto;
-ms-overflow-style: none; // IE 10+
scrollbar-width: none; // Firefox
&::-webkit-scrollbar { display: none; }
}
}
}
</style>

<style lang="scss">
// @keyframes animations need to be un-scoped
.k-slideout {
@keyframes slide {
0% { transform: translateX(100%); }
100% { transform: translateX(0%); }
}

.slide-enter-active { animation: slide .3s cubic-bezier(1.0, 0.5, 0.8, 1.0); }

.slide-leave-active { animation: slide .3s ease reverse; }

.fade-enter-active, .fade-leave-active { transition: opacity 500ms;}

.fade-enter, .fade-leave-to { opacity: 0; }
}
</style>
1 change: 1 addition & 0 deletions src/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,4 @@ export { default as KViewSwitcher } from './KViewSwitcher/KViewSwitcher.vue'
export { default as KPrompt } from './KPrompt/KPrompt.vue'
export { default as KInputSwitch } from './KInputSwitch/KInputSwitch.vue'
export { default as KTabs } from './KTabs/KTabs.vue'
export { default as KSlideout } from './KSlideout/KSlideout.vue'