feat(popover): add closeOnOutsideClick prop

This commit is contained in:
Eric Y Liu 2021-03-19 08:21:52 -07:00
commit b728454a60
6 changed files with 81 additions and 12 deletions

View file

@ -2639,14 +2639,15 @@ None.
### Props ### Props
| Prop name | Kind | Reactive | Type | Default value | Description | | Prop name | Kind | Reactive | Type | Default value | Description |
| :----------- | :--------------- | :------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------ | ------------------------------------------------- | | :------------------ | :--------------- | :------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------ | ------------------------------------------------------ |
| open | <code>let</code> | No | <code>boolean</code> | <code>false</code> | Set to `true` to display the popover | | open | <code>let</code> | Yes | <code>boolean</code> | <code>false</code> | Set to `true` to display the popover |
| caret | <code>let</code> | No | <code>boolean</code> | <code>false</code> | Set to `true` render a caret | | closeOnOutsideClick | <code>let</code> | No | <code>boolean</code> | <code>false</code> | Set to `true` to close the popover on an outside click |
| align | <code>let</code> | No | <code>"top" &#124; "top-left" &#124; "top-right" &#124; "bottom" &#124; "bottom-left" &#124; "bottom-right" &#124; "left" &#124; "left-bottom" &#124; "left-top" &#124; "right" &#124; "right-bottom" &#124; "right-top"</code> | <code>"top"</code> | Specify the alignment of the caret | | caret | <code>let</code> | No | <code>boolean</code> | <code>false</code> | Set to `true` render a caret |
| light | <code>let</code> | No | <code>boolean</code> | <code>false</code> | Set to `true` to enable the light variant | | align | <code>let</code> | No | <code>"top" &#124; "top-left" &#124; "top-right" &#124; "bottom" &#124; "bottom-left" &#124; "bottom-right" &#124; "left" &#124; "left-bottom" &#124; "left-top" &#124; "right" &#124; "right-bottom" &#124; "right-top"</code> | <code>"top"</code> | Specify the alignment of the caret |
| highContrast | <code>let</code> | No | <code>boolean</code> | <code>false</code> | Set to `true` to enable the high contrast variant | | light | <code>let</code> | No | <code>boolean</code> | <code>false</code> | Set to `true` to enable the light variant |
| relative | <code>let</code> | No | <code>boolean</code> | <code>false</code> | Set to `true` to use a relative position | | highContrast | <code>let</code> | No | <code>boolean</code> | <code>false</code> | Set to `true` to enable the high contrast variant |
| relative | <code>let</code> | No | <code>boolean</code> | <code>false</code> | Set to `true` to use a relative position |
### Slots ### Slots
@ -2656,7 +2657,9 @@ None.
### Events ### Events
None. | Event name | Type | Detail |
| :------------ | :--------- | :----- |
| click:outside | dispatched | -- |
## `ProgressIndicator` ## `ProgressIndicator`

View file

@ -6800,6 +6800,16 @@
"value": "false", "value": "false",
"isFunction": false, "isFunction": false,
"constant": false, "constant": false,
"reactive": true
},
{
"name": "closeOnOutsideClick",
"kind": "let",
"description": "Set to `true` to close the popover on an outside click",
"type": "boolean",
"value": "false",
"isFunction": false,
"constant": false,
"reactive": false "reactive": false
}, },
{ {
@ -6854,7 +6864,7 @@
} }
], ],
"slots": [{ "name": "__default__", "default": true, "slot_props": "{}" }], "slots": [{ "name": "__default__", "default": true, "slot_props": "{}" }],
"events": [], "events": [{ "type": "dispatched", "name": "click:outside" }],
"typedefs": [], "typedefs": [],
"rest_props": { "type": "Element", "name": "div" } "rest_props": { "type": "Element", "name": "div" }
}, },

View file

@ -14,7 +14,7 @@ By default, the position of the popover component is absolute.
</Popover> </Popover>
</div> </div>
### Relative ### Relative position
Set `relative` to `true` to use a relative position. Set `relative` to `true` to use a relative position.
@ -25,6 +25,16 @@ Set `relative` to `true` to use a relative position.
</Popover> </Popover>
</div> </div>
### Close on outside click
Set `closeOnOutsideClick` to set `open` to `false` when clicking outside of the popover.
<div data-outline="relative">
Parent
<Popover open closeOnOutsideClick on:click:outside={() => {console.log('on:click:outside')}}>
<div style="padding: var(--cds-spacing-05)">Content</div>
</Popover>
</div>
### With caret ### With caret

View file

@ -2,6 +2,9 @@
/** Set to `true` to display the popover */ /** Set to `true` to display the popover */
export let open = false; export let open = false;
/** Set to `true` to close the popover on an outside click */
export let closeOnOutsideClick = false;
/** Set to `true` render a caret */ /** Set to `true` render a caret */
export let caret = false; export let caret = false;
@ -19,9 +22,26 @@
/** Set to `true` to use a relative position */ /** Set to `true` to use a relative position */
export let relative = false; export let relative = false;
import { createEventDispatcher } from "svelte";
const dispatch = createEventDispatcher();
let ref = null;
</script> </script>
<svelte:window
on:click="{(e) => {
if (!open) return;
if (e.target.contains(ref)) {
dispatch('click:outside');
if (closeOnOutsideClick) open = false;
}
}}"
/>
<div <div
bind:this="{ref}"
class:bx--popover="{true}" class:bx--popover="{true}"
class:bx--popover--caret="{caret}" class:bx--popover--caret="{caret}"
class:bx--popover--light="{light}" class:bx--popover--light="{light}"

20
tests/Popover.test.svelte Normal file
View file

@ -0,0 +1,20 @@
<script lang="ts">
import { Popover } from "../types";
let open = false;
</script>
<Popover
bind:open
closeOnOutsideClick
align="right"
caret
relative
light
highContrast
on:click:outside="{() => {
console.log('on:click:outside');
}}"
>
<div style="padding: var(--cds-spacing-05)">Content</div>
</Popover>

View file

@ -9,6 +9,12 @@ export interface PopoverProps
*/ */
open?: boolean; open?: boolean;
/**
* Set to `true` to close the popover on an outside click
* @default false
*/
closeOnOutsideClick?: boolean;
/** /**
* Set to `true` render a caret * Set to `true` render a caret
* @default false * @default false
@ -54,6 +60,6 @@ export interface PopoverProps
export default class Popover extends SvelteComponentTyped< export default class Popover extends SvelteComponentTyped<
PopoverProps, PopoverProps,
{}, { ["click:outside"]: CustomEvent<any> },
{ default: {} } { default: {} }
> {} > {}