noph-ui 0.24.16 → 0.24.19
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.
- package/dist/button/Button.svelte +1 -2
- package/dist/button/IconButton.svelte +1 -2
- package/dist/button/types.d.ts +0 -4
- package/dist/menu/Menu.svelte +27 -26
- package/dist/menu/types.d.ts +0 -1
- package/dist/tooltip/Tooltip.svelte +61 -46
- package/dist/tooltip/Tooltip.svelte.d.ts +1 -1
- package/dist/tooltip/types.d.ts +1 -1
- package/package.json +8 -8
|
@@ -14,7 +14,6 @@
|
|
|
14
14
|
element = $bindable(),
|
|
15
15
|
disabled = false,
|
|
16
16
|
loading = false,
|
|
17
|
-
keepTooltipOnClick,
|
|
18
17
|
loadingAriaLabel,
|
|
19
18
|
size = 's',
|
|
20
19
|
shape = 'round',
|
|
@@ -106,7 +105,7 @@
|
|
|
106
105
|
{/if}
|
|
107
106
|
|
|
108
107
|
{#if title && !disabled && !loading}
|
|
109
|
-
<Tooltip
|
|
108
|
+
<Tooltip id={uid}>{title}</Tooltip>
|
|
110
109
|
{/if}
|
|
111
110
|
|
|
112
111
|
<style>
|
|
@@ -16,7 +16,6 @@
|
|
|
16
16
|
loadingAriaLabel,
|
|
17
17
|
selected = $bindable(false),
|
|
18
18
|
selectedIcon,
|
|
19
|
-
keepTooltipOnClick,
|
|
20
19
|
width = 'default',
|
|
21
20
|
size = 's',
|
|
22
21
|
shape = 'round',
|
|
@@ -100,7 +99,7 @@
|
|
|
100
99
|
{/if}
|
|
101
100
|
|
|
102
101
|
{#if title && !disabled && !loading}
|
|
103
|
-
<Tooltip
|
|
102
|
+
<Tooltip id={uid}>{title}</Tooltip>
|
|
104
103
|
{/if}
|
|
105
104
|
|
|
106
105
|
<style>
|
package/dist/button/types.d.ts
CHANGED
|
@@ -8,7 +8,6 @@ interface ButtonButtonProps extends HTMLButtonAttributes {
|
|
|
8
8
|
disabled?: boolean;
|
|
9
9
|
loading?: boolean;
|
|
10
10
|
loadingAriaLabel?: string;
|
|
11
|
-
keepTooltipOnClick?: boolean;
|
|
12
11
|
size?: 'xs' | 's' | 'm' | 'l' | 'xl';
|
|
13
12
|
toggle?: boolean;
|
|
14
13
|
shape?: 'round' | 'square';
|
|
@@ -19,7 +18,6 @@ interface ButtonAnchorProps extends HTMLAnchorAttributes {
|
|
|
19
18
|
start?: Snippet;
|
|
20
19
|
end?: Snippet;
|
|
21
20
|
element?: HTMLElement;
|
|
22
|
-
keepTooltipOnClick?: boolean;
|
|
23
21
|
disabled?: boolean;
|
|
24
22
|
loading?: boolean;
|
|
25
23
|
loadingAriaLabel?: string;
|
|
@@ -35,7 +33,6 @@ interface IconButtonButtonProps extends HTMLButtonAttributes {
|
|
|
35
33
|
selected?: boolean;
|
|
36
34
|
loading?: boolean;
|
|
37
35
|
loadingAriaLabel?: string;
|
|
38
|
-
keepTooltipOnClick?: boolean;
|
|
39
36
|
selectedIcon?: Snippet;
|
|
40
37
|
shape?: 'round' | 'square';
|
|
41
38
|
size?: 'xs' | 's' | 'm' | 'l' | 'xl';
|
|
@@ -49,7 +46,6 @@ interface IconButtonAnchorProps extends HTMLAnchorAttributes {
|
|
|
49
46
|
loadingAriaLabel?: string;
|
|
50
47
|
toggle?: boolean;
|
|
51
48
|
selected?: boolean;
|
|
52
|
-
keepTooltipOnClick?: boolean;
|
|
53
49
|
selectedIcon?: Snippet;
|
|
54
50
|
shape?: 'round' | 'square';
|
|
55
51
|
size?: 'xs' | 's' | 'm' | 'l' | 'xl';
|
package/dist/menu/Menu.svelte
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
+
import { onMount } from 'svelte'
|
|
2
3
|
import type { MenuProps } from './types.ts'
|
|
3
4
|
|
|
4
5
|
let {
|
|
@@ -7,7 +8,6 @@
|
|
|
7
8
|
showPopover = $bindable(),
|
|
8
9
|
hidePopover = $bindable(),
|
|
9
10
|
open = $bindable(),
|
|
10
|
-
quick = false,
|
|
11
11
|
style,
|
|
12
12
|
popover = 'auto',
|
|
13
13
|
anchor,
|
|
@@ -82,10 +82,13 @@
|
|
|
82
82
|
refreshValues()
|
|
83
83
|
}
|
|
84
84
|
|
|
85
|
-
|
|
86
|
-
if (
|
|
87
|
-
getScrollableParent(
|
|
85
|
+
const attachScrollableParent = (el: HTMLDivElement) => {
|
|
86
|
+
if (!('anchorName' in document.documentElement.style)) {
|
|
87
|
+
getScrollableParent(el).addEventListener('scroll', onScroll, { passive: true })
|
|
88
88
|
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
onMount(() => {
|
|
89
92
|
return () => {
|
|
90
93
|
if (element && !('anchorName' in document.documentElement.style)) {
|
|
91
94
|
getScrollableParent(element).removeEventListener('scroll', onScroll)
|
|
@@ -98,6 +101,7 @@
|
|
|
98
101
|
<div
|
|
99
102
|
role="menu"
|
|
100
103
|
{...attributes}
|
|
104
|
+
{@attach attachScrollableParent}
|
|
101
105
|
bind:this={element}
|
|
102
106
|
bind:clientWidth
|
|
103
107
|
bind:clientHeight
|
|
@@ -107,7 +111,7 @@
|
|
|
107
111
|
attributes.ontoggle?.(event)
|
|
108
112
|
}}
|
|
109
113
|
{popover}
|
|
110
|
-
class={['np-menu-container',
|
|
114
|
+
class={['np-menu-container', attributes.class]}
|
|
111
115
|
{style}
|
|
112
116
|
>
|
|
113
117
|
<div class="np-menu">
|
|
@@ -116,7 +120,18 @@
|
|
|
116
120
|
</div>
|
|
117
121
|
|
|
118
122
|
<style>
|
|
119
|
-
.np-menu
|
|
123
|
+
.np-menu {
|
|
124
|
+
overflow-y: auto;
|
|
125
|
+
overflow-x: hidden;
|
|
126
|
+
flex: 1;
|
|
127
|
+
padding: 0.5rem 0;
|
|
128
|
+
scrollbar-color: var(--np-color-on-surface-variant) transparent;
|
|
129
|
+
scrollbar-width: thin;
|
|
130
|
+
}
|
|
131
|
+
:global(.np-menu .np-divider) {
|
|
132
|
+
margin-block: 0.5rem;
|
|
133
|
+
}
|
|
134
|
+
.np-menu-container[popover] {
|
|
120
135
|
color: var(--np-menu-text-color, var(--np-color-on-surface));
|
|
121
136
|
background-color: var(--np-menu-container-color, var(--np-color-surface-container));
|
|
122
137
|
border: none;
|
|
@@ -125,35 +140,21 @@
|
|
|
125
140
|
box-shadow: var(--np-elevation-2);
|
|
126
141
|
margin: var(--np-menu-margin, 2px);
|
|
127
142
|
inset: auto;
|
|
143
|
+
transition:
|
|
144
|
+
display 0.2s allow-discrete,
|
|
145
|
+
opacity 0.2s linear;
|
|
146
|
+
opacity: 0;
|
|
128
147
|
justify-self: var(--np-menu-justify-self, anchor-center);
|
|
129
148
|
position-area: var(--np-menu-position-area, bottom center);
|
|
130
149
|
position-try: normal flip-block;
|
|
131
150
|
z-index: 1000;
|
|
132
151
|
}
|
|
133
152
|
|
|
134
|
-
.np-
|
|
135
|
-
transition:
|
|
136
|
-
opacity 0.2s ease,
|
|
137
|
-
display 0.2s allow-discrete,
|
|
138
|
-
overlay 0.2s allow-discrete;
|
|
139
|
-
opacity: 0;
|
|
140
|
-
}
|
|
141
|
-
.np-animate[popover]:popover-open {
|
|
153
|
+
.np-menu-container:popover-open {
|
|
142
154
|
opacity: 1;
|
|
155
|
+
display: flex;
|
|
143
156
|
@starting-style {
|
|
144
157
|
opacity: 0;
|
|
145
158
|
}
|
|
146
159
|
}
|
|
147
|
-
|
|
148
|
-
.np-menu {
|
|
149
|
-
overflow-y: auto;
|
|
150
|
-
overflow-x: hidden;
|
|
151
|
-
flex: 1;
|
|
152
|
-
padding: 0.5rem 0;
|
|
153
|
-
scrollbar-color: var(--np-color-on-surface-variant) transparent;
|
|
154
|
-
scrollbar-width: thin;
|
|
155
|
-
}
|
|
156
|
-
:global(.np-menu .np-divider) {
|
|
157
|
-
margin-block: 0.5rem;
|
|
158
|
-
}
|
|
159
160
|
</style>
|
package/dist/menu/types.d.ts
CHANGED
|
@@ -1,82 +1,97 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
import { MediaQuery } from 'svelte/reactivity'
|
|
3
|
-
import type { TooltipProps } from './types.ts'
|
|
4
2
|
import { onMount } from 'svelte'
|
|
3
|
+
import type { TooltipProps } from './types.ts'
|
|
4
|
+
import { MediaQuery } from 'svelte/reactivity'
|
|
5
5
|
|
|
6
6
|
let {
|
|
7
7
|
children,
|
|
8
|
+
open = $bindable(),
|
|
8
9
|
element = $bindable(),
|
|
9
10
|
id,
|
|
10
|
-
keepTooltipOnClick = false,
|
|
11
11
|
...attributes
|
|
12
12
|
}: TooltipProps = $props()
|
|
13
|
+
let clientWidth = $state(0)
|
|
14
|
+
let clientHeight = $state(0)
|
|
15
|
+
let innerHeight = $state(0)
|
|
16
|
+
let anchor: HTMLElement | undefined = $state()
|
|
17
|
+
const uid = $props.id()
|
|
13
18
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
let touch = new MediaQuery('(pointer: coarse) and (hover: none)', false)
|
|
17
|
-
let anchor = $state<HTMLElement>()
|
|
19
|
+
let isTouch = new MediaQuery('(hover: none) and (pointer: coarse)', false)
|
|
18
20
|
|
|
19
|
-
const
|
|
20
|
-
|
|
21
|
+
const refreshValues = () => {
|
|
22
|
+
if (element && anchor && open && !('positionArea' in document.documentElement.style)) {
|
|
23
|
+
const docClientWidth = document.documentElement.clientWidth
|
|
24
|
+
const anchorRect = anchor.getBoundingClientRect()
|
|
25
|
+
if (anchorRect.bottom + clientHeight > innerHeight && anchorRect.top - clientHeight > 0) {
|
|
26
|
+
element.style.top = `${anchorRect.top - clientHeight - 8}px`
|
|
27
|
+
} else {
|
|
28
|
+
element.style.top = `${anchorRect.bottom}px`
|
|
29
|
+
}
|
|
30
|
+
const left = anchorRect.left + anchorRect.width / 2 - clientWidth / 2
|
|
31
|
+
if (left < 2) {
|
|
32
|
+
element.style.left = '2px'
|
|
33
|
+
} else if (left > docClientWidth - clientWidth) {
|
|
34
|
+
element.style.left = `${docClientWidth - clientWidth - 2}px`
|
|
35
|
+
} else {
|
|
36
|
+
element.style.left = `${anchorRect.left + anchorRect.width / 2 - clientWidth / 2}px`
|
|
37
|
+
}
|
|
38
|
+
}
|
|
21
39
|
}
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
40
|
+
$effect(refreshValues)
|
|
41
|
+
let attachAnchor = (el: HTMLDivElement) => {
|
|
42
|
+
anchor = (document.querySelector(`[aria-describedby="${id}"]`) as HTMLElement) ?? undefined
|
|
43
|
+
if (!anchor) return
|
|
44
|
+
if ('anchorName' in document.documentElement.style) {
|
|
45
|
+
const anchorName = anchor.style.getPropertyValue('anchor-name')
|
|
46
|
+
const generatedId = anchorName || `--${uid}`
|
|
47
|
+
el.style.setProperty('position-anchor', generatedId)
|
|
48
|
+
if (!anchorName) {
|
|
49
|
+
anchor.style.setProperty('anchor-name', generatedId)
|
|
50
|
+
}
|
|
26
51
|
}
|
|
52
|
+
anchor.addEventListener('pointerenter', showPopover)
|
|
53
|
+
anchor.addEventListener('pointerleave', hidePopover)
|
|
54
|
+
anchor.addEventListener('focus', showPopover)
|
|
55
|
+
anchor.addEventListener('blur', hidePopover)
|
|
27
56
|
}
|
|
28
57
|
|
|
29
|
-
const
|
|
30
|
-
|
|
31
|
-
element?.hidePopover()
|
|
32
|
-
}
|
|
58
|
+
const showPopover = () => {
|
|
59
|
+
element?.showPopover()
|
|
33
60
|
}
|
|
34
61
|
|
|
35
|
-
const
|
|
36
|
-
|
|
37
|
-
element?.hidePopover()
|
|
38
|
-
}
|
|
62
|
+
const hidePopover = () => {
|
|
63
|
+
element?.hidePopover()
|
|
39
64
|
}
|
|
65
|
+
|
|
40
66
|
onMount(() => {
|
|
41
67
|
return () => {
|
|
42
68
|
if (anchor) {
|
|
43
|
-
anchor.
|
|
44
|
-
anchor.removeEventListener('
|
|
45
|
-
anchor.removeEventListener('
|
|
46
|
-
anchor.removeEventListener('
|
|
69
|
+
anchor.removeEventListener('pointerenter', showPopover)
|
|
70
|
+
anchor.removeEventListener('pointerleave', hidePopover)
|
|
71
|
+
anchor.removeEventListener('focus', showPopover)
|
|
72
|
+
anchor.removeEventListener('blur', hidePopover)
|
|
47
73
|
}
|
|
48
74
|
}
|
|
49
75
|
})
|
|
50
76
|
</script>
|
|
51
77
|
|
|
52
|
-
|
|
78
|
+
<svelte:window bind:innerHeight />
|
|
79
|
+
|
|
80
|
+
{#if !isTouch.current}
|
|
53
81
|
<div
|
|
54
82
|
{...attributes}
|
|
55
|
-
{@attach (element) => {
|
|
56
|
-
if (id && 'positionArea' in document.documentElement.style) {
|
|
57
|
-
anchor = (document.querySelector(`[aria-describedby="${id}"]`) as HTMLElement) ?? undefined
|
|
58
|
-
|
|
59
|
-
if ('anchorName' in document.documentElement.style) {
|
|
60
|
-
const anchorName = anchor.style.getPropertyValue('anchor-name')
|
|
61
|
-
const generatedId = anchorName || `--${anchorNameFallback}`
|
|
62
|
-
element.style.setProperty('position-anchor', generatedId)
|
|
63
|
-
if (!anchorName) {
|
|
64
|
-
anchor.style.setProperty('anchor-name', generatedId)
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
anchor.addEventListener('pointerenter', onPointerenter)
|
|
68
|
-
anchor.addEventListener('pointerleave', onPointerleave)
|
|
69
|
-
if (!keepTooltipOnClick) {
|
|
70
|
-
anchor.addEventListener('pointerup', onPointerup)
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
}}
|
|
74
83
|
{id}
|
|
84
|
+
{@attach attachAnchor}
|
|
75
85
|
class={['np-tooltip', attributes.class]}
|
|
76
86
|
role="tooltip"
|
|
77
|
-
aria-live="polite"
|
|
78
87
|
popover="manual"
|
|
79
88
|
bind:this={element}
|
|
89
|
+
bind:clientWidth
|
|
90
|
+
bind:clientHeight
|
|
91
|
+
ontoggle={(event) => {
|
|
92
|
+
let { newState } = event
|
|
93
|
+
open = newState === 'open'
|
|
94
|
+
}}
|
|
80
95
|
>
|
|
81
96
|
{#if children}{@render children()}{/if}
|
|
82
97
|
</div>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import type { TooltipProps } from './types.ts';
|
|
2
|
-
declare const Tooltip: import("svelte").Component<TooltipProps, {}, "element">;
|
|
2
|
+
declare const Tooltip: import("svelte").Component<TooltipProps, {}, "element" | "open">;
|
|
3
3
|
type Tooltip = ReturnType<typeof Tooltip>;
|
|
4
4
|
export default Tooltip;
|
package/dist/tooltip/types.d.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "noph-ui",
|
|
3
|
-
"version": "0.24.
|
|
3
|
+
"version": "0.24.19",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"homepage": "https://noph.dev",
|
|
6
6
|
"repository": {
|
|
@@ -54,26 +54,26 @@
|
|
|
54
54
|
"svelte": "^5.32.1"
|
|
55
55
|
},
|
|
56
56
|
"devDependencies": {
|
|
57
|
-
"@eslint/js": "^9.
|
|
57
|
+
"@eslint/js": "^9.35.0",
|
|
58
58
|
"@material/material-color-utilities": "^0.3.0",
|
|
59
59
|
"@playwright/test": "^1.55.0",
|
|
60
60
|
"@sveltejs/adapter-vercel": "^5.10.2",
|
|
61
|
-
"@sveltejs/kit": "^2.37.
|
|
61
|
+
"@sveltejs/kit": "^2.37.1",
|
|
62
62
|
"@sveltejs/package": "^2.5.0",
|
|
63
63
|
"@sveltejs/vite-plugin-svelte": "^6.1.4",
|
|
64
64
|
"@types/eslint": "^9.6.1",
|
|
65
|
-
"eslint": "^9.
|
|
65
|
+
"eslint": "^9.35.0",
|
|
66
66
|
"eslint-config-prettier": "^10.1.8",
|
|
67
|
-
"eslint-plugin-svelte": "^3.12.
|
|
67
|
+
"eslint-plugin-svelte": "^3.12.2",
|
|
68
68
|
"globals": "^16.3.0",
|
|
69
69
|
"prettier": "^3.6.2",
|
|
70
70
|
"prettier-plugin-svelte": "^3.4.0",
|
|
71
71
|
"publint": "^0.3.12",
|
|
72
|
-
"svelte": "^5.38.
|
|
72
|
+
"svelte": "^5.38.7",
|
|
73
73
|
"svelte-check": "^4.3.1",
|
|
74
74
|
"typescript": "^5.9.2",
|
|
75
|
-
"typescript-eslint": "^8.
|
|
76
|
-
"vite": "^7.1.
|
|
75
|
+
"typescript-eslint": "^8.43.0",
|
|
76
|
+
"vite": "^7.1.5",
|
|
77
77
|
"vitest": "^3.2.4"
|
|
78
78
|
},
|
|
79
79
|
"svelte": "./dist/index.js",
|