Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit ad02b14

Browse files
committed
immediately hide tooltip on scroll + icon fixes in MultiSelect + type fixes in CmdPalette and PrevNext
- unit tests for tooltip to verify new scroll behavior - remove RadioButtons component and related tests
1 parent a278b5c commit ad02b14

File tree

10 files changed

+86
-201
lines changed

10 files changed

+86
-201
lines changed

.pre-commit-config.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ repos:
4343
exclude: changelog\.md
4444

4545
- repo: https://github.com/pre-commit/mirrors-eslint
46-
rev: v9.36.0
46+
rev: v9.37.0
4747
hooks:
4848
- id: eslint
4949
types: [file]

package.json

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -13,30 +13,30 @@
1313
"svelte": "^5.35.6"
1414
},
1515
"devDependencies": {
16-
"@playwright/test": "^1.55.0",
16+
"@playwright/test": "^1.55.1",
1717
"@stylistic/eslint-plugin": "^5.4.0",
18-
"@sveltejs/adapter-static": "^3.0.9",
19-
"@sveltejs/kit": "^2.42.2",
20-
"@sveltejs/package": "2.5.3",
21-
"@sveltejs/vite-plugin-svelte": "^6.2.0",
22-
"@types/node": "^24.5.2",
18+
"@sveltejs/adapter-static": "^3.0.10",
19+
"@sveltejs/kit": "^2.43.8",
20+
"@sveltejs/package": "2.5.4",
21+
"@sveltejs/vite-plugin-svelte": "^6.2.1",
22+
"@types/node": "^24.6.2",
2323
"@vitest/coverage-v8": "^3.2.4",
24-
"eslint": "^9.36.0",
25-
"eslint-plugin-svelte": "^3.12.3",
26-
"happy-dom": "^18.0.1",
24+
"eslint": "^9.37.0",
25+
"eslint-plugin-svelte": "^3.12.4",
26+
"happy-dom": "^19.0.2",
2727
"hastscript": "^9.0.1",
2828
"mdsvex": "^0.12.6",
2929
"mdsvexamples": "^0.5.0",
3030
"rehype-autolink-headings": "^7.1.0",
3131
"rehype-slug": "^6.0.0",
32-
"svelte": "^5.39.3",
33-
"svelte-check": "^4.3.1",
32+
"svelte": "^5.39.8",
33+
"svelte-check": "^4.3.2",
3434
"svelte-preprocess": "^6.0.3",
3535
"svelte-toc": "^0.6.2",
36-
"svelte2tsx": "^0.7.43",
37-
"typescript": "5.9.2",
38-
"typescript-eslint": "^8.44.0",
39-
"vite": "^7.1.6",
36+
"svelte2tsx": "^0.7.44",
37+
"typescript": "5.9.3",
38+
"typescript-eslint": "^8.45.0",
39+
"vite": "^7.1.9",
4040
"vitest": "^3.2.4"
4141
},
4242
"keywords": [

src/lib/CmdPalette.svelte

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@
99
action: (label: string) => void
1010
}
1111
12-
interface Props extends Omit<ComponentProps<typeof MultiSelect>, `options`> {
12+
interface Props
13+
extends Omit<ComponentProps<typeof MultiSelect<Action>>, `options`> {
1314
actions: Action[]
1415
triggers?: string[]
1516
close_keys?: string[]
@@ -46,14 +47,16 @@
4647
}
4748
4849
function close_if_outside(event: MouseEvent) {
49-
const target = event.target as HTMLElement
50+
const target = event.target
51+
if (!target || !(target instanceof HTMLElement)) return
5052
if (open && !dialog?.contains(target) && !target.closest(`ul.options`)) {
5153
open = false
5254
}
5355
}
5456
55-
function trigger_action_and_close(data: { option: Option }) {
56-
const { action, label } = data.option as Action
57+
function trigger_action_and_close({ option }: { option: Option }) {
58+
const { action, label } = (option ?? {}) as Action
59+
if (!action) return
5760
action(label)
5861
open = false
5962
}

src/lib/MultiSelect.svelte

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -437,7 +437,8 @@
437437
event.stopPropagation()
438438
// Only remove option if it wouldn't violate minSelect
439439
if (minSelect === null || selected.length > minSelect) {
440-
remove(selected.at(-1) as Option, event)
440+
const last_option = selected.at(-1)
441+
if (last_option) remove(last_option, event)
441442
}
442443
// Don't prevent default, allow normal backspace behavior if not removing
443444
} // make first matching option active on any keypress (if none of the above special cases match)
@@ -597,7 +598,7 @@
597598
window.addEventListener(`scroll`, update_position, true)
598599
window.addEventListener(`resize`, update_position)
599600
600-
$effect.pre(() => {
601+
$effect(() => {
601602
if (open && target_node) update_position()
602603
else node.hidden = true
603604
})
@@ -669,8 +670,7 @@
669670
{:else}
670671
<Icon
671672
icon="ChevronExpand"
672-
width="15px"
673-
style="min-width: 1em; padding: 0 1pt; cursor: pointer"
673+
style="width: 15px; min-width: 1em; padding: 0 1pt; cursor: pointer"
674674
/>
675675
{/if}
676676
<ul
@@ -725,7 +725,7 @@
725725
{#if removeIcon}
726726
{@render removeIcon()}
727727
{:else}
728-
<Icon icon="Cross" width="15px" />
728+
<Icon icon="Cross" style="width: 15px" />
729729
{/if}
730730
</button>
731731
{/if}
@@ -741,7 +741,7 @@
741741
{autocomplete}
742742
{inputmode}
743743
{pattern}
744-
placeholder={selected.length == 0 ? placeholder : null}
744+
placeholder={selected.length === 0 ? placeholder : null}
745745
aria-invalid={invalid ? `true` : null}
746746
ondrop={() => false}
747747
onmouseup={open_dropdown}
@@ -782,8 +782,7 @@
782782
{:else}
783783
<Icon
784784
icon="Disabled"
785-
width="14pt"
786-
style="margin: 0 2pt"
785+
style="width: 14pt; margin: 0 2pt"
787786
data-name="disabled-icon"
788787
aria-disabled="true"
789788
/>
@@ -807,7 +806,7 @@
807806
{#if removeIcon}
808807
{@render removeIcon()}
809808
{:else}
810-
<Icon icon="Cross" width="15px" />
809+
<Icon icon="Cross" style="width: 15px" />
811810
{/if}
812811
</button>
813812
{/if}
@@ -917,7 +916,7 @@
917916
{@const text_input_is_duplicate = selected.map(get_label).includes(searchText)}
918917
{@const is_dupe = !duplicates && text_input_is_duplicate && `dupe`}
919918
{@const can_create = Boolean(allowUserOptions && createOptionMsg) && `create`}
920-
{@const no_match = Boolean(matchingOptions?.length == 0 && noMatchingOptionsMsg) &&
919+
{@const no_match = Boolean(matchingOptions?.length === 0 && noMatchingOptionsMsg) &&
921920
`no-match`}
922921
{@const msgType = is_dupe || can_create || no_match}
923922
{#if msgType}

src/lib/PrevNext.svelte

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,18 @@
22
import type { Snippet } from 'svelte'
33
import type { HTMLAttributes } from 'svelte/elements'
44
5-
export type Item = string | [string, unknown]
6-
type T = $$Generic<Item>
5+
export type Item = [string, unknown]
76
87
interface Props extends Omit<HTMLAttributes<HTMLElement>, `children` | `onkeyup`> {
9-
items?: T[]
8+
items?: (string | Item)[]
109
node?: string
1110
current?: string
1211
log?: `verbose` | `errors` | `silent`
1312
nav_options?: { replace_state: boolean; no_scroll: boolean }
1413
titles?: { prev: string; next: string }
15-
onkeyup?: ((obj: { prev: Item; next: Item }) => Record<string, string>) | null
14+
onkeyup?:
15+
| ((obj: { prev: Item; next: Item }) => Record<string, string | undefined>)
16+
| null
1617
prev_snippet?: Snippet<[{ item: Item }]>
1718
children?: Snippet<[{ kind: `prev` | `next`; item: Item }]>
1819
between?: Snippet<[]>
@@ -26,10 +27,7 @@
2627
log = `errors`,
2728
nav_options = { replace_state: true, no_scroll: true },
2829
titles = { prev: `&larr; Previous`, next: `Next &rarr;` },
29-
onkeyup = ({ prev, next }) => ({
30-
ArrowLeft: prev[0],
31-
ArrowRight: next[0],
32-
}),
30+
onkeyup = ({ prev, next }) => ({ ArrowLeft: prev[0], ArrowRight: next[0] }),
3331
prev_snippet,
3432
children,
3533
between,
@@ -40,9 +38,9 @@
4038
4139
// Convert items to consistent [key, value] format
4240
let items_arr = $derived(
43-
(items ?? []).map((
44-
itm,
45-
) => (typeof itm === `string` ? [itm, itm] : itm)) as Item[],
41+
(items ?? []).map(
42+
(itm) => (typeof itm === `string` ? [itm, itm] : itm),
43+
) as Item[],
4644
)
4745
4846
// Calculate prev/next items with wraparound
@@ -71,9 +69,10 @@
7169
function handle_keyup(event: KeyboardEvent) {
7270
if (!onkeyup) return
7371
if ((items_arr?.length ?? 0) < min_items) return
72+
if (!prev || !next) return
7473
const key_map = onkeyup({ prev, next })
7574
const to = key_map[event.key]
76-
if (to) {
75+
if (to !== undefined) {
7776
const { replace_state, no_scroll } = nav_options
7877
const [scroll_x, scroll_y] = no_scroll
7978
? [window.scrollX, window.scrollY]

src/lib/RadioButtons.svelte

Lines changed: 0 additions & 108 deletions
This file was deleted.

src/lib/attachments.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -531,8 +531,12 @@ export const tooltip = (options: TooltipOptions = {}): Attachment => (node: Elem
531531

532532
events.forEach((event, idx) => element.addEventListener(event, handlers[idx]))
533533

534+
// Hide tooltip when user scrolls
535+
globalThis.addEventListener(`scroll`, hide_tooltip, true)
536+
534537
return () => {
535538
events.forEach((event, idx) => element.removeEventListener(event, handlers[idx]))
539+
globalThis.removeEventListener(`scroll`, hide_tooltip, true)
536540

537541
const original_title = element.getAttribute(`data-original-title`)
538542
if (original_title) {

src/lib/index.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ export { default as GitHubCorner } from './GitHubCorner.svelte'
88
export { default as Icon } from './Icon.svelte'
99
export { default, default as MultiSelect } from './MultiSelect.svelte'
1010
export { default as PrevNext } from './PrevNext.svelte'
11-
export { default as RadioButtons } from './RadioButtons.svelte'
1211
export { default as Toggle } from './Toggle.svelte'
1312
export * from './types'
1413
export * from './utils'

tests/vitest/RadioButtons.test.ts

Lines changed: 0 additions & 45 deletions
This file was deleted.

0 commit comments

Comments
 (0)