Merge pull request #27829 from overleaf/rh-pug-contact-suggestions

Show subject suggestions list in pug contact form

GitOrigin-RevId: 509506ab1ad629eafcc34df7d841c095321ae72b
This commit is contained in:
roo hutton
2025-08-18 08:05:48 +00:00
committed by Copybot
parent ea028442cd
commit f342d77221
4 changed files with 60 additions and 28 deletions
@@ -9,7 +9,6 @@ document
.forEach(el => {
el.addEventListener('click', function (e) {
e.preventDefault()
$('[data-ol-contact-form-modal="contact-us"]').modal()
})
})
@@ -18,7 +17,6 @@ document
.forEach(el => {
el.addEventListener('click', function (e) {
e.preventDefault()
$('[data-ol-contact-form-modal="general"]').modal()
})
})
@@ -1,17 +1,21 @@
import _ from 'lodash'
import DOMPurify from 'dompurify'
import { formatWikiHit, searchWiki } from '../algolia-search/search-wiki'
import { sendMB } from '../../infrastructure/event-tracking'
import { materialIcon } from '@/features/utils/material-icon'
export function setupSearch(formEl) {
const inputEl = formEl.querySelector('[name="subject"]')
const resultsEl = formEl.querySelector('[data-ol-search-results]')
const resultsContainerEl = formEl.querySelector(
'[data-ol-search-results-container]'
)
const wrapperEl = formEl.querySelector('[data-ol-search-results-wrapper]')
let lastValue = ''
function hideResults() {
wrapperEl.setAttribute('hidden', '')
}
function showResults() {
wrapperEl.removeAttribute('hidden')
}
@@ -25,32 +29,55 @@ export function setupSearch(formEl) {
return
}
DOMPurify.addHook('uponSanitizeElement', node => {
if (node.nodeName === 'EM') {
const strong = document.createElement('strong')
strong.textContent = node.textContent
node.parentNode?.replaceChild(strong, node)
}
})
try {
const { hits, nbHits } = await searchWiki(value, {
hitsPerPage: 3,
typoTolerance: 'strict',
})
resultsEl.innerText = ''
resultsContainerEl.innerHTML = ''
for (const hit of hits) {
const { url, pageName } = formatWikiHit(hit)
const { url, rawPageName, sectionName } = formatWikiHit(hit)
const liEl = document.createElement('li')
const linkEl = document.createElement('a')
linkEl.className = 'contact-suggestion-list-item'
linkEl.className = 'dropdown-item'
linkEl.href = url
linkEl.target = '_blank'
linkEl.rel = 'noopener noreferrer'
linkEl.setAttribute('role', 'menuitem')
liEl.append(linkEl)
const contentEl = document.createElement('span')
contentEl.innerHTML = pageName
linkEl.append(contentEl)
const contentWrapperEl = document.createElement('div')
contentWrapperEl.className = 'dropdown-item-description-container'
linkEl.append(contentWrapperEl)
const pageNameEl = document.createElement('div')
pageNameEl.innerHTML = DOMPurify.sanitize(rawPageName)
contentWrapperEl.append(pageNameEl)
const iconEl = materialIcon('open_in_new')
iconEl.classList.add('dropdown-item-trailing-icon')
linkEl.append(iconEl)
iconEl.setAttribute('aria-hidden', 'true')
contentWrapperEl.append(iconEl)
resultsEl.append(liEl)
if (sectionName) {
const sectionEl = document.createElement('span')
sectionEl.className = 'dropdown-item-description'
sectionEl.innerHTML = DOMPurify.sanitize(sectionName)
contentWrapperEl.append(sectionEl)
}
resultsContainerEl.append(liEl)
}
if (nbHits > 0) {
showResults()
@@ -61,10 +88,31 @@ export function setupSearch(formEl) {
} catch (e) {
hideResults()
}
DOMPurify.removeHook('uponSanitizeElement')
}
inputEl.addEventListener('input', _.debounce(handleChange, 350))
// display initial results
function handleClickOutside(event) {
if (!wrapperEl.contains(event.target) && !inputEl.contains(event.target)) {
hideResults()
}
}
document.addEventListener('click', handleClickOutside)
function handleKeyDown(event) {
if (event.key === 'Escape') {
if (!wrapperEl.hasAttribute('hidden')) {
hideResults()
event.stopPropagation()
event.preventDefault()
}
}
}
formEl.addEventListener('keydown', handleKeyDown)
handleChange()
}
+1
View File
@@ -10,3 +10,4 @@ import './features/multi-submit'
import './features/cookie-banner'
import './features/autoplay-video'
import './features/mathjax'
import './features/contact-form'
@@ -15,22 +15,6 @@
margin-bottom: var(--spacing-05);
}
.contact-suggestions {
@include body-sm;
margin: 0 calc(-1 * var(--bs-modal-padding)) var(--spacing-05);
padding: var(--spacing-05) 0;
color: var(--content-secondary);
background-color: var(--bg-light-secondary);
border-top: solid 1px var(--border-primary-dark);
border-bottom: solid 1px var(--border-primary-dark);
}
.contact-suggestion-label {
margin-bottom: var(--spacing-05);
padding: 0 var(--spacing-07);
}
.contact-suggestion-list {
padding-left: 0;
list-style: none;
@@ -64,6 +48,7 @@
}
.contact-suggestions-dropdown {
margin-top: $spacing-02;
width: calc(100% - 2 * var(--bs-modal-padding));
.dropdown-header {