Skip to content

Commit 69f5f65

Browse files
committed
chore: cleanup
1 parent 0405b42 commit 69f5f65

1 file changed

Lines changed: 91 additions & 27 deletions

File tree

packages/ui/src/components/code.tsx

Lines changed: 91 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -109,9 +109,8 @@ function installFindShortcuts() {
109109
return
110110
}
111111

112-
if (isEditable(event.target)) return
113-
114-
const host = hostForNode(document.activeElement) ?? findTarget ?? Array.from(findHosts)[0]
112+
const host =
113+
hostForNode(document.activeElement) ?? hostForNode(event.target) ?? findTarget ?? Array.from(findHosts)[0]
115114
if (!host) return
116115

117116
event.preventDefault()
@@ -126,9 +125,11 @@ export function Code<T>(props: CodeProps<T>) {
126125
let wrapper!: HTMLDivElement
127126
let container!: HTMLDivElement
128127
let findInput: HTMLInputElement | undefined
128+
let findBar: HTMLDivElement | undefined
129129
let findOverlay!: HTMLDivElement
130130
let findOverlayFrame: number | undefined
131131
let findOverlayScroll: HTMLElement[] = []
132+
let findPositionFrame: number | undefined
132133
let observer: MutationObserver | undefined
133134
let renderToken = 0
134135
let selectionFrame: number | undefined
@@ -290,6 +291,41 @@ export function Code<T>(props: CodeProps<T>) {
290291
setFindIndex(0)
291292
}
292293

294+
const getScrollParent = (el: HTMLElement): HTMLElement | null => {
295+
let parent = el.parentElement
296+
while (parent) {
297+
const style = getComputedStyle(parent)
298+
if (style.overflowY === "auto" || style.overflowY === "scroll") return parent
299+
parent = parent.parentElement
300+
}
301+
return null
302+
}
303+
304+
const positionFindBar = () => {
305+
if (!findBar || !wrapper) return
306+
const scrollParent = getScrollParent(wrapper)
307+
if (!scrollParent) {
308+
findBar.style.position = "absolute"
309+
findBar.style.top = "8px"
310+
findBar.style.right = "8px"
311+
findBar.style.left = ""
312+
return
313+
}
314+
const scrollTop = scrollParent.scrollTop
315+
findBar.style.position = "absolute"
316+
findBar.style.top = `${scrollTop + 8}px`
317+
findBar.style.right = "8px"
318+
findBar.style.left = ""
319+
}
320+
321+
const scheduleFindPosition = () => {
322+
if (findPositionFrame !== undefined) return
323+
findPositionFrame = requestAnimationFrame(() => {
324+
findPositionFrame = undefined
325+
positionFindBar()
326+
})
327+
}
328+
293329
const scanFind = (root: ShadowRoot, query: string) => {
294330
const needle = query.toLowerCase()
295331
const out: Range[] = []
@@ -458,6 +494,7 @@ export function Code<T>(props: CodeProps<T>) {
458494

459495
if (!findOpen()) setFindOpen(true)
460496
requestAnimationFrame(() => {
497+
positionFindBar()
461498
findInput?.focus()
462499
findInput?.select()
463500
})
@@ -482,6 +519,25 @@ export function Code<T>(props: CodeProps<T>) {
482519
})
483520
})
484521

522+
createEffect(() => {
523+
if (!findOpen()) return
524+
const scrollParent = getScrollParent(wrapper)
525+
const target = scrollParent ?? window
526+
527+
const handler = () => scheduleFindPosition()
528+
target.addEventListener("scroll", handler, { passive: true })
529+
window.addEventListener("resize", handler, { passive: true })
530+
531+
onCleanup(() => {
532+
target.removeEventListener("scroll", handler)
533+
window.removeEventListener("resize", handler)
534+
if (findPositionFrame !== undefined) {
535+
cancelAnimationFrame(findPositionFrame)
536+
findPositionFrame = undefined
537+
}
538+
})
539+
})
540+
485541
const applyCommentedLines = (ranges: SelectedLineRange[]) => {
486542
const root = getRoot()
487543
if (!root) return
@@ -862,6 +918,11 @@ export function Code<T>(props: CodeProps<T>) {
862918
dragFrame = undefined
863919
}
864920

921+
if (findPositionFrame !== undefined) {
922+
cancelAnimationFrame(findPositionFrame)
923+
findPositionFrame = undefined
924+
}
925+
865926
dragStart = undefined
866927
dragEnd = undefined
867928
dragMoved = false
@@ -888,19 +949,18 @@ export function Code<T>(props: CodeProps<T>) {
888949
findTarget = host
889950
}}
890951
>
891-
<div ref={container} />
892-
<div ref={findOverlay} class="pointer-events-none absolute inset-0 z-0" />
893952
<Show when={findOpen()}>
894953
<div
895-
class="absolute top-2 right-2 z-10 flex items-center gap-1 rounded-md border border-border-weak-base bg-surface-raised-base px-2 py-1 shadow-xs-border"
954+
ref={findBar}
955+
class="z-50 flex h-8 items-center gap-2 rounded-md border border-border-base bg-background-base px-3 shadow-md"
896956
onPointerDown={(e) => e.stopPropagation()}
897957
>
898-
<Icon name="magnifying-glass" size="small" class="text-text-weak" />
958+
<Icon name="magnifying-glass" size="small" class="text-text-weak shrink-0" />
899959
<input
900960
ref={findInput}
901961
placeholder="Find"
902962
value={findQuery()}
903-
class="w-48 bg-transparent outline-none text-12-regular text-text-strong placeholder:text-text-weak"
963+
class="w-40 bg-transparent outline-none text-14-regular text-text-strong placeholder:text-text-weak"
904964
onInput={(e) => {
905965
setFindQuery(e.currentTarget.value)
906966
setFindIndex(0)
@@ -917,37 +977,41 @@ export function Code<T>(props: CodeProps<T>) {
917977
stepFind(e.shiftKey ? -1 : 1)
918978
}}
919979
/>
920-
<div class="px-1 text-12-regular text-text-weak tabular-nums">
980+
<div class="shrink-0 text-12-regular text-text-weak tabular-nums">
921981
{findCount() ? `${findIndex() + 1}/${findCount()}` : "0/0"}
922982
</div>
983+
<div class="flex items-center">
984+
<button
985+
type="button"
986+
class="size-6 grid place-items-center rounded text-text-weak hover:bg-surface-base-hover hover:text-text-strong disabled:opacity-40 disabled:pointer-events-none"
987+
disabled={findCount() === 0}
988+
aria-label="Previous match"
989+
onClick={() => stepFind(-1)}
990+
>
991+
<Icon name="chevron-down" size="small" class="rotate-180" />
992+
</button>
993+
<button
994+
type="button"
995+
class="size-6 grid place-items-center rounded text-text-weak hover:bg-surface-base-hover hover:text-text-strong disabled:opacity-40 disabled:pointer-events-none"
996+
disabled={findCount() === 0}
997+
aria-label="Next match"
998+
onClick={() => stepFind(1)}
999+
>
1000+
<Icon name="chevron-down" size="small" />
1001+
</button>
1002+
</div>
9231003
<button
9241004
type="button"
9251005
class="size-6 grid place-items-center rounded text-text-weak hover:bg-surface-base-hover hover:text-text-strong"
926-
disabled={findCount() === 0}
927-
aria-label="Previous match"
928-
onClick={() => stepFind(-1)}
929-
>
930-
<Icon name="chevron-down" size="small" class="rotate-180" />
931-
</button>
932-
<button
933-
type="button"
934-
class="size-6 grid place-items-center rounded text-text-weak hover:bg-surface-base-hover hover:text-text-strong"
935-
disabled={findCount() === 0}
936-
aria-label="Next match"
937-
onClick={() => stepFind(1)}
938-
>
939-
<Icon name="chevron-down" size="small" />
940-
</button>
941-
<button
942-
type="button"
943-
class="ml-1 size-6 grid place-items-center rounded text-text-weak hover:bg-surface-base-hover hover:text-text-strong"
9441006
aria-label="Close search"
9451007
onClick={closeFind}
9461008
>
9471009
<Icon name="close-small" size="small" />
9481010
</button>
9491011
</div>
9501012
</Show>
1013+
<div ref={container} />
1014+
<div ref={findOverlay} class="pointer-events-none absolute inset-0 z-0" />
9511015
</div>
9521016
)
9531017
}

0 commit comments

Comments
 (0)