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

fix(kslideout): title and content styles #1773

Closed
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
56 changes: 53 additions & 3 deletions docs/components/slideout.md
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,9 @@ This prop takes a string that will be displayed as the title of the slide-out.

## Slots

- `default` - used to place content into the slideout panel
### default

Used to place content into the slideout panel.

```html
<KSlideout :is-visible="isToggled" @close="toggle">
Expand All @@ -235,8 +237,56 @@ This prop takes a string that will be displayed as the title of the slide-out.
</KSlideout>
```

- `before-title` - used to customize the header to add content before title
- `after-title` - used to customize the header to add content after title
### before-title

Used to customize the header to add content before title.

### title

Used to place title content into the header area.

<KToggle v-slot="{ isToggled, toggle }">
<div>
<KButton @click="toggle">Toggle Panel With Title</KButton>
<KSlideout :is-visible="isToggled.value" @close="toggle" :has-overlay="false" close-button-alignment="end">
<template #before-title>
<KIcon icon="kong" />
</template>
<template #title>
<router-link to="route">Title</router-link>
</template>
<template #after-title>
<KIcon icon="check" />
</template>
Default content
</KSlideout>
</div>
</KToggle>

```html
<KToggle v-slot="{ isToggled, toggle }">
<div>
<KButton @click="toggle">Toggle Panel With Title</KButton>
<KSlideout :is-visible="isToggled.value" @close="toggle" :has-overlay="false" close-button-alignment="end">
<template #before-title>
<KIcon icon="kong" />
</template>
<template #title>
<router-link to="route">Title</router-link>
</template>
<template #after-title>
<KIcon icon="check" />
</template>
Default content
</KSlideout>
</div>
</KToggle>
```

### after-title

Used to customize the header to add content after title.


## Events

Expand Down
16 changes: 16 additions & 0 deletions src/components/KSlideout/KSlideout.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,22 @@ describe('KSlideout', () => {
cy.getTestId('k-slideout-title').should('be.visible')
})

it('renders title slot when providing both title prop and slot', () => {
mount(KSlideout, {
props: {
isVisible: true,
title: 'Title prop',
},
slots: {
title: () => h('div', {}, [
h('span', {}, 'Title slot'),
]),
},
})

cy.getTestId('k-slideout-title').contains('Title slot')
})

it('renders cancel button on right when prop is used', () => {
const closeButtonAlignmentProp = 'end'

Expand Down
123 changes: 56 additions & 67 deletions src/components/KSlideout/KSlideout.vue
Original file line number Diff line number Diff line change
Expand Up @@ -15,45 +15,51 @@
data-testid="slideout-panel"
>
<div class="k-slideout-header-content">
<div
v-if="hasBeforeTitle"
class="k-slideout-before-title"
>
<slot name="before-title" />
</div>

<!-- title -->
<div class="k-slideout-main-title">
<p
<div
v-if="$slots['before-title']"
class="k-slideout-before-title"
>
<slot name="before-title" />
</div>

<div
class="k-slideout-title"
data-testid="k-slideout-title"
:title="title"
:title="title ? title : undefined"
>
{{ title }}
</p>
<slot
v-if="$slots.title"
name="title"
/>

<template v-else>
{{ title }}
</template>
</div>

<div
v-if="$slots['after-title']"
class="k-slideout-after-title"
>
<slot name="after-title" />
</div>
</div>

<div
v-if="hasAfterTitle"
class="k-slideout-after-title"
<button
class="k-slideout-close-button"
:class="closeButtonAlignment === 'start' ? 'close-button-start' : 'close-button-end'"
:data-testid="closeButtonAlignment === 'start' ? 'close-button-start' : 'close-button-end'"
@click="emit('close')"
>
<slot name="after-title" />
</div>
<KIcon
:color="KUI_COLOR_TEXT_NEUTRAL_STRONGER"
icon="close"
:size="KUI_ICON_SIZE_50"
/>
</button>
</div>

<!-- cancelButton -->
<button
:class="closeButtonAlignment === 'start' ? 'close-button-start' : 'close-button-end'"
:data-testid="closeButtonAlignment === 'start' ? 'close-button-start' : 'close-button-end'"
@click="(event: any) => emit('close')"
>
<KIcon
:color="KUI_COLOR_TEXT_NEUTRAL_STRONGER"
icon="close"
:size="KUI_ICON_SIZE_50"
/>
</button>

<div class="content">
<KCard border-variant="noBorder">
<template #body>
Expand All @@ -67,7 +73,7 @@
</template>

<script lang="ts" setup>
import { computed, useSlots, ref, onMounted, onUnmounted } from 'vue'
import { computed, ref, onMounted, onUnmounted } from 'vue'
import KCard from '@/components/KCard/KCard.vue'
import KIcon from '@/components/KIcon/KIcon.vue'
import useUtilities from '@/composables/useUtilities'
Expand Down Expand Up @@ -111,9 +117,6 @@ const emit = defineEmits<{
(e: 'close'): void
}>()

const slots = useSlots()
const hasBeforeTitle = computed((): boolean => !!slots['before-title'])
const hasAfterTitle = computed((): boolean => !!slots['after-title'])
const { getSizeFromString } = useUtilities()
const slideOutRef = ref(null)

Expand Down Expand Up @@ -154,32 +157,36 @@ const offsetTopValue = computed((): string => {
@import '@/styles/tmp-variables';

.k-slideout {
:deep(.kong-card) {
padding: var(--kui-space-110, $kui-space-110) var(--kui-space-90, $kui-space-90);
}

.k-slideout-header-content {
align-items: center;
display: flex;
.k-slideout-before-title,
.k-slideout-after-title {
margin-top: var(--kui-space-60, $kui-space-60);
}
gap: var(--kui-space-80, $kui-space-80);
justify-content: space-between;
padding: var(--kui-space-80, $kui-space-80) var(--kui-space-80, $kui-space-80) 0 var(--kui-space-80, $kui-space-80);

.k-slideout-main-title {
align-items: center;
display: flex;
gap: var(--kui-space-40, $kui-space-40);

.k-slideout-title {
color: var(--kui-color-text-neutral, $kui-color-text-neutral);
flex:1;
font-size: var(--kui-font-size-40, $kui-font-size-40);
font-weight: var(--kui-font-weight-medium, $kui-font-weight-medium);
line-height: var(--kui-line-height-40, $kui-line-height-40);
margin-left: var(--kui-space-50, $kui-space-50);
margin-right: var(--kui-space-100, $kui-space-100);
margin-top: var(--kui-space-60, $kui-space-60);
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
}
}

.k-slideout-before-title,
.k-slideout-after-title {
align-items: center;
display: flex;
}

.panel {
background-color: var(--kui-color-background, $kui-color-background);
display: flex;
Expand All @@ -193,40 +200,22 @@ const offsetTopValue = computed((): string => {
width: 100%;
z-index: 9999;

.close-button-start {
align-self: flex-start;
.k-slideout-close-button {
background: none;
border: none;
cursor: pointer;
display: flex;
height: auto;
margin-left: var(--kui-space-50, $kui-space-50);
margin-top: var(--kui-space-50, $kui-space-50);
outline: inherit;
position: absolute;
transition: $tmp-animation-timing-2 ease;

&:focus{
box-shadow: 0 0 0 2px var(--kui-color-border-primary, $kui-color-border-primary);
}
}

.close-button-end {
align-self: flex-end;
background: none;
border: none;
cursor: pointer;
display: flex;
height: auto;
margin-right: var(--kui-space-50, $kui-space-50);
margin-top: var(--kui-space-50, $kui-space-50);
outline: inherit;
position: absolute;
transition: $tmp-animation-timing-2 ease;

&:focus{
box-shadow: 0 0 0 2px var(--kui-color-border-primary, $kui-color-border-primary);
}
.close-button-start {
order: -1;
}

.content {
Expand Down