noph-ui 0.8.14 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -74,8 +74,8 @@
74
74
  </a>
75
75
  {/if}
76
76
 
77
- {#if title && element}
78
- <Tooltip anchor={element} id={tooltipId}>{title}</Tooltip>
77
+ {#if title}
78
+ <Tooltip id={tooltipId}>{title}</Tooltip>
79
79
  {/if}
80
80
 
81
81
  <style>
@@ -85,8 +85,8 @@
85
85
  </a>
86
86
  {/if}
87
87
 
88
- {#if title && element}
89
- <Tooltip anchor={element} id={tooltipId}>{title}</Tooltip>
88
+ {#if title}
89
+ <Tooltip id={tooltipId}>{title}</Tooltip>
90
90
  {/if}
91
91
 
92
92
  <style>
@@ -1,5 +1,12 @@
1
1
  <script lang="ts">
2
- let { children } = $props()
2
+ import type { Snippet } from 'svelte'
3
+ import type { HTMLAttributes } from 'svelte/elements'
4
+
5
+ interface IconProps extends HTMLAttributes<HTMLSpanElement> {
6
+ children: Snippet
7
+ element?: HTMLSpanElement
8
+ }
9
+ let { children, element = $bindable(), ...attributes }: IconProps = $props()
3
10
  </script>
4
11
 
5
12
  <svelte:head>
@@ -40,4 +47,6 @@
40
47
  </style>
41
48
  </svelte:head>
42
49
 
43
- <span class="np-icon">{@render children()}</span>
50
+ <span {...attributes} class={['np-icon', attributes.class]} bind:this={element}
51
+ >{@render children()}</span
52
+ >
@@ -1,5 +1,8 @@
1
- declare const Icon: import("svelte").Component<{
2
- children: any;
3
- }, {}, "">;
1
+ import type { Snippet } from 'svelte';
2
+ import type { HTMLAttributes } from 'svelte/elements';
3
+ declare const Icon: import("svelte").Component<HTMLAttributes<HTMLSpanElement> & {
4
+ children: Snippet;
5
+ element?: HTMLSpanElement;
6
+ }, {}, "element">;
4
7
  type Icon = ReturnType<typeof Icon>;
5
8
  export default Icon;
@@ -1,17 +1,15 @@
1
1
  <script lang="ts">
2
2
  import type { TooltipProps } from './types.ts'
3
3
 
4
- let { children, anchor, ...attributes }: TooltipProps = $props()
4
+ let { children, element = $bindable(), id, ...attributes }: TooltipProps = $props()
5
5
  let clientWidth = $state(0)
6
6
  let clientHeight = $state(0)
7
7
  let innerHeight = $state(0)
8
8
  let innerWidth = $state(0)
9
- let anchorRect: DOMRect | undefined = $state(anchor.getBoundingClientRect())
9
+ let anchor: HTMLElement | undefined = $state()
10
+ let anchorRect: DOMRect | undefined = $state()
10
11
 
11
12
  const distanceToBorder = 8
12
- const refreshValues = () => {
13
- anchorRect = anchor?.getBoundingClientRect()
14
- }
15
13
 
16
14
  let calculateLeftPos = $derived.by(() => {
17
15
  if (!anchor || !anchorRect) {
@@ -37,18 +35,34 @@
37
35
  }
38
36
  return top
39
37
  })
40
- anchor.addEventListener('mouseenter', () => {
41
- refreshValues()
38
+ let setAnchor = (document: Document) => {
39
+ anchor = (document.querySelector(`[aria-describedby="${id}"]`) as HTMLElement) ?? undefined
40
+ }
41
+
42
+ $effect(() => {
43
+ if (anchor) {
44
+ anchor.addEventListener('pointerenter', () => {
45
+ anchorRect = anchor?.getBoundingClientRect() ?? undefined
46
+ element?.showPopover()
47
+ })
48
+ anchor.addEventListener('pointerleave', () => {
49
+ element?.hidePopover()
50
+ })
51
+ }
42
52
  })
43
53
  </script>
44
54
 
45
- <svelte:window bind:innerHeight bind:innerWidth onresize={refreshValues} onscroll={refreshValues} />
55
+ <svelte:document use:setAnchor />
56
+ <svelte:window bind:innerHeight bind:innerWidth />
46
57
 
47
58
  <div
48
59
  {...attributes}
49
- class={['tooltip', attributes.class]}
60
+ {id}
61
+ class={['np-tooltip', attributes.class]}
50
62
  style="top:{calculateTopPos}px;left:{calculateLeftPos}px;{attributes.style}"
51
63
  role="tooltip"
64
+ popover="manual"
65
+ bind:this={element}
52
66
  bind:clientWidth
53
67
  bind:clientHeight
54
68
  >
@@ -56,23 +70,31 @@
56
70
  </div>
57
71
 
58
72
  <style>
59
- .tooltip {
60
- visibility: hidden;
73
+ .np-tooltip {
61
74
  width: max-content;
62
- position: fixed;
75
+ margin: 0;
63
76
  background: var(--np-color-inverse-surface);
64
77
  color: var(--np-color-inverse-on-surface);
65
- scale: 0;
66
- z-index: 1;
67
78
  padding: 0.25rem 0.5rem;
68
79
  border-radius: 0.25rem;
69
80
  line-height: 1rem;
70
81
  font-size: 0.75rem;
71
- transition: scale 0.3s ease;
82
+ opacity: 0;
83
+ transition:
84
+ overlay 0.3s allow-discrete,
85
+ display 0.3s allow-discrete,
86
+ opacity 0.3s ease;
72
87
  }
73
- @media (hover: hover) {
74
- :global([aria-describedby]:hover + [role='tooltip']) {
75
- visibility: visible;
88
+ .np-tooltip:popover-open {
89
+ opacity: 1;
90
+ animation: scaleIn 0.3s ease;
91
+ }
92
+
93
+ @keyframes scaleIn {
94
+ from {
95
+ scale: 0;
96
+ }
97
+ to {
76
98
  scale: 1;
77
99
  }
78
100
  }
@@ -1,4 +1,4 @@
1
1
  import type { TooltipProps } from './types.ts';
2
- declare const Tooltip: import("svelte").Component<TooltipProps, {}, "">;
2
+ declare const Tooltip: import("svelte").Component<TooltipProps, {}, "element">;
3
3
  type Tooltip = ReturnType<typeof Tooltip>;
4
4
  export default Tooltip;
@@ -1,4 +1,4 @@
1
1
  import type { HTMLAttributes } from 'svelte/elements';
2
2
  export interface TooltipProps extends Omit<HTMLAttributes<HTMLDivElement>, 'role'> {
3
- anchor: HTMLElement;
3
+ element?: HTMLDivElement;
4
4
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "noph-ui",
3
- "version": "0.8.14",
3
+ "version": "0.9.0",
4
4
  "license": "MIT",
5
5
  "homepage": "https://noph.dev",
6
6
  "repository": {