noph-ui 0.21.10 → 0.21.12

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.
@@ -26,6 +26,8 @@
26
26
  onkeydown,
27
27
  onclick,
28
28
  oninput,
29
+ onblur,
30
+ onfocusout,
29
31
  focused = $bindable(false),
30
32
  ...attributes
31
33
  }: AutoCompleteProps = $props()
@@ -46,22 +48,25 @@
46
48
  let clientWidth = $state(0)
47
49
  let menuElement: HTMLDivElement | undefined = $state()
48
50
  let finalPopulated = $state(populated)
51
+ let blockEvent = $state(false)
49
52
  </script>
50
53
 
51
54
  {#snippet item(option: AutoCompleteOption)}
52
55
  <Item
53
56
  onclick={(event) => {
54
57
  event.preventDefault()
55
- onoptionselect(option)
56
58
  element?.focus()
59
+ onoptionselect(option)
57
60
  }}
58
61
  disabled={option.disabled}
59
62
  onkeydown={(event) => {
60
63
  if (event.key === 'ArrowDown') {
64
+ blockEvent = true
61
65
  ;(event.currentTarget?.nextElementSibling as HTMLElement)?.focus()
62
66
  event.preventDefault()
63
67
  }
64
68
  if (event.key === 'ArrowUp') {
69
+ blockEvent = true
65
70
  ;(event.currentTarget?.previousElementSibling as HTMLElement)?.focus()
66
71
  event.preventDefault()
67
72
  }
@@ -70,7 +75,8 @@
70
75
  }
71
76
  if (event.key === 'Tab') {
72
77
  finalPopulated = populated
73
- menuElement?.hidePopover()
78
+ blockEvent = false
79
+ hidePopover?.()
74
80
  }
75
81
  }}
76
82
  variant="button"
@@ -90,26 +96,38 @@
90
96
  style="anchor-name:--{uid};"
91
97
  onclick={(event) => {
92
98
  finalPopulated = true
93
- menuElement?.showPopover()
99
+ showPopover()
94
100
  onclick?.(event)
95
101
  }}
96
102
  oninput={(event) => {
97
- menuElement?.showPopover()
103
+ showPopover()
98
104
  oninput?.(event)
99
105
  }}
100
106
  onkeydown={(event) => {
101
107
  if (event.key === 'Tab' || event.key === 'Escape') {
102
- menuElement?.hidePopover()
108
+ blockEvent = false
109
+ hidePopover()
103
110
  } else {
104
111
  if (event.key === 'ArrowDown' || event.key === 'ArrowUp') {
105
112
  event.preventDefault()
106
113
  finalPopulated = true
107
- menuElement?.showPopover()
114
+ blockEvent = true
115
+ showPopover()
108
116
  ;(menuElement?.firstElementChild?.firstElementChild as HTMLElement)?.focus()
109
117
  }
110
118
  }
111
119
  onkeydown?.(event)
112
120
  }}
121
+ onblur={(event) => {
122
+ if (!blockEvent) {
123
+ onblur?.(event)
124
+ }
125
+ }}
126
+ onfocusout={(event) => {
127
+ if (!blockEvent) {
128
+ onfocusout?.(event)
129
+ }
130
+ }}
113
131
  bind:reportValidity
114
132
  bind:checkValidity
115
133
  bind:element
@@ -128,9 +146,25 @@
128
146
  ? 'var(--np-outlined-select-text-field-container-shape)'
129
147
  : 'var(--np-filled-select-text-field-container-shape)'}
130
148
  anchor={element}
149
+ onbeforetoggle={(e) => {
150
+ if (e.newState !== 'closed') {
151
+ blockEvent = true
152
+ }
153
+ }}
131
154
  ontoggle={(e) => {
132
- if (e.newState === 'closed' && !populated && finalPopulated && !value) {
133
- finalPopulated = false
155
+ if (e.newState === 'closed') {
156
+ blockEvent = false
157
+ if (!populated && finalPopulated && !value) {
158
+ finalPopulated = false
159
+ }
160
+ }
161
+ if (!focused) {
162
+ const event = {
163
+ ...new FocusEvent('blur', { relatedTarget: element }),
164
+ currentTarget: element as EventTarget & HTMLInputElement,
165
+ } as FocusEvent & { currentTarget: EventTarget & HTMLInputElement }
166
+ onblur?.(event)
167
+ onfocusout?.(event)
134
168
  }
135
169
  }}
136
170
  bind:element={menuElement}
@@ -78,6 +78,7 @@
78
78
  {:else if attributes.variant === 'button'}
79
79
  <button
80
80
  {...attributes}
81
+ type="button"
81
82
  onfocus={(event) => {
82
83
  focused = true
83
84
  ;(onfocus as FocusEventHandler<HTMLButtonElement>)?.(event)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "noph-ui",
3
- "version": "0.21.10",
3
+ "version": "0.21.12",
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.31.0",
57
+ "@eslint/js": "^9.33.0",
58
58
  "@material/material-color-utilities": "^0.3.0",
59
- "@playwright/test": "^1.54.1",
60
- "@sveltejs/adapter-vercel": "^5.8.0",
61
- "@sveltejs/kit": "^2.25.1",
62
- "@sveltejs/package": "^2.4.0",
63
- "@sveltejs/vite-plugin-svelte": "^6.1.0",
59
+ "@playwright/test": "^1.54.2",
60
+ "@sveltejs/adapter-vercel": "^5.8.2",
61
+ "@sveltejs/kit": "^2.29.1",
62
+ "@sveltejs/package": "^2.4.1",
63
+ "@sveltejs/vite-plugin-svelte": "^6.1.2",
64
64
  "@types/eslint": "^9.6.1",
65
- "eslint": "^9.31.0",
65
+ "eslint": "^9.33.0",
66
66
  "eslint-config-prettier": "^10.1.8",
67
67
  "eslint-plugin-svelte": "^3.11.0",
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.36.13",
73
- "svelte-check": "^4.3.0",
74
- "typescript": "^5.8.3",
75
- "typescript-eslint": "^8.38.0",
76
- "vite": "^7.0.5",
72
+ "svelte": "^5.38.1",
73
+ "svelte-check": "^4.3.1",
74
+ "typescript": "^5.9.2",
75
+ "typescript-eslint": "^8.39.1",
76
+ "vite": "^7.1.2",
77
77
  "vitest": "^3.2.4"
78
78
  },
79
79
  "svelte": "./dist/index.js",