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(ktooltip): hide tooltip if no label or content #1783

Merged
merged 4 commits into from
Oct 20, 2023
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
30 changes: 0 additions & 30 deletions docs/components/button.md
Original file line number Diff line number Diff line change
Expand Up @@ -154,36 +154,6 @@ KButton also supports the disabled attribute with both Button and Anchor types.
<KButton to="http://google.com" appearance="btn-link" disabled>Disabled Native Anchor Link</KButton>
```

:::warning NOTE
Should you need to use a KTooltip component on a KButton with `disabled` attribute, don't forget to wrap an additional tag around your KButton, like shown in the example below. Otherwise KTooltip won't be triggered since elements with `disabled` attribute don't trigger pointer events.
:::

<KCard>
<template #body>
<div class="spacing-container">
<KTooltip label="I won't pop up">
<KButton disabled>❌</KButton>
</KTooltip>
<KTooltip label="I will pop up">
<span>
<KButton disabled>✅</KButton>
</span>
</KTooltip>
</div>
</template>
</KCard>

```html
<KTooltip label="I won't show up">
<KButton disabled>❌</KButton>
</KTooltip>
<KTooltip label="I will pop up">
<span>
<KButton disabled>✅</KButton>
</span>
</KTooltip>
```

## Slots

### Icon
Expand Down
73 changes: 35 additions & 38 deletions docs/components/tooltip.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,7 @@

### label

Here you can pass in the text to display in the toolip.

- `I am a new sample label`
Here you can pass in the text to display in the tooltip.

<KTooltip label="I am a new sample label">
<KButton>Sample Button</KButton>
Expand All @@ -30,43 +28,24 @@ Here you can pass in the text to display in the toolip.
</KTooltip>
```

:::warning NOTE
KTooltip won't be triggered if the element you pass through `default` slot has `disabled` attribute. You can get around that by wrapping your disabled element around an additional tag, like shown in the example below.
:::

<KCard>
<template #body>
<div class="my-tooltip">
<KTooltip label="I won't pop up" class="my-tooltip-label">
<KButton disabled>❌</KButton>
</KTooltip>
<KTooltip label="I will pop up">
<span>
<KButton disabled>✅</KButton>
</span>
</KTooltip>
</div>
</template>
</KCard>
When using the `label` prop (or the [`content` slot](#content)), passing a value of `undefined`, an empty string, or no `content` slot content will prevent the tooltip from showing, while still displaying your `default` slot content.

<style>
.my-tooltip {
display: flex !important;
}
.my-tooltip-label {
margin-right: 4px !important;
}
</style>
<KTooltip :label="labelProptooltipText">
<KButton>My tooltip label is empty</KButton>
</KTooltip>

```html
<KTooltip label="I won't show up">
<KButton disabled>❌</KButton>
</KTooltip>
<KTooltip label="I will pop up">
<span>
<KButton disabled>✅</KButton>
</span>
<KTooltip :label="tooltipLabel">
<KButton>My tooltip label is empty</KButton>
</KTooltip>

<script setup lang="ts">
import { ref } from 'vue'

// The tooltip doesn't have label text yet,
// so hovering over the button will not render an empty tooltip
const tooltipLabel = ref<string>('')
</script>
```

### placement
Expand Down Expand Up @@ -131,7 +110,9 @@ You can set the maximum width of a Tooltip with the `maxWidth` property. `maxWid

## Slots

- `Default` There is a main slot that takes in the element you want the popover to be triggered over.
### default

The `default` slot takes in the element you want the popover to be triggered over.

```html
<KTooltip label="a cool label">
Expand All @@ -140,7 +121,9 @@ You can set the maximum width of a Tooltip with the `maxWidth` property. `maxWid
</KTooltip>
```

- `Content` This allows you to slot in any html content
### content

The content slot allows you to slot in any html content

<KTooltip label="Video Games">
<KButton>&nbsp;✌🏻</KButton>
Expand Down Expand Up @@ -186,6 +169,20 @@ Example:
</style>
```

<script setup lang="ts">
import { ref } from 'vue'

const labelProptooltipText = ref<string>('')

const toggleTooltipLabel = () => {
if (!labelProptooltipText.value) {
labelProptooltipText.value = 'Here I am!'
} else {
labelProptooltipText.value = ''
}
}
</script>

<style>
.tooltip-blue {
--KTooltipBackground: blue;
Expand Down
29 changes: 28 additions & 1 deletion src/components/KTooltip/KTooltip.cy.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { mount } from 'cypress/vue'
import KTooltip from '@/components/KTooltip/KTooltip.vue'
import { h } from 'vue'

const positions = ['top', 'topStart', 'topEnd', 'left', 'leftStart', 'leftEnd', 'right', 'rightStart', 'rightEnd', 'bottom', 'bottomStart', 'bottomEnd']

Expand All @@ -13,19 +14,45 @@ const positions = ['top', 'topStart', 'topEnd', 'left', 'leftStart', 'leftEnd',
*/
const rendersCorrectPosition = (variant: string) => {
it(`renders tooltip to the ${variant} side`, () => {
const text = 'Button text'

mount(KTooltip, {
props: {
testMode: true,
placement: variant,
label: `I'm on the ${variant} side!`,
trigger: 'click',
},
slots: {
default: () => h('button', {}, text),
},
})

cy.get('.k-tooltip').should('have.text', `I'm on the ${variant} side!`)
cy.get('button').click()

cy.get('.k-tooltip').should('be.visible').and('not.have.class', 'k-tooltip-hidden').and('have.text', `I'm on the ${variant} side!`)
})
}

describe('KTooltip', () => {
// Loop through varients
positions.map(p => rendersCorrectPosition(p))

it('does not render the tooltip if the `label` prop is empty', () => {
const text = 'Button text'

mount(KTooltip, {
props: {
testMode: true,
trigger: 'click',
},
slots: {
default: () => h('button', {}, text),
},
})

cy.get('button').click()

cy.get('.k-tooltip').should('have.class', 'k-tooltip-hidden').and('not.be.visible')
})
})
33 changes: 23 additions & 10 deletions src/components/KTooltip/KTooltip.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
hide-caret
:max-width="maxWidth"
:placement="placement"
:popover-classes="`k-tooltip ${computedClass} ${className}`"
:popover-classes="`k-tooltip ${computedClass}`"
:popover-timeout="0"
:position-fixed="positionFixed"
:test-mode="!!testMode || undefined"
Expand All @@ -13,7 +13,10 @@
>
<slot />

<template #content>
<template
v-if="showTooltip"
#content
>
<div role="tooltip">
<slot
:label="label"
Expand All @@ -27,8 +30,8 @@
</template>

<script setup lang="ts">
import { computed, useSlots } from 'vue'
import type { PropType } from 'vue'
import { computed, ref } from 'vue'
import KPop from '@/components/KPop/KPop.vue'
import type { PopPlacements } from '@/types'
import { PopPlacementsArray } from '@/types'
Expand Down Expand Up @@ -76,25 +79,31 @@ const props = defineProps({
},
})

const className = ref('')
const slots = useSlots()
const showTooltip = computed((): boolean => !!props.label || !!slots.content)

const computedClass = computed((): string => {
let result = ''
const result = []
switch (props.placement) {
case 'top':
result = 'k-tooltip-top'
result.push('k-tooltip-top')
break
case 'right':
result = 'k-tooltip-right'
result.push('k-tooltip-right')
break
case 'bottom':
result = 'k-tooltip-bottom'
result.push('k-tooltip-bottom')
break
case 'left':
result = 'k-tooltip-left'
result.push('k-tooltip-left')
break
}

return result
if (!showTooltip.value) {
result.push('k-tooltip-hidden')
}

return result.join(' ')
})
</script>

Expand All @@ -111,6 +120,10 @@ const computedClass = computed((): string => {
--KPopBorder: none;
pointer-events: none;
z-index: 9999;

&.k-tooltip-hidden {
display: none;
}
}

.k-tooltip-top {
Expand Down