Skip to content

Commit

Permalink
Merge pull request #223 from bestguy/correctPopoverTriggers
Browse files Browse the repository at this point in the history
Correct Popover triggers
  • Loading branch information
bestguy authored Jan 20, 2021
2 parents 3d20f5d + e12ec69 commit 9cdb7e9
Show file tree
Hide file tree
Showing 5 changed files with 80 additions and 12 deletions.
3 changes: 3 additions & 0 deletions src/Popover.d.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
import { LocalSvelteComponent } from './shared';

declare type PopoverPlacement = 'left' | 'top' | 'bottom' | 'right';
declare type Triggers = 'click' | 'hover' | 'focus';

interface IPopoverProps {
animation?: boolean;
children?: string;
dismissable?: boolean;
isOpen?: boolean;
placement?: PopoverPlacement;
target: string;
title?: string;
trigger?: Triggers;
}

declare class Popover extends LocalSvelteComponent<IPopoverProps> {}
Expand Down
49 changes: 38 additions & 11 deletions src/Popover.svelte
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
<script>
import { onMount, tick } from 'svelte';
import { onMount } from 'svelte';
import { createPopper } from '@popperjs/core';
import classnames from './utils';
let className = '';
export { className as class };
export let children = undefined;
export let animation = true;
export let hover = false;
export let children = undefined;
export let dismissable = false;
export let isOpen = false;
export let placement = 'top';
export let target = '';
export let title = '';
export let isOpen = false;
export let trigger = 'click';
let targetEl;
let popoverEl;
let popperInstance;
Expand Down Expand Up @@ -48,16 +49,42 @@
}
};
const open = () => isOpen = true;
const close = () => isOpen = false;
const toggle = () => isOpen = !isOpen;
onMount(() => {
targetEl = document.querySelector(`#${target}`);
if (hover) {
targetEl.addEventListener('mouseover', () => isOpen = true);
targetEl.addEventListener('mouseleave', () => isOpen = false);
} else {
targetEl.addEventListener('click', () => isOpen = !isOpen);
switch (trigger) {
case 'hover':
targetEl.addEventListener('mouseover', open);
targetEl.addEventListener('mouseleave', close);
break;
case 'focus':
targetEl.addEventListener('focus', open);
targetEl.addEventListener('blur', close);
break;
default:
targetEl.addEventListener('click', toggle);
if (dismissable) targetEl.addEventListener('blur', close);
break;
}
targetEl.addEventListener('focus', () => isOpen = true);
targetEl.addEventListener('blur', () => isOpen = false);
return () => {
switch (trigger) {
case 'hover':
targetEl.removeEventListener('mouseover', open);
targetEl.removeEventListener('mouseleave', close);
break;
case 'focus':
targetEl.removeEventListener('focus', open);
targetEl.removeEventListener('blur', close);
break;
default:
targetEl.removeEventListener('click', toggle);
if (dismissable) targetEl.removeEventListener('blur', close);
break;
}
};
});
$: if (!target) {
Expand Down
12 changes: 12 additions & 0 deletions stories/popover/Dismissable.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<script lang="ts">
import Popover from '../../src/Popover.svelte';
import Button from '../../src/Button.svelte';
</script>

<a class="btn btn-secondary" id="btnDismissable" tabindex="0">Click me</a>
<Popover placement="right" target="btnDismissable" dismissable>
<div slot="title">
<i>Hello</i> <b>World!</b>
</div>
This Popover dismisses when clicked outside.
</Popover>
15 changes: 15 additions & 0 deletions stories/popover/Index.svelte
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
<script lang="ts">
import { Alert } from 'sveltestrap';
import Example from '../Example.svelte';
import Controlled from './Controlled.svelte';
import Dismissable from './Dismissable.svelte';
import Sample from './Sample.svelte';
import Slots from './Slots.svelte'
import Triggers from './Triggers.svelte'
import controlledSource from '!!raw-loader!./Controlled.svelte';
import dismissableSource from '!!raw-loader!./Dismissable.svelte';
import sampleSource from '!!raw-loader!./Sample.svelte';
import slotsSource from '!!raw-loader!./Slots.svelte';
import triggersSource from '!!raw-loader!./Triggers.svelte';
Expand All @@ -27,6 +30,18 @@
<Triggers />
</Example>

<Example title="Dismissable" source={dismissableSource}>
<div slot="info">
<Alert color="info">
<b>Note:</b>
For proper cross-browser and cross-platform behavior for dismiss-on-next-click,
you must use the &lt;a&gt; tag, not the &lt;Button&gt; tag,
and you also must include a tabindex attribute.
</Alert>
</div>
<Dismissable />
</Example>

<Example title="Controlled" source={controlledSource}>
<Controlled />
</Example>
13 changes: 12 additions & 1 deletion stories/popover/Triggers.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,21 @@
<div class="mt-3">
<Button id="btn-trigger">Hover me</Button>
<Popover
hover
trigger="hover"
placement="right"
target="btn-trigger"
title="Popover with hover">
This is a Popover with hover as the trigger.
</Popover>
</div>

<div class="mt-3">
<Button id="btn-trigger2">Focus me</Button>
<Popover
trigger="focus"
placement="right"
target="btn-trigger2"
title="Popover with focus">
This is a Popover with focus as the trigger.
</Popover>
</div>

0 comments on commit 9cdb7e9

Please sign in to comment.