75 lines
1.6 KiB
Svelte
75 lines
1.6 KiB
Svelte
<svelte:options customElement="ui-data-table-shell" />
|
|
|
|
<script lang="ts">
|
|
export let endpoint = '';
|
|
export let target = '';
|
|
export let pageSize = 10;
|
|
|
|
let query = '';
|
|
|
|
function submit(page = 1) {
|
|
if (!endpoint || !target) return;
|
|
|
|
const params = new URLSearchParams();
|
|
if (query.trim()) params.set('q', query.trim());
|
|
params.set('page', String(page));
|
|
params.set('pageSize', String(pageSize));
|
|
|
|
const url = `${endpoint}${endpoint.includes('?') ? '&' : '?'}${params.toString()}`;
|
|
|
|
const htmxApi = (window as any).htmx;
|
|
if (htmxApi && typeof htmxApi.ajax === 'function') {
|
|
htmxApi.ajax('GET', url, { target });
|
|
return;
|
|
}
|
|
|
|
const targetEl = document.querySelector(target);
|
|
if (!targetEl) return;
|
|
|
|
fetch(url)
|
|
.then((res) => res.text())
|
|
.then((html) => {
|
|
targetEl.innerHTML = html;
|
|
})
|
|
.catch(() => {
|
|
// no-op fallback
|
|
});
|
|
}
|
|
</script>
|
|
|
|
<form class="toolbar" on:submit|preventDefault={() => submit(1)}>
|
|
<input
|
|
type="search"
|
|
placeholder="Search..."
|
|
bind:value={query}
|
|
on:keydown={(e) => e.key === 'Enter' && submit(1)}
|
|
/>
|
|
<button type="submit">Search</button>
|
|
</form>
|
|
|
|
<style>
|
|
.toolbar {
|
|
display: flex;
|
|
gap: 8px;
|
|
align-items: center;
|
|
margin-bottom: 12px;
|
|
}
|
|
|
|
input[type='search'] {
|
|
flex: 1;
|
|
min-width: 180px;
|
|
padding: 10px;
|
|
border: 1px solid var(--ui-border);
|
|
border-radius: 8px;
|
|
}
|
|
|
|
button {
|
|
border: 0;
|
|
border-radius: 8px;
|
|
background: var(--ui-primary);
|
|
color: var(--ui-primary-contrast);
|
|
padding: 10px 12px;
|
|
cursor: pointer;
|
|
}
|
|
</style>
|