@govbr-ds/webcomponents
Version:
Biblioteca de Web Components baseado no GovBR-DS
180 lines (150 loc) • 6.21 kB
JavaScript
const CONTENT_ELEMENT = document.getElementById('content')
const COMPONENTS_FILTER = document.getElementById('components-filter')
const CLEAR_COMPONENTS_FILTER = document.getElementById('clear-components-filter')
let renderedFilesContent = {}
function getBaseUrl() {
const baseUrl = window.location.pathname.split('/').slice(0, -1).join('/')
return baseUrl === '' ? '' : baseUrl
}
function loadPage(path, files) {
CONTENT_ELEMENT.innerHTML = ''
renderedFilesContent = {}
COMPONENTS_FILTER.value = '' // Limpa o campo de busca ao trocar de página
CLEAR_COMPONENTS_FILTER.style.display = 'none' // Esconde o botão de limpar
const baseUrl = getBaseUrl()
const promises = files.map((file) =>
fetch(`${baseUrl}/pages/components/${path}/${file}.html`).then((response) =>
response.text().then((text) => ({ file, text }))
)
)
Promise.all(promises)
.then((results) => {
if (results.length > 0) {
results.forEach(({ file, text }) => {
const contentDiv = document.createElement('div')
contentDiv.classList.add('file', 'mt-2', 'mb-5')
const titleHTML = `<h3>${file}</h3><div class="br-divider"></div>`
contentDiv.insertAdjacentHTML('beforeend', titleHTML + text)
renderedFilesContent[file] = { content: text.toLowerCase(), element: contentDiv }
CONTENT_ELEMENT.appendChild(contentDiv)
})
}
const relatedScript = document.createElement('script')
relatedScript.src = `${getBaseUrl()}/pages/components/${path}/index.js`
document.body.appendChild(relatedScript)
})
.catch((error) => {
console.log('Erro ao carregar a página:', error)
})
}
function loadMarkdown(path) {
CONTENT_ELEMENT.innerHTML = ''
renderedFilesContent = {}
COMPONENTS_FILTER.value = '' // Limpa o campo de busca ao trocar de página
CLEAR_COMPONENTS_FILTER.style.display = 'none' // Esconde o botão de limpar
const baseUrl = getBaseUrl()
fetch(`${baseUrl}/assets/stencil-generated-docs/${path}.md`)
.then((response) => response.text())
.then((text) => {
const contentDiv = document.createElement('div')
contentDiv.classList.add('file', 'mt-2', 'mb-5')
contentDiv.innerHTML = marked.parse(text)
CONTENT_ELEMENT.appendChild(contentDiv)
renderedFilesContent[path] = { content: contentDiv.innerHTML.toLowerCase(), element: contentDiv }
})
.catch((error) => {
console.error('Erro ao carregar a página:', error)
})
}
function filterContent() {
const filterValue = COMPONENTS_FILTER.value.toLowerCase()
const normalizedFilterValue = filterValue.normalize('NFD').replace(/[\u0300-\u036f]/g, '')
Object.values(renderedFilesContent).forEach(({ content, element }) => {
const titleElement = element.querySelector('h3')
const titleText = titleElement ? titleElement.textContent.toLowerCase() : ''
const normalizedTitleText = titleText.normalize('NFD').replace(/[\u0300-\u036f]/g, '')
// Inicializa o conteúdo do shadow DOM para componentes personalizados
let shadowContent = ''
// Função para coletar o conteúdo dos slots de um custom element
const collectSlotContent = (customElement) => {
if (customElement.shadowRoot) {
const slots = customElement.shadowRoot.querySelectorAll('slot')
slots.forEach((slot) => {
const assignedNodes = slot.assignedNodes()
assignedNodes.forEach((node) => {
shadowContent += node.textContent.toLowerCase() + ' '
})
})
}
}
// Procura todos os custom elements dentro do elemento
const customElements = element.querySelectorAll('*')
customElements.forEach((customElement) => {
if (customElement.tagName.includes('-')) {
// Identifica se é um custom element
collectSlotContent(customElement)
}
})
// Filtra o conteúdo
const combinedContent = content + ' ' + shadowContent // Combina conteúdo e shadow content
if (element.querySelector('table')) {
const rows = element.querySelectorAll('table tr')
rows.forEach((row, index) => {
if (index === 0) {
row.style.display = ''
} else {
const rowText = row.textContent
.toLowerCase()
.normalize('NFD')
.replace(/[\u0300-\u036f]/g, '')
row.style.display = rowText.includes(normalizedFilterValue) ? '' : 'none'
}
})
} else if (
normalizedFilterValue &&
(combinedContent.includes(normalizedFilterValue) || normalizedTitleText.includes(normalizedFilterValue))
) {
element.style.display = '' // Exibe o elemento se o conteúdo combinado inclui o valor filtrado
} else {
element.style.display = normalizedFilterValue ? 'none' : '' // Oculta se não houver filtro
}
})
CLEAR_COMPONENTS_FILTER.style.display = filterValue ? 'block' : 'none'
}
COMPONENTS_FILTER.addEventListener('input', filterContent)
CLEAR_COMPONENTS_FILTER.addEventListener('click', () => {
COMPONENTS_FILTER.value = ''
filterContent()
})
function loadPageFromURL() {
const baseUrl = getBaseUrl()
const currentPath = window.location.pathname.replace(baseUrl, '').split('/').filter(Boolean)[0] || ''
MENU_ITEMS.forEach((page) => {
if (page.path === currentPath) {
const link = Array.from(MENU_BODY.children).find((item) => item.getAttribute('href') === `/${page.path}`)
if (link) {
link.classList.add('active')
loadPage(page.path, page.files)
}
}
})
MENU_STATIC_ITEMS.forEach((page) => {
if (page.path === currentPath) {
const link = Array.from(MENU_BODY.children).find((item) => item.getAttribute('href') === `/${page.path}`)
if (link) {
link.classList.add('active')
loadMarkdown(page.path)
}
}
})
if (currentPath.trim().length === 0) {
const firstPage = MENU_ITEMS[0]
loadPage(firstPage.path, firstPage.files)
const firstLink = MENU_BODY.querySelector('.menu-item')
if (firstLink) {
firstLink.classList.add('active')
window.history.pushState({}, '', `${baseUrl}/${firstPage.path}`)
}
}
}
loadPageFromURL()