import { island } from './static/koh-js/core/index.js'
import { fromValue, fromFetch } from './static/koh-js/stream/index.js'
import {
map,
debounce,
startWith,
tap,
filter,
} from './static/koh-js/operators/index.js'
island('fetch-island', k => {
const loading$ = fromValue(false)
const users$ = fromFetch(
`https://dummyjson.com/users`,
{},
{ limit: 10, skip: 0 }
)
const userData$ = users$.pipe(
filter(data => data?.users?.length > 0),
map(val => val?.users)
)
const pagination$ = users$.pipe(
map(data => {
const { total, skip, limit } = data
const totalPages = Math.round(total / limit)
if (limit + skip === total) {
return { lastPage: true, ...data }
} // last page
return { lastPage: false, ...data }
}),
map(data => {
const { lastPage, total, skip, limit } = data
const totalPages = Math.round(total / limit)
const currentPage = skip < limit ? 1 : (skip + limit) / limit
return { lastPage, currentPage, totalPages, pageSize: limit }
})
)
k.foreach('#users', {
stream: userData$,
key: u => u.id,
render: u => {
const li = document.createElement('li')
li.innerHTML = `
${u.id}.
${u.firstName} ${u.lastName}
`
return li
},
})
k.foreach('#buttons', {
stream: pagination$.pipe(
map(({ totalPages }) => {
return Array.from({ length: totalPages }, (_, i) => ({
id: i,
}))
})
),
key: u => u.id,
render: itm => {
const btn = document.createElement('button')
btn.innerHTML = `${itm.id}`
k.on(btn, 'click', () => {
users$.next(({ url, baseUrl, params }) => ({
params: { skip: itm.id * params.limit },
}))
})
return btn
},
})
k.sync(
'#buttons',
pagination$.pipe(filter(page => page.totalPages > 0)),
(el, page) => {
const buttons = k.qsa('button', el)
const { currentPage, totalPages } = page
const windowSize = 2
const realIdx = currentPage - 1
const windowStart = Math.max(realIdx - windowSize, 1)
const windowEnd = Math.min(realIdx + windowSize, totalPages - 2)
buttons.forEach((btn, idx) => {
btn.classList.remove('active')
btn.hidden = false
// Active page
if (idx === realIdx) btn.classList.add('active')
// Always show first & last
if (idx === 0 || idx === totalPages - 1) {
btn.hidden = false
btn.textContent = (idx + 1).toString()
return
}
// Window pages
if (idx >= windowStart && idx <= windowEnd) {
btn.textContent = (idx + 1).toString()
btn.hidden = false
return
}
// Ellipsis
if (idx === windowStart - 1 || idx === windowEnd + 1) {
btn.textContent = '...'
btn.hidden = false
return
}
// Rest
btn.hidden = true
})
}
)
})