/
githubmirror
/
tabler
Обзор
Документация
Войти
/
githubmirror
/
tabler
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
dev
shared/ui/AdvancedTable.astro
209 строк
8 KB
Bartosz-Do
Fix all `pnpm type-check` warnings and restore lost `Props` typing (#2805)
08 авг 2026, 18:35
Не верифицирован
08 авг 2026, 18:35
0085eeb
Код
Авторство
О чём код?
--- import BadgesList from './BadgesList.astro' import Icon from './Icon.astro' import { formatLongDate } from '@shared/lib/date-format' import { randomItem, randomDate } from '@shared/lib/pseudo-random' import Avatar from './Avatar.astro' import Button from './Button.astro' import ButtonList from './ButtonList.astro' import Pagination from './Pagination.astro' import people from '@data/people.json' import tableProperties from '@data/table-properties.json' import CaptureScript from '../components/CaptureScript.astro' import { requireIndex } from '@shared/lib/array' interface Props { id?: string } interface Person { full_name?: string city?: string country?: string [key: string]: unknown } interface AdvancedTableProperties { headers: { 'data-sort': string; 'name': string }[] } const { id: tableId = 'advanced-table' } = Astro.props const statuses = ['Active', 'Inactive', 'Requested'] const perPage = ['10', '20', '50', '100'] const categories = ['Agencies', 'Individual', 'Event', 'Ticket'] const tags = ['QTA,Event,Tickets,TODO', 'Event,Tickets', 'QTA,Event', 'Tickets'] const advancedTable = (tableProperties as { 'advanced-table': AdvancedTableProperties })['advanced-table'] const headers = advancedTable.headers const rows = (people as Person[]).map((person, i) => { const index = i + 1 const status = randomItem(index + 5, statuses) const itemTags = randomItem(index + 5, tags).split(',') const category = randomItem(index, categories) const date = formatLongDate(randomDate(index)) return { person, index, status, itemTags, category, date } }) const perPageDefault = requireIndex(perPage, 1) const sortKeys = headers.map((header) => header['data-sort']) --- <div class="card"> <div class="card-table"> <div class="card-header"> <div class="row w-full"> <div class="col"> <h3 class="card-title mb-0">Employee</h3> <p class="text-secondary m-0">Table description.</p> </div> <div class="col-md-auto col-sm-12"> <ButtonList class="ms-auto d-flex flex-wrap"> <div class="input-group input-group-flat w-auto"> <span class="input-group-text"> <Icon name="search" /> </span> <input id={`${tableId}-search`} type="text" class="form-control" autocomplete="off" /> <span class="input-group-text"> <kbd>ctrl + K</kbd> </span> </div> <button type="button" class="btn btn-icon" aria-label="More actions"> <Icon name="dots" /> </button> <div class="dropdown"> <button type="button" class="btn dropdown-toggle" data-bs-toggle="dropdown" aria-expanded="false">Download</button> <div class="dropdown-menu"> <button type="button" class="dropdown-item">Action</button> <button type="button" class="dropdown-item">Another action</button> <button type="button" class="dropdown-item">Third action</button> </div> </div> <Button /> </ButtonList> </div> </div> </div> <div id={tableId}> <div class="table-responsive"> <table class="table table-vcenter table-selectable"> <thead> <tr> <th class="w-1"></th> { headers.map((header) => ( <th> <button type="button" class="table-sort d-flex justify-content-between" data-sort={header['data-sort']}> {header.name} </button> </th> )) } </tr> </thead> <tbody class="table-tbody"> { rows.map(({ person, status, itemTags, category, date }) => ( <tr> <td> <input class="form-check-input m-0 align-middle table-selectable-check" type="checkbox" aria-label="Select invoice" value="true" /> </td> <td class={requireIndex(headers, 0)['data-sort']}> <Avatar person={person} size="xs" class="me-2" /> {person.full_name} </td> <td class={requireIndex(headers, 1)['data-sort']}> {person.city}, {person.country} </td> <td class={requireIndex(headers, 2)['data-sort']}>{status === 'Active' ? <span class="badge bg-success-lt">Active</span> : status === 'Inactive' ? <span class="badge bg-danger-lt">Inactive</span> : <span class="badge">Requested</span>}</td> <td class={requireIndex(headers, 3)['data-sort']}>{date}</td> <td class={requireIndex(headers, 4)['data-sort']}> <BadgesList> {itemTags.map((tag) => ( <span class="badge">{tag}</span> ))} </BadgesList> </td> <td class={`${requireIndex(headers, 5)['data-sort']} py-0`}> <span class="on-unchecked">{category}</span> <div class="on-checked"> <div class="d-flex justify-content-end"> <Button icon="dots" iconOnly /> </div> </div> </td> </tr> )) } </tbody> </table> </div> <div class="card-footer d-flex align-items-center"> <div class="dropdown" data-table-id={tableId}> <button type="button" class="btn dropdown-toggle" data-bs-toggle="dropdown" aria-expanded="false"> <span id={`${tableId}-page-count`} class="me-1">{perPageDefault}</span> <span>records</span> </button> <div class="dropdown-menu"> { perPage.map((record) => ( <button type="button" class="dropdown-item" onclick="setPageListItems(this)" data-value={record}> {record} records </button> )) } </div> </div> <Pagination class="m-0 ms-auto" count={10} /> </div> </div> </div> </div> <CaptureScript> <!-- BEGIN ADVANCED TABLE --> <script is:inline define:vars={{ tableId, sortKeys, perPageDefault }}> // Astro wraps define:vars scripts in an IIFE, so this needs an explicit window // assignment to stay reachable from the onclick="setPageListItems(this)" markup below. // Each AdvancedTable instance redefines this identically, so it stays safe to share: // the table id is resolved from the clicked element instead of being closed over. window.setPageListItems = function setPageListItems(el) { const id = el.closest('[data-table-id]')?.dataset.tableId if (!id || !window.tabler_list?.[id]) return window.tabler_list[id].page = parseInt(el.dataset.value) window.tabler_list[id].update() document.querySelector(`#${id}-page-count`).innerHTML = el.dataset.value } function initAdvancedTable() { window.tabler_list ??= {} window.tabler_list[tableId] = new List(tableId, { sortClass: 'table-sort', listClass: 'table-tbody', page: parseInt(perPageDefault), pagination: { item: (value) => `<li class="page-item"><a class="page-link cursor-pointer">${value.page}</a></li>`, innerWindow: 1, outerWindow: 1, left: 0, right: 0, }, valueNames: sortKeys, }) const list = window.tabler_list[tableId] const searchInput = document.querySelector(`#${tableId}-search`) searchInput?.addEventListener('input', () => list.search(searchInput.value)) } document.readyState !== 'loading' ? initAdvancedTable() : document.addEventListener('DOMContentLoaded', initAdvancedTable, { once: true }) </script> <!-- END ADVANCED TABLE --> </CaptureScript>