Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions src/components/pdf-viewer/page/pdf-page.js
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ export default class PDFPage extends PDFViewerComponent {
const itemEnd = charPosition + normalizedText.length

const overlappingMatches = pageMatches.filter(match => {
const matchEnd = match.charIndex + this.searchTerm.length
const matchEnd = match.charIndex + (match.length || this.searchTerm.length)
return match.charIndex < itemEnd && matchEnd > itemStart
})

Expand All @@ -151,7 +151,8 @@ export default class PDFPage extends PDFViewerComponent {

matches.forEach(match => {
const relativeStart = Math.max(0, match.charIndex - itemStart)
const relativeEnd = Math.min(text.length, match.charIndex + this.searchTerm.length - itemStart)
const matchLength = match.length || this.searchTerm.length
const relativeEnd = Math.min(text.length, match.charIndex + matchLength - itemStart)

if (relativeStart > currentPos) {
segments.push({ text: text.substring(currentPos, relativeStart), highlight: false })
Expand Down
70 changes: 55 additions & 15 deletions src/components/pdf-viewer/pdf-viewer.js
Original file line number Diff line number Diff line change
Expand Up @@ -85,21 +85,59 @@ export default class PDFViewer extends LitElement {
_handleKeyDown(event) {
if (!this.open) return

if (event.key === 'Escape') {
if (this.searchOpen) {
this.searchOpen = false
event.preventDefault()
} else if (this.escapeClosesViewer) {
this.open = false
event.preventDefault()
}
} else if (event.key === '/' && !this.searchOpen) {
const target = event.target
if (target.tagName !== 'INPUT' && target.tagName !== 'TEXTAREA') {
this.searchOpen = true
event.preventDefault()
const target = event.composedPath()[0]
const isInputField = target.tagName === 'INPUT' || target.tagName === 'TEXTAREA'

if (isInputField && event.key !== 'Escape') return

const shortcuts = {
'Escape': () => {
if (this.searchOpen) {
this.searchOpen = false
return true
} else if (this.escapeClosesViewer) {
this.open = false
return true
}
return false
},
'/': () => {
if (!this.searchOpen) {
this.searchOpen = true
return true
}
return false
},
's': () => {
this.sidebarCollapsed = !this.sidebarCollapsed
return true
},
'p': () => {
this.printPDF()
return true
},
'ArrowUp': () => {
if (this.currentPage > 1) {
this.shouldScroll = true
this.currentPage--
return true
}
return false
},
'ArrowDown': () => {
if (this.currentPage < this.totalPages) {
this.shouldScroll = true
this.currentPage++
return true
}
return false
}
}

const handler = shortcuts[event.key]
if (handler && handler()) {
event.preventDefault()
}
}

_createContextValue() {
Expand Down Expand Up @@ -387,7 +425,8 @@ export default class PDFViewer extends LitElement {
if (!term || !this.pdfDoc) return

const matches = []
const searchTermLower = term.toLowerCase()
const normalizedTerm = normalizeText(term)
const searchTermLower = normalizedTerm.toLowerCase()

for (let pageNum = 1; pageNum <= this.totalPages; pageNum++) {
try {
Expand All @@ -413,7 +452,8 @@ export default class PDFViewer extends LitElement {
matches.push({
pageNum,
charIndex: index,
text: term
text: term,
length: normalizedTerm.length
})
index = pageTextLower.indexOf(searchTermLower, index + 1)
}
Expand Down
10 changes: 6 additions & 4 deletions src/components/pdf-viewer/toolbar/pdf-toolbar.js
Original file line number Diff line number Diff line change
Expand Up @@ -129,12 +129,14 @@ export default class PDFToolbar extends PDFViewerComponent {
<div class="toolbar">
<div class="toolbar__section">
${sidebarCollapsed ? html`
<button class="btn--icon" @click="${this.toggleSidebar}" title="Open Sidebar">
<button class="btn--icon btn--sidebar" @click="${this.toggleSidebar}" title="Open Sidebar (S)">
${unsafeSVG(openSidebarIcon)}
<span class="btn--sidebar-badge">S</span>
</button>
` : html`
<button class="btn--icon" @click="${this.toggleSidebar}" title="Close Sidebar">
<button class="btn--icon btn--sidebar" @click="${this.toggleSidebar}" title="Close Sidebar (S)">
${unsafeSVG(closeSidebarIcon)}
<span class="btn--sidebar-badge">S</span>
</button>
`}

Expand Down Expand Up @@ -175,12 +177,12 @@ export default class PDFToolbar extends PDFViewerComponent {
</div>

<div class="toolbar__section">
<button class="btn--icon btn--search ${searchOpen ? 'btn--search--active' : ''}" @click="${this.toggleSearch}">
<button class="btn--icon btn--search ${searchOpen ? 'btn--search--active' : ''}" @click="${this.toggleSearch}" title="Search (/)">
${unsafeSVG(searchIcon)}
<span class="btn--search-badge">/</span>
</button>

<button class="btn--icon" @click="${this.print}" title="Print">
<button class="btn--icon" @click="${this.print}" title="Print (P)">
${unsafeSVG(printIcon)}
</button>
<button class="btn--icon btn--download" @click="${this.download}" title="Download">
Expand Down
17 changes: 11 additions & 6 deletions src/components/pdf-viewer/toolbar/pdf-toolbar.styles.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,25 +44,29 @@ export default css`
}
}

.btn--search {
.btn--search,
.btn--sidebar {
background: var(--theme-neutral-100);
display: flex;
align-items: center;
justify-content: center;
gap: var(--theme-spacing-xs, 0.25rem);
}

.btn--search--active {
.btn--search--active,
.btn--sidebar--active {
background: var(--theme-primary-50, #e6f0ff);
color: var(--theme-primary, #0066cc);
}

.btn--search--active .btn--search-badge {
.btn--search--active .btn--search-badge,
.btn--sidebar--active .btn--sidebar-badge {
background: var(--theme-primary, #0066cc);
color: var(--theme-neutral-50, #ffffff);
}

.btn--search-badge {
.btn--search-badge,
.btn--sidebar-badge {
background: var(--theme-neutral-200);
color: var(--theme-neutral-600);
font-size: 9px;
Expand Down Expand Up @@ -172,7 +176,7 @@ export default css`
padding: var(--theme-spacing-sm, 0.5rem);
border: var(--theme-border-width-sm, 1px) solid var(--theme-neutral-300, #ccc);
border-radius: var(--theme-border-radius-md, 4px);
font-size: var(--theme-font-size-base, 0.9rem);
font-size: var(--theme-font-size-md, 14px);
outline: none;
}

Expand All @@ -193,7 +197,8 @@ export default css`
display: none;
}

.btn--search-badge {
.btn--search-badge,
.btn--sidebar-badge {
display: none;
}
}
Expand Down