العناصر
DataTable
DataTable يعرض الصفوف والأعمدة كما تفعل جداول البيانات، ويتمرر في الاتجاهين فوق أي عدد منهما. لا تُنشأ إلا الخلايا الظاهرة، لذا يتمرر جدول من مليون صف وعشرة آلاف عمود كما يتمرر جدول صغير. يمكن تحديد الصفوف أو الأعمدة أو الخلايا بالمؤشر ولوحة المفاتيح. للأعمدة عروض ثابتة، ويمكن تغيير عرضها بسحب حافتها، ونقلها بسحب عنوانها، وتثبيتها عند اليسار بينما تتمرر الأعمدة الأخرى، وفرزها. يمكن وضع العناوين تحت تسميات المجموعات، ويمكن للتطبيق رسم أي خلية أو عنوان.
import { mount, signal, Text, View } from "nsh";
import { DataTable, type DataTableColumn, type DataTableSort } from "nsh/base";
import { dataTableClasses, dataTableFitPadding, Log, Segmented, Split, ui, wide } from "./palette";
const NAMES = ["Ada", "Alan", "Grace", "Linus", "Margaret", "Dennis", "Barbara", "Ken"];
const CITIES = ["Oslo", "Lima", "Kyoto", "Cairo", "Perth", "Quito", "Turin", "Hanoi"];
type Person = { id: number; name: string; city: string; score: number };
const people: Person[] = Array.from({ length: 2000 }, (_, i) => ({
id: i + 1,
name: `${NAMES[i % NAMES.length]} ${i + 1}`,
city: CITIES[(i * 7) % CITIES.length],
score: (i * 37) % 1000,
}));
const columns: DataTableColumn[] = [
{ key: "id", title: "ID", width: 70, align: "end", fixed: true, sortable: true },
{ key: "name", title: "Name", width: 150, sortable: true },
{ key: "city", title: "City", width: 120, sortable: true },
{ key: "score", title: "Score", width: 90, align: "end", sortable: true },
];
// Sorting is the app's: the table reports the next sort (`onSortChange`),
// the app orders its rows and sets `sort`.
function App() {
const mode = signal<"row" | "cell">("row");
const sort = signal<DataTableSort | undefined>(undefined);
const rows = signal<Person[]>(people);
const events = signal<string[]>([]);
const log = (line: string) => events.set([line, ...events()].slice(0, 4));
const sortBy = (next: DataTableSort | undefined) => {
sort.set(next);
if (!next) return rows.set(people);
const key = next.key as keyof Person;
const sign = next.direction === "descending" ? -1 : 1;
rows.set([...people].sort((a, b) => (a[key] < b[key] ? -sign : a[key] > b[key] ? sign : 0)));
};
return (
<View style={{ flex: 1, backgroundColor: ui().page, padding: 20, paddingTop: 24, gap: 14 }}>
<Text style={{ fontSize: 22, fontWeight: "700", color: ui().text }}>data table</Text>
<Text style={{ color: ui().muted }}>Press a title to sort, drag its edge to resize or the title to move it</Text>
<Split
grow
width={680}
inspector={
<>
<Segmented label="selection" options={["row", "cell"] as const} value={mode()} onChange={(v) => mode.set(v)} />
<Log title="events" lines={events()} minHeight={96} />
</>
}
>
<View style={{ height: wide() ? 360 : 320 }}>
<DataTable
columns={columns.map((column) => ({ ...column, fitPadding: dataTableFitPadding }))}
classes={dataTableClasses}
data={rows()}
rowHeader={false}
stripe
cellSelectable={mode() === "cell"}
sort={sort()}
onSortChange={({ sort: next }) => {
sortBy(next ?? undefined);
log(`onSortChange: ${next ? `${next.key} ${next.direction}` : "none"}`);
}}
onSelectionChange={({ selection }) => log(`onSelectionChange: ${selection ? JSON.stringify(selection) : "none"}`)}
onColumnResize={({ key, width }) => log(`onColumnResize: ${key} ${Math.round(width)}`)}
style={{ flex: 1 }}
/>
</View>
</Split>
</View>
);
}
mount(App);DataTable يوفر التخطيط والمحاذاة والافتراضية (virtualization) والتفاعل. أما المسافات الداخلية والألوان والحدود وتأثيرات التحديد لأجزائه فيحددها التطبيق عبر classes وstyles. في Rust يُنشأ الجدول بواسطة nsh_base::data_table()، وفي TSX بواسطة <DataTable> من nsh/base.
use nsh_base::{DataTableColumn, data_table};
use nsh_core::prelude::*;
fn column(key: &str, title: &str) -> DataTableColumn {
let mut column = DataTableColumn::default();
column.key = key.into();
column.title = Some(title.into());
column
}
fn table() -> impl IntoElement {
data_table()
.columns(vec![column("name", "Name"), column("city", "City")])
.flex_1()
}import { mount } from "nsh";
import { DataTable, type DataTableColumn } from "nsh/base";
const columns: DataTableColumn[] = [
{ key: "name", title: "Name", width: 160, sortable: true },
{ key: "city", title: "City", width: 120 },
{ key: "score", title: "Score", width: 90, align: "end" },
];
const rows = [
{ name: "Ada", city: "Oslo", score: 91 },
{ name: "Grace", city: "Lima", score: 87 },
{ name: "Linus", city: "Kyoto", score: 78 },
];
function App() {
return <DataTable columns={columns} data={rows} class="flex-1" />;
}
mount(App);يملأ الجدول الصندوق الذي يعطيه إياه التطبيق (flex-1، وارتفاع) ويتمرر داخله: عموديًا عبر الصفوف وأفقيًا عبر الأعمدة، مع أشرطة تمرير (scrollbar={false} يخفيها، وbounces={false} يوقف الارتداد عند النهايات على المنصات التي فيها ذلك).
#الصفوف والأعمدة
data هي الصفوف: إما كائنات تسمّي حقولها قيم key للأعمدة، أو مصفوفات تفهرسها الأعمدة بالموضع. تظهر الأرقام والقيم المنطقية والنصوص كنص. في Rust تُعطى الصفوف حقلًا بعد حقل، ولكل حقل نوع واحد: DataTableRows::new(2).texts("symbol", ["AAPL", "MSFT"]).numbers("change", [1.2, -0.4]). العمود هو DataTableColumn:
| الحقل | الوصف |
|---|---|
key | هويته، وهي فريدة بين الأعمدة: حقل الصفوف الذي تعرضه خلاياه، والاسم الذي تستخدمه الأحداث والـ ref. |
title | نص عنوانه. الافتراضي: key الخاص به. |
width | عرضه بالنقاط. الافتراضي: 120. |
minWidth، maxWidth | أضيق عرض وأوسع عرض يصل إليهما السحب أو الملاءمة. الافتراضي: 20 و1200. |
fitPadding | مساحة إضافية للمسافات الداخلية والأيقونات والشارات الخاصة بالتطبيق، تُضاف إلى أعرض نص بين العنوان والخلايا عند ملاءمة العمود. |
align | "start" (الافتراضي) أو "center" أو "end"، للأرقام. يشمل الخلايا والعنوان معًا. |
sortable | في عنوانه زر فرز يطلب الفرز (انظر الفرز). |
fixed | يبقى عند اليسار بينما تتمرر الأعمدة الأخرى تحته. تتقدم الأعمدة الثابتة غيرها بترتيبها. |
resizable، movable | هل يغيّر سحب حافته عرضه، وهل ينقله سحب عنوانه. الافتراضي: قيمتا resizableColumns وmovableColumns للجدول. |
selectable | هل يشارك في التحديد. العمود الذي يحوي أزرارًا أو خانات اختيار يضبط false. الافتراضي: true. |
cellClass | أصناف خلايا العمود، بعد أصناف جزء cell: مسافات داخلية أو محاذاة لعمود واحد. |
headerClass | أصناف عنوان العمود، بعد أصناف جزء headerCell. |
positiveClass | أصناف خلايا العمود التي تحمل ارتفاعًا: رقم أكبر من الصفر، أو نص يبدأ بـ +. |
negativeClass | أصناف خلايا العمود التي تحمل انخفاضًا: رقم أصغر من الصفر، أو نص يبدأ بـ -. |
rowHeight هو ارتفاع صف الجسم (الافتراضي 32) وheaderHeight ارتفاع صف العناوين (الافتراضي ارتفاع الصف). rowHeader يضيف عمودًا لأرقام الصفوف عند اليسار، يحدد الصفوف. stripe يعطي الصفوف الفردية الجزء rowOdd.
#تسميات المجموعات
groups يضع تسميات فوق الأعمدة، بدءًا من المستوى الأدنى. كل مستوى قائمة من { label, span } يساوي مجموع امتداداتها عدد الأعمدة، أو عدد تسميات المستوى الأدنى.
<DataTable
columns={columns}
data={rows}
groups={[
[{ label: "Person", span: 2 }, { label: "Result", span: 1 }],
]}
class="flex-1"
/>
#أي عدد من الصفوف
يطلب الجدول الصفوف بالموضع، ويخدمها التطبيق. rowCount هو العدد الكلي للصفوف، وdata الصفوف التي يحتفظ بها التطبيق، وdataStart موضع أول صف منها. الصفوف خارج data تبقى فارغة إلى أن يوفرها التطبيق. onVisibleRowsChange يبلّغ عن الصفوف الظاهرة، { range: { start, end } }، عند كل خطوة تمرير، وهو المكان المناسب لجلب الصفحة المحيطة بها.
const ROWS = 1_000_000;
const page = signal({ start: 0, rows: load(0) });
<DataTable
columns={columns}
data={page().rows}
dataStart={page().start}
rowCount={ROWS}
onVisibleRowsChange={({ range: { start, end } }) => {
// Keep the rows in view inside the page held.
const held = page();
if (start < held.start || end > held.start + held.rows.length) {
const first = Math.max(0, start - 200);
page.set({ start: first, rows: load(first) });
}
}}
class="flex-1"
/>
للقائمة التي تنمو عند نهايتها، اضبط hasMore: يُطلق onLoadMore مرة واحدة لكل عدد من الصفوف عندما تصبح الصفوف الظاهرة ضمن loadMoreThreshold (الافتراضي 20) من آخر صف. وما دام loading صحيحًا ينتظر، ويظهر الفتحة loadingView فوق الصفوف. وتظهر الفتحة empty عندما لا توجد صفوف.
عند تجاوز بضعة ملايين من النقاط في المحتوى، تغطي أشرطة التمرير نطاقًا مُقيَّسًا، فيظل بالإمكان الوصول بالتمرير إلى كل صف حتى مع مليون صف.
#التحديد
ثلاثة مفاتيح تقرر ما الذي تحدده الضغطة، كما في gpui-component:
| الخاصية | ما تحدده الضغطة | selection |
|---|---|---|
rowSelectable (الافتراضي true) | صفًا: أي خلية فيه أو رأس صفه | { row } |
columnSelectable (الافتراضي true) | عمودًا: عنوانه | { column } |
cellSelectable (الافتراضي false) | خلية؛ ورأس الصف (يظهر افتراضيًا معه) يحدد الصفوف | { row, column } |
مع cellSelectable وإخفاء رأس الصف (rowHeader={false})، تؤدي الضغطة على الخلية المحددة مرة أخرى إلى تحديد صفها. لا تحدد الضغطة مع Shift أو مفتاح الأمر في المنصة صفًا إلا بينما selectOnModifierPress (الافتراضي true)، لذا فإن التطبيق الذي يحتفظ بتحديده الخاص لعدة صفوف يعالج هذه الضغطات بنفسه: onRowPress يبلّغ عن كل ضغطة على الجسم مع صفها، والعمود تحت المؤشر، وعدد النقرات في الصف، والمفاتيح المعدِّلة المضغوطة. والعمود الذي قيمة selectable فيه false لا يحدد نفسه ولا خلاياه.
تُعدّ الصفوف في البيانات من 0، والعمود هو فهرسه ضمن columns مهما كان الترتيب الذي نقله إليه المستخدم. onSelectionChange يبلّغ بما حدده المستخدم (null إن لم يحدد شيئًا). الخاصية selection تضبط التحديد من التطبيق؛ وإن تُركت دون ضبط احتفظ الجدول به بنفسه. onDoublePress يبلّغ عن صف أو خلية أو عنوان جرت الضغطة عليه مرتين، وonContextMenu عن ضغطة ثانوية أو مطوّلة مع النقطة التي ينبغي فتح Menu الخاصة بالتطبيق عندها. وكلاهما يسمّي الخلية تحت المؤشر (row وcolumn)، أو رقم صف (row فقط)، أو عنوانًا (column فقط). وإلى الضغطة التالية، تحمل الخلية التي طُلبت لها قائمة الجزء cellActive، أو يحمل صفها الجزء rowActive حيث لا تحدَّد الخلايا.
تحصل قارئات الشاشة على شبكة (اسمها من accessibilityLabel) من رؤوس الأعمدة والخلايا، وتُذكر المحددة منها على أنها محددة.
#لوحة المفاتيح
الضغط على الجدول، أو الوصول إليه بمفتاح Tab (في macOS والويب)، يمنحه لوحة المفاتيح إلى أن تحدث ضغطة أخرى، أو ينتقل التركيز إلى مكان آخر، أو blur()؛ وfocus() يمنحه إياها من التطبيق. الجدول محطة واحدة في Tab: داخله ينقل Tab التحديد، ويعيد Escape لوحة المفاتيح.
| المفاتيح | ما تفعله |
|---|---|
| مفاتيح الأسهم | تنقل التحديد بصف أو عمود أو خلية، مع تمريره إلى حيز الرؤية. |
| Tab، Shift+Tab | الانتقال إلى العمود التالي أو السابق. |
| Page Up، Page Down | الانتقال بمقدار صفحة من الصفوف. |
| Home، End | الانتقال إلى الأول أو الأخير. |
| Escape | يمسح التحديد، ثم يعيد لوحة المفاتيح. |
| اختصار النسخ | يضع نص التحديد في الحافظة (copy()). |
loopSelection (الافتراضي true) يجعل مفاتيح الأسهم تلتف حول النهايات.
#الفرز
للعمود sortable زر فرز في نهاية عنوانه، وهو زر شفاف صغير يخفت ما دام العمود غير مفروز. الضغط عليه يبلّغ بالفرز التالي ({ key, direction }) ضمن الدورة: غير مفروز، تصاعدي، تنازلي، ثم غير مفروز من جديد، مع onSortChange({ sort }) (null للمسح). لا يعيد الجدول ترتيب الصفوف: التطبيق هو من يفرز بياناته، أو يطلب من خادمه الصفوف بالترتيب الجديد، ثم يضبط sort ليظهره العنوان. ولأن التطبيق يملك الترتيب، يعمل الفرز بالطريقة نفسها فوق مليون صف لا يحتفظ بها التطبيق أصلًا.
<DataTable
columns={columns}
data={rows()}
sort={sort()}
onSortChange={({ sort: next }) => {
sort.set(next ?? undefined);
rows.set(sorted(people, next));
}}
class="flex-1"
/>
#تغيير عرض الأعمدة ونقلها
سحب الحافة الخلفية للعمود يغيّر عرضه ضمن minWidth وmaxWidth، وonColumnResize({ key, width }) يبلّغ عن كل خطوة. الضغط على الحافة مرتين متتاليتين يلائم العمود مع أعرض نص فيه وعنوانه. وسحب العنوان ينقل العمود، ويظهر خط يبيّن مكان الإفلات؛ وonColumnMove يبلّغ بـ { key, from, to, order }، حيث order هي key جميع الأعمدة بالترتيب المعروض. تبقى الأعمدة الثابتة بين الأعمدة الثابتة. resizableColumns وmovableColumns يعطّلان الأمرين معًا للجدول، وقيمتا resizable وmovable للعمود تتقدمان عليهما.
#البيانات الحية
جدول الأسعار يتغير عدة مرات في الثانية. ينسّق التطبيق الصفوف الظاهرة ونطاقًا حولها (يعرفها من onVisibleRowsChange) ويسلّمها كـ data من dataStart، فتكلّف أي تحديثات ما هو على الشاشة فقط، مهما كان عدد الصفوف. وتأخذ الارتفاعات والانخفاضات ألوانها من positiveClass وnegativeClass للعمود، وتُطبَّق أصليًا على الخلايا التي قيمتها فوق الصفر أو تحته (أو التي يبدأ نصها بـ + أو -).
const tone = { positiveClass: "text-green-600", negativeClass: "text-red-600" };
const columns: DataTableColumn[] = [
{ key: "symbol", title: "Symbol", fixed: true },
{ key: "price", title: "Price", align: "end", sortable: true },
{ key: "change", title: "Chg%", align: "end", ...tone },
];
الصفوف والأعمدة فتحات ينشئها الجدول مرة واحدة ويحتفظ بها: التمرير يمنحها صفوفًا وأعمدة أخرى لتعرضها، فلا يغيّر التمرير، مهما طال، سوى النصوص والمواضع.
#رسم الخلايا والعناوين
renderCell يرسم خلايا خاصة بالتطبيق حيث لا يكون العمود نصًا فقط (شارة، زر). يُستدعى للخلايا الظاهرة فقط، مع DataTableCell: row وcolumn وkey وtext (ما كان الجدول سيعرضه) وselected. يبحث التطبيق عن بياناته بواسطة row. renderHeaderCell يرسم عنوانًا عبر خليته، ويُمرَّر إليه DataTableHeaderCell: column وkey وtitle وsort (الاتجاه، أو لا شيء) وselected.
<DataTable
columns={columns}
data={rows()}
renderCell={(cell) =>
cell.key === "status" ? (
<View class={cell.text === "open" ? "rounded bg-green-500/20 px-2" : "rounded bg-muted px-2"}>
<Text class="text-xs">{cell.text}</Text>
</View>
) : (
<Text class="px-2 text-sm">{cell.text}</Text>
)
}
class="flex-1"
/>
fontFamily وfontSize (الافتراضي 14) يحددان خط الخلايا، وبه يقيس الجدول النصوص أيضًا لملاءمة الأعمدة.
#الـ ref
ref يعطي DataTableRef. أي دالة تُعطى صفًا أو عمودًا أو مفتاح عمود لا يملكه الجدول لا تغيّر شيئًا وتسجّل تحذيرًا يسمّي الدالة والقيمة؛ وfitColumn يُرفض بـ TypeError عند مفتاح غير معروف.
| الدالة | الوصف |
|---|---|
scrollToRow(row, animated?) | تمرّر صفًا إلى حيز الرؤية. |
scrollToColumn(key, animated?) | تمرّر عمودًا إلى حيز الرؤية. |
selection() | ما هو محدد، وnull إن لم يكن شيء محددًا. |
select(selection) | تحدد (null: لا شيء) وتُظهر المحدد، دون onSelectionChange. |
visibleRows()، visibleColumns() | الصفوف والأعمدة المتمررة الظاهرة، كـ { start, end } (دون end). |
columnWidths() | العروض الحالية، بترتيب columns. |
setColumnWidth(key, width) | تضبط عرض عمود، ضمن حدوده. |
fitColumn(key) | تجعل العمود بعرض أعرض نص وعنوان فيه بين الصفوف الظاهرة وحتى ألف صف إضافي حولها. وتعيد العرض. |
dump(start?, end?) | نصوص الصفوف المعطاة (الافتراضي كل المحتفظ بها) ونصوص العناوين، كما تظهر: { headers, rows }، للتصدير. |
copy() | تضع نص التحديد في الحافظة: خلايا الصف تفصل بينها علامات جدولة، وخلايا العمود تفصل بينها فواصل أسطر، ونص الخلية. |
focus()، blur() | تمنح لوحة المفاتيح للجدول أو تأخذها منه. |
menuTarget()، clearMenuTarget() | ما طُلبت له آخر قائمة سياقية ({ row?, column? }، موسومًا بـ cellActive / rowActive)، وإزالة هذه العلامة عند إغلاق قائمة التطبيق. |
#تنسيق الأجزاء
class وstyle ينسّقان صندوق الجدول. classes يأخذ أصناف Tailwind حسب الجزء، وstyles أنماطًا مضمنة حسب الجزء؛ الأجزاء توفر بنية الجدول ومحاذاته، وأصنافها توفر المظهر، وstyles تتقدم على الأصناف.
<DataTable
columns={columns}
data={rows()}
stripe
class="flex-1 rounded-lg border border-border"
classes={{
header: "bg-secondary",
headerCell: "pl-2 pr-1",
headerContent: "gap-1",
cell: "px-2",
resizeHandle: "bg-border group-hover:bg-primary",
sortAscending: "text-muted-foreground opacity-60 selected:text-foreground selected:opacity-100",
sortDescending: "text-muted-foreground opacity-60 selected:text-foreground selected:opacity-100",
rowSelected: "bg-primary/10",
rowHover: "bg-muted/50",
fixedEdge: "bg-border",
}}
/>
#الخصائص
| الخاصية | Rust | النوع | الافتراضي | الوصف |
|---|---|---|---|---|
columns | .columns(..) | DataTableColumn[] | [] | الأعمدة من اليسار إلى اليمين. الأعمدة الثابتة تأتي أولًا. |
data | .data(..) | Row[] | [] | الصفوف: كائنات بحسب key العمود، أو مصفوفات بحسب الموضع. |
rowCount | .row_count(..) | number | الصفوف المحتفظ بها | العدد الإجمالي للصفوف. |
dataStart | .data_start(..) | number | 0 | رقم الصف الأول في data. |
rowClasses | .row_classes(..) | string[] | [] | فئات الصفوف المحددة بحسب موضعها في data: مظهر خاص بكل صف، دون استدعاء JS لكل صف. |
rowHeight | .row_height(..) | number | 32 | ارتفاع صف المحتوى بالنقاط. |
headerHeight | .header_height(..) | number | ارتفاع الصف | ارتفاع صف العناوين. |
groups | .groups(..) | DataTableColumnGroup[][] | [] | تسميات فوق الأعمدة، بدءًا من المستوى الأدنى. |
sort | .sort(..) | DataTableSort | ما تُرتَّب البيانات بحسبه، ويظهر على العنوان. | |
rowSelectable | .row_selectable(..) | boolean | true | الضغطات والمفاتيح تحدد الصفوف. |
columnSelectable | .column_selectable(..) | boolean | true | الضغط على عنوان يحدد عموده، والمفاتيح الأفقية تنقل بين الأعمدة. |
cellSelectable | .cell_selectable(..) | boolean | false | الضغطات والمفاتيح تحدد الخلايا. |
selectOnModifierPress | .select_on_modifier_press(..) | boolean | true | الضغط مع الاستمرار على Shift أو مفتاح command يحدد صفًا. |
selection | .selection(..) | DataTableSelection | المحدد حاليًا، عندما يضبطه التطبيق. | |
loopSelection | .loop_selection(..) | boolean | true | مفاتيح الأسهم تلتف عند الطرفين. |
accessibilityLabel | .accessibility_label(..) | string | لا شيء | الاسم الذي تنطق به قارئات الشاشة للجدول. |
rowHeader | .row_header(..) | boolean | يظهر مع cellSelectable | عمود لأرقام الصفوف على اليسار. |
stripe | .stripe(..) | boolean | false | الصفوف الفردية تأخذ الجزء rowOdd. |
resizableColumns | .resizable_columns(..) | boolean | true | سحب حافة العمود يغيّر حجمه. |
movableColumns | .movable_columns(..) | boolean | true | سحب عنوان ينقل عموده. |
loading | .loading(..) | boolean | false | الجدول قيد التحميل: onLoadMore ينتظر وloadingView يظهر. |
hasMore | .has_more(..) | boolean | false | توجد صفوف أخرى للتحميل. |
loadMoreThreshold | .load_more_threshold(..) | number | 20 | عدد الصفوف من الصف الأخير التي يُطلق عندها onLoadMore. |
fontFamily | .font_family(..) | string | موروث | خط الخلايا. |
fontSize | .font_size(..) | number | 14 | حجم خط الخلايا بالنقاط. |
scrollbar | .scrollbar(..) | boolean | true | أشرطة التمرير. |
verticalScrollbar، horizontalScrollbar | .vertical_scrollbar(..)، .horizontal_scrollbar(..) | boolean | scrollbar | شريط التمرير لمحور واحد (الأفقي هو شريط أجهزة سطح المكتب أسفل الجدول). |
bounces | .bounces(..) | boolean | true | ما إذا كان التمرير يرتد عند الطرفين، في المنصات التي تدعم ذلك. |
renderCell | .render_cell(..) | (cell: DataTableCell) => JSX.Element | يرسم الخلايا المرئية. | |
renderHeaderCell | .render_header_cell(..) | (cell: DataTableHeaderCell) => JSX.Element | يرسم العناوين. | |
empty | .empty(..) | JSX.Element | ما يظهر عند عدم وجود صفوف. | |
loadingView | .loading_view(..) | JSX.Element | ما يظهر فوق الصفوف أثناء loading. | |
classes | .classes(..) | DataTableClasses | {} | فئات Tailwind بحسب الجزء. |
styles | .styles(..) | DataTableStyles | {} | أنماط مضمّنة بحسب الجزء، تتغلب على الفئات. |
class، style | دوال التنسيق | string، StyleProp<ViewStyle> | صندوق الجدول. |
#الأحداث
| الحدث | Rust | الوصف |
|---|---|---|
onSelectionChange | .on_selection_change(|selection: &Option<DataTableSelection>| ..) | غيّر المستخدم التحديد: { selection }، وهو { row?, column? } أو null. |
onRowPress | .on_row_press(|event: &DataTablePress| ..) | تم الضغط على صف أو خلية: { row, column?, clicks, shift, control, alt, platform }. |
onDoublePress | .on_double_press(|target: &DataTableTarget| ..) | تم الضغط مرتين على صف أو خلية أو عنوان: { target }، وهو { row?, column? }. |
onContextMenu | .on_context_menu(|event: &DataTableContextMenu| ..) | طُلبت قائمة سياقية: { row?, column?, x, y }، النقطة في العرض الجذر. |
onSortChange | .on_sort_change(|sort: &Option<DataTableSort>| ..) | تم الضغط على زر الترتيب: { sort }، والترتيب التالي { key, direction } أو null. |
onColumnResize | .on_column_resize(|key: &SharedString, width: &Points| ..) | تغيّر حجم عمود ({ key, width })، عند كل خطوة من السحب ومرة أخرى عندما تحدده الملاءمة التلقائية. |
onColumnMove | .on_column_move(|event: &DataTableColumnMove| ..) | نُقل عمود: { key, from, to, order }. |
onVisibleRowsChange | .on_visible_rows_change(|range: &DataTableRange| ..) | تغيرت الصفوف المرئية: { range }، وهو { start, end }. اجلب الصفوف من هنا. |
onVisibleColumnsChange | .on_visible_columns_change(|range: &DataTableRange| ..) | تغيرت أعمدة التمرير المرئية: { range }. |
onLoadMore | .on_load_more(|| ..) | اقتربت الصفوف المرئية من الصف الأخير ضمن loadMoreThreshold بينما hasMore وليس loading. |