machineuser commited on
Commit
36befc4
1 Parent(s): 90976b5

Sync widgets demo

Browse files
packages/widgets/src/lib/components/Popover/Popover.svelte CHANGED
@@ -1,7 +1,12 @@
 
 
 
 
 
1
  <script lang="ts">
2
  import { onMount, tick, createEventDispatcher } from "svelte";
3
  import { fade } from "svelte/transition";
4
- import { debounce, portalToBody } from "../../utils/ViewUtils.js";
5
 
6
  export let classNames = "";
7
  export let anchorElement: HTMLElement;
@@ -10,7 +15,6 @@
10
  export let waitForContent = false;
11
  export let size: "sm" | "md" = "md";
12
  export let invertedColors = false;
13
- export let touchOnly = false;
14
 
15
  let popoverElement: HTMLDivElement;
16
 
@@ -30,10 +34,7 @@
30
  let top: number;
31
  let width: number;
32
  let height: number;
33
-
34
  let popoverShift: number;
35
- let isTouchOnly = false;
36
- let isActive = true;
37
 
38
  function updatePlacement(anchorBbox: DOMRect, pageHeight: number) {
39
  if (pageHeight > 0) {
@@ -56,7 +57,7 @@
56
  function updateAlignment(anchorBbox: DOMRect, pageWidth: number) {
57
  if (alignment === "auto" && pageWidth > 0) {
58
  const popoverWidth = popoverElement.getBoundingClientRect().width;
59
- if (anchorBbox.left + popoverWidth > pageWidth - HIT_ZONE_MARGIN) {
60
  computedAlignment = "end";
61
  } else {
62
  computedAlignment = "start";
@@ -82,38 +83,25 @@
82
  }
83
  }
84
 
85
- const debouncedShow = debounce(() => (isActive = true), 250);
86
-
87
- function hide() {
88
- if (!popoverElement?.matches(":hover")) {
89
- isActive = false;
 
90
  }
91
  }
92
- const debouncedHide = debounce(hide, 250);
93
 
94
  onMount(() => {
95
- isTouchOnly = touchOnly && window.matchMedia("(any-hover: none)").matches;
96
-
97
- if (!isTouchOnly) {
98
- updatePosition();
99
- if (anchorElement) {
100
- anchorElement.addEventListener("mouseover", debouncedShow);
101
- anchorElement.addEventListener("mouseleave", debouncedHide);
102
- return () => {
103
- anchorElement.removeEventListener("mouseover", debouncedShow);
104
- anchorElement.removeEventListener("mouseleave", debouncedHide);
105
- };
106
- }
107
- }
108
  });
109
  </script>
110
 
111
- <svelte:window on:resize={() => dispatch("close")} on:scroll={() => dispatch("close")} />
112
 
113
- <div class={isTouchOnly ? "hidden sm:contents" : "contents"} use:portalToBody>
114
  <div
115
- class="pointer-events-none absolute bg-transparent hidden"
116
- class:hidden={!isActive}
117
  style:top="{top}px"
118
  style:left="{left}px"
119
  style:width="{width}px"
@@ -122,7 +110,6 @@
122
  <div
123
  bind:this={popoverElement}
124
  in:fade={{ duration: 100 }}
125
- on:mouseleave={debouncedHide}
126
  class="pointer-events-auto absolute z-10 transform
127
  {computedPlacement === 'top' ? 'bottom-full -translate-y-3' : 'top-full translate-y-2.5'}
128
  {computedAlignment === 'start' ? 'left-0' : computedAlignment === 'end' ? 'right-0' : 'left-1/2 -translate-x-1/2'}
 
1
+ <!--
2
+ In https://github.com/huggingface/huggingface.js/pull/567, this component was changed significantly from the original one in moon/Popover.svelte.
3
+ Therefore, if/when widgets code goes back to moon, make sure not to delete this Popover.svelte right away before reconciling the differences.
4
+ -->
5
+
6
  <script lang="ts">
7
  import { onMount, tick, createEventDispatcher } from "svelte";
8
  import { fade } from "svelte/transition";
9
+ import { portalToBody } from "../../utils/ViewUtils.js";
10
 
11
  export let classNames = "";
12
  export let anchorElement: HTMLElement;
 
15
  export let waitForContent = false;
16
  export let size: "sm" | "md" = "md";
17
  export let invertedColors = false;
 
18
 
19
  let popoverElement: HTMLDivElement;
20
 
 
34
  let top: number;
35
  let width: number;
36
  let height: number;
 
37
  let popoverShift: number;
 
 
38
 
39
  function updatePlacement(anchorBbox: DOMRect, pageHeight: number) {
40
  if (pageHeight > 0) {
 
57
  function updateAlignment(anchorBbox: DOMRect, pageWidth: number) {
58
  if (alignment === "auto" && pageWidth > 0) {
59
  const popoverWidth = popoverElement.getBoundingClientRect().width;
60
+ if (anchorBbox.left + popoverWidth > pageWidth) {
61
  computedAlignment = "end";
62
  } else {
63
  computedAlignment = "start";
 
83
  }
84
  }
85
 
86
+ function handleClickDocument(e: MouseEvent) {
87
+ const targetElement = e.target as HTMLElement;
88
+ if (![popoverElement, anchorElement].some((el) => el === targetElement || el?.contains(targetElement))) {
89
+ e.preventDefault();
90
+ e.stopPropagation();
91
+ dispatch("close");
92
  }
93
  }
 
94
 
95
  onMount(() => {
96
+ updatePosition();
 
 
 
 
 
 
 
 
 
 
 
 
97
  });
98
  </script>
99
 
100
+ <svelte:window on:resize={() => dispatch("close")} on:scroll={() => dispatch("close")} on:click={handleClickDocument} />
101
 
102
+ <div class="contents" use:portalToBody>
103
  <div
104
+ class="pointer-events-none absolute bg-transparent"
 
105
  style:top="{top}px"
106
  style:left="{left}px"
107
  style:width="{width}px"
 
110
  <div
111
  bind:this={popoverElement}
112
  in:fade={{ duration: 100 }}
 
113
  class="pointer-events-auto absolute z-10 transform
114
  {computedPlacement === 'top' ? 'bottom-full -translate-y-3' : 'top-full translate-y-2.5'}
115
  {computedAlignment === 'start' ? 'left-0' : computedAlignment === 'end' ? 'right-0' : 'left-1/2 -translate-x-1/2'}