Lê Phi Nam
Deploy to HF Space
94004a2
Raw
History Blame Contribute Delete
2.85 kB
import React from 'react';
import { Search, X } from 'lucide-react';
import { Input, Button } from './index.js';
import './Table.css';
/**
* Table.Toolbar — search + filters row above a virtualised table.
*
* Use alone when you just want the styled search/filter chrome without the
* full <Table> wrapper; use inside <Table> for a cohesive chrome treatment.
*/
function Toolbar({
search,
onSearch,
searchPlaceholder = 'Search…',
meta, // right-aligned summary (e.g. "42/42 · 3 sel")
children, // extra filter controls between search and meta
className = '',
...rest
}) {
return (
<div className={`ui-table-toolbar ${className}`} {...rest}>
{onSearch != null && (
<div className="ui-table-toolbar__search">
<Search size={10} className="ui-table-toolbar__search-icon" />
<Input
size="sm"
placeholder={searchPlaceholder}
value={search || ''}
onChange={(e) => onSearch(e.target.value)}
className="ui-table-toolbar__search-input"
/>
{search && (
<Button
variant="ghost"
iconSize="sm"
onClick={() => onSearch('')}
className="ui-table-toolbar__search-clear"
title="Clear"
>
<X size={10} />
</Button>
)}
</div>
)}
{children}
{meta != null && <span className="ui-table-toolbar__meta">{meta}</span>}
</div>
);
}
/**
* Table.Header — sticky column header row.
*
* Columns: array of { key, label, width?, flex?, align? }
*/
function Header({ columns = [], leading, trailing, className = '' }) {
return (
<div className={`ui-table-header ${className}`}>
{leading}
{columns.map((c) => (
<span
key={c.key}
className={`ui-table-header__cell ui-table-header__cell--align-${c.align || 'left'}`}
style={c.width ? { width: c.width, flex: 'none' } : { flex: c.flex ?? 1 }}
title={c.title}
>
{c.label}
</span>
))}
{trailing}
</div>
);
}
/**
* Table — thin wrapper that provides a toolbar slot + header slot + children body.
* Caller controls virtualisation (react-window).
*
* <Table>
* <Table.Toolbar search={q} onSearch={setQ} meta={`${n}/${t}`}>
* <Select>…</Select>
* </Table.Toolbar>
* <Table.Header columns={cols} leading={<checkbox />} />
* <div className="...virtualised list...">
* <List rowComponent={Row} ... />
* </div>
* </Table>
*/
export default function Table({ className = '', children, ...rest }) {
return (
<div className={`ui-table ${className}`} {...rest}>
{children}
</div>
);
}
Table.Toolbar = Toolbar;
Table.Header = Header;