noph-ui 0.24.14 → 0.24.16
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/autocomplete/AutoComplete.svelte +1 -2
- package/dist/button/IconButton.svelte +2 -2
- package/dist/menu/Menu.svelte +26 -22
- package/dist/menu/Menu.svelte.d.ts +1 -1
- package/dist/menu/types.d.ts +2 -0
- package/dist/navigation-drawer/NavigationDrawerItem.svelte +3 -0
- package/dist/select/Select.svelte +1 -2
- package/dist/text-field/TextField.svelte +1 -1
- package/dist/tooltip/Tooltip.svelte +39 -58
- package/package.json +1 -1
|
@@ -212,15 +212,14 @@
|
|
|
212
212
|
? 'var(--np-outlined-select-text-field-container-shape)'
|
|
213
213
|
: 'var(--np-filled-select-text-field-container-shape)'}
|
|
214
214
|
anchor={element}
|
|
215
|
+
bind:open={menuOpen}
|
|
215
216
|
ontoggle={(e) => {
|
|
216
217
|
if (e.newState === 'closed') {
|
|
217
|
-
menuOpen = false
|
|
218
218
|
activeIndex = NO_INDEX
|
|
219
219
|
if (!populated && finalPopulated && !value) {
|
|
220
220
|
finalPopulated = false
|
|
221
221
|
}
|
|
222
222
|
} else {
|
|
223
|
-
menuOpen = true
|
|
224
223
|
if (activeIndex >= displayOptions.length) {
|
|
225
224
|
activeIndex = NO_INDEX
|
|
226
225
|
}
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
<span class="np-touch" bind:this={touchEl}></span>
|
|
35
35
|
{/if}
|
|
36
36
|
{#if loading}
|
|
37
|
-
<div class="circular-progress">
|
|
37
|
+
<div class="np-icon-button-circular-progress">
|
|
38
38
|
<CircularProgress aria-label={loadingAriaLabel} indeterminate />
|
|
39
39
|
</div>
|
|
40
40
|
{/if}
|
|
@@ -365,7 +365,7 @@
|
|
|
365
365
|
width: max(calc(var(--_button-width, 40px) + 8px), 100%);
|
|
366
366
|
}
|
|
367
367
|
|
|
368
|
-
.circular-progress {
|
|
368
|
+
.np-icon-button-circular-progress {
|
|
369
369
|
--np-circular-progress-color: color-mix(in srgb, var(--np-color-on-surface) 38%, transparent);
|
|
370
370
|
position: absolute;
|
|
371
371
|
}
|
package/dist/menu/Menu.svelte
CHANGED
|
@@ -6,6 +6,8 @@
|
|
|
6
6
|
element = $bindable(),
|
|
7
7
|
showPopover = $bindable(),
|
|
8
8
|
hidePopover = $bindable(),
|
|
9
|
+
open = $bindable(),
|
|
10
|
+
quick = false,
|
|
9
11
|
style,
|
|
10
12
|
popover = 'auto',
|
|
11
13
|
anchor,
|
|
@@ -15,7 +17,6 @@
|
|
|
15
17
|
let clientWidth = $state(0)
|
|
16
18
|
let clientHeight = $state(0)
|
|
17
19
|
let innerHeight = $state(0)
|
|
18
|
-
let menuOpen = $state(false)
|
|
19
20
|
|
|
20
21
|
showPopover = () => {
|
|
21
22
|
element?.showPopover()
|
|
@@ -25,7 +26,7 @@
|
|
|
25
26
|
element?.hidePopover()
|
|
26
27
|
}
|
|
27
28
|
const refreshValues = () => {
|
|
28
|
-
if (element && anchor &&
|
|
29
|
+
if (element && anchor && open) {
|
|
29
30
|
const anchorRect = anchor.getBoundingClientRect()
|
|
30
31
|
let maxHeight: number
|
|
31
32
|
if (innerHeight - anchorRect.bottom > anchorRect.top) {
|
|
@@ -102,11 +103,11 @@
|
|
|
102
103
|
bind:clientHeight
|
|
103
104
|
ontoggle={(event) => {
|
|
104
105
|
let { newState } = event
|
|
105
|
-
|
|
106
|
+
open = newState === 'open'
|
|
106
107
|
attributes.ontoggle?.(event)
|
|
107
108
|
}}
|
|
108
109
|
{popover}
|
|
109
|
-
class={['np-menu-container', attributes.class]}
|
|
110
|
+
class={['np-menu-container', !quick && 'np-animate', attributes.class]}
|
|
110
111
|
{style}
|
|
111
112
|
>
|
|
112
113
|
<div class="np-menu">
|
|
@@ -115,18 +116,7 @@
|
|
|
115
116
|
</div>
|
|
116
117
|
|
|
117
118
|
<style>
|
|
118
|
-
.np-menu {
|
|
119
|
-
overflow-y: auto;
|
|
120
|
-
overflow-x: hidden;
|
|
121
|
-
flex: 1;
|
|
122
|
-
padding: 0.5rem 0;
|
|
123
|
-
scrollbar-color: var(--np-color-on-surface-variant) transparent;
|
|
124
|
-
scrollbar-width: thin;
|
|
125
|
-
}
|
|
126
|
-
:global(.np-menu .np-divider) {
|
|
127
|
-
margin-block: 0.5rem;
|
|
128
|
-
}
|
|
129
|
-
.np-menu-container[popover] {
|
|
119
|
+
.np-menu-container {
|
|
130
120
|
color: var(--np-menu-text-color, var(--np-color-on-surface));
|
|
131
121
|
background-color: var(--np-menu-container-color, var(--np-color-surface-container));
|
|
132
122
|
border: none;
|
|
@@ -135,21 +125,35 @@
|
|
|
135
125
|
box-shadow: var(--np-elevation-2);
|
|
136
126
|
margin: var(--np-menu-margin, 2px);
|
|
137
127
|
inset: auto;
|
|
138
|
-
transition:
|
|
139
|
-
display 0.2s allow-discrete,
|
|
140
|
-
opacity 0.2s linear;
|
|
141
|
-
opacity: 0;
|
|
142
128
|
justify-self: var(--np-menu-justify-self, anchor-center);
|
|
143
129
|
position-area: var(--np-menu-position-area, bottom center);
|
|
144
130
|
position-try: normal flip-block;
|
|
145
131
|
z-index: 1000;
|
|
146
132
|
}
|
|
147
133
|
|
|
148
|
-
.np-
|
|
134
|
+
.np-animate[popover] {
|
|
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 {
|
|
149
142
|
opacity: 1;
|
|
150
|
-
display: flex;
|
|
151
143
|
@starting-style {
|
|
152
144
|
opacity: 0;
|
|
153
145
|
}
|
|
154
146
|
}
|
|
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
|
+
}
|
|
155
159
|
</style>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import type { MenuProps } from './types.ts';
|
|
2
|
-
declare const Menu: import("svelte").Component<MenuProps, {}, "element" | "showPopover" | "hidePopover">;
|
|
2
|
+
declare const Menu: import("svelte").Component<MenuProps, {}, "element" | "showPopover" | "hidePopover" | "open">;
|
|
3
3
|
type Menu = ReturnType<typeof Menu>;
|
|
4
4
|
export default Menu;
|
package/dist/menu/types.d.ts
CHANGED
|
@@ -6,6 +6,8 @@ export interface MenuProps extends HTMLAttributes<HTMLDivElement> {
|
|
|
6
6
|
showPopover?: () => void;
|
|
7
7
|
hidePopover?: () => void;
|
|
8
8
|
element?: HTMLDivElement;
|
|
9
|
+
quick?: boolean;
|
|
10
|
+
open?: boolean;
|
|
9
11
|
}
|
|
10
12
|
interface ButtonProps extends HTMLButtonAttributes {
|
|
11
13
|
selected?: boolean;
|
|
@@ -31,6 +31,7 @@
|
|
|
31
31
|
selected && 'np-navigation-drawer-item-selected',
|
|
32
32
|
attributes.class,
|
|
33
33
|
]}
|
|
34
|
+
aria-current={selected ? 'page' : undefined}
|
|
34
35
|
>
|
|
35
36
|
{@render content()}
|
|
36
37
|
</a>
|
|
@@ -42,6 +43,8 @@
|
|
|
42
43
|
selected && 'np-navigation-drawer-item-selected',
|
|
43
44
|
attributes.class,
|
|
44
45
|
]}
|
|
46
|
+
type="button"
|
|
47
|
+
aria-pressed={selected ? 'true' : undefined}
|
|
45
48
|
>
|
|
46
49
|
{@render content()}
|
|
47
50
|
</button>
|
|
@@ -577,9 +577,9 @@
|
|
|
577
577
|
? 'var(--np-outlined-select-text-field-container-shape)'
|
|
578
578
|
: 'var(--np-filled-select-text-field-container-shape)'}
|
|
579
579
|
anchor={anchorElement}
|
|
580
|
+
bind:open={menuOpen}
|
|
580
581
|
ontoggle={async ({ newState }) => {
|
|
581
582
|
if (newState === 'open') {
|
|
582
|
-
menuOpen = true
|
|
583
583
|
let idx = -1
|
|
584
584
|
if (multiple) {
|
|
585
585
|
if (Array.isArray(value) && value.length) {
|
|
@@ -594,7 +594,6 @@
|
|
|
594
594
|
if (idx < 0) idx = 0
|
|
595
595
|
focusIndex = idx
|
|
596
596
|
} else {
|
|
597
|
-
menuOpen = false
|
|
598
597
|
focusIndex = -1
|
|
599
598
|
}
|
|
600
599
|
}}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
+
import { MediaQuery } from 'svelte/reactivity'
|
|
2
3
|
import type { TooltipProps } from './types.ts'
|
|
4
|
+
import { onMount } from 'svelte'
|
|
3
5
|
|
|
4
6
|
let {
|
|
5
7
|
children,
|
|
@@ -8,34 +10,11 @@
|
|
|
8
10
|
keepTooltipOnClick = false,
|
|
9
11
|
...attributes
|
|
10
12
|
}: TooltipProps = $props()
|
|
11
|
-
let clientWidth = $state(0)
|
|
12
|
-
let clientHeight = $state(0)
|
|
13
|
-
let innerHeight = $state(0)
|
|
14
|
-
let anchor: HTMLElement | undefined = $state()
|
|
15
13
|
|
|
16
|
-
const
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
if (anchorRect.bottom + clientHeight > innerHeight && anchorRect.top - clientHeight > 0) {
|
|
21
|
-
element.style.top = `${anchorRect.top - clientHeight - 8}px`
|
|
22
|
-
} else {
|
|
23
|
-
element.style.top = `${anchorRect.bottom}px`
|
|
24
|
-
}
|
|
25
|
-
const left = anchorRect.left + anchorRect.width / 2 - clientWidth / 2
|
|
26
|
-
if (left < 2) {
|
|
27
|
-
element.style.left = '2px'
|
|
28
|
-
} else if (left > docClientWidth - clientWidth) {
|
|
29
|
-
element.style.left = `${docClientWidth - clientWidth - 2}px`
|
|
30
|
-
} else {
|
|
31
|
-
element.style.left = `${anchorRect.left + anchorRect.width / 2 - clientWidth / 2}px`
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
$effect(refreshValues)
|
|
36
|
-
let setAnchor = (document: Document) => {
|
|
37
|
-
anchor = (document.querySelector(`[aria-describedby="${id}"]`) as HTMLElement) ?? undefined
|
|
38
|
-
}
|
|
14
|
+
const anchorNameFallback = $props.id()
|
|
15
|
+
|
|
16
|
+
let touch = new MediaQuery('(pointer: coarse) and (hover: none)', false)
|
|
17
|
+
let anchor = $state<HTMLElement>()
|
|
39
18
|
|
|
40
19
|
const isTouch = (event: PointerEvent) => {
|
|
41
20
|
return event.pointerType === 'touch'
|
|
@@ -58,25 +37,10 @@
|
|
|
58
37
|
element?.hidePopover()
|
|
59
38
|
}
|
|
60
39
|
}
|
|
61
|
-
|
|
62
|
-
$effect(() => {
|
|
63
|
-
if (anchor && element) {
|
|
64
|
-
if ('anchorName' in document.documentElement.style) {
|
|
65
|
-
const anchorName = anchor.style.getPropertyValue('anchor-name')
|
|
66
|
-
const generatedId = anchorName || `--${crypto.randomUUID()}`
|
|
67
|
-
element.style.setProperty('position-anchor', generatedId)
|
|
68
|
-
if (!anchorName) {
|
|
69
|
-
anchor.style.setProperty('anchor-name', generatedId)
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
anchor.addEventListener('pointerenter', onPointerenter)
|
|
73
|
-
anchor.addEventListener('pointerleave', onPointerleave)
|
|
74
|
-
if (!keepTooltipOnClick) {
|
|
75
|
-
anchor.addEventListener('pointerup', onPointerup)
|
|
76
|
-
}
|
|
77
|
-
}
|
|
40
|
+
onMount(() => {
|
|
78
41
|
return () => {
|
|
79
42
|
if (anchor) {
|
|
43
|
+
anchor.style.removeProperty('anchor-name')
|
|
80
44
|
anchor.removeEventListener('pointerenter', onPointerenter)
|
|
81
45
|
anchor.removeEventListener('pointerleave', onPointerleave)
|
|
82
46
|
anchor.removeEventListener('pointerup', onPointerup)
|
|
@@ -85,21 +49,38 @@
|
|
|
85
49
|
})
|
|
86
50
|
</script>
|
|
87
51
|
|
|
88
|
-
|
|
89
|
-
<
|
|
52
|
+
{#if !touch.current}
|
|
53
|
+
<div
|
|
54
|
+
{...attributes}
|
|
55
|
+
{@attach (element) => {
|
|
56
|
+
if (id && 'positionArea' in document.documentElement.style) {
|
|
57
|
+
anchor = (document.querySelector(`[aria-describedby="${id}"]`) as HTMLElement) ?? undefined
|
|
90
58
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
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
|
+
{id}
|
|
75
|
+
class={['np-tooltip', attributes.class]}
|
|
76
|
+
role="tooltip"
|
|
77
|
+
aria-live="polite"
|
|
78
|
+
popover="manual"
|
|
79
|
+
bind:this={element}
|
|
80
|
+
>
|
|
81
|
+
{#if children}{@render children()}{/if}
|
|
82
|
+
</div>
|
|
83
|
+
{/if}
|
|
103
84
|
|
|
104
85
|
<style>
|
|
105
86
|
.np-tooltip[popover] {
|