diff --git a/.github/workflows/autofix.yml b/.github/workflows/autofix.yml index 53051c6d5f..b3a92ed505 100644 --- a/.github/workflows/autofix.yml +++ b/.github/workflows/autofix.yml @@ -16,6 +16,7 @@ jobs: autofix: name: autofix runs-on: ubuntu-latest + if: github.repository_owner == 'TanStack' steps: - name: Checkout uses: actions/checkout@v4 diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index 7af298149a..2f5c384cd1 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -21,6 +21,7 @@ jobs: test: name: Test runs-on: ubuntu-latest + if: github.repository_owner == 'TanStack' steps: - name: Checkout uses: actions/checkout@v4 @@ -42,6 +43,7 @@ jobs: preview: name: Preview runs-on: ubuntu-latest + if: github.repository_owner == 'TanStack' steps: - name: Checkout uses: actions/checkout@v4 diff --git a/.github/workflows/translate.yml b/.github/workflows/translate.yml new file mode 100644 index 0000000000..33d69ce162 --- /dev/null +++ b/.github/workflows/translate.yml @@ -0,0 +1,52 @@ +name: Translate Documentation + +on: + schedule: + - cron: + '0 20 * * *' # Daily at 20:00 UTC (DeepSeek API off-peak pricing window 16:30-00:30 UTC) + # Pacific Time: 1:00 PM PDT / 12:00 PM PST + # Off-peak window in PT: ~9:30 AM to 5:30 PM PDT / ~8:30 AM to 4:30 PM PST + push: + # Run when merging from official repo to check if translations are outdated + branches: + - main + workflow_dispatch: # Allow manual triggering + inputs: + custom_arguments: + description: 'Custom arguments to pass to the translation package command. e.g., "-t zh-hans"' + required: false + type: string + +# Add permissions needed for creating PRs +permissions: + contents: write + pull-requests: write + +jobs: + translate: + runs-on: ubuntu-latest + # Run when manually triggered OR scheduled OR when the commit message contains "Merge pull request" + if: ${{ github.event_name == 'workflow_dispatch' || github.event_name == 'schedule' || contains(github.event.head_commit.message, 'Merge pull request') }} + steps: + # Use the translate-docs-action + - name: Translate documentation + uses: TanStack-dev/translate-docs-action@main + with: + # Required inputs + api_key: ${{ secrets.OPENAI_API_KEY }} + # Optional inputs with their default values shown + github_token: ${{ secrets.GITHUB_TOKEN }} + custom_arguments: ${{ github.event.inputs.custom_arguments }} + # translation_package: '@tanstack-dev/translate-docs' + # base_branch: 'main' + # pr_branch: 'docs/update-translations' + # pr_title: 'Update translations' + # The following uses YAML pipe syntax for multi-line strings + # pr_body: | + # This PR updates the documentation translations automatically. + # + # Generated by the translate workflow. + # commit_message: 'docs: update documentation translations' + # add_paths: 'docs/**' + # enable_formatting: 'true' + # format_command: 'pnpm prettier:write' diff --git a/docs/ar/config.json b/docs/ar/config.json new file mode 100644 index 0000000000..9bd599b50b --- /dev/null +++ b/docs/ar/config.json @@ -0,0 +1,790 @@ +{ + "$schema": "https://raw.githubusercontent.com/TanStack/tanstack.com/main/tanstack-docs-config.schema.json", + "docSearch": { + "appId": "74SF5EKVW9", + "apiKey": "9fc015a3310be6669ed66c6c459f319f", + "indexName": "tanstack-table" + }, + "sections": [ + { + "label": "البداية", + "children": [ + { + "label": "المقدمة", + "to": "introduction" + }, + { + "label": "نظرة عامة", + "to": "overview" + }, + { + "label": "التثبيت", + "to": "installation" + }, + { + "label": "الترقية إلى الإصدار 8", + "to": "guide/migrating" + }, + { + "label": "الأسئلة الشائعة", + "to": "faq" + } + ], + "frameworks": [ + { + "label": "angular", + "children": [ + { + "label": "محول جدول Angular", + "to": "framework/angular/angular-table" + } + ] + }, + { + "label": "lit", + "children": [ + { + "label": "محول جدول Lit", + "to": "framework/lit/lit-table" + } + ] + }, + { + "label": "qwik", + "children": [ + { + "label": "محول جدول Qwik", + "to": "framework/qwik/qwik-table" + } + ] + }, + { + "label": "react", + "children": [ + { + "label": "محول جدول React", + "to": "framework/react/react-table" + } + ] + }, + { + "label": "solid", + "children": [ + { + "label": "محول جدول Solid", + "to": "framework/solid/solid-table" + } + ] + }, + { + "label": "svelte", + "children": [ + { + "label": "محول جدول Svelte", + "to": "framework/svelte/svelte-table" + } + ] + }, + { + "label": "vue", + "children": [ + { + "label": "محول جدول Vue", + "to": "framework/vue/vue-table" + } + ] + }, + { + "label": "vanilla", + "children": [ + { + "label": "جافاسكريبت عادي (بدون إطار عمل)", + "to": "vanilla" + } + ] + } + ] + }, + { + "label": "الدليل الأساسي", + "children": [ + { + "label": "البيانات", + "to": "guide/data" + }, + { + "label": "تعريفات الأعمدة", + "to": "guide/column-defs" + }, + { + "label": "نسخة الجدول", + "to": "guide/tables" + }, + { + "label": "نماذج الصفوف", + "to": "guide/row-models" + }, + { + "label": "الصفوف", + "to": "guide/rows" + }, + { + "label": "الخلايا", + "to": "guide/cells" + }, + { + "label": "مجموعات الرؤوس", + "to": "guide/header-groups" + }, + { + "label": "الرؤوس", + "to": "guide/headers" + }, + { + "label": "الأعمدة", + "to": "guide/columns" + } + ], + "frameworks": [ + { + "label": "angular", + "children": [ + { + "label": "حالة الجدول", + "to": "framework/angular/guide/table-state" + } + ] + }, + { + "label": "lit", + "children": [ + { + "label": "حالة الجدول", + "to": "framework/lit/guide/table-state" + } + ] + }, + { + "label": "qwik", + "children": [ + { + "label": "حالة الجدول", + "to": "framework/qwik/guide/table-state" + } + ] + }, + { + "label": "react", + "children": [ + { + "label": "حالة الجدول", + "to": "framework/react/guide/table-state" + } + ] + }, + { + "label": "solid", + "children": [ + { + "label": "حالة الجدول", + "to": "framework/solid/guide/table-state" + } + ] + }, + { + "label": "svelte", + "children": [ + { + "label": "حالة الجدول", + "to": "framework/svelte/guide/table-state" + } + ] + }, + { + "label": "vue", + "children": [ + { + "label": "حالة الجدول", + "to": "framework/vue/guide/table-state" + } + ] + }, + { + "label": "vanilla", + "children": [ + { + "label": "حالة الجدول", + "to": "framework/vanilla/guide/table-state" + } + ] + } + ] + }, + { + "label": "دليل الميزات", + "children": [ + { + "label": "ترتيب الأعمدة", + "to": "guide/column-ordering" + }, + { + "label": "تثبيت الأعمدة", + "to": "guide/column-pinning" + }, + { + "label": "تغيير حجم الأعمدة", + "to": "guide/column-sizing" + }, + { + "label": "إظهار/إخفاء الأعمدة", + "to": "guide/column-visibility" + }, + { + "label": "تصفية الأعمدة", + "to": "guide/column-filtering" + }, + { + "label": "التصفية العامة", + "to": "guide/global-filtering" + }, + { + "label": "التصفية الضبابية", + "to": "guide/fuzzy-filtering" + }, + { + "label": "تقسيم الأعمدة", + "to": "guide/column-faceting" + }, + { + "label": "التقسيم العام", + "to": "guide/global-faceting" + }, + { + "label": "التجميع", + "to": "guide/grouping" + }, + { + "label": "التوسيع", + "to": "guide/expanding" + }, + { + "label": "ترقيم الصفحات", + "to": "guide/pagination" + }, + { + "label": "تثبيت الصفوف", + "to": "guide/row-pinning" + }, + { + "label": "اختيار الصفوف", + "to": "guide/row-selection" + }, + { + "label": "الفرز", + "to": "guide/sorting" + }, + { + "label": "التخيل", + "to": "guide/virtualization" + }, + { + "label": "ميزات مخصصة", + "to": "guide/custom-features" + } + ] + }, + { + "label": "واجهات برمجة التطبيقات الأساسية", + "children": [ + { + "label": "تعريف العمود", + "to": "api/core/column-def" + }, + { + "label": "الجدول", + "to": "api/core/table" + }, + { + "label": "العمود", + "to": "api/core/column" + }, + { + "label": "مجموعة الرؤوس", + "to": "api/core/header-group" + }, + { + "label": "الرأس", + "to": "api/core/header" + }, + { + "label": "الصف", + "to": "api/core/row" + }, + { + "label": "الخلية", + "to": "api/core/cell" + } + ] + }, + { + "label": "واجهات برمجة التطبيقات للميزات", + "children": [ + { + "label": "تصفية الأعمدة", + "to": "api/features/column-filtering" + }, + { + "label": "تقسيم الأعمدة", + "to": "api/features/column-faceting" + }, + { + "label": "ترتيب الأعمدة", + "to": "api/features/column-ordering" + }, + { + "label": "تثبيت الأعمدة", + "to": "api/features/column-pinning" + }, + { + "label": "تغيير حجم الأعمدة", + "to": "api/features/column-sizing" + }, + { + "label": "إظهار/إخفاء الأعمدة", + "to": "api/features/column-visibility" + }, + { + "label": "التقسيم العام", + "to": "api/features/global-faceting" + }, + { + "label": "التصفية العامة", + "to": "api/features/global-filtering" + }, + { + "label": "الفرز", + "to": "api/features/sorting" + }, + { + "label": "التجميع", + "to": "api/features/grouping" + }, + { + "label": "التوسيع", + "to": "api/features/expanding" + }, + { + "label": "ترقيم الصفحات", + "to": "api/features/pagination" + }, + { + "label": "تثبيت الصفوف", + "to": "api/features/row-pinning" + }, + { + "label": "اختيار الصفوف", + "to": "api/features/row-selection" + } + ] + }, + { + "label": "المؤسسة", + "children": [ + { + "label": "AG Grid", + "to": "enterprise/ag-grid" + } + ] + }, + { + "label": "الأمثلة", + "children": [], + "frameworks": [ + { + "label": "angular", + "children": [ + { + "to": "framework/angular/examples/basic", + "label": "أساسي" + }, + { + "to": "framework/angular/examples/grouping", + "label": "تجميع الأعمدة" + }, + { + "to": "framework/angular/examples/column-ordering", + "label": "ترتيب الأعمدة" + }, + { + "to": "framework/angular/examples/column-pinning", + "label": "تثبيت الأعمدة" + }, + { + "to": "framework/angular/examples/column-pinning-sticky", + "label": "تثبيت الأعمدة اللاصق" + }, + { + "to": "framework/angular/examples/column-visibility", + "label": "إظهار/إخفاء الأعمدة" + }, + { + "to": "framework/angular/examples/filters", + "label": "مرشحات الأعمدة" + }, + { + "to": "framework/angular/examples/row-selection", + "label": "اختيار الصفوف" + }, + { + "to": "framework/angular/examples/expanding", + "label": "التوسيع" + }, + { + "to": "framework/angular/examples/sub-components", + "label": "المكونات الفرعية" + }, + { + "to": "framework/angular/examples/signal-input", + "label": "إدخال الإشارة" + }, + { + "to": "framework/angular/examples/editable", + "label": "بيانات قابلة للتعديل" + }, + { + "to": "framework/angular/examples/row-dnd", + "label": "سحب وإفلات الصفوف" + }, + { + "to": "framework/angular/examples/column-resizing-performant", + "label": "تغيير حجم الأعمدة بكفاءة" + } + ] + }, + { + "label": "lit", + "children": [ + { + "to": "framework/lit/examples/basic", + "label": "أساسي" + }, + { + "to": "framework/lit/examples/column-sizing", + "label": "تغيير حجم الأعمدة" + }, + { + "to": "framework/lit/examples/filters", + "label": "المرشحات" + }, + { + "to": "framework/lit/examples/row-selection", + "label": "اختيار الصفوف" + }, + { + "to": "framework/lit/examples/sorting", + "label": "الفرز" + }, + { + "to": "framework/lit/examples/virtualized-rows", + "label": "صفوف مخيلة" + } + ] + }, + { + "label": "qwik", + "children": [ + { + "to": "framework/qwik/examples/basic", + "label": "أساسي" + }, + { + "to": "framework/qwik/examples/filters", + "label": "المرشحات" + }, + { + "to": "framework/qwik/examples/row-selection", + "label": "اختيار الصفوف" + }, + { + "to": "framework/qwik/examples/sorting", + "label": "الفرز" + } + ] + }, + { + "label": "react", + "children": [ + { + "to": "framework/react/examples/basic", + "label": "أساسي" + }, + { + "to": "framework/react/examples/column-groups", + "label": "مجموعات الرؤوس" + }, + { + "to": "framework/react/examples/filters", + "label": "مرشحات الأعمدة" + }, + { + "to": "framework/react/examples/filters-faceted", + "label": "مرشحات الأعمدة (المقسمة)" + }, + { + "to": "framework/react/examples/filters-fuzzy", + "label": "مرشحات البحث الضبابي" + }, + { + "to": "framework/react/examples/column-ordering", + "label": "ترتيب الأعمدة" + }, + { + "to": "framework/react/examples/column-dnd", + "label": "ترتيب الأعمدة (سحب وإفلات)" + }, + { + "to": "framework/react/examples/column-pinning", + "label": "تثبيت الأعمدة" + }, + { + "to": "framework/react/examples/column-pinning-sticky", + "label": "تثبيت الأعمدة اللاصق" + }, + { + "to": "framework/react/examples/column-sizing", + "label": "تغيير حجم الأعمدة" + }, + { + "to": "framework/react/examples/column-resizing-performant", + "label": "تغيير حجم الأعمدة بكفاءة" + }, + { + "to": "framework/react/examples/column-visibility", + "label": "إظهار/إخفاء الأعمدة" + }, + { + "to": "framework/react/examples/editable-data", + "label": "بيانات قابلة للتعديل" + }, + { + "to": "framework/react/examples/expanding", + "label": "التوسيع" + }, + { + "to": "framework/react/examples/sub-components", + "label": "المكونات الفرعية" + }, + { + "to": "framework/react/examples/fully-controlled", + "label": "تحكم كامل" + }, + { + "to": "framework/react/examples/grouping", + "label": "التجميع" + }, + { + "to": "framework/react/examples/pagination", + "label": "ترقيم الصفحات" + }, + { + "to": "framework/react/examples/pagination-controlled", + "label": "ترقيم الصفحات المتحكم به" + }, + { + "to": "framework/react/examples/row-dnd", + "label": "سحب وإفلات الصفوف" + }, + { + "to": "framework/react/examples/row-pinning", + "label": "تثبيت الصفوف" + }, + { + "to": "framework/react/examples/row-selection", + "label": "اختيار الصفوف" + }, + { + "to": "framework/react/examples/sorting", + "label": "الفرز" + }, + { + "to": "framework/react/examples/virtualized-columns", + "label": "أعمدة مخيلة" + }, + { + "to": "framework/react/examples/virtualized-columns-experimental", + "label": "أعمدة مخيلة (تجريبي)" + }, + { + "to": "framework/react/examples/virtualized-rows", + "label": "صفوف مخيلة" + }, + { + "to": "framework/react/examples/virtualized-rows-experimental", + "label": "صفوف مخيلة (تجريبي)" + }, + { + "to": "framework/react/examples/virtualized-infinite-scrolling", + "label": "التمرير اللانهائي المخيل" + }, + { + "to": "framework/react/examples/kitchen-sink", + "label": "كل شيء في واحد" + }, + { + "to": "framework/react/examples/bootstrap", + "label": "React Bootstrap" + }, + { + "to": "framework/react/examples/material-ui-pagination", + "label": "ترقيم صفحات Material UI" + }, + { + "to": "framework/react/examples/full-width-table", + "label": "جدول بعرض كامل React" + }, + { + "to": "framework/react/examples/full-width-resizable-table", + "label": "جدول قابل لتغيير الحجم بعرض كامل React" + }, + { + "to": "framework/react/examples/custom-features", + "label": "ميزات مخصصة" + }, + { + "to": "framework/react/examples/query-router-search-params", + "label": "معلمات بحث الموجه الاستعلامي" + } + ] + }, + { + "label": "solid", + "children": [ + { + "to": "framework/solid/examples/basic", + "label": "أساسي" + }, + { + "to": "framework/solid/examples/column-groups", + "label": "مجموعات الأعمدة" + }, + { + "to": "framework/solid/examples/column-ordering", + "label": "ترتيب الأعمدة" + }, + { + "to": "framework/solid/examples/column-visibility", + "label": "إظهار/إخفاء الأعمدة" + }, + { + "to": "framework/solid/examples/filters", + "label": "المرشحات" + }, + { + "to": "framework/solid/examples/sorting", + "label": "الفرز" + }, + { + "to": "framework/solid/examples/bootstrap", + "label": "Solid Bootstrap" + } + ] + }, + { + "label": "svelte", + "children": [ + { + "to": "framework/svelte/examples/basic", + "label": "أساسي" + }, + { + "to": "framework/svelte/examples/column-groups", + "label": "مجموعات الأعمدة" + }, + { + "to": "framework/svelte/examples/column-ordering", + "label": "ترتيب الأعمدة" + }, + { + "to": "framework/svelte/examples/column-pinning", + "label": "تثبيت الأعمدة" + }, + { + "to": "framework/svelte/examples/column-visibility", + "label": "إظهار/إخفاء الأعمدة" + }, + { + "to": "framework/svelte/examples/filtering", + "label": "التصفية" + }, + { + "to": "framework/svelte/examples/sorting", + "label": "الفرز" + } + ] + }, + { + "label": "vue", + "children": [ + { + "to": "framework/vue/examples/basic", + "label": "أساسي" + }, + { + "to": "framework/vue/examples/column-ordering", + "label": "ترتيب الأعمدة" + }, + { + "to": "framework/vue/examples/column-pinning", + "label": "تثبيت الأعمدة" + }, + { + "to": "framework/vue/examples/pagination", + "label": "ترقيم الصفحات" + }, + { + "to": "framework/vue/examples/row-selection", + "label": "اختيار الصفوف" + }, + { + "to": "framework/vue/examples/sorting", + "label": "الفرز" + }, + { + "to": "framework/vue/examples/sub-components", + "label": "المكونات الفرعية" + }, + { + "to": "framework/vue/examples/filters", + "label": "مرشحات الأعمدة" + }, + { + "to": "framework/vue/examples/virtualized-rows", + "label": "صفوف مخيلة" + }, + { + "to": "framework/vue/examples/grouping", + "label": "التجميع" + } + ] + }, + { + "label": "vanilla", + "children": [ + { + "to": "framework/vanilla/examples/basic", + "label": "أساسي" + }, + { + "to": "framework/vanilla/examples/pagination", + "label": "ترقيم الصفحات" + }, + { + "to": "framework/vanilla/examples/sorting", + "label": "الفرز" + } + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/docs/fr/config.json b/docs/fr/config.json new file mode 100644 index 0000000000..e4c91a0c7d --- /dev/null +++ b/docs/fr/config.json @@ -0,0 +1,790 @@ +{ + "$schema": "https://raw.githubusercontent.com/TanStack/tanstack.com/main/tanstack-docs-config.schema.json", + "docSearch": { + "appId": "74SF5EKVW9", + "apiKey": "9fc015a3310be6669ed66c6c459f319f", + "indexName": "tanstack-table" + }, + "sections": [ + { + "label": "Premiers pas", + "children": [ + { + "label": "Introduction", + "to": "introduction" + }, + { + "label": "Vue d'ensemble", + "to": "overview" + }, + { + "label": "Installation", + "to": "installation" + }, + { + "label": "Migration vers V8", + "to": "guide/migrating" + }, + { + "label": "FAQ", + "to": "faq" + } + ], + "frameworks": [ + { + "label": "angular", + "children": [ + { + "label": "Adaptateur de table Angular", + "to": "framework/angular/angular-table" + } + ] + }, + { + "label": "lit", + "children": [ + { + "label": "Adaptateur de table Lit", + "to": "framework/lit/lit-table" + } + ] + }, + { + "label": "qwik", + "children": [ + { + "label": "Adaptateur de table Qwik", + "to": "framework/qwik/qwik-table" + } + ] + }, + { + "label": "react", + "children": [ + { + "label": "Adaptateur de table React", + "to": "framework/react/react-table" + } + ] + }, + { + "label": "solid", + "children": [ + { + "label": "Adaptateur de table Solid", + "to": "framework/solid/solid-table" + } + ] + }, + { + "label": "svelte", + "children": [ + { + "label": "Adaptateur de table Svelte", + "to": "framework/svelte/svelte-table" + } + ] + }, + { + "label": "vue", + "children": [ + { + "label": "Adaptateur de table Vue", + "to": "framework/vue/vue-table" + } + ] + }, + { + "label": "vanilla", + "children": [ + { + "label": "Vanilla JS (sans framework)", + "to": "vanilla" + } + ] + } + ] + }, + { + "label": "Guides principaux", + "children": [ + { + "label": "Données", + "to": "guide/data" + }, + { + "label": "Définitions de colonnes", + "to": "guide/column-defs" + }, + { + "label": "Instance de table", + "to": "guide/tables" + }, + { + "label": "Modèles de lignes", + "to": "guide/row-models" + }, + { + "label": "Lignes", + "to": "guide/rows" + }, + { + "label": "Cellules", + "to": "guide/cells" + }, + { + "label": "Groupes d'en-têtes", + "to": "guide/header-groups" + }, + { + "label": "En-têtes", + "to": "guide/headers" + }, + { + "label": "Colonnes", + "to": "guide/columns" + } + ], + "frameworks": [ + { + "label": "angular", + "children": [ + { + "label": "État de la table", + "to": "framework/angular/guide/table-state" + } + ] + }, + { + "label": "lit", + "children": [ + { + "label": "État de la table", + "to": "framework/lit/guide/table-state" + } + ] + }, + { + "label": "qwik", + "children": [ + { + "label": "État de la table", + "to": "framework/qwik/guide/table-state" + } + ] + }, + { + "label": "react", + "children": [ + { + "label": "État de la table", + "to": "framework/react/guide/table-state" + } + ] + }, + { + "label": "solid", + "children": [ + { + "label": "État de la table", + "to": "framework/solid/guide/table-state" + } + ] + }, + { + "label": "svelte", + "children": [ + { + "label": "État de la table", + "to": "framework/svelte/guide/table-state" + } + ] + }, + { + "label": "vue", + "children": [ + { + "label": "État de la table", + "to": "framework/vue/guide/table-state" + } + ] + }, + { + "label": "vanilla", + "children": [ + { + "label": "État de la table", + "to": "framework/vanilla/guide/table-state" + } + ] + } + ] + }, + { + "label": "Guides des fonctionnalités", + "children": [ + { + "label": "Ordonnancement des colonnes", + "to": "guide/column-ordering" + }, + { + "label": "Épinglage des colonnes", + "to": "guide/column-pinning" + }, + { + "label": "Dimensionnement des colonnes", + "to": "guide/column-sizing" + }, + { + "label": "Visibilité des colonnes", + "to": "guide/column-visibility" + }, + { + "label": "Filtrage des colonnes", + "to": "guide/column-filtering" + }, + { + "label": "Filtrage global", + "to": "guide/global-filtering" + }, + { + "label": "Filtrage flou", + "to": "guide/fuzzy-filtering" + }, + { + "label": "Facettage des colonnes", + "to": "guide/column-faceting" + }, + { + "label": "Facettage global", + "to": "guide/global-faceting" + }, + { + "label": "Regroupement", + "to": "guide/grouping" + }, + { + "label": "Expansion", + "to": "guide/expanding" + }, + { + "label": "Pagination", + "to": "guide/pagination" + }, + { + "label": "Épinglage des lignes", + "to": "guide/row-pinning" + }, + { + "label": "Sélection des lignes", + "to": "guide/row-selection" + }, + { + "label": "Tri", + "to": "guide/sorting" + }, + { + "label": "Virtualisation", + "to": "guide/virtualization" + }, + { + "label": "Fonctionnalités personnalisées", + "to": "guide/custom-features" + } + ] + }, + { + "label": "API principales", + "children": [ + { + "label": "Définition de colonne", + "to": "api/core/column-def" + }, + { + "label": "Table", + "to": "api/core/table" + }, + { + "label": "Colonne", + "to": "api/core/column" + }, + { + "label": "Groupe d'en-têtes", + "to": "api/core/header-group" + }, + { + "label": "En-tête", + "to": "api/core/header" + }, + { + "label": "Ligne", + "to": "api/core/row" + }, + { + "label": "Cellule", + "to": "api/core/cell" + } + ] + }, + { + "label": "API des fonctionnalités", + "children": [ + { + "label": "Filtrage des colonnes", + "to": "api/features/column-filtering" + }, + { + "label": "Facettage des colonnes", + "to": "api/features/column-faceting" + }, + { + "label": "Ordonnancement des colonnes", + "to": "api/features/column-ordering" + }, + { + "label": "Épinglage des colonnes", + "to": "api/features/column-pinning" + }, + { + "label": "Dimensionnement des colonnes", + "to": "api/features/column-sizing" + }, + { + "label": "Visibilité des colonnes", + "to": "api/features/column-visibility" + }, + { + "label": "Facettage global", + "to": "api/features/global-faceting" + }, + { + "label": "Filtrage global", + "to": "api/features/global-filtering" + }, + { + "label": "Tri", + "to": "api/features/sorting" + }, + { + "label": "Regroupement", + "to": "api/features/grouping" + }, + { + "label": "Expansion", + "to": "api/features/expanding" + }, + { + "label": "Pagination", + "to": "api/features/pagination" + }, + { + "label": "Épinglage des lignes", + "to": "api/features/row-pinning" + }, + { + "label": "Sélection des lignes", + "to": "api/features/row-selection" + } + ] + }, + { + "label": "Entreprise", + "children": [ + { + "label": "AG Grid", + "to": "enterprise/ag-grid" + } + ] + }, + { + "label": "Exemples", + "children": [], + "frameworks": [ + { + "label": "angular", + "children": [ + { + "to": "framework/angular/examples/basic", + "label": "Basique" + }, + { + "to": "framework/angular/examples/grouping", + "label": "Regroupement de colonnes" + }, + { + "to": "framework/angular/examples/column-ordering", + "label": "Ordonnancement des colonnes" + }, + { + "to": "framework/angular/examples/column-pinning", + "label": "Épinglage des colonnes" + }, + { + "to": "framework/angular/examples/column-pinning-sticky", + "label": "Épinglage des colonnes collant" + }, + { + "to": "framework/angular/examples/column-visibility", + "label": "Visibilité des colonnes" + }, + { + "to": "framework/angular/examples/filters", + "label": "Filtres de colonnes" + }, + { + "to": "framework/angular/examples/row-selection", + "label": "Sélection des lignes" + }, + { + "to": "framework/angular/examples/expanding", + "label": "Expansion" + }, + { + "to": "framework/angular/examples/sub-components", + "label": "Sous-composants" + }, + { + "to": "framework/angular/examples/signal-input", + "label": "Entrée Signal" + }, + { + "to": "framework/angular/examples/editable", + "label": "Données modifiables" + }, + { + "to": "framework/angular/examples/row-dnd", + "label": "Glisser-déposer des lignes" + }, + { + "to": "framework/angular/examples/column-resizing-performant", + "label": "Redimensionnement performant des colonnes" + } + ] + }, + { + "label": "lit", + "children": [ + { + "to": "framework/lit/examples/basic", + "label": "Basique" + }, + { + "to": "framework/lit/examples/column-sizing", + "label": "Dimensionnement des colonnes" + }, + { + "to": "framework/lit/examples/filters", + "label": "Filtres" + }, + { + "to": "framework/lit/examples/row-selection", + "label": "Sélection des lignes" + }, + { + "to": "framework/lit/examples/sorting", + "label": "Tri" + }, + { + "to": "framework/lit/examples/virtualized-rows", + "label": "Lignes virtualisées" + } + ] + }, + { + "label": "qwik", + "children": [ + { + "to": "framework/qwik/examples/basic", + "label": "Basique" + }, + { + "to": "framework/qwik/examples/filters", + "label": "Filtres" + }, + { + "to": "framework/qwik/examples/row-selection", + "label": "Sélection des lignes" + }, + { + "to": "framework/qwik/examples/sorting", + "label": "Tri" + } + ] + }, + { + "label": "react", + "children": [ + { + "to": "framework/react/examples/basic", + "label": "Basique" + }, + { + "to": "framework/react/examples/column-groups", + "label": "Groupes d'en-têtes" + }, + { + "to": "framework/react/examples/filters", + "label": "Filtres de colonnes" + }, + { + "to": "framework/react/examples/filters-faceted", + "label": "Filtres de colonnes (à facettes)" + }, + { + "to": "framework/react/examples/filters-fuzzy", + "label": "Filtres de recherche floue" + }, + { + "to": "framework/react/examples/column-ordering", + "label": "Ordonnancement des colonnes" + }, + { + "to": "framework/react/examples/column-dnd", + "label": "Ordonnancement des colonnes (Glisser-déposer)" + }, + { + "to": "framework/react/examples/column-pinning", + "label": "Épinglage des colonnes" + }, + { + "to": "framework/react/examples/column-pinning-sticky", + "label": "Épinglage des colonnes collant" + }, + { + "to": "framework/react/examples/column-sizing", + "label": "Dimensionnement des colonnes" + }, + { + "to": "framework/react/examples/column-resizing-performant", + "label": "Redimensionnement performant des colonnes" + }, + { + "to": "framework/react/examples/column-visibility", + "label": "Visibilité des colonnes" + }, + { + "to": "framework/react/examples/editable-data", + "label": "Données modifiables" + }, + { + "to": "framework/react/examples/expanding", + "label": "Expansion" + }, + { + "to": "framework/react/examples/sub-components", + "label": "Sous-composants" + }, + { + "to": "framework/react/examples/fully-controlled", + "label": "Entièrement contrôlé" + }, + { + "to": "framework/react/examples/grouping", + "label": "Regroupement" + }, + { + "to": "framework/react/examples/pagination", + "label": "Pagination" + }, + { + "to": "framework/react/examples/pagination-controlled", + "label": "Pagination contrôlée" + }, + { + "to": "framework/react/examples/row-dnd", + "label": "Glisser-déposer des lignes" + }, + { + "to": "framework/react/examples/row-pinning", + "label": "Épinglage des lignes" + }, + { + "to": "framework/react/examples/row-selection", + "label": "Sélection des lignes" + }, + { + "to": "framework/react/examples/sorting", + "label": "Tri" + }, + { + "to": "framework/react/examples/virtualized-columns", + "label": "Colonnes virtualisées" + }, + { + "to": "framework/react/examples/virtualized-columns-experimental", + "label": "Colonnes virtualisées (expérimental)" + }, + { + "to": "framework/react/examples/virtualized-rows", + "label": "Lignes virtualisées" + }, + { + "to": "framework/react/examples/virtualized-rows-experimental", + "label": "Lignes virtualisées (expérimental)" + }, + { + "to": "framework/react/examples/virtualized-infinite-scrolling", + "label": "Défilement infini virtualisé" + }, + { + "to": "framework/react/examples/kitchen-sink", + "label": "Tout-en-un" + }, + { + "to": "framework/react/examples/bootstrap", + "label": "React Bootstrap" + }, + { + "to": "framework/react/examples/material-ui-pagination", + "label": "Pagination Material UI" + }, + { + "to": "framework/react/examples/full-width-table", + "label": "Table pleine largeur React" + }, + { + "to": "framework/react/examples/full-width-resizable-table", + "label": "Table pleine largeur redimensionnable React" + }, + { + "to": "framework/react/examples/custom-features", + "label": "Fonctionnalités personnalisées" + }, + { + "to": "framework/react/examples/query-router-search-params", + "label": "Paramètres de recherche du routeur de requêtes" + } + ] + }, + { + "label": "solid", + "children": [ + { + "to": "framework/solid/examples/basic", + "label": "Basique" + }, + { + "to": "framework/solid/examples/column-groups", + "label": "Groupes de colonnes" + }, + { + "to": "framework/solid/examples/column-ordering", + "label": "Ordonnancement des colonnes" + }, + { + "to": "framework/solid/examples/column-visibility", + "label": "Visibilité des colonnes" + }, + { + "to": "framework/solid/examples/filters", + "label": "Filtres" + }, + { + "to": "framework/solid/examples/sorting", + "label": "Tri" + }, + { + "to": "framework/solid/examples/bootstrap", + "label": "Solid Bootstrap" + } + ] + }, + { + "label": "svelte", + "children": [ + { + "to": "framework/svelte/examples/basic", + "label": "Basique" + }, + { + "to": "framework/svelte/examples/column-groups", + "label": "Groupes de colonnes" + }, + { + "to": "framework/svelte/examples/column-ordering", + "label": "Ordonnancement des colonnes" + }, + { + "to": "framework/svelte/examples/column-pinning", + "label": "Épinglage des colonnes" + }, + { + "to": "framework/svelte/examples/column-visibility", + "label": "Visibilité des colonnes" + }, + { + "to": "framework/svelte/examples/filtering", + "label": "Filtrage" + }, + { + "to": "framework/svelte/examples/sorting", + "label": "Tri" + } + ] + }, + { + "label": "vue", + "children": [ + { + "to": "framework/vue/examples/basic", + "label": "Basique" + }, + { + "to": "framework/vue/examples/column-ordering", + "label": "Ordonnancement des colonnes" + }, + { + "to": "framework/vue/examples/column-pinning", + "label": "Épinglage des colonnes" + }, + { + "to": "framework/vue/examples/pagination", + "label": "Pagination" + }, + { + "to": "framework/vue/examples/row-selection", + "label": "Sélection des lignes" + }, + { + "to": "framework/vue/examples/sorting", + "label": "Tri" + }, + { + "to": "framework/vue/examples/sub-components", + "label": "Sous-composants" + }, + { + "to": "framework/vue/examples/filters", + "label": "Filtres de colonnes" + }, + { + "to": "framework/vue/examples/virtualized-rows", + "label": "Lignes virtualisées" + }, + { + "to": "framework/vue/examples/grouping", + "label": "Regroupement" + } + ] + }, + { + "label": "vanilla", + "children": [ + { + "to": "framework/vanilla/examples/basic", + "label": "Basique" + }, + { + "to": "framework/vanilla/examples/pagination", + "label": "Pagination" + }, + { + "to": "framework/vanilla/examples/sorting", + "label": "Tri" + } + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/docs/ja/api/core/cell.md b/docs/ja/api/core/cell.md new file mode 100644 index 0000000000..951a7088fa --- /dev/null +++ b/docs/ja/api/core/cell.md @@ -0,0 +1,73 @@ +--- +source-updated-at: '2025-03-20T21:15:29.000Z' +translation-updated-at: '2025-05-05T19:28:16.242Z' +title: セル +--- +# セルAPI (Cell APIs) + +TanStack Tableのコアは**フレームワーク非依存 (framework agnostic)** です。つまり、使用するフレームワークに関係なくAPIは同じです。各フレームワークでテーブルコアを簡単に操作できるように、アダプターが提供されています。利用可能なアダプターについては、アダプターメニューを参照してください。 + +これらはすべてのセルに対する**コア (core)** オプションとAPIプロパティです。他の[テーブル機能](../guide/features)では、さらに多くのオプションとAPIプロパティが利用可能です。 + +## セルAPI (Cell API) + +すべてのセルオブジェクトは以下のプロパティを持ちます: + +### `id` + +```tsx +id: string +``` + +テーブル全体で一意のセルID。 + +### `getValue` + +```tsx +getValue: () => any +``` + +関連するカラムのアクセサーキーまたはアクセサー関数を介して、セルの値を取得します。 + +### `renderValue` + +```tsx +renderValue: () => any +``` + +`getValue`と同じ方法でセルの値をレンダリングしますが、値が見つからない場合は`renderFallbackValue`を返します。 + +### `row` + +```tsx +row: Row +``` + +セルに関連付けられた行オブジェクト。 + +### `column` + +```tsx +column: Column +``` + +セルに関連付けられたカラムオブジェクト。 + +### `getContext` + +```tsx +getContext: () => { + table: Table + column: Column + row: Row + cell: Cell + getValue: () => TTValue + renderValue: () => TTValue | null +} +``` + +セルや集計セルなどのセルベースのコンポーネントのレンダリングコンテキスト(またはプロパティ)を返します。これらのプロパティをフレームワークの`flexRender`ユーティリティと一緒に使用して、選択したテンプレートでこれらをレンダリングします: + +```tsx +flexRender(cell.column.columnDef.cell, cell.getContext()) +``` diff --git a/docs/ja/api/core/column-def.md b/docs/ja/api/core/column-def.md new file mode 100644 index 0000000000..3a4735ade8 --- /dev/null +++ b/docs/ja/api/core/column-def.md @@ -0,0 +1,110 @@ +--- +source-updated-at: '2024-03-22T01:02:38.000Z' +translation-updated-at: '2025-05-05T19:27:36.041Z' +title: カラム定義 +--- +# ColumnDef API + +カラム定義は以下のオプションを持つプレーンオブジェクトです。 + +## オプション + +### `id` + +```tsx +id: string +``` + +カラムの一意な識別子。 + +> 🧠 カラムIDは以下の場合オプションです: +> +> - オブジェクトキーアクセサーでアクセサーカラムが作成された場合 +> - カラムヘッダーが文字列で定義されている場合 + +### `accessorKey` + +```tsx +accessorKey?: string & typeof TData +``` + +カラムの値を抽出する際に使用する行オブジェクトのキー。 + +### `accessorFn` + +```tsx +accessorFn?: (originalRow: TData, index: number) => any +``` + +各行からカラムの値を抽出する際に使用するアクセサー関数。 + +### `columns` + +```tsx +columns?: ColumnDef[] +``` + +グループカラムに含める子カラム定義。 + +### `header` + +```tsx +header?: + | string + | ((props: { + table: Table + header: Header + column: Column + }) => unknown) +``` + +カラムに表示するヘッダー。文字列が渡された場合、カラムIDのデフォルトとして使用できます。関数が渡された場合、ヘッダーのpropsオブジェクトが渡され、レンダリングされたヘッダー値を返す必要があります(正確な型は使用するアダプターによって異なります)。 + +### `footer` + +```tsx +footer?: + | string + | ((props: { + table: Table + header: Header + column: Column + }) => unknown) +``` + +カラムに表示するフッター。関数が渡された場合、フッターのpropsオブジェクトが渡され、レンダリングされたフッター値を返す必要があります(正確な型は使用するアダプターによって異なります)。 + +### `cell` + +```tsx +cell?: + | string + | ((props: { + table: Table + row: Row + column: Column + cell: Cell + getValue: () => any + renderValue: () => any + }) => unknown) +``` + +カラムの各行に表示するセル。関数が渡された場合、セルのpropsオブジェクトが渡され、レンダリングされたセル値を返す必要があります(正確な型は使用するアダプターによって異なります)。 + +### `meta` + +```tsx +meta?: ColumnMeta // このインターフェースは宣言マージで拡張可能です。下記を参照! +``` + +カラムに関連付けるメタデータ。`column.columnDef.meta`を通じてカラムが利用可能な場所ならどこからでもアクセスできます。この型はすべてのテーブルでグローバルであり、以下のように拡張できます: + +```tsx +import '@tanstack/react-table' // または vue, svelte, solid, qwik など + +declare module '@tanstack/react-table' { + interface ColumnMeta { + foo: string + } +} +``` diff --git a/docs/ja/api/core/column.md b/docs/ja/api/core/column.md new file mode 100644 index 0000000000..c5e1f9136c --- /dev/null +++ b/docs/ja/api/core/column.md @@ -0,0 +1,82 @@ +--- +source-updated-at: '2025-03-20T21:15:29.000Z' +translation-updated-at: '2025-05-05T19:27:54.156Z' +title: カラム +--- +# カラムAPI (Column APIs) + +TanStack Tableのコアは**フレームワーク非依存 (framework agnostic)** です。つまり、使用するフレームワークに関係なくAPIは同じです。各フレームワーク向けにアダプターが提供されており、テーブルコアを簡単に操作できます。利用可能なアダプターについては、アダプターメニューを参照してください。 + +これらはすべてのカラムに適用される**コア**オプションとAPIプロパティです。他の[テーブル機能](../guide/features)については、さらに多くのオプションとAPIプロパティが利用可能です。 + +## カラムAPI + +すべてのカラムオブジェクトは以下のプロパティを持ちます: + +### `id` + +```tsx +id: string +``` + +カラムの解決済み一意識別子で、以下の優先順位で決定されます: + +- カラム定義からの手動`id`プロパティ +- カラム定義からのアクセサーキー +- カラム定義からのヘッダー文字列 + +### `depth` + +```tsx +depth: number +``` + +(グループ化されている場合の) ルートカラム定義配列に対するカラムの深さ。 + +### `accessorFn` + +```tsx +accessorFn?: AccessorFn +``` + +各行からカラムの値を抽出する際に使用する解決済みアクセサー関数。カラム定義に有効なアクセサーキーまたは関数が定義されている場合のみ設定されます。 + +### `columnDef` + +```tsx +columnDef: ColumnDef +``` + +カラムの作成に使用された元のカラム定義。 + +### `columns` + +```tsx +type columns = ColumnDef[] +``` + +(カラムがグループカラムの場合の) 子カラム。カラムがグループカラムでない場合は空の配列になります。 + +### `parent` + +```tsx +parent?: Column +``` + +このカラムの親カラム。ルートカラムの場合はundefinedになります。 + +### `getFlatColumns` + +```tsx +type getFlatColumns = () => Column[] +``` + +このカラムとすべての子/孫カラムを含む平坦化された配列を返します。 + +### `getLeafColumns` + +```tsx +type getLeafColumns = () => Column[] +``` + +このカラムのすべてのリーフノードカラムの配列を返します。カラムに子がない場合、そのカラム自体が唯一のリーフノードカラムとみなされます。 diff --git a/docs/ja/api/core/header-group.md b/docs/ja/api/core/header-group.md new file mode 100644 index 0000000000..774e1bdffb --- /dev/null +++ b/docs/ja/api/core/header-group.md @@ -0,0 +1,36 @@ +--- +source-updated-at: '2025-03-20T21:15:29.000Z' +translation-updated-at: '2025-05-05T19:27:46.207Z' +title: ヘッダーグループ +--- +以下は翻訳です: + +これらはすべてのヘッダーグループに対する**コア**なオプションとAPIプロパティです。他の[テーブル機能](../guide/features)ではさらに多くのオプションとAPIプロパティが利用可能です。 + +## ヘッダーグループ API + +すべてのヘッダーグループオブジェクトは以下のプロパティを持ちます: + +### `id` + +```tsx +id: string +``` + +ヘッダーグループの一意な識別子。 + +### `depth` + +```tsx +depth: number +``` + +ヘッダーグループの深さ(0から始まるインデックス)。 + +### `headers` + +```tsx +type headers = Header[] +``` + +このヘッダーグループに属する[Header](../api/core/header)オブジェクトの配列。 diff --git a/docs/ja/api/core/header.md b/docs/ja/api/core/header.md new file mode 100644 index 0000000000..1c607a7c68 --- /dev/null +++ b/docs/ja/api/core/header.md @@ -0,0 +1,246 @@ +--- +source-updated-at: '2025-03-20T21:15:29.000Z' +translation-updated-at: '2025-05-05T19:28:38.037Z' +title: ヘッダー +--- +以下は翻訳です: + +これらはすべてのヘッダーに対する**コア**オプションとAPIプロパティです。他の[テーブル機能](../guide/features)では、さらに多くのオプションとAPIプロパティが利用可能な場合があります。 + +## ヘッダーAPI + +すべてのヘッダーオブジェクトは以下のプロパティを持ちます: + +### `id` + +```tsx +id: string +``` + +ヘッダーの一意な識別子。 + +### `index` + +```tsx +index: number +``` + +ヘッダーグループ内でのヘッダーのインデックス。 + +### `depth` + +```tsx +depth: number +``` + +ヘッダーの深さ(0から始まるインデックス)。 + +### `column` + +```tsx +column: Column +``` + +ヘッダーに関連付けられた[Column](../api/core/column)オブジェクト。 + +### `headerGroup` + +```tsx +headerGroup: HeaderGroup +``` + +ヘッダーに関連付けられた[HeaderGroup](../api/core/header-group)オブジェクト。 + +### `subHeaders` + +```tsx +type subHeaders = Header[] +``` + +ヘッダーの階層的なサブ/子ヘッダー。ヘッダーに関連付けられたカラムがリーフカラムの場合、空になります。 + +### `colSpan` + +```tsx +colSpan: number +``` + +ヘッダーのcol-span(列結合数)。 + +### `rowSpan` + +```tsx +rowSpan: number +``` + +ヘッダーのrow-span(行結合数)。 + +### `getLeafHeaders` + +```tsx +type getLeafHeaders = () => Header[] +``` + +このヘッダーの下に階層的にネストされたリーフヘッダーを返します。 + +### `isPlaceholder` + +```tsx +isPlaceholder: boolean +``` + +ヘッダーがプレースホルダーヘッダーかどうかを示すブール値。 + +### `placeholderId` + +```tsx +placeholderId?: string +``` + +ヘッダーがプレースホルダーヘッダーの場合、テーブル全体で他のヘッダーと競合しない一意のヘッダーID。 + +### `getContext` + +```tsx +getContext: () => { + table: Table + header: Header + column: Column +} +``` + +ヘッダー、フッター、フィルターなどのカラムベースのコンポーネントのレンダリングコンテキスト(またはプロパティ)を返します。これらのプロパティをフレームワークの`flexRender`ユーティリティと共に使用して、選択したテンプレートでこれらをレンダリングします: + +```tsx +flexRender(header.column.columnDef.header, header.getContext()) +``` + +## テーブルAPI + +### `getHeaderGroups` + +```tsx +type getHeaderGroups = () => HeaderGroup[] +``` + +テーブルのすべてのヘッダーグループを返します。 + +### `getLeftHeaderGroups` + +```tsx +type getLeftHeaderGroups = () => HeaderGroup[] +``` + +ピン留めされている場合、左側にピン留めされたカラムのヘッダーグループを返します。 + +### `getCenterHeaderGroups` + +```tsx +type getCenterHeaderGroups = () => HeaderGroup[] +``` + +ピン留めされている場合、ピン留めされていないカラムのヘッダーグループを返します。 + +### `getRightHeaderGroups` + +```tsx +type getRightHeaderGroups = () => HeaderGroup[] +``` + +ピン留めされている場合、右側にピン留めされたカラムのヘッダーグループを返します。 + +### `getFooterGroups` + +```tsx +type getFooterGroups = () => HeaderGroup[] +``` + +テーブルのすべてのフッターグループを返します。 + +### `getLeftFooterGroups` + +```tsx +type getLeftFooterGroups = () => HeaderGroup[] +``` + +ピン留めされている場合、左側にピン留めされたカラムのフッターグループを返します。 + +### `getCenterFooterGroups` + +```tsx +type getCenterFooterGroups = () => HeaderGroup[] +``` + +ピン留めされている場合、ピン留めされていないカラムのフッターグループを返します。 + +### `getRightFooterGroups` + +```tsx +type getRightFooterGroups = () => HeaderGroup[] +``` + +ピン留めされている場合、右側にピン留めされたカラムのフッターグループを返します。 + +### `getFlatHeaders` + +```tsx +type getFlatHeaders = () => Header[] +``` + +親ヘッダーを含む、テーブルのすべてのカラムのヘッダーを返します。 + +### `getLeftFlatHeaders` + +```tsx +type getLeftFlatHeaders = () => Header[] +``` + +ピン留めされている場合、親ヘッダーを含む、左側にピン留めされたすべてのカラムのヘッダーを返します。 + +### `getCenterFlatHeaders` + +```tsx +type getCenterFlatHeaders = () => Header[] +``` + +ピン留めされている場合、親ヘッダーを含む、ピン留めされていないすべてのカラムのヘッダーを返します。 + +### `getRightFlatHeaders` + +```tsx +type getRightFlatHeaders = () => Header[] +``` + +ピン留めされている場合、親ヘッダーを含む、右側にピン留めされたすべてのカラムのヘッダーを返します。 + +### `getLeafHeaders` + +```tsx +type getLeafHeaders = () => Header[] +``` + +親ヘッダーを含まない、テーブルのすべてのリーフカラムのヘッダーを返します。 + +### `getLeftLeafHeaders` + +```tsx +type getLeftLeafHeaders = () => Header[] +``` + +ピン留めされている場合、親ヘッダーを含まない、左側にピン留めされたすべてのリーフカラムのヘッダーを返します。 + +### `getCenterLeafHeaders` + +```tsx +type getCenterLeafHeaders = () => Header[] +``` + +ピン留めされている場合、親ヘッダーを含まない、ピン留めされていないすべてのカラムのヘッダーを返します。 + +### `getRightLeafHeaders` + +```tsx +type getRightLeafHeaders = () => Header[] +``` + +ピン留めされている場合、親ヘッダーを含まない、右側にピン留めされたすべてのリーフカラムのヘッダーを返します。 diff --git a/docs/ja/api/core/row.md b/docs/ja/api/core/row.md new file mode 100644 index 0000000000..4cee0b5b0f --- /dev/null +++ b/docs/ja/api/core/row.md @@ -0,0 +1,126 @@ +--- +source-updated-at: '2025-03-20T21:15:29.000Z' +translation-updated-at: '2025-05-05T19:28:11.843Z' +title: 行 +--- +以下は翻訳です: + +これらはすべての行に対する**コア**オプションとAPIプロパティです。他の[テーブル機能](../guide/features)にはさらに多くのオプションとAPIプロパティが利用可能です。 + +## 行 (Row) API + +すべての行オブジェクトは以下のプロパティを持ちます: + +### `id` + +```tsx +id: string +``` + +`options.getRowId`オプションによって解決された、行の一意の識別子。デフォルトでは行のインデックス(またはサブ行の場合は相対インデックス)が使用されます。 + +### `depth` + +```tsx +depth: number +``` + +ルート行配列に対する行の深さ(ネストまたはグループ化されている場合)。 + +### `index` + +```tsx +index: number +``` + +親配列(またはルートデータ配列)内での行のインデックス。 + +### `original` + +```tsx +original: TData +``` + +テーブルに提供された元の行オブジェクト。 + +> 🧠 行がグループ化された行の場合、元の行オブジェクトはグループ内の最初の元の行になります。 + +### `parentId` + +```tsx +parentId?: string +``` + +ネストされている場合、この行の親行のID。 + +### `getValue` + +```tsx +getValue: (columnId: string) => TValue +``` + +指定されたcolumnIdに対応する行の値を返します。 + +### `renderValue` + +```tsx +renderValue: (columnId: string) => TValue +``` + +指定されたcolumnIdに対応する行の値をレンダリングしますが、値が見つからない場合は`renderFallbackValue`を返します。 + +### `getUniqueValues` + +```tsx +getUniqueValues: (columnId: string) => TValue[] +``` + +指定されたcolumnIdに対応する行から一意の値の配列を返します。 + +### `subRows` + +```tsx +type subRows = Row[] +``` + +`options.getSubRows`オプションによって返され作成された行のサブ行の配列。 + +### `getParentRow` + +```tsx +type getParentRow = () => Row | undefined +``` + +存在する場合、行の親行を返します。 + +### `getParentRows` + +```tsx +type getParentRows = () => Row[] +``` + +行の親行をルート行まで遡ってすべて返します。 + +### `getLeafRows` + +```tsx +type getLeafRows = () => Row[] +``` + +行のリーフ行(親行を含まない)を返します。 + +### `originalSubRows` + +```tsx +originalSubRows?: TData[] +``` + +`options.getSubRows`オプションによって返された元のサブ行の配列。 + +### `getAllCells` + +```tsx +type getAllCells = () => Cell[] +``` + +行のすべての[セル (Cell)](../api/core/cell)を返します。 diff --git a/docs/ja/api/core/table.md b/docs/ja/api/core/table.md new file mode 100644 index 0000000000..687528c928 --- /dev/null +++ b/docs/ja/api/core/table.md @@ -0,0 +1,388 @@ +--- +source-updated-at: '2025-03-20T21:15:29.000Z' +translation-updated-at: '2025-05-05T19:29:11.249Z' +title: テーブル +--- +```markdown +## `createAngularTable` / `useReactTable` / `createSolidTable` / `useQwikTable` / `useVueTable` / `createSvelteTable` + +```tsx +type useReactTable = ( + options: TableOptions +) => Table +``` + +これらの関数はテーブルを作成するために使用されます。使用する関数は、使用しているフレームワークアダプターによって異なります。 + +## オプション + +これらはテーブルの**コア**オプションとAPIプロパティです。他の[テーブル機能](../guide/features)にはさらに多くのオプションとAPIプロパティが利用可能です。 + +### `data` + +```tsx +data: TData[] +``` + +テーブルに表示するデータ。この配列は`table.setRowType<...>`に指定した型と一致する必要がありますが、理論的には任意の配列を指定できます。配列の各要素はキー/値のオブジェクトであることが一般的ですが、必須ではありません。カラムは文字列/インデックスまたは関数アクセサーを通じてこのデータにアクセスし、任意の値を返すことができます。 + +`data`オプションの参照が変更されると(`Object.is`で比較)、テーブルはデータを再処理します。コアデータモデルに依存する他のデータ処理(グループ化、ソート、フィルタリングなど)も再処理されます。 + +> 🧠 テーブルに再処理させたい場合にのみ`data`オプションを変更するようにしてください。インラインの`[]`を指定したり、テーブルをレンダリングするたびに新しいデータ配列を構築すると、不要な再処理が大量に発生します。小規模なテーブルでは気付きにくいかもしれませんが、大規模なテーブルでは明らかになるでしょう。 + +### `columns` + +```tsx +type columns = ColumnDef[] +``` + +テーブルで使用するカラム定義の配列。カラム定義の作成方法については[カラム定義ガイド](../../docs/guide/column-defs)を参照してください。 + +### `defaultColumn` + +```tsx +defaultColumn?: Partial> +``` + +テーブルに渡されるすべてのカラム定義で使用するデフォルトのカラムオプション。デフォルトのセル/ヘッダー/フッターレンダラー、ソート/フィルタリング/グループ化オプションなどを提供するのに便利です。`options.columns`に渡されるすべてのカラム定義は、このデフォルトカラム定義とマージされて最終的なカラム定義が生成されます。 + +### `initialState` + +```tsx +initialState?: Partial< + VisibilityTableState & + ColumnOrderTableState & + ColumnPinningTableState & + FiltersTableState & + SortingTableState & + ExpandedTableState & + GroupingTableState & + ColumnSizingTableState & + PaginationTableState & + RowSelectionTableState +> +``` + +このオプションを使用して、テーブルに初期状態をオプションで渡します。この状態は、テーブルによって自動的に(例: `options.autoResetPageIndex`)または`table.resetRowSelection()`などの関数によってさまざまなテーブル状態をリセットする際に使用されます。ほとんどのリセット関数では、初期状態ではなく空白/デフォルト状態にリセットするためのフラグをオプションで渡すことができます。 + +> 🧠 このオブジェクトが変更されてもテーブル状態はリセットされません。つまり、初期状態オブジェクトは安定している必要はありません。 + +### `autoResetAll` + +```tsx +autoResetAll?: boolean +``` + +このオプションを設定すると、すべての`autoReset...`機能オプションを上書きします。 + +### `meta` + +```tsx +meta?: TableMeta // このインターフェースは宣言マージで拡張可能です。下記を参照! +``` + +任意のオブジェクトを`options.meta`に渡すことができ、`table.options.meta`を通じて`table`が利用可能な場所であればどこからでもアクセスできます。この型はすべてのテーブルでグローバルであり、次のように拡張できます: + +```tsx +declare module '@tanstack/table-core' { + interface TableMeta { + foo: string + } +} +``` + +> 🧠 このオプションは、テーブルの任意の「コンテキスト」として考えてください。これは、テーブルが触れるすべてのものに渡すことなく、任意のデータや関数をテーブルに渡す優れた方法です。良い例は、日付、数値などのフォーマットに使用するロケールオブジェクトをテーブルに渡したり、[編集可能データの例](../framework/react/examples/editable-data)のように編集可能なデータを更新するために使用できる関数を渡すことです。 + +### `state` + +```tsx +state?: Partial< + VisibilityTableState & + ColumnOrderTableState & + ColumnPinningTableState & + FiltersTableState & + SortingTableState & + ExpandedTableState & + GroupingTableState & + ColumnSizingTableState & + PaginationTableState & + RowSelectionTableState +> +``` + +`state`オプションは、テーブル状態の一部または全部をオプションで**制御**するために使用できます。ここに渡す状態は、内部で自動管理されている状態とマージされ、上書きされてテーブルの最終的な状態が生成されます。また、`onStateChange`オプションを通じて状態の変更を監視することもできます。 + +### `onStateChange` + +```tsx +onStateChange: (updater: Updater) => void +``` + +`onStateChange`オプションは、テーブル内の状態変更をオプションで監視するために使用できます。このオプションを提供する場合、テーブル状態の制御と更新は自分で行う必要があります。`state`オプションを使用して状態をテーブルに戻すことができます。 + +### `debugAll` + +> ⚠️ デバッグは開発モードでのみ利用可能です。 + +```tsx +debugAll?: boolean +``` + +このオプションをtrueに設定すると、すべてのデバッグ情報がコンソールに出力されます。 + +### `debugTable` + +> ⚠️ デバッグは開発モードでのみ利用可能です。 + +```tsx +debugTable?: boolean +``` + +このオプションをtrueに設定すると、テーブルのデバッグ情報がコンソールに出力されます。 + +### `debugHeaders` + +> ⚠️ デバッグは開発モードでのみ利用可能です。 + +```tsx +debugHeaders?: boolean +``` + +このオプションをtrueに設定すると、ヘッダーのデバッグ情報がコンソールに出力されます。 + +### `debugColumns` + +> ⚠️ デバッグは開発モードでのみ利用可能です。 + +```tsx +debugColumns?: boolean +``` + +このオプションをtrueに設定すると、カラムのデバッグ情報がコンソールに出力されます。 + +### `debugRows` + +> ⚠️ デバッグは開発モードでのみ利用可能です。 + +```tsx +debugRows?: boolean +``` + +このオプションをtrueに設定すると、行のデバッグ情報がコンソールに出力されます。 + +### `_features` + +```tsx +_features?: TableFeature[] +``` + +テーブルインスタンスに追加できる追加機能の配列。 + +### `render` + +> ⚠️ このオプションはテーブルアダプターを実装する場合にのみ必要です。 + +```tsx +type render = (template: Renderable, props: TProps) => any +``` + +`render`オプションは、テーブルにレンダラー実装を提供します。この実装は、テーブルのさまざまなカラムヘッダーとセルのテンプレートを、ユーザーのフレームワークでサポートされている結果に変換するために使用されます。 + +### `mergeOptions` + +> ⚠️ このオプションはテーブルアダプターを実装する場合にのみ必要です。 + +```tsx +type mergeOptions = (defaultOptions: T, options: Partial) => T +``` + +このオプションは、テーブルオプションのマージをオプションで実装するために使用されます。solid-jsなどの一部のフレームワークは、リアクティビティと使用状況を追跡するためにプロキシを使用するため、リアクティブオブジェクトのマージは慎重に処理する必要があります。このオプションは、このプロセスの制御をアダプターに逆転させます。 + +### `getCoreRowModel` + +```tsx +getCoreRowModel: (table: Table) => () => RowModel +``` + +この必須オプションは、テーブルのコア行モデルを計算して返す関数のファクトリです。テーブルごとに**1回**呼び出され、テーブルの行モデルを計算して返す**新しい関数**を返す必要があります。 + +デフォルトの実装は、任意のテーブルアダプターの`{ getCoreRowModel }`エクスポートを通じて提供されます。 + +### `getSubRows` + +```tsx +getSubRows?: ( + originalRow: TData, + index: number +) => undefined | TData[] +``` + +このオプションの関数は、任意の行のサブ行にアクセスするために使用されます。ネストされた行を使用している場合、この関数を使用して行からサブ行オブジェクト(またはundefined)を返す必要があります。 + +### `getRowId` + +```tsx +getRowId?: ( + originalRow: TData, + index: number, + parent?: Row +) => string +``` + +このオプションの関数は、任意の行の一意のIDを導出するために使用されます。提供されない場合、行のインデックスが使用されます(ネストされた行は、祖父母のインデックスと`.`で結合されます。例: `index.index.index`)。サーバー側の操作から発生する個々の行を識別する必要がある場合は、ネットワークIO/あいまいさに関係なく意味のあるID(userId、taskId、データベースIDフィールドなど)を返すためにこの関数を使用することをお勧めします。 + +## テーブルAPI + +これらのプロパティとメソッドはテーブルオブジェクトで利用できます: + +### `initialState` + +```tsx +initialState: VisibilityTableState & + ColumnOrderTableState & + ColumnPinningTableState & + FiltersTableState & + SortingTableState & + ExpandedTableState & + GroupingTableState & + ColumnSizingTableState & + PaginationTableState & + RowSelectionTableState +``` + +これはテーブルの解決された初期状態です。 + +### `reset` + +```tsx +reset: () => void +``` + +この関数を呼び出すと、テーブル状態が初期状態にリセットされます。 + +### `getState` + +```tsx +getState: () => TableState +``` + +この関数を呼び出すと、テーブルの現在の状態を取得できます。特にテーブル状態を手動で管理する場合、この関数とその状態を使用することをお勧めします。これは、テーブルが提供するすべての機能と関数で内部で使用されている状態とまったく同じです。 + +> 🧠 この関数によって返される状態は、自動管理される内部テーブル状態と`options.state`を介して手動で管理される状態の浅いマージ結果です。 + +### `setState` + +```tsx +setState: (updater: Updater) => void +``` + +この関数を呼び出すと、テーブル状態を更新できます。状態を更新するために`(prevState) => newState`の形式のアップデータ関数を渡すことをお勧めしますが、直接オブジェクトを渡すこともできます。 + +> 🧠 `options.onStateChange`が提供されている場合、この関数によって新しい状態でトリガーされます。 + +### `options` + +```tsx +options: TableOptions +``` + +テーブルの現在のオプションへの読み取り専用参照。 + +> ⚠️ このプロパティは一般的に内部またはアダプターによって使用されます。新しいオプションをテーブルに渡すことで更新できます。これはアダプターごとに異なります。アダプター自体の場合、テーブルオプションは`setOptions`関数を介して更新する必要があります。 + +### `setOptions` + +```tsx +setOptions: (newOptions: Updater>) => void +``` + +> ⚠️ この関数は一般的にアダプターがテーブルオプションを更新するために使用されます。テーブルオプションを直接更新するために使用できますが、テーブルオプションを更新するためのアダプターの戦略をバイパスすることは一般的に推奨されません。 + +### `getCoreRowModel` + +```tsx +getCoreRowModel: () => { + rows: Row[], + flatRows: Row[], + rowsById: Record>, +} +``` + +処理が適用される前のコア行モデルを返します。 + +### `getRowModel` + +```tsx +getRowModel: () => { + rows: Row[], + flatRows: Row[], + rowsById: Record>, +} +``` + +他の使用された機能からのすべての処理が適用された後の最終モデルを返します。 + +### `getAllColumns` + +```tsx +type getAllColumns = () => Column[] +``` + +テーブルに渡されたカラム定義からミラーリングされた、正規化されネストされた階層内のすべてのカラムを返します。 + +### `getAllFlatColumns` + +```tsx +type getAllFlatColumns = () => Column[] +``` + +階層全体の親カラムオブジェクトを含む、単一レベルに平坦化されたテーブル内のすべてのカラムを返します。 + +### `getAllLeafColumns` + +```tsx +type getAllLeafColumns = () => Column[] +``` + +親カラムを含まない、単一レベルに平坦化されたテーブル内のすべてのリーフノードカラムを返します。 + +### `getColumn` + +```tsx +type getColumn = (id: string) => Column | undefined +``` + +IDで単一のカラムを返します。 + +### `getHeaderGroups` + +```tsx +type getHeaderGroups = () => HeaderGroup[] +``` + +テーブルのヘッダーグループを返します。 + +### `getFooterGroups` + +```tsx +type getFooterGroups = () => HeaderGroup[] +``` + +テーブルのフッターグループを返します。 + +### `getFlatHeaders` + +```tsx +type getFlatHeaders = () => Header[] +``` + +親ヘッダーを含む、テーブルのHeaderオブジェクトの平坦化された配列を返します。 + +### `getLeafHeaders` + +```tsx +type getLeafHeaders = () => Header[] +``` + +テーブルのリーフノードHeaderオブジェクトの平坦化された配列を返します。 +``` diff --git a/docs/ja/api/features/column-faceting.md b/docs/ja/api/features/column-faceting.md new file mode 100644 index 0000000000..fef4f03f55 --- /dev/null +++ b/docs/ja/api/features/column-faceting.md @@ -0,0 +1,47 @@ +--- +source-updated-at: '2024-03-27T23:32:27.000Z' +translation-updated-at: '2025-05-05T19:28:23.588Z' +title: カラムファセット +id: column-faceting +--- +## カラム API (Column API) + +### `getFacetedRowModel` + +```tsx +type getFacetedRowModel = () => RowModel +``` + +> ⚠️ `options.facetedRowModel` に有効な `getFacetedRowModel` 関数を渡す必要があります。デフォルト実装はエクスポートされた `getFacetedRowModel` 関数で提供されます。 + +自身のフィルターを除く、他のすべてのカラムフィルターが適用された行モデル (Row Model) を返します。ファセットされた結果カウントを表示するのに便利です。 + +### `getFacetedUniqueValues` + +```tsx +getFacetedUniqueValues: () => Map +``` + +> ⚠️ `options.getFacetedUniqueValues` に有効な `getFacetedUniqueValues` 関数を渡す必要があります。デフォルト実装はエクスポートされた `getFacetedUniqueValues` 関数で提供されます。 + +`column.getFacetedRowModel` から導出されたユニークな値とその出現回数の `Map` を**計算して返す**関数です。ファセットされた結果値を表示するのに便利です。 + +### `getFacetedMinMaxValues` + +```tsx +getFacetedMinMaxValues: () => Map +``` + +> ⚠️ `options.getFacetedMinMaxValues` に有効な `getFacetedMinMaxValues` 関数を渡す必要があります。デフォルト実装はエクスポートされた `getFacetedMinMaxValues` 関数で提供されます。 + +`column.getFacetedRowModel` から導出された最小値/最大値のタプルを**計算して返す**関数です。ファセットされた結果値を表示するのに便利です。 + +## テーブルオプション (Table Options) + +### `getColumnFacetedRowModel` + +```tsx +getColumnFacetedRowModel: (columnId: string) => RowModel +``` + +指定された columnId のファセットされた行モデル (Row Model) を返します。 diff --git a/docs/ja/api/features/column-filtering.md b/docs/ja/api/features/column-filtering.md new file mode 100644 index 0000000000..9e1ecdf06a --- /dev/null +++ b/docs/ja/api/features/column-filtering.md @@ -0,0 +1,401 @@ +--- +source-updated-at: '2024-03-27T23:32:27.000Z' +translation-updated-at: '2025-05-05T19:29:52.520Z' +title: カラムフィルタリング +id: column-filtering +--- +## カラムフィルタリングAPI + +TanStack Tableのコアは**フレームワーク非依存**であり、使用するフレームワークに関係なくAPIは同じです。各フレームワーク向けのアダプターが提供されており、テーブルコアを簡単に操作できます。利用可能なアダプターについては、Adaptersメニューを参照してください。 + +## Can-Filter + +カラムが**カラム**フィルタリング可能かどうかは、以下によって決定されます: + +- カラムが有効な`accessorKey`/`accessorFn`で定義されている +- `column.enableColumnFilter`が`false`に設定されていない +- `options.enableColumnFilters`が`false`に設定されていない +- `options.enableFilters`が`false`に設定されていない + +## ステート + +フィルタリングの状態は、以下の形式でテーブルに保存されます: + +```tsx +export interface ColumnFiltersTableState { + columnFilters: ColumnFiltersState +} + +export type ColumnFiltersState = ColumnFilter[] + +export interface ColumnFilter { + id: string + value: unknown +} +``` + +## フィルタ関数 + +以下のフィルタ関数がテーブルコアに組み込まれています: + +- `includesString` + - 大文字小文字を区別しない文字列包含 +- `includesStringSensitive` + - 大文字小文字を区別する文字列包含 +- `equalsString` + - 大文字小文字を区別しない文字列一致 +- `equalsStringSensitive` + - 大文字小文字を区別する文字列一致 +- `arrIncludes` + - 配列内のアイテム包含 +- `arrIncludesAll` + - 配列内の全アイテム包含 +- `arrIncludesSome` + - 配列内の一部アイテム包含 +- `equals` + - オブジェクト/参照一致 `Object.is`/`===` +- `weakEquals` + - 弱いオブジェクト/参照一致 `==` +- `inNumberRange` + - 数値範囲包含 + +各フィルタ関数は以下を受け取ります: + +- フィルタリングする行 +- 行の値を取得するためのcolumnId +- フィルタ値 + +そして、行がフィルタリングされた行に含まれるべき場合は`true`を、削除されるべき場合は`false`を返します。 + +これが各フィルタ関数の型シグネチャです: + +```tsx +export type FilterFn = { + ( + row: Row, + columnId: string, + filterValue: any, + addMeta: (meta: any) => void + ): boolean + resolveFilterValue?: TransformFilterValueFn + autoRemove?: ColumnFilterAutoRemoveTestFn + addMeta?: (meta?: any) => void +} + +export type TransformFilterValueFn = ( + value: any, + column?: Column +) => unknown + +export type ColumnFilterAutoRemoveTestFn = ( + value: any, + column?: Column +) => boolean + +export type CustomFilterFns = Record< + string, + FilterFn +> +``` + +### `filterFn.resolveFilterValue` + +任意の`filterFn`に設定可能なこの「ハンギング」メソッドは、フィルタ関数に渡される前にフィルタ値を変換/サニタイズ/フォーマットできます。 + +### `filterFn.autoRemove` + +任意の`filterFn`に設定可能なこの「ハンギング」メソッドは、フィルタ値を受け取り、そのフィルタ値をフィルタ状態から削除すべきかどうかを`true`/`false`で返します。例えば、一部のブール型フィルタでは、フィルタ値が`false`に設定されている場合にフィルタ値をテーブル状態から削除したい場合があります。 + +#### フィルタ関数の使用 + +フィルタ関数は、以下を`columnDefinition.filterFn`に渡すことで使用/参照/定義できます: + +- 組み込みフィルタ関数を参照する`文字列` +- `columnDefinition.filterFn`オプションに直接提供される関数 + +`columnDef.filterFn`オプションで利用可能な最終的なフィルタ関数のリストは、以下の型を使用します: + +```tsx +export type FilterFnOption = + | 'auto' + | BuiltInFilterFn + | FilterFn +``` + +#### フィルタメタ + +データのフィルタリングは、しばしばデータに関する追加情報を明らかにし、同じデータに対する将来の操作を支援するために使用できます。この概念の良い例は、[`match-sorter`](https://github.com/kentcdodds/match-sorter)のようなランキングシステムで、データのランク付け、フィルタリング、並べ替えを同時に行います。`match-sorter`のようなユーティリティは、単一次元のフィルタ+ソートタスクには非常に理にかなっていますが、テーブルを構築する際の分離されたフィルタリング/ソートアーキテクチャでは、それらを使用することが非常に難しく、遅くなります。 + +ランキング/フィルタリング/ソートシステムをテーブルで機能させるために、`filterFn`はオプションで結果に**フィルタメタ**値をマークでき、これは後でデータを好きなようにソート/グループ化するために使用できます。これは、カスタム`filterFn`に提供される`addMeta`関数を呼び出すことで行われます。 + +以下は、`match-sorter-utils`パッケージ(`match-sorter`のユーティリティフォーク)を使用してデータのランク付け、フィルタリング、並べ替えを行う例です: + +```tsx +import { sortingFns } from '@tanstack/react-table' + +import { rankItem, compareItems } from '@tanstack/match-sorter-utils' + +const fuzzyFilter = (row, columnId, value, addMeta) => { + // アイテムのランク付け + const itemRank = rankItem(row.getValue(columnId), value) + + // ランキング情報を保存 + addMeta(itemRank) + + // アイテムがフィルタリングされるべきかどうかを返す + return itemRank.passed +} + +const fuzzySort = (rowA, rowB, columnId) => { + let dir = 0 + + // カラムにランキング情報がある場合のみランクでソート + if (rowA.columnFiltersMeta[columnId]) { + dir = compareItems( + rowA.columnFiltersMeta[columnId]!, + rowB.columnFiltersMeta[columnId]! + ) + } + + // アイテムランクが等しい場合の英数字フォールバックを提供 + return dir === 0 ? sortingFns.alphanumeric(rowA, rowB, columnId) : dir +} +``` + +## カラム定義オプション + +### `filterFn` + +```tsx +filterFn?: FilterFn | keyof FilterFns | keyof BuiltInFilterFns +``` + +このカラムで使用するフィルタ関数。 + +オプション: + +- [組み込みフィルタ関数](#filter-functions)を参照する`文字列` +- [カスタムフィルタ関数](#filter-functions) + +### `enableColumnFilter` + +```tsx +enableColumnFilter?: boolean +``` + +このカラムの**カラム**フィルタを有効/無効にします。 + +## カラムAPI + +### `getCanFilter` + +```tsx +getCanFilter: () => boolean +``` + +カラムが**カラム**フィルタ可能かどうかを返します。 + +### `getFilterIndex` + +```tsx +getFilterIndex: () => number +``` + +テーブルの`state.columnFilters`配列におけるカラムフィルタのインデックス(`-1`を含む)を返します。 + +### `getIsFiltered` + +```tsx +getIsFiltered: () => boolean +``` + +カラムが現在フィルタされているかどうかを返します。 + +### `getFilterValue` + +```tsx +getFilterValue: () => unknown +``` + +カラムの現在のフィルタ値を返します。 + +### `setFilterValue` + +```tsx +setFilterValue: (updater: Updater) => void +``` + +カラムの現在のフィルタ値を設定する関数。値または既存の値に対して不変性を保った操作を行うアップデーター関数を渡せます。 + +### `getAutoFilterFn` + +```tsx +getAutoFilterFn: (columnId: string) => FilterFn | undefined +``` + +カラムの最初の既知の値に基づいて自動計算されたフィルタ関数を返します。 + +### `getFilterFn` + +```tsx +getFilterFn: (columnId: string) => FilterFn | undefined +``` + +指定されたcolumnIdのフィルタ関数(ユーザー定義または自動、設定に応じて)を返します。 + +## 行API + +### `columnFilters` + +```tsx +columnFilters: Record +``` + +行のカラムフィルタマップ。このオブジェクトは、行が特定のフィルタを通過/失敗しているかをcolumn IDで追跡します。 + +### `columnFiltersMeta` + +```tsx +columnFiltersMeta: Record +``` + +行のカラムフィルタメタマップ。このオブジェクトは、フィルタリングプロセス中にオプションで提供される行のフィルタメタを追跡します。 + +## テーブルオプション + +### `filterFns` + +```tsx +filterFns?: Record +``` + +このオプションにより、カラムの`filterFn`オプションでキーによって参照できるカスタムフィルタ関数を定義できます。 +例: + +```tsx +declare module '@tanstack/[adapter]-table' { + interface FilterFns { + myCustomFilter: FilterFn + } +} + +const column = columnHelper.data('key', { + filterFn: 'myCustomFilter', +}) + +const table = useReactTable({ + columns: [column], + filterFns: { + myCustomFilter: (rows, columnIds, filterValue) => { + // フィルタリングされた行を返す + }, + }, +}) +``` + +### `filterFromLeafRows` + +```tsx +filterFromLeafRows?: boolean +``` + +デフォルトでは、フィルタリングは親行から下に向かって行われます(親行がフィルタリングされると、そのすべての子行もフィルタリングされます)。このオプションを`true`に設定すると、フィルタリングはリーフ行から上に向かって行われます(つまり、親行は、その子または孫行のいずれかが含まれている限り含まれます)。 + +### `maxLeafRowFilterDepth` + +```tsx +maxLeafRowFilterDepth?: number +``` + +デフォルトでは、フィルタリングはすべての行(最大深度100)に対して行われ、それらがルートレベルの親行であるか親行の子リーフ行であるかに関係ありません。このオプションを`0`に設定すると、フィルタリングはルートレベルの親行にのみ適用され、すべてのサブ行はフィルタリングされません。同様に、このオプションを`1`に設定すると、フィルタリングは1レベルの深さの子リーフ行にのみ適用されます。 + +これは、適用されたフィルタに関係なく行の子階層全体を表示したい場合に便利です。 + +### `enableFilters` + +```tsx +enableFilters?: boolean +``` + +テーブルのすべてのフィルタを有効/無効にします。 + +### `manualFiltering` + +```tsx +manualFiltering?: boolean +``` + +`getFilteredRowModel`を使用してデータをフィルタリングすることを無効にします。これは、テーブルがクライアントサイドとサーバーサイドのフィルタリングを動的にサポートする必要がある場合に役立ちます。 + +### `onColumnFiltersChange` + +```tsx +onColumnFiltersChange?: OnChangeFn +``` + +提供された場合、この関数は`state.columnFilters`が変更されたときに`updaterFn`とともに呼び出されます。これはデフォルトの内部状態管理をオーバーライドするため、状態変更を完全または部分的にテーブルの外部で永続化する必要があります。 + +### `enableColumnFilters` + +```tsx +enableColumnFilters?: boolean +``` + +テーブルの**すべての**カラムフィルタを有効/無効にします。 + +### `getFilteredRowModel` + +```tsx +getFilteredRowModel?: ( + table: Table +) => () => RowModel +``` + +提供された場合、この関数はテーブルごとに**1回**呼び出され、テーブルがフィルタリングされたときに計算して行モデルを返す**新しい関数**を返す必要があります。 + +- サーバーサイドフィルタリングの場合、この関数は不要であり、サーバーがすでにフィルタリングされた行モデルを返すため無視できます。 +- クライアントサイドフィルタリングの場合、この関数は必須です。デフォルトの実装は、任意のテーブルアダプターの`{ getFilteredRowModel }`エクスポートを介して提供されます。 + +例: + +```tsx +import { getFilteredRowModel } from '@tanstack/[adapter]-table' + + + getFilteredRowModel: getFilteredRowModel(), +}) +``` + +## テーブルAPI + +### `setColumnFilters` + +```tsx +setColumnFilters: (updater: Updater) => void +``` + +`state.columnFilters`状態を設定または更新します。 + +### `resetColumnFilters` + +```tsx +resetColumnFilters: (defaultState?: boolean) => void +``` + +**columnFilters**状態を`initialState.columnFilters`にリセットします。`true`を渡すと、デフォルトの空白状態`[]`に強制的にリセットされます。 + +### `getPreFilteredRowModel` + +```tsx +getPreFilteredRowModel: () => RowModel +``` + +**カラム**フィルタリングが適用される前のテーブルの行モデルを返します。 + +### `getFilteredRowModel` + +```tsx +getFilteredRowModel: () => RowModel +``` + +**カラム**フィルタリングが適用された後のテーブルの行モデルを返します。 diff --git a/docs/ja/api/features/column-ordering.md b/docs/ja/api/features/column-ordering.md new file mode 100644 index 0000000000..89d00e258d --- /dev/null +++ b/docs/ja/api/features/column-ordering.md @@ -0,0 +1,71 @@ +--- +source-updated-at: '2024-02-18T00:06:36.000Z' +translation-updated-at: '2025-05-05T19:28:37.175Z' +title: カラム順序 +id: column-ordering +--- +## ステート (State) + +カラムの並び順 (column ordering) ステートは、以下の形式でテーブルに保存されます: + +```tsx +export type ColumnOrderTableState = { + columnOrder: ColumnOrderState +} + +export type ColumnOrderState = string[] +``` + +## テーブルオプション (Table Options) + +### `onColumnOrderChange` + +```tsx +onColumnOrderChange?: OnChangeFn +``` + +この関数が提供されると、`state.columnOrder` が変更された際に `updaterFn` と共に呼び出されます。これはデフォルトの内部ステート管理を上書きするため、テーブルの外部でステート変更を完全または部分的に永続化する必要があります。 + +## テーブルAPI (Table API) + +### `setColumnOrder` + +```tsx +setColumnOrder: (updater: Updater) => void +``` + +`state.columnOrder` ステートを設定または更新します。 + +### `resetColumnOrder` + +```tsx +resetColumnOrder: (defaultState?: boolean) => void +``` + +**columnOrder** ステートを `initialState.columnOrder` にリセットします。`true` を渡すと、デフォルトの空のステート `[]` に強制的にリセットされます。 + +## カラムAPI (Column API) + +### `getIndex` + +```tsx +getIndex: (position?: ColumnPinningPosition) => number +``` + +表示されているカラムの順序におけるカラムのインデックスを返します。オプションで `position` パラメータを渡すと、テーブルの特定のセクションにおけるカラムのインデックスを取得できます。 + +### `getIsFirstColumn` + +```tsx +getIsFirstColumn: (position?: ColumnPinningPosition) => boolean +``` + +カラムが表示順で最初のカラムであれば `true` を返します。オプションで `position` パラメータを渡すと、テーブルの特定のセクションで最初のカラムかどうかをチェックできます。 + +### `getIsLastColumn` + +```tsx +getIsLastColumn: (position?: ColumnPinningPosition) => boolean +``` + +カラムが表示順で最後のカラムであれば `true` を返します。オプションで `position` パラメータを渡すと、テーブルの特定のセクションで最後のカラムかどうかをチェックできます。 diff --git a/docs/ja/api/features/column-pinning.md b/docs/ja/api/features/column-pinning.md new file mode 100644 index 0000000000..2c26c2ff57 --- /dev/null +++ b/docs/ja/api/features/column-pinning.md @@ -0,0 +1,267 @@ +--- +source-updated-at: '2024-03-10T17:31:15.000Z' +translation-updated-at: '2025-05-05T19:29:16.704Z' +title: カラム固定 +id: column-pinning +--- +## ピン留め可能 (Can-Pin) + +列が**ピン留め (pinned)** 可能かどうかは、以下の条件で決まります: + +- `options.enablePinning` が `false` に設定されていない +- `options.enableColumnPinning` が `false` に設定されていない +- `columnDefinition.enablePinning` が `false` に設定されていない + +## 状態管理 (State) + +ピン留めの状態はテーブル上で以下の形式で保持されます: + +```tsx +export type ColumnPinningPosition = false | 'left' | 'right' + +export type ColumnPinningState = { + left?: string[] + right?: string[] +} + + +export type ColumnPinningTableState = { + columnPinning: ColumnPinningState +} +``` + +## テーブルオプション (Table Options) + +### `enableColumnPinning` + +```tsx +enableColumnPinning?: boolean +``` + +テーブル内のすべての列に対してピン留めを有効/無効にします。 + +### `onColumnPinningChange` + +```tsx +onColumnPinningChange?: OnChangeFn +``` + +提供された場合、`state.columnPinning` が変更されると `updaterFn` と共にこの関数が呼び出されます。これによりデフォルトの内部状態管理が上書きされるため、自身で管理する状態から `state.columnPinning` を提供する必要があります。 + +## 列定義オプション (Column Def Options) + +### `enablePinning` + +```tsx +enablePinning?: boolean +``` + +列のピン留めを有効/無効にします。 + +## テーブルAPI (Table API) + +### `setColumnPinning` + +```tsx +setColumnPinning: (updater: Updater) => void +``` + +`state.columnPinning` の状態を設定または更新します。 + +### `resetColumnPinning` + +```tsx +resetColumnPinning: (defaultState?: boolean) => void +``` + +**columnPinning** の状態を `initialState.columnPinning` にリセットします。`true` を渡すとデフォルトの空状態 `{ left: [], right: [], }` に強制リセットされます。 + +### `getIsSomeColumnsPinned` + +```tsx +getIsSomeColumnsPinned: (position?: ColumnPinningPosition) => boolean +``` + +いずれかの列がピン留めされているかどうかを返します。オプションで `left` または `right` の位置にあるピン留め列のみをチェックできます。 + +_注: 列の可視性は考慮されません_ + +### `getLeftHeaderGroups` + +```tsx +getLeftHeaderGroups: () => HeaderGroup[] +``` + +テーブルの左側にピン留めされたヘッダーグループを返します。 + +### `getCenterHeaderGroups` + +```tsx +getCenterHeaderGroups: () => HeaderGroup[] +``` + +ピン留めされていない/中央のヘッダーグループを返します。 + +### `getRightHeaderGroups` + +```tsx +getRightHeaderGroups: () => HeaderGroup[] +``` + +テーブルの右側にピン留めされたヘッダーグループを返します。 + +### `getLeftFooterGroups` + +```tsx +getLeftFooterGroups: () => HeaderGroup[] +``` + +テーブルの左側にピン留めされたフッターグループを返します。 + +### `getCenterFooterGroups` + +```tsx +getCenterFooterGroups: () => HeaderGroup[] +``` + +ピン留めされていない/中央のフッターグループを返します。 + +### `getRightFooterGroups` + +```tsx +getRightFooterGroups: () => HeaderGroup[] +``` + +テーブルの右側にピン留めされたフッターグループを返します。 + +### `getLeftFlatHeaders` + +```tsx +getLeftFlatHeaders: () => Header[] +``` + +親ヘッダーを含む、左側にピン留めされたヘッダーのフラット配列を返します。 + +### `getCenterFlatHeaders` + +```tsx +getCenterFlatHeaders: () => Header[] +``` + +親ヘッダーを含む、ピン留めされていない/中央のヘッダーのフラット配列を返します。 + +### `getRightFlatHeaders` + +```tsx +getRightFlatHeaders: () => Header[] +``` + +親ヘッダーを含む、右側にピン留めされたヘッダーのフラット配列を返します。 + +### `getLeftLeafHeaders` + +```tsx +getLeftLeafHeaders: () => Header[] +``` + +左側にピン留めされたリーフノードヘッダーのフラット配列を返します。 + +### `getCenterLeafHeaders` + +```tsx +getCenterLeafHeaders: () => Header[] +``` + +ピン留めされていない/中央のリーフノードヘッダーのフラット配列を返します。 + +### `getRightLeafHeaders` + +```tsx +getRightLeafHeaders: () => Header[] +``` + +右側にピン留めされたリーフノードヘッダーのフラット配列を返します。 + +### `getLeftLeafColumns` + +```tsx +getLeftLeafColumns: () => Column[] +``` + +左側にピン留めされたすべてのリーフ列を返します。 + +### `getRightLeafColumns` + +```tsx +getRightLeafColumns: () => Column[] +``` + +右側にピン留めされたすべてのリーフ列を返します。 + +### `getCenterLeafColumns` + +```tsx +getCenterLeafColumns: () => Column[] +``` + +中央(ピン留めされていない)のすべてのリーフ列を返します。 + +## 列API (Column API) + +### `getCanPin` + +```tsx +getCanPin: () => boolean +``` + +列がピン留め可能かどうかを返します。 + +### `getPinnedIndex` + +```tsx +getPinnedIndex: () => number +``` + +ピン留め列グループ内での列の数値インデックスを返します。 + +### `getIsPinned` + +```tsx +getIsPinned: () => ColumnPinningPosition +``` + +列のピン留め位置を返します (`'left'`, `'right'` または `false`)。 + +### `pin` + +```tsx +pin: (position: ColumnPinningPosition) => void +``` + +列を `'left'` または `'right'` にピン留めします。`false` を渡すと中央に配置(ピン留め解除)されます。 + +## 行API (Row API) + +### `getLeftVisibleCells` + +```tsx +getLeftVisibleCells: () => Cell[] +``` + +行内の左側にピン留めされたすべてのリーフセルを返します。 + +### `getRightVisibleCells` + +```tsx +getRightVisibleCells: () => Cell[] +``` + +行内の右側にピン留めされたすべてのリーフセルを返します。 + +### `getCenterVisibleCells` + +```tsx +getCenterVisibleCells: () => Cell[] +``` + +行内の中央(ピン留めされていない)のすべてのリーフセルを返します。 diff --git a/docs/ja/api/features/column-visibility.md b/docs/ja/api/features/column-visibility.md new file mode 100644 index 0000000000..6aa8719424 --- /dev/null +++ b/docs/ja/api/features/column-visibility.md @@ -0,0 +1,179 @@ +--- +source-updated-at: '2024-02-18T00:06:36.000Z' +translation-updated-at: '2025-05-05T19:29:02.756Z' +title: カラム表示/非表示 +id: column-visibility +--- +## 状態 (State) + +カラムの可視性 (visibility) 状態は、以下の形式でテーブルに保存されます: + +```tsx +export type VisibilityState = Record + +export type VisibilityTableState = { + columnVisibility: VisibilityState +} +``` + +## カラム定義 (Column Def) オプション + +### `enableHiding` + +```tsx +enableHiding?: boolean +``` + +カラムの非表示を有効/無効にします + +## カラム API + +### `getCanHide` + +```tsx +getCanHide: () => boolean +``` + +カラムが非表示にできるかどうかを返します + +### `getIsVisible` + +```tsx +getIsVisible: () => boolean +``` + +カラムが表示されているかどうかを返します + +### `toggleVisibility` + +```tsx +toggleVisibility: (value?: boolean) => void +``` + +カラムの可視性をトグルします + +### `getToggleVisibilityHandler` + +```tsx +getToggleVisibilityHandler: () => (event: unknown) => void +``` + +カラムの可視性をトグルする関数を返します。この関数はチェックボックスのイベントハンドラにバインドするために使用できます。 + +## テーブルオプション + +### `onColumnVisibilityChange` + +```tsx +onColumnVisibilityChange?: OnChangeFn +``` + +提供された場合、`state.columnVisibility` が変更されるとこの関数が `updaterFn` と共に呼び出されます。これはデフォルトの内部状態管理を上書きするため、テーブルの外部で状態変更を完全または部分的に永続化する必要があります。 + +### `enableHiding` + +```tsx +enableHiding?: boolean +``` + +カラムの非表示を有効/無効にします。 + +## テーブル API + +### `getVisibleFlatColumns` + +```tsx +getVisibleFlatColumns: () => Column[] +``` + +表示されているカラムのフラットな配列を返します(親カラムを含む)。 + +### `getVisibleLeafColumns` + +```tsx +getVisibleLeafColumns: () => Column[] +``` + +表示されているリーフノードカラムのフラットな配列を返します。 + +### `getLeftVisibleLeafColumns` + +```tsx +getLeftVisibleLeafColumns: () => Column[] +``` + +カラムピニング (pinning) が有効な場合、テーブルの左側に表示されているリーフノードカラムのフラットな配列を返します。 + +### `getRightVisibleLeafColumns` + +```tsx +getRightVisibleLeafColumns: () => Column[] +``` + +カラムピニングが有効な場合、テーブルの右側に表示されているリーフノードカラムのフラットな配列を返します。 + +### `getCenterVisibleLeafColumns` + +```tsx +getCenterVisibleLeafColumns: () => Column[] +``` + +カラムピニングが有効な場合、テーブルのピンされていない中央部分に表示されているリーフノードカラムのフラットな配列を返します。 + +### `setColumnVisibility` + +```tsx +setColumnVisibility: (updater: Updater) => void +``` + +アップデータ関数または値を使用してカラムの可視性状態を更新します + +### `resetColumnVisibility` + +```tsx +resetColumnVisibility: (defaultState?: boolean) => void +``` + +カラムの可視性状態を初期状態にリセットします。`defaultState` が提供された場合、状態は `{}` にリセットされます + +### `toggleAllColumnsVisible` + +```tsx +toggleAllColumnsVisible: (value?: boolean) => void +``` + +すべてのカラムの可視性をトグルします + +### `getIsAllColumnsVisible` + +```tsx +getIsAllColumnsVisible: () => boolean +``` + +すべてのカラムが表示されているかどうかを返します + +### `getIsSomeColumnsVisible` + +```tsx +getIsSomeColumnsVisible: () => boolean +``` + +一部のカラムが表示されているかどうかを返します + +### `getToggleAllColumnsVisibilityHandler` + +```tsx +getToggleAllColumnsVisibilityHandler: () => ((event: unknown) => void) +``` + +すべてのカラムの可視性をトグルするハンドラを返します。`input[type=checkbox]` 要素にバインドすることを想定しています。 + +## 行 (Row) API + +### `getVisibleCells` + +```tsx +getVisibleCells: () => Cell[] +``` + +カラムの可視性を考慮した行のセルの配列を返します。 diff --git a/docs/ja/api/features/expanding.md b/docs/ja/api/features/expanding.md new file mode 100644 index 0000000000..242a68defe --- /dev/null +++ b/docs/ja/api/features/expanding.md @@ -0,0 +1,209 @@ +--- +source-updated-at: '2024-02-18T00:06:36.000Z' +translation-updated-at: '2025-05-05T19:29:36.248Z' +title: 展開 +id: expanding +--- +## 状態 (State) + +展開状態 (expanded state) はテーブル上で以下の形式で保存されます: + +```tsx +export type ExpandedState = true | Record + +export type ExpandedTableState = { + expanded: ExpandedState +} +``` + +## 行 API (Row API) + +### `toggleExpanded` + +```tsx +toggleExpanded: (expanded?: boolean) => void +``` + +行の展開状態をトグルします(`expanded` が指定されている場合は設定します)。 + +### `getIsExpanded` + +```tsx +getIsExpanded: () => boolean +``` + +行が展開されているかどうかを返します。 + +### `getIsAllParentsExpanded` + +```tsx +getIsAllParentsExpanded: () => boolean +``` + +行のすべての親行が展開されているかどうかを返します。 + +### `getCanExpand` + +```tsx +getCanExpand: () => boolean +``` + +行を展開できるかどうかを返します。 + +### `getToggleExpandedHandler` + +```tsx +getToggleExpandedHandler: () => () => void +``` + +行の展開状態をトグルする関数を返します。この関数はボタンのイベントハンドラにバインドするために使用できます。 + +## テーブルオプション (Table Options) + +### `manualExpanding` + +```tsx +manualExpanding?: boolean +``` + +手動行展開を有効にします。`true` に設定すると、`getExpandedRowModel` は行の展開に使用されず、独自のデータモデルで展開を実行する必要があります。これはサーバーサイド展開 (server-side expansion) を行う場合に便利です。 + +### `onExpandedChange` + +```tsx +onExpandedChange?: OnChangeFn +``` + +`expanded` テーブル状態が変更されたときに呼び出される関数です。関数が提供されている場合、この状態を自分で管理する必要があります。管理された状態をテーブルに戻すには、`tableOptions.state.expanded` オプションを使用します。 + +### `autoResetExpanded` + +```tsx +autoResetExpanded?: boolean +``` + +展開状態が変更されたときに、テーブルの展開状態を自動的にリセットするには、この設定を有効にします。 + +### `enableExpanding` + +```tsx +enableExpanding?: boolean +``` + +すべての行の展開を有効/無効にします。 + +### `getExpandedRowModel` + +```tsx +getExpandedRowModel?: (table: Table) => () => RowModel +``` + +この関数は展開された行モデルを返す役割を担います。この関数が提供されていない場合、テーブルは行を展開しません。デフォルトでエクスポートされている `getExpandedRowModel` 関数を使用して展開された行モデルを取得するか、独自の実装を提供できます。 + +### `getIsRowExpanded` + +```tsx +getIsRowExpanded?: (row: Row) => boolean +``` + +提供されている場合、行が現在展開されているかどうかを決定するデフォルトの動作をオーバーライドできます。 + +### `getRowCanExpand` + +```tsx +getRowCanExpand?: (row: Row) => boolean +``` + +提供されている場合、行を展開できるかどうかを決定するデフォルトの動作をオーバーライドできます。 + +### `paginateExpandedRows` + +```tsx +paginateExpandedRows?: boolean +``` + +`true` の場合、展開された行はテーブルの他の部分と一緒にページネーションされます(展開された行が複数のページにまたがる可能性があることを意味します)。 + +`false` の場合、展開された行はページネーションの対象外になります(展開された行は常に親行のページにレンダリングされます。これにより、設定されたページサイズよりも多くの行がレンダリングされることも意味します)。 + +## テーブル API (Table API) + +### `setExpanded` + +```tsx +setExpanded: (updater: Updater) => void +``` + +更新関数または値を使用して、テーブルの展開状態を更新します。 + +### `toggleAllRowsExpanded` + +```tsx +toggleAllRowsExpanded: (expanded?: boolean) => void +``` + +すべての行の展開状態をトグルします。オプションで、展開状態を設定する値を指定できます。 + +### `resetExpanded` + +```tsx +resetExpanded: (defaultState?: boolean) => void +``` + +テーブルの展開状態を初期状態にリセットします。`defaultState` が提供されている場合、展開状態は `{}` にリセットされます。 + +### `getCanSomeRowsExpand` + +```tsx +getCanSomeRowsExpand: () => boolean +``` + +展開可能な行があるかどうかを返します。 + +### `getToggleAllRowsExpandedHandler` + +```tsx +getToggleAllRowsExpandedHandler: () => (event: unknown) => void +``` + +すべての行の展開状態をトグルするハンドラを返します。このハンドラは `input[type=checkbox]` 要素で使用することを想定しています。 + +### `getIsSomeRowsExpanded` + +```tsx +getIsSomeRowsExpanded: () => boolean +``` + +現在展開されている行があるかどうかを返します。 + +### `getIsAllRowsExpanded` + +```tsx +getIsAllRowsExpanded: () => boolean +``` + +すべての行が現在展開されているかどうかを返します。 + +### `getExpandedDepth` + +```tsx +getExpandedDepth: () => number +``` + +展開された行の最大深度を返します。 + +### `getExpandedRowModel` + +```tsx +getExpandedRowModel: () => RowModel +``` + +展開が適用された後の行モデルを返します。 + +### `getPreExpandedRowModel` + +```tsx +getPreExpandedRowModel: () => RowModel +``` + +展開が適用される前の行モデルを返します。 diff --git a/docs/ja/api/features/global-faceting.md b/docs/ja/api/features/global-faceting.md new file mode 100644 index 0000000000..03b5cc35f6 --- /dev/null +++ b/docs/ja/api/features/global-faceting.md @@ -0,0 +1,31 @@ +--- +source-updated-at: '2024-03-27T23:32:27.000Z' +translation-updated-at: '2025-05-05T19:28:44.701Z' +title: グローバルファセット +id: global-faceting +--- +## テーブルAPI (Table API) + +### `getGlobalFacetedRowModel` + +```tsx +getGlobalFacetedRowModel: () => RowModel +``` + +グローバルフィルター (global filter) 用のファセットされた行モデル (faceted row model) を返します。 + +### `getGlobalFacetedUniqueValues` + +```tsx +getGlobalFacetedUniqueValues: () => Map +``` + +グローバルフィルター (global filter) 用のファセットされた一意の値 (faceted unique values) を返します。 + +### `getGlobalFacetedMinMaxValues` + +```tsx +getGlobalFacetedMinMaxValues: () => [number, number] +``` + +グローバルフィルター (global filter) 用のファセットされた最小値と最大値 (faceted min and max values) を返します。 diff --git a/docs/ja/api/features/global-filtering.md b/docs/ja/api/features/global-filtering.md new file mode 100644 index 0000000000..d0a16c445a --- /dev/null +++ b/docs/ja/api/features/global-filtering.md @@ -0,0 +1,294 @@ +--- +source-updated-at: '2025-03-20T21:15:29.000Z' +translation-updated-at: '2025-05-05T19:30:17.142Z' +title: グローバルフィルタリング +id: global-filtering +--- +## グローバルフィルタリング (Global Filtering) + +### Can-Filter + +列が**グローバル**にフィルタリング可能かどうかは、以下の条件で決定されます: + +- 列に有効な `accessorKey`/`accessorFn` が定義されている +- 提供されている場合、`options.getColumnCanGlobalFilter` がその列に対して `true` を返す。提供されていない場合、最初の行の値が `string` または `number` 型であれば、列はグローバルフィルタリング可能と見なされる +- `column.enableColumnFilter` が `false` に設定されていない +- `options.enableColumnFilters` が `false` に設定されていない +- `options.enableFilters` が `false` に設定されていない + +### ステート (State) + +フィルターの状態は、以下の形式でテーブルに保存されます: + +```tsx +export interface GlobalFilterTableState { + globalFilter: any +} +``` + +### フィルター関数 (Filter Functions) + +グローバルフィルタリングには、カラムフィルタリングで利用可能な同じフィルター関数を使用できます。フィルター関数の詳細については、[カラムフィルタリングAPI](../api/features/column-filtering)を参照してください。 + +#### フィルター関数の使用 + +フィルター関数は、以下のいずれかを `options.globalFilterFn` に渡すことで使用/参照/定義できます: + +- 組み込みフィルター関数を参照する `string` +- `options.globalFilterFn` オプションに直接提供される関数 + +`tableOptions.globalFilterFn` オプションで利用可能なフィルター関数の最終リストは、以下の型を使用します: + +```tsx +export type FilterFnOption = + | 'auto' + | BuiltInFilterFn + | FilterFn +``` + +#### フィルターメタ (Filter Meta) + +データのフィルタリングは、そのデータに関する追加情報を提供することが多く、これを使って同じデータに対する他の操作を支援できます。この概念の良い例は、[`match-sorter`](https://github.com/kentcdodds/match-sorter) のようなランキングシステムで、データのランク付け、フィルタリング、並べ替えを同時に行います。`match-sorter` のようなユーティリティは、単一の次元でのフィルター+ソートタスクには非常に理にかなっていますが、テーブルを構築する際の分離されたフィルタリング/ソートアーキテクチャでは、それらを使用することが非常に難しく、遅くなります。 + +ランキング/フィルタリング/ソートシステムをテーブルで動作させるために、`filterFn` はオプションで結果に**フィルターメタ**値をマークし、後でデータを好みに合わせてソート/グループ化などに使用できます。これは、カスタム `filterFn` に提供される `addMeta` 関数を呼び出すことで行われます。 + +以下は、独自の `match-sorter-utils` パッケージ (`match-sorter` のユーティリティフォーク) を使用して、データをランク付け、フィルタリング、並べ替える例です: + +```tsx +import { sortingFns } from '@tanstack/[adapter]-table' + +import { rankItem, compareItems } from '@tanstack/match-sorter-utils' + +const fuzzyFilter = (row, columnId, value, addMeta) => { + // アイテムをランク付け + const itemRank = rankItem(row.getValue(columnId), value) + + // ランキング情報を保存 + addMeta(itemRank) + + // アイテムをフィルタリングするかどうかを返す + return itemRank.passed +} + +const fuzzySort = (rowA, rowB, columnId) => { + let dir = 0 + + // 列にランキング情報がある場合のみランクでソート + if (rowA.columnFiltersMeta[columnId]) { + dir = compareItems( + rowA.columnFiltersMeta[columnId]!, + rowB.columnFiltersMeta[columnId]! + ) + } + + // ランクが等しい場合の英数字フォールバックを提供 + return dir === 0 ? sortingFns.alphanumeric(rowA, rowB, columnId) : dir +} +``` + +### カラム定義オプション (Column Def Options) + +#### `enableGlobalFilter` + +```tsx +enableGlobalFilter?: boolean +``` + +このカラムの**グローバル**フィルターを有効/無効にします。 + +### カラムAPI (Column API) + +#### `getCanGlobalFilter` + +```tsx +getCanGlobalFilter: () => boolean +``` + +カラムが**グローバル**にフィルタリング可能かどうかを返します。グローバルフィルタリング中にカラムをスキャンしないようにするには、`false` に設定します。 + +### 行API (Row API) + +#### `columnFiltersMeta` + +```tsx +columnFiltersMeta: Record +``` + +行のカラムフィルターメタマップ。このオブジェクトは、フィルタリングプロセス中にオプションで提供される行のフィルターメタを追跡します。 + +### テーブルオプション (Table Options) + +#### `filterFns` + +```tsx +filterFns?: Record +``` + +このオプションを使用すると、カラムの `filterFn` オプションでキーによって参照できるカスタムフィルター関数を定義できます。 +例: + +```tsx +declare module '@tanstack/table-core' { + interface FilterFns { + myCustomFilter: FilterFn + } +} + +const column = columnHelper.data('key', { + filterFn: 'myCustomFilter', +}) + +const table = useReactTable({ + columns: [column], + filterFns: { + myCustomFilter: (rows, columnIds, filterValue) => { + // フィルタリングされた行を返す + }, + }, +}) +``` + +#### `filterFromLeafRows` + +```tsx +filterFromLeafRows?: boolean +``` + +デフォルトでは、フィルタリングは親行から下に向かって行われます(親行がフィルタリングされると、そのすべての子行もフィルタリングされます)。このオプションを `true` に設定すると、フィルタリングはリーフ行から上に向かって行われます(つまり、親行は、その子行または孫行のいずれかが含まれている限り含まれます)。 + +#### `maxLeafRowFilterDepth` + +```tsx +maxLeafRowFilterDepth?: number +``` + +デフォルトでは、フィルタリングはすべての行(最大深度100)に対して行われ、それらがルートレベルの親行であっても、親行の子リーフ行であっても関係ありません。このオプションを `0` に設定すると、フィルタリングはルートレベルの親行にのみ適用され、すべてのサブ行はフィルタリングされません。同様に、このオプションを `1` に設定すると、フィルタリングは1レベルの深さの子リーフ行にのみ適用されます。 + +これは、適用されたフィルターに関係なく、行の子階層全体を表示したい場合に役立ちます。 + +#### `enableFilters` + +```tsx +enableFilters?: boolean +``` + +テーブルのすべてのフィルターを有効/無効にします。 + +#### `manualFiltering` + +```tsx +manualFiltering?: boolean +``` + +`getFilteredRowModel` を使用してデータをフィルタリングすることを無効にします。これは、テーブルがクライアントサイドとサーバーサイドのフィルタリングを動的にサポートする必要がある場合に役立ちます。 + +#### `getFilteredRowModel` + +```tsx +getFilteredRowModel?: ( + table: Table +) => () => RowModel +``` + +提供されている場合、この関数はテーブルごとに**1回**呼び出され、フィルタリングされたときにテーブルの行モデルを計算して返す**新しい関数**を返す必要があります。 + +- サーバーサイドフィルタリングの場合、この関数は不要であり、無視できます。サーバーはすでにフィルタリングされた行モデルを返すべきです。 +- クライアントサイドフィルタリングの場合、この関数は必須です。デフォルトの実装は、任意のテーブルアダプターの `{ getFilteredRowModel }` エクスポートを介して提供されます。 + +例: + +```tsx +import { getFilteredRowModel } from '@tanstack/[adapter]-table' + + getFilteredRowModel: getFilteredRowModel(), +}) +``` + +#### `globalFilterFn` + +```tsx +globalFilterFn?: FilterFn | keyof FilterFns | keyof BuiltInFilterFns +``` + +グローバルフィルタリングに使用するフィルター関数。 + +オプション: + +- [組み込みフィルター関数](#filter-functions)を参照する `string` +- `tableOptions.filterFns` オプションで提供されるカスタムフィルター関数を参照する `string` +- [カスタムフィルター関数](#filter-functions) + +#### `onGlobalFilterChange` + +```tsx +onGlobalFilterChange?: OnChangeFn +``` + +提供されている場合、この関数は `state.globalFilter` が変更されると `updaterFn` とともに呼び出されます。これにより、デフォルトの内部状態管理が上書きされるため、状態の変更を完全にまたは部分的にテーブルの外部で永続化する必要があります。 + +#### `enableGlobalFilter` + +```tsx +enableGlobalFilter?: boolean +``` + +テーブルのグローバルフィルターを有効/無効にします。 + +#### `getColumnCanGlobalFilter` + +```tsx +getColumnCanGlobalFilter?: (column: Column) => boolean +``` + +提供されている場合、この関数はカラムとともに呼び出され、このカラムをグローバルフィルタリングに使用するかどうかを示す `true` または `false` を返す必要があります。 +これは、カラムに `string` や `number` ではないデータ(例: `undefined`)が含まれる場合に役立ちます。 + +### テーブルAPI (Table API) + +#### `getPreFilteredRowModel` + +```tsx +getPreFilteredRowModel: () => RowModel +``` + +**カラム**フィルタリングが適用される前のテーブルの行モデルを返します。 + +#### `getFilteredRowModel` + +```tsx +getFilteredRowModel: () => RowModel +``` + +**カラム**フィルタリングが適用された後のテーブルの行モデルを返します。 + +#### `setGlobalFilter` + +```tsx +setGlobalFilter: (updater: Updater) => void +``` + +`state.globalFilter` 状態を設定または更新します。 + +#### `resetGlobalFilter` + +```tsx +resetGlobalFilter: (defaultState?: boolean) => void +``` + +**globalFilter** 状態を `initialState.globalFilter` にリセットします。または、`true` を渡すと、デフォルトの空白状態に強制的にリセットされ `undefined` になります。 + +#### `getGlobalAutoFilterFn` + +```tsx +getGlobalAutoFilterFn: (columnId: string) => FilterFn | undefined +``` + +現在、この関数は組み込みの `includesString` フィルター関数を返します。将来のリリースでは、提供されたデータの性質に基づいて、より動的なフィルター関数を返す可能性があります。 + +#### `getGlobalFilterFn` + +```tsx +getGlobalFilterFn: (columnId: string) => FilterFn | undefined +``` + +テーブルのグローバルフィルター関数(ユーザー定義または自動、設定に応じて)を返します。 diff --git a/docs/ja/api/features/grouping.md b/docs/ja/api/features/grouping.md new file mode 100644 index 0000000000..e7a3056a45 --- /dev/null +++ b/docs/ja/api/features/grouping.md @@ -0,0 +1,356 @@ +--- +source-updated-at: '2024-02-18T00:06:36.000Z' +translation-updated-at: '2025-05-05T19:30:05.770Z' +title: グループ化 +id: grouping +--- +## グループ化 API + +## ステート (State) + +グループ化の状態は、以下の形式でテーブルに保存されます: + +```tsx +export type GroupingState = string[] + +export type GroupingTableState = { + grouping: GroupingState +} +``` + +## 集計関数 (Aggregation Functions) + +以下の集計関数がテーブルコアに組み込まれています: + +- `sum` + - 行グループの値を合計します +- `min` + - 行グループの最小値を求めます +- `max` + - 行グループの最大値を求めます +- `extent` + - 行グループの最小値と最大値を求めます +- `mean` + - 行グループの平均値を求めます +- `median` + - 行グループの中央値を求めます +- `unique` + - 行グループの一意の値を求めます +- `uniqueCount` + - 行グループの一意の値の数を求めます +- `count` + - グループ内の行数を計算します + +すべての集計関数は以下を受け取ります: + +- グループ行のリーフ値を取得する関数 +- グループ行の直接の子値を取得する関数 + +そして通常はプリミティブな値を返し、集計された行モデルを構築します。 + +これがすべての集計関数の型シグネチャです: + +```tsx +export type AggregationFn = ( + getLeafRows: () => Row[], + getChildRows: () => Row[] +) => any +``` + +#### 集計関数の使用 + +集計関数は、以下を`columnDefinition.aggregationFn`に渡すことで使用/参照/定義できます: + +- 組み込み集計関数を参照する`string` +- `tableOptions.aggregationFns`オプションで提供されるカスタム集計関数を参照する`string` +- `columnDefinition.aggregationFn`オプションに直接提供される関数 + +`columnDef.aggregationFn`で利用可能な集計関数の最終的なリストは以下の型を使用します: + +```tsx +export type AggregationFnOption = + | 'auto' + | keyof AggregationFns + | BuiltInAggregationFn + | AggregationFn +``` + +## カラム定義オプション (Column Def Options) + +### `aggregationFn` + +```tsx +aggregationFn?: AggregationFn | keyof AggregationFns | keyof BuiltInAggregationFns +``` + +このカラムで使用する集計関数。 + +オプション: + +- [組み込み集計関数](#aggregation-functions)を参照する`string` +- [カスタム集計関数](#aggregation-functions) + +### `aggregatedCell` + +```tsx +aggregatedCell?: Renderable< + { + table: Table + row: Row + column: Column + cell: Cell + getValue: () => any + renderValue: () => any + } +> +``` + +セルが集計されている場合に、カラムの各行に表示するセル。関数が渡された場合、セルのコンテキストを含むpropsオブジェクトが渡され、使用するアダプターのプロパティタイプを返す必要があります(正確なタイプは使用するアダプターによって異なります)。 + +### `enableGrouping` + +```tsx +enableGrouping?: boolean +``` + +このカラムのグループ化を有効/無効にします。 + +### `getGroupingValue` + +```tsx +getGroupingValue?: (row: TData) => any +``` + +このカラムで行をグループ化するために使用する値を指定します。このオプションが指定されていない場合、`accessorKey`/`accessorFn`から派生した値が代わりに使用されます。 + +## カラム API (Column API) + +### `aggregationFn` + +```tsx +aggregationFn?: AggregationFnOption +``` + +カラムの解決済み集計関数。 + +### `getCanGroup` + +```tsx +getCanGroup: () => boolean +``` + +カラムがグループ化可能かどうかを返します。 + +### `getIsGrouped` + +```tsx +getIsGrouped: () => boolean +``` + +カラムが現在グループ化されているかどうかを返します。 + +### `getGroupedIndex` + +```tsx +getGroupedIndex: () => number +``` + +グループ化状態におけるカラムのインデックスを返します。 + +### `toggleGrouping` + +```tsx +toggleGrouping: () => void +``` + +カラムのグループ化状態をトグルします。 + +### `getToggleGroupingHandler` + +```tsx +getToggleGroupingHandler: () => () => void +``` + +カラムのグループ化状態をトグルする関数を返します。これはボタンの`onClick`プロップに渡すのに便利です。 + +### `getAutoAggregationFn` + +```tsx +getAutoAggregationFn: () => AggregationFn | undefined +``` + +カラムの自動推論された集計関数を返します。 + +### `getAggregationFn` + +```tsx +getAggregationFn: () => AggregationFn | undefined +``` + +カラムの集計関数を返します。 + +## 行 API (Row API) + +### `groupingColumnId` + +```tsx +groupingColumnId?: string +``` + +この行がグループ化されている場合、この行がグループ化されているカラムのIDです。 + +### `groupingValue` + +```tsx +groupingValue?: any +``` + +この行がグループ化されている場合、このグループ内のすべての行の`groupingColumnId`に対する一意/共有の値です。 + +### `getIsGrouped` + +```tsx +getIsGrouped: () => boolean +``` + +行が現在グループ化されているかどうかを返します。 + +### `getGroupingValue` + +```tsx +getGroupingValue: (columnId: string) => unknown +``` + +任意の行とカラム(リーフ行を含む)のグループ化値を返します。 + +## テーブルオプション (Table Options) + +### `aggregationFns` + +```tsx +aggregationFns?: Record +``` + +このオプションを使用すると、カラムの`aggregationFn`オプションでキーによって参照できるカスタム集計関数を定義できます。 +例: + +```tsx +declare module '@tanstack/table-core' { + interface AggregationFns { + myCustomAggregation: AggregationFn + } +} + +const column = columnHelper.data('key', { + aggregationFn: 'myCustomAggregation', +}) + +const table = useReactTable({ + columns: [column], + aggregationFns: { + myCustomAggregation: (columnId, leafRows, childRows) => { + // 集計値を返す + }, + }, +}) +``` + +### `manualGrouping` + +```tsx +manualGrouping?: boolean +``` + +手動グループ化を有効にします。このオプションが`true`に設定されている場合、テーブルは`getGroupedRowModel()`を使用して行を自動的にグループ化せず、代わりにテーブルに渡す前に手動で行をグループ化することを期待します。これはサーバーサイドでのグループ化と集計を行う場合に便利です。 + +### `onGroupingChange` + +```tsx +onGroupingChange?: OnChangeFn +``` + +この関数が提供されている場合、グループ化状態が変更されると呼び出され、状態を自分で管理する必要があります。管理された状態は、`tableOptions.state.grouping`オプションを介してテーブルに戻すことができます。 + +### `enableGrouping` + +```tsx +enableGrouping?: boolean +``` + +すべてのカラムのグループ化を有効/無効にします。 + +### `getGroupedRowModel` + +```tsx +getGroupedRowModel?: (table: Table) => () => RowModel +``` + +グループ化が行われた後の行モデルを返しますが、それ以上は行いません。 + +### `groupedColumnMode` + +```tsx +groupedColumnMode?: false | 'reorder' | 'remove' // デフォルト: `reorder` +``` + +グループ化カラムはデフォルトで自動的にカラムリストの先頭に再配置されます。それらを削除するか、そのままにしたい場合は、ここで適切なモードを設定します。 + +## テーブル API (Table API) + +### `setGrouping` + +```tsx +setGrouping: (updater: Updater) => void +``` + +`state.grouping`状態を設定または更新します。 + +### `resetGrouping` + +```tsx +resetGrouping: (defaultState?: boolean) => void +``` + +**グループ化**状態を`initialState.grouping`にリセットします。`true`を渡すと、デフォルトの空白状態`[]`に強制的にリセットされます。 + +### `getPreGroupedRowModel` + +```tsx +getPreGroupedRowModel: () => RowModel +``` + +グループ化が適用される前のテーブルの行モデルを返します。 + +### `getGroupedRowModel` + +```tsx +getGroupedRowModel: () => RowModel +``` + +グループ化が適用された後のテーブルの行モデルを返します。 + +## セル API (Cell API) + +### `getIsAggregated` + +```tsx +getIsAggregated: () => boolean +``` + +セルが現在集計されているかどうかを返します。 + +### `getIsGrouped` + +```tsx +getIsGrouped: () => boolean +``` + +セルが現在グループ化されているかどうかを返します。 + +### `getIsPlaceholder` + +```tsx +getIsPlaceholder: () => boolean +``` + +セルが現在プレースホルダーかどうかを返します。 diff --git a/docs/ja/api/features/pagination.md b/docs/ja/api/features/pagination.md new file mode 100644 index 0000000000..45aaddf6c5 --- /dev/null +++ b/docs/ja/api/features/pagination.md @@ -0,0 +1,208 @@ +--- +source-updated-at: '2024-02-27T21:03:18.000Z' +translation-updated-at: '2025-05-05T19:29:53.716Z' +title: ページネーション +id: pagination +--- +## ステート (State) + +ページネーションの状態は、以下の形式でテーブルに保存されます。 + +```tsx +export type PaginationState = { + pageIndex: number + pageSize: number +} + +export type PaginationTableState = { + pagination: PaginationState +} + +export type PaginationInitialTableState = { + pagination?: Partial +} +``` + +## テーブルオプション (Table Options) + +### `manualPagination` + +```tsx +manualPagination?: boolean +``` + +手動ページネーションを有効にします。このオプションを `true` に設定すると、テーブルは `getPaginationRowModel()` を使用して行を自動的にページ分割せず、代わりに行を手動でページ分割してテーブルに渡すことが期待されます。これはサーバーサイドページネーションや集計を行う場合に便利です。 + +### `pageCount` + +```tsx +pageCount?: number +``` + +手動でページネーションを制御する場合、総 `pageCount` 値をテーブルに提供できます。ページ数がわからない場合は、これを `-1` に設定できます。または、`rowCount` 値を提供すると、テーブルは内部で `pageCount` を計算します。 + +### `rowCount` + +```tsx +rowCount?: number +``` + +手動でページネーションを制御する場合、総 `rowCount` 値をテーブルに提供できます。`pageCount` は `rowCount` と `pageSize` から内部で計算されます。 + +### `autoResetPageIndex` + +```tsx +autoResetPageIndex?: boolean +``` + +`true` に設定すると、ページネーションはページ変更状態の変化(例: `data` の更新、フィルターの変更、グループ化の変更など)に伴って最初のページにリセットされます。 + +> 🧠 注意: このオプションは `manualPagination` が `true` の場合、デフォルトで `false` になります + +### `onPaginationChange` + +```tsx +onPaginationChange?: OnChangeFn +``` + +この関数が提供されている場合、ページネーション状態が変更されると呼び出され、状態を自身で管理することが期待されます。管理された状態は `tableOptions.state.pagination` オプションを介してテーブルに戻すことができます。 + +### `getPaginationRowModel` + +```tsx +getPaginationRowModel?: (table: Table) => () => RowModel +``` + +ページネーションが適用された後の行モデルを返しますが、それ以上は適用しません。 + +ページネーション列はデフォルトで自動的に列リストの先頭に並べ替えられます。削除したりそのままにしたい場合は、適切なモードを設定してください。 + +## テーブルAPI (Table API) + +### `setPagination` + +```tsx +setPagination: (updater: Updater) => void +``` + +`state.pagination` 状態を設定または更新します。 + +### `resetPagination` + +```tsx +resetPagination: (defaultState?: boolean) => void +``` + +**ページネーション**状態を `initialState.pagination` にリセットします。`true` を渡すと、デフォルトの空白状態 `[]` に強制的にリセットされます。 + +### `setPageIndex` + +```tsx +setPageIndex: (updater: Updater) => void +``` + +提供された関数または値を使用してページインデックスを更新します。 + +### `resetPageIndex` + +```tsx +resetPageIndex: (defaultState?: boolean) => void +``` + +ページインデックスを初期状態にリセットします。`defaultState` が `true` の場合、初期状態に関係なくページインデックスは `0` にリセットされます。 + +### `setPageSize` + +```tsx +setPageSize: (updater: Updater) => void +``` + +提供された関数または値を使用してページサイズを更新します。 + +### `resetPageSize` + +```tsx +resetPageSize: (defaultState?: boolean) => void +``` + +ページサイズを初期状態にリセットします。`defaultState` が `true` の場合、初期状態に関係なくページサイズは `10` にリセットされます。 + +### `getPageOptions` + +```tsx +getPageOptions: () => number[] +``` + +現在のページサイズに対するページオプション(ゼロベース)の配列を返します。 + +### `getCanPreviousPage` + +```tsx +getCanPreviousPage: () => boolean +``` + +テーブルが前のページに移動できるかどうかを返します。 + +### `getCanNextPage` + +```tsx +getCanNextPage: () => boolean +``` + +テーブルが次のページに移動できるかどうかを返します。 + +### `previousPage` + +```tsx +previousPage: () => void +``` + +可能であれば、ページインデックスを1つ減らします。 + +### `nextPage` + +```tsx +nextPage: () => void +``` + +可能であれば、ページインデックスを1つ増やします。 + +### `firstPage` + +```tsx +firstPage: () => void +``` + +ページインデックスを `0` に設定します。 + +### `lastPage` + +```tsx +lastPage: () => void +``` + +ページインデックスを最後の利用可能なページに設定します。 + +### `getPageCount` + +```tsx +getPageCount: () => number +``` + +ページ数を返します。手動でページネーションを制御している場合、これは `options.pageCount` テーブルオプションから直接取得されます。それ以外の場合は、総行数と現在のページサイズを使用してテーブルデータから計算されます。 + +### `getPrePaginationRowModel` + +```tsx +getPrePaginationRowModel: () => RowModel +``` + +ページネーションが適用される前のテーブルの行モデルを返します。 + +### `getPaginationRowModel` + +```tsx +getPaginationRowModel: () => RowModel +``` + +ページネーションが適用された後のテーブルの行モデルを返します。 diff --git a/docs/ja/api/features/row-pinning.md b/docs/ja/api/features/row-pinning.md new file mode 100644 index 0000000000..9f278dc411 --- /dev/null +++ b/docs/ja/api/features/row-pinning.md @@ -0,0 +1,141 @@ +--- +source-updated-at: '2024-06-30T17:39:45.000Z' +translation-updated-at: '2025-05-05T19:29:47.522Z' +title: 行固定 +id: row-pinning +--- +## 行ピン留め (Row Pinning) API + +## ピン留め可能 (Can-Pin) + +行を**ピン留め (pinned)** できるかどうかは、以下によって決定されます: + +- `options.enableRowPinning` が `true` と解決される +- `options.enablePinning` が `false` に設定されていない + +## 状態 (State) + +ピン留めの状態は、以下の形式でテーブルに保存されます: + +```tsx +export type RowPinningPosition = false | 'top' | 'bottom' + +export type RowPinningState = { + top?: string[] + bottom?: string[] +} + +export type RowPinningRowState = { + rowPinning: RowPinningState +} +``` + +## テーブルオプション (Table Options) + +### `enableRowPinning` + +```tsx +enableRowPinning?: boolean | ((row: Row) => boolean) +``` + +テーブル内のすべての行に対して行ピン留めを有効/無効にします。 + +### `keepPinnedRows` + +```tsx +keepPinnedRows?: boolean +``` + +`false`の場合、ピン留めされた行がフィルタリングまたはページネーションによってテーブルから除外されると表示されません。`true`の場合、ピン留めされた行はフィルタリングやページネーションに関係なく常に表示されます。デフォルトは`true`です。 + +### `onRowPinningChange` + +```tsx +onRowPinningChange?: OnChangeFn +``` + +この関数が提供されると、`state.rowPinning`が変更されたときに`updaterFn`とともに呼び出されます。これによりデフォルトの内部状態管理が上書きされるため、`state.rowPinning`を自身で管理する必要があります。 + +## テーブルAPI (Table API) + +### `setRowPinning` + +```tsx +setRowPinning: (updater: Updater) => void +``` + +`state.rowPinning`の状態を設定または更新します。 + +### `resetRowPinning` + +```tsx +resetRowPinning: (defaultState?: boolean) => void +``` + +**rowPinning**の状態を`initialState.rowPinning`にリセットします。`true`を渡すと、デフォルトの空白状態`{}`に強制的にリセットされます。 + +### `getIsSomeRowsPinned` + +```tsx +getIsSomeRowsPinned: (position?: RowPinningPosition) => boolean +``` + +ピン留めされた行があるかどうかを返します。オプションで`top`または`bottom`の位置にあるピン留めされた行のみをチェックできます。 + +### `getTopRows` + +```tsx +getTopRows: () => Row[] +``` + +上部にピン留めされたすべての行を返します。 + +### `getBottomRows` + +```tsx +getBottomRows: () => Row[] +``` + +下部にピン留めされたすべての行を返します。 + +### `getCenterRows` + +```tsx +getCenterRows: () => Row[] +``` + +上部または下部にピン留めされていないすべての行を返します。 + +## 行API (Row API) + +### `pin` + +```tsx +pin: (position: RowPinningPosition) => void +``` + +行を`'top'`または`'bottom'`にピン留めします。`false`を渡すと中央にピン留めを解除します。 + +### `getCanPin` + +```tsx +getCanPin: () => boolean +``` + +行がピン留め可能かどうかを返します。 + +### `getIsPinned` + +```tsx +getIsPinned: () => RowPinningPosition +``` + +行のピン留め位置を返します。(`'top'`、`'bottom'`または`false`) + +### `getPinnedIndex` + +```tsx +getPinnedIndex: () => number +``` + +ピン留めされた行グループ内での行の数値インデックスを返します。 diff --git a/docs/ja/api/features/row-selection.md b/docs/ja/api/features/row-selection.md new file mode 100644 index 0000000000..5bd94d1167 --- /dev/null +++ b/docs/ja/api/features/row-selection.md @@ -0,0 +1,231 @@ +--- +source-updated-at: '2025-03-20T21:15:29.000Z' +translation-updated-at: '2025-05-05T19:30:04.671Z' +title: 行選択 +id: row-selection +--- +## ステート (State) + +行選択のステートは、以下の形式でテーブルに保存されます: + +```tsx +export type RowSelectionState = Record + +export type RowSelectionTableState = { + rowSelection: RowSelectionState +} +``` + +デフォルトでは、行選択のステートは各行のインデックスを行識別子として使用します。行選択のステートは、テーブルにカスタムの[getRowId](../core/table.md#getrowid)関数を渡すことで、カスタムの一意な行IDで追跡することもできます。 + +## テーブルオプション (Table Options) + +### `enableRowSelection` + +```tsx +enableRowSelection?: boolean | ((row: Row) => boolean) +``` + +- テーブル内のすべての行に対して行選択を有効/無効にする OR +- 行を受け取り、その行の行選択を有効/無効にするかどうかを返す関数 + +### `enableMultiRowSelection` + +```tsx +enableMultiRowSelection?: boolean | ((row: Row) => boolean) +``` + +- テーブル内のすべての行に対して複数行選択を有効/無効にする OR +- 行を受け取り、その行の子/孫行に対する複数行選択を有効/無効にするかどうかを返す関数 + +### `enableSubRowSelection` + +```tsx +enableSubRowSelection?: boolean | ((row: Row) => boolean) +``` + +親行が選択されたときに自動的にサブ行を選択するかどうかを有効/無効にする、または各行に対して自動サブ行選択を有効/無効にする関数。 + +(展開またはグループ化機能と組み合わせて使用) + +### `onRowSelectionChange` + +```tsx +onRowSelectionChange?: OnChangeFn +``` + +提供された場合、`state.rowSelection`が変更されるとこの関数が`updaterFn`と共に呼び出されます。これによりデフォルトの内部ステート管理が上書きされるため、テーブルの外部でステート変更を完全または部分的に永続化する必要があります。 + +## テーブルAPI (Table API) + +### `getToggleAllRowsSelectedHandler` + +```tsx +getToggleAllRowsSelectedHandler: () => (event: unknown) => void +``` + +テーブル内のすべての行をトグルするために使用できるハンドラーを返します。 + +### `getToggleAllPageRowsSelectedHandler` + +```tsx +getToggleAllPageRowsSelectedHandler: () => (event: unknown) => void +``` + +現在のページのすべての行をトグルするために使用できるハンドラーを返します。 + +### `setRowSelection` + +```tsx +setRowSelection: (updater: Updater) => void +``` + +`state.rowSelection`ステートを設定または更新します。 + +### `resetRowSelection` + +```tsx +resetRowSelection: (defaultState?: boolean) => void +``` + +**rowSelection**ステートを`initialState.rowSelection`にリセットします。`true`を渡すと、デフォルトの空白ステート`{}`に強制的にリセットされます。 + +### `getIsAllRowsSelected` + +```tsx +getIsAllRowsSelected: () => boolean +``` + +テーブル内のすべての行が選択されているかどうかを返します。 + +### `getIsAllPageRowsSelected` + +```tsx +getIsAllPageRowsSelected: () => boolean +``` + +現在のページのすべての行が選択されているかどうかを返します。 + +### `getIsSomeRowsSelected` + +```tsx +getIsSomeRowsSelected: () => boolean +``` + +テーブル内のいずれかの行が選択されているかどうかを返します。 + +注: すべての行が選択されている場合は`false`を返します。 + +### `getIsSomePageRowsSelected` + +```tsx +getIsSomePageRowsSelected: () => boolean +``` + +現在のページのいずれかの行が選択されているかどうかを返します。 + +### `toggleAllRowsSelected` + +```tsx +toggleAllRowsSelected: (value: boolean) => void +``` + +テーブル内のすべての行を選択/選択解除します。 + +### `toggleAllPageRowsSelected` + +```tsx +toggleAllPageRowsSelected: (value: boolean) => void +``` + +現在のページのすべての行を選択/選択解除します。 + +### `getPreSelectedRowModel` + +```tsx +getPreSelectedRowModel: () => RowModel +``` + +### `getSelectedRowModel` + +```tsx +getSelectedRowModel: () => RowModel +``` + +### `getFilteredSelectedRowModel` + +```tsx +getFilteredSelectedRowModel: () => RowModel +``` + +### `getGroupedSelectedRowModel` + +```tsx +getGroupedSelectedRowModel: () => RowModel +``` + +## 行API (Row API) + +### `getIsSelected` + +```tsx +getIsSelected: () => boolean +``` + +行が選択されているかどうかを返します。 + +### `getIsSomeSelected` + +```tsx +getIsSomeSelected: () => boolean +``` + +行のサブ行の一部が選択されているかどうかを返します。 + +### `getIsAllSubRowsSelected` + +```tsx +getIsAllSubRowsSelected: () => boolean +``` + +行のすべてのサブ行が選択されているかどうかを返します。 + +### `getCanSelect` + +```tsx +getCanSelect: () => boolean +``` + +行が選択可能かどうかを返します。 + +### `getCanMultiSelect` + +```tsx +getCanMultiSelect: () => boolean +``` + +行が複数選択可能かどうかを返します。 + +### `getCanSelectSubRows` + +```tsx +getCanSelectSubRows: () => boolean +``` + +親行が選択されたときに自動的にサブ行を選択できるかどうかを返します。 + +### `toggleSelected` + +```tsx +toggleSelected: (value?: boolean) => void +``` + +行を選択/選択解除します。 + +### `getToggleSelectedHandler` + +```tsx +getToggleSelectedHandler: () => (event: unknown) => void +``` + +行をトグルするために使用できるハンドラーを返します。 diff --git a/docs/ja/api/features/sorting.md b/docs/ja/api/features/sorting.md new file mode 100644 index 0000000000..7a07744f01 --- /dev/null +++ b/docs/ja/api/features/sorting.md @@ -0,0 +1,385 @@ +--- +source-updated-at: '2024-04-13T00:46:18.000Z' +translation-updated-at: '2025-05-05T19:30:20.145Z' +title: ソート +id: sorting +--- +## ソート状態 (State) + +ソート状態はテーブル上で以下の形式で保持されます: + +```tsx +export type SortDirection = 'asc' | 'desc' + +export type ColumnSort = { + id: string + desc: boolean +} + +export type SortingState = ColumnSort[] + +export type SortingTableState = { + sorting: SortingState +} +``` + +## ソート関数 (Sorting Functions) + +テーブルコアには以下の組み込みソート関数が用意されています: + +- `alphanumeric` + - 大文字小文字を区別せず、英数字混合の値をソートします。速度は遅いですが、自然なソートが必要な数値を含む文字列に対してより正確です。 +- `alphanumericCaseSensitive` + - 大文字小文字を区別して、英数字混合の値をソートします。速度は遅いですが、自然なソートが必要な数値を含む文字列に対してより正確です。 +- `text` + - 大文字小文字を区別せず、テキスト/文字列値をソートします。高速ですが、自然なソートが必要な数値を含む文字列に対しては精度が低くなります。 +- `textCaseSensitive` + - 大文字小文字を区別して、テキスト/文字列値をソートします。高速ですが、自然なソートが必要な数値を含む文字列に対しては精度が低くなります。 +- `datetime` + - 日時でソートします。値が `Date` オブジェクトの場合に使用します。 +- `basic` + - 基本的な `a > b ? 1 : a < b ? -1 : 0` 比較を使用してソートします。最も高速なソート関数ですが、精度は最も低くなる可能性があります。 + +各ソート関数は2つの行と列IDを受け取り、列IDを使用して2つの行を比較し、昇順で `-1`、`0`、または `1` を返すことが期待されます。以下は早見表です: + +| 戻り値 | 昇順 | +| ------ | ------------ | +| `-1` | `a < b` | +| `0` | `a === b` | +| `1` | `a > b` | + +すべてのソート関数の型シグネチャは以下の通りです: + +```tsx +export type SortingFn = { + (rowA: Row, rowB: Row, columnId: string): number +} +``` + +#### ソート関数の使用 + +ソート関数は以下のいずれかを `columnDefinition.sortingFn` に渡すことで使用/参照/定義できます: + +- 組み込みソート関数を参照する `string` +- `tableOptions.sortingFns` オプションで提供されるカスタムソート関数を参照する `string` +- `columnDefinition.sortingFn` オプションに直接提供される関数 + +`columnDef.sortingFn` で使用可能な最終的なソート関数のリストは以下の型を使用します: + +```tsx +export type SortingFnOption = + | 'auto' + | SortingFns + | BuiltInSortingFns + | SortingFn +``` + +## 列定義オプション (Column Def Options) + +### `sortingFn` + +```tsx +sortingFn?: SortingFn | keyof SortingFns | keyof BuiltInSortingFns +``` + +この列で使用するソート関数。 + +オプション: +- [組み込みソート関数](#sorting-functions) を参照する `string` +- [カスタムソート関数](#sorting-functions) + +### `sortDescFirst` + +```tsx +sortDescFirst?: boolean +``` + +この列のソートトグルを降順で開始する場合は `true` に設定します。 + +### `enableSorting` + +```tsx +enableSorting?: boolean +``` + +この列のソートを有効/無効にします。 + +### `enableMultiSort` + +```tsx +enableMultiSort?: boolean +``` + +この列のマルチソートを有効/無効にします。 + +### `invertSorting` + +```tsx +invertSorting?: boolean +``` + +この列のソート順序を反転します。これは、低い数字が良いことを示す逆のベスト/ワーストスケールを持つ値(例: ランキング(1位、2位、3位)やゴルフのようなスコアリング)に有用です。 + +### `sortUndefined` + +```tsx +sortUndefined?: 'first' | 'last' | false | -1 | 1 // デフォルトは 1 +``` + +- `'first'` + - 未定義の値はリストの先頭に移動します +- `'last'` + - 未定義の値はリストの末尾に移動します +- `false` + - 未定義の値は同値と見なされ、次の列フィルターまたは元のインデックス(該当する場合)でソートする必要があります +- `-1` + - 未定義の値はより高い優先度(昇順)でソートされます(昇順の場合、未定義はリストの先頭に表示されます) +- `1` + - 未定義の値はより低い優先度(降順)でソートされます(昇順の場合、未定義はリストの末尾に表示されます) + +> 注: `'first'` と `'last'` オプションは v8.16.0 で新しく追加されました + +## 列API (Column API) + +### `getAutoSortingFn` + +```tsx +getAutoSortingFn: () => SortingFn +``` + +列の値に基づいて自動的に推論されたソート関数を返します。 + +### `getAutoSortDir` + +```tsx +getAutoSortDir: () => SortDirection +``` + +列の値に基づいて自動的に推論されたソート方向を返します。 + +### `getSortingFn` + +```tsx +getSortingFn: () => SortingFn +``` + +この列に使用される解決済みのソート関数を返します。 + +### `getNextSortingOrder` + +```tsx +getNextSortingOrder: () => SortDirection | false +``` + +次のソート順序を返します。 + +### `getCanSort` + +```tsx +getCanSort: () => boolean +``` + +この列がソート可能かどうかを返します。 + +### `getCanMultiSort` + +```tsx +getCanMultiSort: () => boolean +``` + +この列がマルチソート可能かどうかを返します。 + +### `getSortIndex` + +```tsx +getSortIndex: () => number +``` + +ソート状態内でのこの列のソート位置インデックスを返します。 + +### `getIsSorted` + +```tsx +getIsSorted: () => false | SortDirection +``` + +この列がソートされているかどうかを返します。 + +### `getFirstSortDir` + +```tsx +getFirstSortDir: () => SortDirection +``` + +この列をソートする際に使用される最初の方向を返します。 + +### `clearSorting` + +```tsx +clearSorting: () => void +``` + +この列をテーブルのソート状態から削除します。 + +### `toggleSorting` + +```tsx +toggleSorting: (desc?: boolean, isMulti?: boolean) => void +``` + +この列のソート状態をトグルします。`desc` が指定されている場合、ソート方向はその値に強制されます。`isMulti` が指定されている場合、列を追加的にマルチソートします(または既にソートされている場合はトグルします)。 + +### `getToggleSortingHandler` + +```tsx +getToggleSortingHandler: () => undefined | ((event: unknown) => void) +``` + +この列のソート状態をトグルするために使用できる関数を返します。これは列ヘッダーにクリックハンドラーをアタッチする際に便利です。 + +## テーブルオプション (Table Options) + +### `sortingFns` + +```tsx +sortingFns?: Record +``` + +このオプションを使用すると、カスタムソート関数を定義でき、そのキーを列の `sortingFn` オプションで参照できます。 +例: + +```tsx +declare module '@tanstack/table-core' { + interface SortingFns { + myCustomSorting: SortingFn + } +} + +const column = columnHelper.data('key', { + sortingFn: 'myCustomSorting', +}) + +const table = useReactTable({ + columns: [column], + sortingFns: { + myCustomSorting: (rowA: any, rowB: any, columnId: any): number => + rowA.getValue(columnId).value < rowB.getValue(columnId).value ? 1 : -1, + }, +}) +``` + +### `manualSorting` + +```tsx +manualSorting?: boolean +``` + +テーブルの手動ソートを有効にします。これが `true` の場合、データをテーブルに渡す前にソートする必要があります。これはサーバーサイドソートを行う場合に便利です。 + +### `onSortingChange` + +```tsx +onSortingChange?: OnChangeFn +``` + +提供されている場合、この関数は `state.sorting` が変更されると `updaterFn` と共に呼び出されます。これによりデフォルトの内部状態管理が上書きされるため、テーブルの外部で状態変更を完全または部分的に永続化する必要があります。 + +### `enableSorting` + +```tsx +enableSorting?: boolean +``` + +テーブルのソートを有効/無効にします。 + +### `enableSortingRemoval` + +```tsx +enableSortingRemoval?: boolean +``` + +テーブルのソート削除機能を有効/無効にします。 +- `true` の場合、ソート順序は次のように循環します: 'none' -> 'desc' -> 'asc' -> 'none' -> ... +- `false` の場合、ソート順序は次のように循環します: 'none' -> 'desc' -> 'asc' -> 'desc' -> 'asc' -> ... + +### `enableMultiRemove` + +```tsx +enableMultiRemove?: boolean +``` + +マルチソートの削除機能を有効/無効にします。 + +### `enableMultiSort` + +```tsx +enableMultiSort?: boolean +``` + +テーブルのマルチソートを有効/無効にします。 + +### `sortDescFirst` + +```tsx +sortDescFirst?: boolean +``` + +`true` の場合、すべてのソートは最初のトグル状態として降順をデフォルトとします。 + +### `getSortedRowModel` + +```tsx +getSortedRowModel?: (table: Table) => () => RowModel +``` + +この関数はソートされた行モデルを取得するために使用されます。サーバーサイドソートを使用している場合、この関数は必要ありません。クライアントサイドソートを使用するには、アダプターからエクスポートされた `getSortedRowModel()` をテーブルに渡すか、独自の実装を提供します。 + +### `maxMultiSortColCount` + +```tsx +maxMultiSortColCount?: number +``` + +マルチソート可能な列の最大数を設定します。 + +### `isMultiSortEvent` + +```tsx +isMultiSortEvent?: (e: unknown) => boolean +``` + +マルチソートイベントをトリガーするかどうかを判断するためのカスタム関数を渡します。これはソートトグルハンドラーからのイベントを受け取り、イベントがマルチソートをトリガーする必要がある場合は `true` を返す必要があります。 + +## テーブルAPI (Table API) + +### `setSorting` + +```tsx +setSorting: (updater: Updater) => void +``` + +`state.sorting` 状態を設定または更新します。 + +### `resetSorting` + +```tsx +resetSorting: (defaultState?: boolean) => void +``` + +**ソート**状態を `initialState.sorting` にリセットします。または `true` を渡してデフォルトの空白状態 `[]` に強制的にリセットします。 + +### `getPreSortedRowModel` + +```tsx +getPreSortedRowModel: () => RowModel +``` + +ソートが適用される前のテーブルの行モデルを返します。 + +### `getSortedRowModel` + +```tsx +getSortedRowModel: () => RowModel +``` + +ソートが適用された後のテーブルの行モデルを返します。 diff --git a/docs/ja/config.json b/docs/ja/config.json new file mode 100644 index 0000000000..4e8d471fc5 --- /dev/null +++ b/docs/ja/config.json @@ -0,0 +1,790 @@ +{ + "$schema": "https://raw.githubusercontent.com/TanStack/tanstack.com/main/tanstack-docs-config.schema.json", + "docSearch": { + "appId": "74SF5EKVW9", + "apiKey": "9fc015a3310be6669ed66c6c459f319f", + "indexName": "tanstack-table" + }, + "sections": [ + { + "label": "はじめに", + "children": [ + { + "label": "イントロダクション", + "to": "introduction" + }, + { + "label": "概要", + "to": "overview" + }, + { + "label": "インストール", + "to": "installation" + }, + { + "label": "V8への移行", + "to": "guide/migrating" + }, + { + "label": "FAQ", + "to": "faq" + } + ], + "frameworks": [ + { + "label": "angular", + "children": [ + { + "label": "Angularテーブルアダプター", + "to": "framework/angular/angular-table" + } + ] + }, + { + "label": "lit", + "children": [ + { + "label": "Litテーブルアダプター", + "to": "framework/lit/lit-table" + } + ] + }, + { + "label": "qwik", + "children": [ + { + "label": "Qwikテーブルアダプター", + "to": "framework/qwik/qwik-table" + } + ] + }, + { + "label": "react", + "children": [ + { + "label": "Reactテーブルアダプター", + "to": "framework/react/react-table" + } + ] + }, + { + "label": "solid", + "children": [ + { + "label": "Solidテーブルアダプター", + "to": "framework/solid/solid-table" + } + ] + }, + { + "label": "svelte", + "children": [ + { + "label": "Svelteテーブルアダプター", + "to": "framework/svelte/svelte-table" + } + ] + }, + { + "label": "vue", + "children": [ + { + "label": "Vueテーブルアダプター", + "to": "framework/vue/vue-table" + } + ] + }, + { + "label": "vanilla", + "children": [ + { + "label": "Vanilla JS (フレームワークなし)", + "to": "vanilla" + } + ] + } + ] + }, + { + "label": "コアガイド", + "children": [ + { + "label": "データ", + "to": "guide/data" + }, + { + "label": "カラム定義", + "to": "guide/column-defs" + }, + { + "label": "テーブルインスタンス", + "to": "guide/tables" + }, + { + "label": "行モデル", + "to": "guide/row-models" + }, + { + "label": "行", + "to": "guide/rows" + }, + { + "label": "セル", + "to": "guide/cells" + }, + { + "label": "ヘッダーグループ", + "to": "guide/header-groups" + }, + { + "label": "ヘッダー", + "to": "guide/headers" + }, + { + "label": "カラム", + "to": "guide/columns" + } + ], + "frameworks": [ + { + "label": "angular", + "children": [ + { + "label": "テーブル状態", + "to": "framework/angular/guide/table-state" + } + ] + }, + { + "label": "lit", + "children": [ + { + "label": "テーブル状態", + "to": "framework/lit/guide/table-state" + } + ] + }, + { + "label": "qwik", + "children": [ + { + "label": "テーブル状態", + "to": "framework/qwik/guide/table-state" + } + ] + }, + { + "label": "react", + "children": [ + { + "label": "テーブル状態", + "to": "framework/react/guide/table-state" + } + ] + }, + { + "label": "solid", + "children": [ + { + "label": "テーブル状態", + "to": "framework/solid/guide/table-state" + } + ] + }, + { + "label": "svelte", + "children": [ + { + "label": "テーブル状態", + "to": "framework/svelte/guide/table-state" + } + ] + }, + { + "label": "vue", + "children": [ + { + "label": "テーブル状態", + "to": "framework/vue/guide/table-state" + } + ] + }, + { + "label": "vanilla", + "children": [ + { + "label": "テーブル状態", + "to": "framework/vanilla/guide/table-state" + } + ] + } + ] + }, + { + "label": "機能ガイド", + "children": [ + { + "label": "カラム順序", + "to": "guide/column-ordering" + }, + { + "label": "カラム固定", + "to": "guide/column-pinning" + }, + { + "label": "カラムサイズ調整", + "to": "guide/column-sizing" + }, + { + "label": "カラム表示/非表示", + "to": "guide/column-visibility" + }, + { + "label": "カラムフィルタリング", + "to": "guide/column-filtering" + }, + { + "label": "グローバルフィルタリング", + "to": "guide/global-filtering" + }, + { + "label": "ファジーフィルタリング", + "to": "guide/fuzzy-filtering" + }, + { + "label": "カラムファセット", + "to": "guide/column-faceting" + }, + { + "label": "グローバルファセット", + "to": "guide/global-faceting" + }, + { + "label": "グループ化", + "to": "guide/grouping" + }, + { + "label": "展開", + "to": "guide/expanding" + }, + { + "label": "ページネーション", + "to": "guide/pagination" + }, + { + "label": "行固定", + "to": "guide/row-pinning" + }, + { + "label": "行選択", + "to": "guide/row-selection" + }, + { + "label": "ソート", + "to": "guide/sorting" + }, + { + "label": "仮想化", + "to": "guide/virtualization" + }, + { + "label": "カスタム機能", + "to": "guide/custom-features" + } + ] + }, + { + "label": "コアAPI", + "children": [ + { + "label": "カラム定義", + "to": "api/core/column-def" + }, + { + "label": "テーブル", + "to": "api/core/table" + }, + { + "label": "カラム", + "to": "api/core/column" + }, + { + "label": "ヘッダーグループ", + "to": "api/core/header-group" + }, + { + "label": "ヘッダー", + "to": "api/core/header" + }, + { + "label": "行", + "to": "api/core/row" + }, + { + "label": "セル", + "to": "api/core/cell" + } + ] + }, + { + "label": "機能API", + "children": [ + { + "label": "カラムフィルタリング", + "to": "api/features/column-filtering" + }, + { + "label": "カラムファセット", + "to": "api/features/column-faceting" + }, + { + "label": "カラム順序", + "to": "api/features/column-ordering" + }, + { + "label": "カラム固定", + "to": "api/features/column-pinning" + }, + { + "label": "カラムサイズ調整", + "to": "api/features/column-sizing" + }, + { + "label": "カラム表示/非表示", + "to": "api/features/column-visibility" + }, + { + "label": "グローバルファセット", + "to": "api/features/global-faceting" + }, + { + "label": "グローバルフィルタリング", + "to": "api/features/global-filtering" + }, + { + "label": "ソート", + "to": "api/features/sorting" + }, + { + "label": "グループ化", + "to": "api/features/grouping" + }, + { + "label": "展開", + "to": "api/features/expanding" + }, + { + "label": "ページネーション", + "to": "api/features/pagination" + }, + { + "label": "行固定", + "to": "api/features/row-pinning" + }, + { + "label": "行選択", + "to": "api/features/row-selection" + } + ] + }, + { + "label": "エンタープライズ", + "children": [ + { + "label": "AG Grid", + "to": "enterprise/ag-grid" + } + ] + }, + { + "label": "例", + "children": [], + "frameworks": [ + { + "label": "angular", + "children": [ + { + "to": "framework/angular/examples/basic", + "label": "基本" + }, + { + "to": "framework/angular/examples/grouping", + "label": "カラムグループ化" + }, + { + "to": "framework/angular/examples/column-ordering", + "label": "カラム順序" + }, + { + "to": "framework/angular/examples/column-pinning", + "label": "カラム固定" + }, + { + "to": "framework/angular/examples/column-pinning-sticky", + "label": "固定カラム" + }, + { + "to": "framework/angular/examples/column-visibility", + "label": "カラム表示/非表示" + }, + { + "to": "framework/angular/examples/filters", + "label": "カラムフィルター" + }, + { + "to": "framework/angular/examples/row-selection", + "label": "行選択" + }, + { + "to": "framework/angular/examples/expanding", + "label": "展開" + }, + { + "to": "framework/angular/examples/sub-components", + "label": "サブコンポーネント" + }, + { + "to": "framework/angular/examples/signal-input", + "label": "シグナル入力" + }, + { + "to": "framework/angular/examples/editable", + "label": "編集可能データ" + }, + { + "to": "framework/angular/examples/row-dnd", + "label": "行DnD" + }, + { + "to": "framework/angular/examples/column-resizing-performant", + "label": "パフォーマンス重視のカラムサイズ変更" + } + ] + }, + { + "label": "lit", + "children": [ + { + "to": "framework/lit/examples/basic", + "label": "基本" + }, + { + "to": "framework/lit/examples/column-sizing", + "label": "カラムサイズ調整" + }, + { + "to": "framework/lit/examples/filters", + "label": "フィルター" + }, + { + "to": "framework/lit/examples/row-selection", + "label": "行選択" + }, + { + "to": "framework/lit/examples/sorting", + "label": "ソート" + }, + { + "to": "framework/lit/examples/virtualized-rows", + "label": "仮想化行" + } + ] + }, + { + "label": "qwik", + "children": [ + { + "to": "framework/qwik/examples/basic", + "label": "基本" + }, + { + "to": "framework/qwik/examples/filters", + "label": "フィルター" + }, + { + "to": "framework/qwik/examples/row-selection", + "label": "行選択" + }, + { + "to": "framework/qwik/examples/sorting", + "label": "ソート" + } + ] + }, + { + "label": "react", + "children": [ + { + "to": "framework/react/examples/basic", + "label": "基本" + }, + { + "to": "framework/react/examples/column-groups", + "label": "ヘッダーグループ" + }, + { + "to": "framework/react/examples/filters", + "label": "カラムフィルター" + }, + { + "to": "framework/react/examples/filters-faceted", + "label": "カラムフィルター (ファセット)" + }, + { + "to": "framework/react/examples/filters-fuzzy", + "label": "ファジー検索フィルター" + }, + { + "to": "framework/react/examples/column-ordering", + "label": "カラム順序" + }, + { + "to": "framework/react/examples/column-dnd", + "label": "カラム順序 (DnD)" + }, + { + "to": "framework/react/examples/column-pinning", + "label": "カラム固定" + }, + { + "to": "framework/react/examples/column-pinning-sticky", + "label": "固定カラム" + }, + { + "to": "framework/react/examples/column-sizing", + "label": "カラムサイズ調整" + }, + { + "to": "framework/react/examples/column-resizing-performant", + "label": "パフォーマンス重視のカラムサイズ変更" + }, + { + "to": "framework/react/examples/column-visibility", + "label": "カラム表示/非表示" + }, + { + "to": "framework/react/examples/editable-data", + "label": "編集可能データ" + }, + { + "to": "framework/react/examples/expanding", + "label": "展開" + }, + { + "to": "framework/react/examples/sub-components", + "label": "サブコンポーネント" + }, + { + "to": "framework/react/examples/fully-controlled", + "label": "完全制御" + }, + { + "to": "framework/react/examples/grouping", + "label": "グループ化" + }, + { + "to": "framework/react/examples/pagination", + "label": "ページネーション" + }, + { + "to": "framework/react/examples/pagination-controlled", + "label": "ページネーション制御" + }, + { + "to": "framework/react/examples/row-dnd", + "label": "行DnD" + }, + { + "to": "framework/react/examples/row-pinning", + "label": "行固定" + }, + { + "to": "framework/react/examples/row-selection", + "label": "行選択" + }, + { + "to": "framework/react/examples/sorting", + "label": "ソート" + }, + { + "to": "framework/react/examples/virtualized-columns", + "label": "仮想化カラム" + }, + { + "to": "framework/react/examples/virtualized-columns-experimental", + "label": "仮想化カラム (実験的)" + }, + { + "to": "framework/react/examples/virtualized-rows", + "label": "仮想化行" + }, + { + "to": "framework/react/examples/virtualized-rows-experimental", + "label": "仮想化行 (実験的)" + }, + { + "to": "framework/react/examples/virtualized-infinite-scrolling", + "label": "仮想化無限スクロール" + }, + { + "to": "framework/react/examples/kitchen-sink", + "label": "キッチンシンク" + }, + { + "to": "framework/react/examples/bootstrap", + "label": "React Bootstrap" + }, + { + "to": "framework/react/examples/material-ui-pagination", + "label": "Material UIページネーション" + }, + { + "to": "framework/react/examples/full-width-table", + "label": "React全幅テーブル" + }, + { + "to": "framework/react/examples/full-width-resizable-table", + "label": "React全幅リサイズ可能テーブル" + }, + { + "to": "framework/react/examples/custom-features", + "label": "カスタム機能" + }, + { + "to": "framework/react/examples/query-router-search-params", + "label": "クエリルーター検索パラメータ" + } + ] + }, + { + "label": "solid", + "children": [ + { + "to": "framework/solid/examples/basic", + "label": "基本" + }, + { + "to": "framework/solid/examples/column-groups", + "label": "カラムグループ" + }, + { + "to": "framework/solid/examples/column-ordering", + "label": "カラム順序" + }, + { + "to": "framework/solid/examples/column-visibility", + "label": "カラム表示/非表示" + }, + { + "to": "framework/solid/examples/filters", + "label": "フィルター" + }, + { + "to": "framework/solid/examples/sorting", + "label": "ソート" + }, + { + "to": "framework/solid/examples/bootstrap", + "label": "Solid Bootstrap" + } + ] + }, + { + "label": "svelte", + "children": [ + { + "to": "framework/svelte/examples/basic", + "label": "基本" + }, + { + "to": "framework/svelte/examples/column-groups", + "label": "カラムグループ" + }, + { + "to": "framework/svelte/examples/column-ordering", + "label": "カラム順序" + }, + { + "to": "framework/svelte/examples/column-pinning", + "label": "カラム固定" + }, + { + "to": "framework/svelte/examples/column-visibility", + "label": "カラム表示/非表示" + }, + { + "to": "framework/svelte/examples/filtering", + "label": "フィルタリング" + }, + { + "to": "framework/svelte/examples/sorting", + "label": "ソート" + } + ] + }, + { + "label": "vue", + "children": [ + { + "to": "framework/vue/examples/basic", + "label": "基本" + }, + { + "to": "framework/vue/examples/column-ordering", + "label": "カラム順序" + }, + { + "to": "framework/vue/examples/column-pinning", + "label": "カラム固定" + }, + { + "to": "framework/vue/examples/pagination", + "label": "ページネーション" + }, + { + "to": "framework/vue/examples/row-selection", + "label": "行選択" + }, + { + "to": "framework/vue/examples/sorting", + "label": "ソート" + }, + { + "to": "framework/vue/examples/sub-components", + "label": "サブコンポーネント" + }, + { + "to": "framework/vue/examples/filters", + "label": "カラムフィルター" + }, + { + "to": "framework/vue/examples/virtualized-rows", + "label": "仮想化行" + }, + { + "to": "framework/vue/examples/grouping", + "label": "グループ化" + } + ] + }, + { + "label": "vanilla", + "children": [ + { + "to": "framework/vanilla/examples/basic", + "label": "基本" + }, + { + "to": "framework/vanilla/examples/pagination", + "label": "ページネーション" + }, + { + "to": "framework/vanilla/examples/sorting", + "label": "ソート" + } + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/docs/ja/enterprise/ag-grid.md b/docs/ja/enterprise/ag-grid.md new file mode 100644 index 0000000000..79dfb65023 --- /dev/null +++ b/docs/ja/enterprise/ag-grid.md @@ -0,0 +1,44 @@ +--- +source-updated-at: '2023-12-17T15:54:46.000Z' +translation-updated-at: '2025-05-05T19:30:03.237Z' +title: AG Grid +--- +

+ + + +

+ +私たちはTanStack Tableを高く評価していますが、カスタマーサポートやエンタープライズレベルの完成度を備えた「バッテリー込み」の製品ではないことも理解しています。しかし、一部のユーザーにはそれが必要な場合もあるでしょう!そこで、皆様にAG Gridをご紹介します。AG Gridはエンタープライズグレードのデータグリッドソリューションで、豊富な機能セットと堅牢なパフォーマンスによりアプリケーションを強化できます。TanStack Tableもデータグリッド実装の強力な選択肢ですが、私たちはユーザーに多様な選択肢を提供し、それぞれの要件に最適なソリューションを選んでいただきたいと考えています。AG Gridはそのような選択肢の一つであり、その能力を紹介できることを嬉しく思います。 + +## [AG Grid](https://ag-grid.com/react-data-grid/?utm_source=reacttable&utm_campaign=githubreacttable)を選ぶ理由 + +次のプロジェクトでAG Gridを検討すべき理由をご紹介します: + +### 包括的な機能セット + +AG Gridは多様で強力なデータグリッドソリューションを実現する豊富な機能を提供します。高度なソート、フィルタリング、グループ化機能から、列の固定、マルチレベルヘッダー、ツリーデータ構造のサポートまで、複雑なエンタープライズアプリケーションのニーズに対応するツールが揃っています。これにより、アプリケーションの独自の要件を満たす動的でインタラクティブなデータグリッドを作成できます。 + +### 高いパフォーマンス + +大規模なデータセットを扱い、優れたパフォーマンスを実現する点で、AG Gridは卓越した結果を提供します。高度に最適化されたレンダリング技術、効率的なデータ更新、仮想化を採用しており、数千から数百万行のデータを扱う場合でもスムーズなスクロールと高速な応答時間を保証します。AG Gridのパフォーマンス最適化は、高速なデータ操作と可視化を必要とするアプリケーションに最適です。 + +### カスタマイズと拡張性 + +AG Gridは高度なカスタマイズと拡張が可能な設計になっており、特定のニーズに合わせてグリッドを調整できます。カスタム機能をシームレスに統合できる豊富なAPIとイベントを提供します。カスタムセルレンダラー、エディター、フィルター、アグリゲーターを定義して、グリッドの動作と外観を強化できます。また、様々なテーマをサポートしており、アプリケーションのデザインに合わせてグリッドの視覚スタイルを調整可能です。 + +### エンタープライズニーズへの対応 + +エンタープライズ向けソリューションとして、AG Gridは複雑なビジネスアプリケーションの要件に対応しています。行グループ化、列固定、サーバーサイド行モデル、マスター/ディテールグリッド、リッチ編集機能などのエンタープライズ向け機能を提供します。AG Gridは他のエンタープライズフレームワークやライブラリとも良好に統合するため、大規模プロジェクトでも信頼性の高い選択肢となります。 + +### 活発な開発とコミュニティサポート + +AG Gridは活発な開発と活気ある開発者コミュニティの恩恵を受けています。AG Gridの開発チームは常に新機能と機能強化を導入し、業界の変化するニーズに対応するよう製品を進化させ続けています。フォーラム、ドキュメント、サンプルが充実しており、AG Gridの可能性を最大限に活用するためのサポートが手厚く提供されています。 + +## まとめ + +TanStack Tableがデータグリッド実装の強力で柔軟な選択肢であることに変わりはありませんが、プロジェクトごとに異なる要件があることを理解しています。AG Gridは、特にエンタープライズグレードのソリューションを必要とする場合に有力な選択肢となり得ます。包括的な機能セット、高いパフォーマンス、カスタマイズオプション、エンタープライズ要件への対応により、堅牢でスケーラブルなデータグリッドソリューションを求めるプロジェクトに最適です。 + +AG Gridのウェブサイトを訪問し、デモを試してさらに詳しく調べてみることをお勧めします。TanStack TableとAG Gridにはそれぞれ独自の強みと考慮点があることを忘れないでください。私たちはユーザーに選択肢を提供し、具体的なユースケースに最適なソリューションを選んでいただけるようサポートしたいと考えています。 + +[AG Gridのウェブサイト](https://www.ag-grid.com)を訪れてください。 diff --git a/docs/ja/faq.md b/docs/ja/faq.md new file mode 100644 index 0000000000..0eb1d3d8fe --- /dev/null +++ b/docs/ja/faq.md @@ -0,0 +1,166 @@ +--- +source-updated-at: '2024-03-28T21:06:30.000Z' +translation-updated-at: '2025-05-05T19:24:20.984Z' +title: FAQ +--- +## 無限レンダリングループを防ぐ方法 + +Reactを使用している場合、無限レンダリングを引き起こす非常に一般的な落とし穴があります。`columns`、`data`、または`state`に安定した参照を提供しないと、テーブルの状態が変更されるたびにReactが無限に再レンダリングを繰り返します。 + +なぜこれが起こるのでしょうか?これはTanStack Tableのバグでしょうか?**いいえ**、そうではありません。*これはReactの基本的な動作*であり、columns、data、stateを適切に管理することで防ぐことができます。 + +TanStack Tableは、テーブルに渡される`data`または`columns`が変更されたとき、またはテーブルの状態が変更されたときに再レンダリングをトリガーするように設計されています。 + +> `columns`や`data`に安定した参照を提供しないと、無限の再レンダリングループが発生する可能性があります。 + +### 落とし穴1: 毎回のレンダリングで新しいcolumnsやdataを作成する + +```js +export default function MyComponent() { + //😵 悪い例: `columns`が毎回のレンダリングで新しい配列として再定義されるため、無限レンダリングループが発生します! + const columns = [ + // ... + ]; + + //😵 悪い例: `data`が毎回のレンダリングで新しい配列として再定義されるため、無限レンダリングループが発生します! + const data = [ + // ... + ]; + + //❌ columnsとdataが`useReactTable`と同じスコープで定義されており、安定した参照がないため、無限ループが発生します! + const table = useReactTable({ + columns, + data, + }); + + return ...
; +} +``` + +### 解決策1: useMemoまたはuseStateで安定した参照を提供する + +Reactでは、変数に「安定した」参照を提供するために、コンポーネントの外側/上部で定義するか、`useMemo`や`useState`を使用するか、サードパーティの状態管理ライブラリ(ReduxやReact Queryなど😉)を使用します。 + +```js +//✅ 良い例: コンポーネントの外側でcolumnsを定義 +const columns = [ + // ... +]; + +//✅ 良い例: コンポーネントの外側でdataを定義 +const data = [ + // ... +]; + +// 通常、columnsとdataはコンポーネント内で定義する方が実用的なので、`useMemo`や`useState`を使用して安定した参照を提供します +export default function MyComponent() { + //✅ 良い例: `columns`が安定した参照を持つため、無限レンダリングループが発生しません + const columns = useMemo(() => [ + // ... + ], []); + + //✅ 良い例: `data`が安定した参照を持つため、無限レンダリングループが発生しません + const [data, setData] = useState(() => [ + // ... + ]); + + // columnsとdataが安定した参照を持つため、無限ループが発生しません! + const table = useReactTable({ + columns, + data, + }); + + return ...
; +} +``` + +### 落とし穴2: columnsやdataを直接変更する + +初期の`columns`や`data`に安定した参照を提供していても、それらを直接変更すると無限ループに陥る可能性があります。これは最初は気づきにくい落とし穴です。単純なインラインの`data.filter()`でさえ、注意しないと無限ループを引き起こす可能性があります。 + +```js +export default function MyComponent() { + //✅ 良い例 + const columns = useMemo(() => [ + // ... + ], []); + + //✅ 良い例 (React Queryは自動的にdataに安定した参照を提供します) + const { data, isLoading } = useQuery({ + //... + }); + + const table = useReactTable({ + columns, + //❌ 悪い例: `data`が直接変更されるため(安定した参照が破壊される)、無限レンダリングループが発生します + data: data?.filter(d => d.isActive) ?? [], + }); + + return ...
; +} +``` + +### 解決策2: データ変換をメモ化する + +無限ループを防ぐためには、データ変換を常にメモ化する必要があります。これは`useMemo`などで行うことができます。 + +```js +export default function MyComponent() { + //✅ 良い例 + const columns = useMemo(() => [ + // ... + ], []); + + //✅ 良い例 + const { data, isLoading } = useQuery({ + //... + }); + + //✅ 良い例: `filteredData`がメモ化されているため、無限レンダリングループが発生しません + const filteredData = useMemo(() => data?.filter(d => d.isActive) ?? [], [data]); + + const table = useReactTable({ + columns, + data: filteredData, // 安定した参照! + }); + + return ...
; +} +``` + +### React Forget + +React Forgetがリリースされれば、これらの問題は過去のものになるかもしれません。またはSolid.jsを使うのも手です... 🤓 + +## データ変更時にテーブルの状態が自動リセットされるのを防ぐ方法 + +ほとんどのプラグインは、データソースが変更されたときに通常リセットされるべき状態を使用しますが、外部でデータをフィルタリングしている場合や、データを不変的に編集しながら表示している場合、または単にデータに対して自動的にテーブルの状態をリセットさせたくない操作を行っている場合には、これを抑制する必要があるかもしれません。 + +そのような状況では、各プラグインはデータや他の依存関係が変更されたときに内部で状態が自動リセットされるのを無効にする方法を提供しています。いずれかを`false`に設定することで、自動リセットがトリガーされるのを防ぐことができます。 + +以下は、テーブルの`data`ソースを編集している間に、通常発生するすべての状態変更を基本的に停止するReactベースの例です: + +```js +const [data, setData] = React.useState([]) +const skipPageResetRef = React.useRef() + +const updateData = newData => { + // この関数でデータが更新されるとき、すべての自動リセットを無効にするフラグを設定します + skipPageResetRef.current = true + + setData(newData) +} + +React.useEffect(() => { + // テーブルが更新された後、常にフラグを削除します + skipPageResetRef.current = false +}) + +useReactTable({ + ... + autoResetPageIndex: !skipPageResetRef.current, + autoResetExpanded: !skipPageResetRef.current, +}) +``` + +これで、データを更新しても上記のテーブル状態は自動的にリセットされません! diff --git a/docs/ja/framework/angular/angular-table.md b/docs/ja/framework/angular/angular-table.md new file mode 100644 index 0000000000..beb8a12c03 --- /dev/null +++ b/docs/ja/framework/angular/angular-table.md @@ -0,0 +1,293 @@ +--- +source-updated-at: '2025-01-20T06:07:15.000Z' +translation-updated-at: '2025-05-05T19:24:47.875Z' +title: Angularテーブルアダプター +--- +`@tanstack/angular-table`アダプターは、コアのテーブルロジックをラップするものです。その主な役割は、状態を「Angularシグナル」の方法で管理し、型を提供し、セル/ヘッダー/フッターテンプレートのレンダリング実装を行うことです。 + +## エクスポート + +`@tanstack/angular-table`は、`@tanstack/table-core`のすべてのAPIと以下を再エクスポートします: + +### `createAngularTable` + +テーブルオプションを返すオプション関数または計算値を受け取り、テーブルを返します。 + +```ts +import {createAngularTable} from '@tanstack/angular-table' + +export class AppComponent { + data = signal([]) + + table = createAngularTable(() => ({ + data: this.data(), + columns: defaultColumns, + getCoreRowModel: getCoreRowModel(), + })) +} + +// ...テンプレートでテーブルをレンダリング +``` + +### `FlexRender` + +セル/ヘッダー/フッターテンプレートを動的な値でレンダリングするためのAngular構造ディレクティブです。 + +FlexRenderは、Angularがサポートするあらゆるタイプのコンテンツをサポートします: + +- 文字列、または`innerHTML`経由のHTML文字列 +- [TemplateRef](https://angular.dev/api/core/TemplateRef) +- `FlexRenderComponent`でラップされた[Component](https://angular.dev/api/core/Component) + +テーブルのセルをレンダリングするには、`cell.renderValue`や`cell.getValue` APIを使用できます。ただし、これらのAPIは生のセル値(アクセサ関数からの値)のみを出力します。`cell: () => any`カラム定義オプションを使用している場合、アダプターの`FlexRenderDirective`を使用する必要があります。 + +セルカラム定義は**リアクティブ**であり、**インジェクションコンテキスト**で実行されるため、サービスを注入したりシグナルを使用してレンダリングされるコンテンツを自動的に変更したりできます。 + +#### 例 + +```ts +@Component({ + imports: [FlexRenderDirective], + //... +}) +class YourComponent {} +``` + +```angular-html + +@for (row of table.getRowModel().rows; track row.id) { + + @for (cell of row.getVisibleCells(); track cell.id) { + + + + {{ cell }} + +
+
+ + } + +} + +``` + +#### コンポーネントのレンダリング + +特定のカラムのヘッダー/セル/フッターにコンポーネントをレンダリングするには、`FlexRenderComponent`に`ComponentType`を渡し、入力、出力、カスタムインジェクターなどのパラメータを含めることができます。 + +```ts +import {flexRenderComponent} from "./flex-render-component"; +import {ChangeDetectionStrategy, input, output} from "@angular/core"; + +@Component({ + template: ` + ... + `, + standalone: true, + changeDetectionStrategy: ChangeDetectionStrategy.OnPush, + host: { + '(click)': 'clickEvent.emit($event)' + } +}) +class CustomCell { + readonly content = input.required(); + readonly cellType = input(); + + // セルクリックごとに発火する出力 + readonly clickEvent = output(); +} + +class AppComponent { + columns: ColumnDef[] = [ + { + id: 'custom-cell', + header: () => { + const translateService = inject(TranslateService); + return translateService.translate('...'); + }, + cell: (context) => { + return flexRenderComponent( + MyCustomComponent, + { + injector, // オプショナルなインジェクター + inputs: { + // `input.required()`を使用しているため必須の入力 + content: context.row.original.rowProperty, + // cellType? - オプショナルな入力 + }, + outputs: { + clickEvent: () => { + // 何か処理を行う + } + } + } + ) + }, + }, + ] +} +``` + +内部的には、これは[ViewContainerRef#createComponent](https://angular.dev/api/core/ViewContainerRef#createComponent) APIを利用しています。そのため、カスタム入力は@Inputデコレータまたはinput/modelシグナルを使用して宣言する必要があります。 + +`FlexRenderDirective`に渡すpropsに基づいてコンテキスト値を返す`injectFlexRenderContext`関数を通じて、テーブルセルのコンテキストにアクセスできます。 + +```ts +@Component({ + // ... +}) +class CustomCellComponent { + // セルコンポーネントのコンテキスト + readonly context = injectFlexRenderContext>(); + // ヘッダー/フッターコンポーネントのコンテキスト + readonly context = injectFlexRenderContext>(); +} +``` + +あるいは、コンポーネントタイプを対応するカラム定義に渡すことで、特定のカラムのヘッダー、セル、またはフッターにコンポーネントをレンダリングできます。これらのカラム定義は、`context`とともに`flexRender`ディレクティブに提供されます。 + +```ts +class AppComponent { + columns: ColumnDef[] = [ + { + id: 'select', + header: () => TableHeadSelectionComponent, + cell: () => TableRowSelectionComponent, + }, + ] +} +``` + +```angular-html + + {{ headerCell }} + +``` + +`flexRender`ディレクティブで提供される`context`のプロパティは、コンポーネントからアクセス可能です。コンポーネントが必要とするコンテキストプロパティを明示的に定義できます。この例では、flexRenderに提供されるコンテキストはHeaderContext型です。HeaderContextのプロパティである`table`、`column`、`header`のうち、`table`入力シグナルがコンポーネントで使用されるように定義されています。コンテキストプロパティのいずれかが必要な場合は、自由に使用してください。このアプローチを使用する場合、コンテキストプロパティへのアクセスを定義する際には、入力シグナルのみがサポートされていることに注意してください。 + +```angular-ts +@Component({ + template: ` + + `, + // ... +}) +export class TableHeadSelectionComponent { + //column = input.required>() + //header = input.required>() + table = input.required>() +} +``` + +#### TemplateRefのレンダリング + +特定のカラムのヘッダー/セル/フッターにTemplateRefをレンダリングするには、TemplateRefをカラム定義に渡します。 + +TemplateRefのデータには、flexRenderのpropsフィールドで渡された内容に基づいて値が設定される`$implicit`プロパティを介してアクセスできます。 + +ほとんどの場合、各TemplateRefは以下のようにセルタイプに基づいた`$implicit`コンテキストでレンダリングされます: + +- ヘッダー: `HeaderContext` +- セル: `CellContext`, +- フッター: `HeaderContext` + +```angular-html + + + {{ cell }} + +
+
+ + + + +``` + +完全な例: + +```angular-ts +import type { + CellContext, + ColumnDef, + HeaderContext, +} from '@tanstack/angular-table' +import {Component, TemplateRef, viewChild} from '@angular/core' + +@Component({ + template: ` + + @for (row of table.getRowModel().rows; track row.id) { + + @for (cell of row.getVisibleCells(); track cell.id) { + + + + {{ cell }} + +
+
+ + } + + } + + + + {{ context.getValue() }} + + + {{ context.getValue() }} + + `, +}) +class AppComponent { + customHeader = + viewChild.required }>>( + 'customHeader' + ) + customCell = + viewChild.required }>>( + 'customCell' + ) + + columns: ColumnDef[] = [ + { + id: 'customCell', + header: () => this.customHeader(), + cell: () => this.customCell(), + }, + ] +} +``` diff --git a/docs/ja/framework/angular/guide/table-state.md b/docs/ja/framework/angular/guide/table-state.md new file mode 100644 index 0000000000..8e58c09b5e --- /dev/null +++ b/docs/ja/framework/angular/guide/table-state.md @@ -0,0 +1,215 @@ +--- +source-updated-at: '2024-07-27T18:15:45.000Z' +translation-updated-at: '2025-05-05T19:26:12.183Z' +title: テーブル状態 +--- +## テーブルステート (Angular) ガイド + +TanStack Tableは、テーブルの状態を保存・管理するためのシンプルな内部ステート管理システムを備えています。また、独自のステート管理で管理が必要な状態を選択的に取り出すことも可能です。このガイドでは、テーブルの状態を操作・管理するさまざまな方法について説明します。 + +### テーブルステートへのアクセス + +テーブルステートを機能させるために特別な設定は必要ありません。`state`、`initialState`、または`on[State]Change`テーブルオプションに何も渡さない場合、テーブルは内部で独自に状態を管理します。この内部状態の任意の部分には、`table.getState()`テーブルインスタンスAPIを使用してアクセスできます。 + +```ts +table = createAngularTable(() => ({ + columns: this.columns, + data: this.data(), + //... +})) + +someHandler() { + console.log(this.table.getState()) //内部状態全体にアクセス + console.log(this.table.getState().rowSelection) //行選択状態のみにアクセス +} +``` + +### カスタム初期状態 + +特定の状態について初期値をカスタマイズするだけでよい場合、依然としてステートを自分で管理する必要はありません。テーブルインスタンスの`initialState`オプションに値を設定するだけで済みます。 + +```jsx +table = createAngularTable(() => ({ + columns: this.columns, + data: this.data(), + initialState: { + columnOrder: ['age', 'firstName', 'lastName'], //初期カラム順をカスタマイズ + columnVisibility: { + id: false //デフォルトでidカラムを非表示 + }, + expanded: true, //デフォルトですべての行を展開 + sorting: [ + { + id: 'age', + desc: true //デフォルトでageで降順ソート + } + ] + }, + //... +})) +``` + +> **注**: 各状態は`initialState`または`state`のいずれか一方でのみ指定してください。特定の状態値を`initialState`と`state`の両方に渡した場合、`state`で初期化された値が`initialState`の対応する値を上書きします。 + +### 制御されたステート + +アプリケーションの他の領域でテーブルステートに簡単にアクセスする必要がある場合、TanStack Tableでは独自のステート管理システムでテーブルステートの一部または全部を簡単に制御・管理できます。これは、`state`と`on[State]Change`テーブルオプションに独自のステートとステート管理関数を渡すことで実現します。 + +#### 個別に制御されたステート + +必要なステートのみを制御できます。すべてのテーブルステートを制御する必要はありません。ケースバイケースで必要なステートのみを制御することを推奨します。 + +特定のステートを制御するには、対応する`state`値と`on[State]Change`関数の両方をテーブルインスタンスに渡す必要があります。 + +「手動」のサーバーサイドデータ取得シナリオで、フィルタリング、ソート、ページネーションを例に挙げましょう。フィルタリング、ソート、ページネーションの状態は独自のステート管理で保存できますが、APIが関心を持たないカラム順序やカラム表示状態などは除外できます。 + +```ts +import {signal} from '@angular/core'; +import {SortingState, ColumnFiltersState, PaginationState} from '@tanstack/angular-table' +import {toObservable} from "@angular/core/rxjs-interop"; +import {combineLatest, switchMap} from 'rxjs'; + +class TableComponent { + readonly columnFilters = signal([]) //デフォルトフィルターなし + readonly sorting = signal([ + { + id: 'age', + desc: true, //デフォルトでageで降順ソート + } + ]) + readonly pagination = signal({ + pageIndex: 0, + pageSize: 15 + }) + + //制御されたステート値を使用してデータを取得 + readonly data$ = combineLatest({ + filters: toObservable(this.columnFilters), + sorting: toObservable(this.sorting), + pagination: toObservable(this.pagination) + }).pipe( + switchMap(({filters, sorting, pagination}) => fetchData(filters, sorting, pagination)) + ) + readonly data = toSignal(this.data$); + + readonly table = createAngularTable(() => ({ + columns: this.columns, + data: this.data(), + //... + state: { + columnFilters: this.columnFilters(), //制御されたステートをテーブルに戻す(内部状態を上書き) + sorting: this.sorting(), + pagination: this.pagination(), + }, + onColumnFiltersChange: updater => { //columnFiltersステートを独自のステート管理に引き上げ + updater instanceof Function + ? this.columnFilters.update(updater) + : this.columnFilters.set(updater) + }, + onSortingChange: updater => { + updater instanceof Function + ? this.sorting.update(updater) + : this.sorting.set(updater) + }, + onPaginationChange: updater => { + updater instanceof Function + ? this.pagination.update(updater) + : this.pagination.set(updater) + }, + })) +} + +//... +``` + +#### 完全に制御されたステート + +あるいは、`onStateChange`テーブルオプションでテーブルステート全体を制御できます。これにより、テーブルステート全体が独自のステート管理システムに引き上げられます。ただし、`columnSizingInfo`ステートのように頻繁に変更される状態値をコンポーネントツリーの上位に引き上げるとパフォーマンス問題を引き起こす可能性があるため、このアプローチには注意が必要です。 + +これを機能させるには、さらにいくつかの工夫が必要かもしれません。`onStateChange`テーブルオプションを使用する場合、`state`の初期値には、使用したいすべての機能に関連するすべてのステート値を入力する必要があります。すべての初期状態値を手動で入力するか、以下のように特別な方法でコンストラクターを使用できます。 + +```ts +class TableComponent { + // 空のテーブルステートを作成、後で上書きします + readonly state = signal({} as TableState); + + // デフォルトのステート値でテーブルインスタンスを作成 + readonly table = createAngularTable(() => ({ + columns: this.columns, + data: this.data(), + // 完全に制御されたステートが内部状態を上書き + state: this.state(), + onStateChange: updater => { + // 状態変更は独自のステート管理に反映されます + this.state.set( + updater instanceof Function ? updater(this.state()) : updater + ) + } + })) + + constructor() { + // 初期テーブルステートを設定 + this.state.set({ + // テーブルインスタンスからすべてのデフォルトステート値を取り込む + ...this.table.initialState, + pagination: { + pageIndex: 0, + pageSize: 15, // オプションで初期ページネーション状態をカスタマイズ + }, + }) + } +} +``` + +### ステート変更コールバック + +これまで、`on[State]Change`と`onStateChange`テーブルオプションが、テーブルステートの変更を独自のステート管理に「引き上げる」働きを見てきました。しかし、これらのオプションを使用する際に注意すべき点がいくつかあります。 + +#### 1. **ステート変更コールバックには、`state`オプションに対応するステート値が必要です** + +`on[State]Change`コールバックを指定すると、テーブルインスタンスはこれが制御されたステートであると認識します。対応する`state`値を指定しない場合、その状態は初期値で「凍結」されます。 + +```ts +class TableComponent { + sorting = signal([]) + + table = createAngularTable(() => ({ + columns: this.columns, + data: this.data(), + //... + state: { + sorting: this.sorting(), // `onSortingChange`を使用するため必須 + }, + onSortingChange: updater => { // `state.sorting`を制御 + updater instanceof Function + ? this.sorting.update(updater) + : this.sorting.set(updater) + } + })) +} +``` + +#### 2. **アップデータは生の値またはコールバック関数のいずれかです** + +`on[State]Change`と`onStateChange`コールバックは、Reactの`setState`関数とまったく同じように機能します。アップデータ値は、新しいステート値か、前のステート値を受け取って新しいステート値を返すコールバック関数のいずれかになります。 + +これにはどのような意味があるでしょうか? `on[State]Change`コールバックに追加のロジックを含めたい場合、新しいアップデータ値が関数か値かを確認する必要があるということです。 + +これが、上記の例で`updater instanceof Function ? this.state.update(updater) : this.state.set(updater)`というパターンが見られる理由です。このパターンは、アップデータが関数かどうかをチェックし、関数の場合は前のステート値で関数を呼び出して新しいステート値を取得します。そうでない場合、シグナルは`signal.set`ではなく`signal.update`をアップデータで呼び出す必要があります。 + +### ステートタイプ + +TanStack Tableのすべての複雑なステートには、インポートして使用できる独自のTypeScriptタイプがあります。これは、制御しているステート値に対して正しいデータ構造とプロパティを使用していることを確認するのに便利です。 + +```ts +import {createAngularTable, type SortingState} from '@tanstack/angular-table' + +class TableComponent { + readonly sorting = signal([ + { + id: 'age', // `id`と`desc`プロパティのオートコンプリートが得られます + desc: true, + } + ]) +} +``` diff --git a/docs/ja/framework/lit/guide/table-state.md b/docs/ja/framework/lit/guide/table-state.md new file mode 100644 index 0000000000..784d86c090 --- /dev/null +++ b/docs/ja/framework/lit/guide/table-state.md @@ -0,0 +1,194 @@ +--- +source-updated-at: '2024-05-17T05:10:48.000Z' +translation-updated-at: '2025-05-05T19:25:59.411Z' +title: テーブル状態 +--- +## Table State (Lit) ガイド + +TanStack Tableは、テーブルの状態を保存・管理するためのシンプルな内部状態管理システムを備えています。また、独自の状態管理で扱う必要がある状態を選択的に取り出すことも可能です。このガイドでは、テーブルの状態を操作・管理するさまざまな方法について説明します。 + +### テーブル状態へのアクセス + +テーブル状態を機能させるために特別な設定は必要ありません。`state`、`initialState`、または`on[State]Change`テーブルオプションに何も渡さない場合、テーブルは内部で独自に状態を管理します。この内部状態の任意の部分には、`table.getState()`テーブルインスタンスAPIを使用してアクセスできます。 + +```ts +private tableController = new TableController(this); + +render() { + const table = this.tableController.table({ + columns, + data, + ... + }) + + console.log(table.getState()) //内部状態全体にアクセス + console.log(table.getState().rowSelection) //行選択状態のみにアクセス + // ... +} +``` + +### カスタム初期状態 + +特定の状態について初期値をカスタマイズするだけでよい場合、依然として状態を自分で管理する必要はありません。テーブルインスタンスの`initialState`オプションに値を設定するだけで済みます。 + +```ts +render() { + const table = this.tableController.table({ + columns, + data, + initialState: { + columnOrder: ['age', 'firstName', 'lastName'], //初期カラム順をカスタマイズ + columnVisibility: { + id: false //デフォルトでidカラムを非表示 + }, + expanded: true, //デフォルトですべての行を展開 + sorting: [ + { + id: 'age', + desc: true //デフォルトでageで降順ソート + } + ] + }, + }) + + return html`...`; +} +``` + +> **注意**: `initialState`と`state`の両方に同じ状態を指定しないでください。特定の状態値を`initialState`と`state`の両方に渡した場合、`state`で初期化された値が`initialState`の対応する値を上書きします。 + +### 制御された状態 + +アプリケーションの他の部分でテーブル状態に簡単にアクセスする必要がある場合、TanStack Tableでは独自の状態管理システムでテーブル状態の一部または全部を簡単に制御・管理できます。これを行うには、`state`と`on[State]Change`テーブルオプションに独自の状態と状態管理関数を渡します。 + +#### 個別に制御された状態 + +簡単にアクセスが必要な状態のみを制御できます。必要のないテーブル状態をすべて制御する必要はありません。ケースバイケースで必要な状態のみを制御することを推奨します。 + +特定の状態を制御するには、対応する`state`値と`on[State]Change`関数の両方をテーブルインスタンスに渡す必要があります。 + +「手動」のサーバーサイドデータフェッチシナリオで、フィルタリング、ソート、ページネーションを例に挙げましょう。フィルタリング、ソート、ページネーションの状態は独自の状態管理に保存できますが、APIが関与しないカラム順序やカラム表示状態などは制御外に残せます。 + +```jsx +import {html} from "lit"; + +@customElement('my-component') +class MyComponent extends LitElement { + @state() + private _sorting: SortingState = [] + + render() { + const table = this.tableController.table({ + columns, + data, + state: { + sorting: this._sorting, + }, + onSortingChange: updaterOrValue => { + if (typeof updaterOrValue === 'function') { + this._sorting = updaterOrValue(this._sorting) + } else { + this._sorting = updaterOrValue + } + }, + getSortedRowModel: getSortedRowModel(), + getCoreRowModel: getCoreRowModel(), + }) + + return html`...` + } +} +//... +``` + +#### 完全に制御された状態 + +あるいは、`onStateChange`テーブルオプションを使用してテーブル状態全体を制御できます。これにより、テーブル状態全体が独自の状態管理システムに引き上げられます。ただし、`columnSizingInfo`状態のように頻繁に変更される状態値をコンポーネントツリーの上位に引き上げるとパフォーマンス問題を引き起こす可能性があるため、このアプローチには注意が必要です。 + +これを機能させるには、さらにいくつかの工夫が必要かもしれません。`onStateChange`テーブルオプションを使用する場合、`state`の初期値には使用するすべての機能に関連する状態値を設定する必要があります。すべての初期状態値を手動で入力するか、以下のように`table.setOptions` APIを特別な方法で使用できます。 + +```ts + +private tableController = new TableController(this); + +@state() +private _tableState; + +render() { + const table = this.tableController.table({ + columns, + data, + getCoreRowModel: getCoreRowModel(), + getSortedRowModel: getSortedRowModel() + }) + const state = { ...table.initialState, ...this._tableState }; + table.setOptions(prev => ({ + ...prev, + state, + onStateChange: updater => { + this._tableState = + updater instanceof Function ? updater(state) : updater //状態変更が独自の状態管理に反映される + }, + })) + + return html`...`; +} +``` + +### 状態変更コールバック + +これまで、`on[State]Change`と`onStateChange`テーブルオプションがテーブル状態の変更を独自の状態管理に「引き上げる」働きを見てきました。しかし、これらのオプションを使用する際に注意すべき点がいくつかあります。 + +#### 1. **状態変更コールバックには、`state`オプションに対応する状態値が必要** + +`on[State]Change`コールバックを指定すると、テーブルインスタンスはこれが制御された状態であると認識します。対応する`state`値を指定しない場合、その状態は初期値で「凍結」されます。 + +```jsx +@state() +private _sorting = []; +//... +render() { + const table = this.tableController.table({ + columns, + data, + state: { + sorting: this._sorting, + }, + onSortingChange: updaterOrValue => { + if (typeof updaterOrValue === 'function') { + this._sorting = updaterOrValue(this._sorting) + } else { + this._sorting = updaterOrValue + } + }, + getSortedRowModel: getSortedRowModel(), + getCoreRowModel: getCoreRowModel(), + }) + + return html`...`; +} +``` + +#### 2. **アップデータは生の値またはコールバック関数のいずれか** + +`on[State]Change`と`onStateChange`コールバックは、Reactの`setState`関数とまったく同じように機能します。アップデータ値は、新しい状態値または前の状態値を受け取って新しい状態値を返すコールバック関数のいずれかになります。 + +これにはどのような意味があるのでしょうか?`on[State]Change`コールバックに追加のロジックを含めたい場合、新しいアップデータ値が関数か値かを確認する必要があるということです。 + +これが、上記の例で`updater instanceof Function ? updater(state.value) : updater`というパターンが見られる理由です。このパターンは、アップデータが関数かどうかを確認し、関数であれば前の状態値で呼び出して新しい状態値を取得します。 + +### 状態の型 + +TanStack Tableのすべての複雑な状態には、インポートして使用できる独自のTypeScript型があります。これは、制御している状態値に適切なデータ構造とプロパティを使用していることを確認するのに便利です。 + +```tsx +import { TableController, type SortingState } from '@tanstack/lit-table' +//... +@state() +private _sorting: SortingState = [ + { + id: 'age', //`id`と`desc`プロパティのオートコンプリートが得られる + desc: true, + } +] +``` diff --git a/docs/ja/framework/lit/lit-table.md b/docs/ja/framework/lit/lit-table.md new file mode 100644 index 0000000000..04bfe71d4c --- /dev/null +++ b/docs/ja/framework/lit/lit-table.md @@ -0,0 +1,66 @@ +--- +source-updated-at: '2024-05-17T05:10:48.000Z' +translation-updated-at: '2025-05-05T19:23:42.386Z' +title: Litテーブルアダプター +--- +以下は翻訳です: + +`@tanstack/lit-table` アダプターは、コアテーブルロジックをラップするものです。その主な役割は、状態管理を「Lit」の方法で行い、セル/ヘッダー/フッターテンプレートのレンダリング実装と型を提供することです。 + +## エクスポート + +`@tanstack/lit-table` は `@tanstack/table-core` のすべてのAPIと以下を再エクスポートします: + +### `TableController` + +リアクティブコントローラーで、`options` オブジェクトを受け取りテーブルインスタンスを返す `table` APIを提供します。 + +```ts +import { TableController } from '@tanstack/lit-table' + +@customElement('my-table-element') +class MyTableElement extends LitElement { + private tableController = new TableController(this) + + protected render() { + const table = this.tableController.table(options) + // ...テーブルをレンダリング + } +} +``` + +### `flexRender` + +動的な値を持つセル/ヘッダー/フッターテンプレートをレンダリングするためのユーティリティ関数です。 + +例: + +```jsx +import { flexRender } from '@tanstack/lit-table' +//... +return html` + + ${table + .getRowModel() + .rows.slice(0, 10) + .map( + row => html` + + ${row + .getVisibleCells() + .map( + cell => html` + + ${flexRender( + cell.column.columnDef.cell, + cell.getContext() + )} + + ` + )} + + ` + )} + +` +``` diff --git a/docs/ja/framework/qwik/guide/table-state.md b/docs/ja/framework/qwik/guide/table-state.md new file mode 100644 index 0000000000..f14e0629ee --- /dev/null +++ b/docs/ja/framework/qwik/guide/table-state.md @@ -0,0 +1,179 @@ +--- +source-updated-at: '2024-05-17T05:10:48.000Z' +translation-updated-at: '2025-05-05T19:26:07.479Z' +title: テーブル状態 +--- +## テーブルステート (Qwik) ガイド + +TanStack Tableは、テーブルの状態を保存・管理するためのシンプルな内部ステート管理システムを備えています。また、独自のステート管理で管理する必要がある状態を選択的に取り出すことも可能です。このガイドでは、テーブルの状態を操作・管理するさまざまな方法について説明します。 + +### テーブルステートへのアクセス + +テーブルステートを機能させるために特別な設定は必要ありません。`state`、`initialState`、または`on[State]Change`テーブルオプションに何も渡さない場合、テーブルは内部で独自に状態を管理します。この内部状態の任意の部分には、`table.getState()`テーブルインスタンスAPIを使用してアクセスできます。 + +```jsx +const table = useQwikTable({ + columns, + data, + //... +}) + +console.log(table.getState()) //内部状態全体にアクセス +console.log(table.getState().rowSelection) //行選択状態のみにアクセス +``` + +### カスタム初期状態 + +特定の状態について初期値をカスタマイズするだけでよい場合、依然として状態を自分で管理する必要はありません。テーブルインスタンスの`initialState`オプションに値を設定するだけで済みます。 + +```jsx +const table = useQwikTable({ + columns, + data, + initialState: { + columnOrder: ['age', 'firstName', 'lastName'], //初期カラム順をカスタマイズ + columnVisibility: { + id: false //デフォルトでidカラムを非表示 + }, + expanded: true, //デフォルトですべての行を展開 + sorting: [ + { + id: 'age', + desc: true //デフォルトで年齢の降順にソート + } + ] + }, + //... +}) +``` + +> **注意**: 各状態は`initialState`または`state`のいずれか一方でのみ指定してください。両方に同じ状態値を渡した場合、`state`で初期化された値が`initialState`の対応する値を上書きします。 + +### 制御されたステート + +アプリケーションの他の部分でテーブルステートに簡単にアクセスする必要がある場合、TanStack Tableでは独自のステート管理システムでテーブルステートの一部または全部を簡単に制御・管理できます。これを行うには、独自の状態と状態管理関数を`state`および`on[State]Change`テーブルオプションに渡します。 + +#### 個別に制御されたステート + +簡単にアクセスが必要な状態のみを制御できます。必要のないテーブルステートをすべて制御する必要はありません。ケースバイケースで必要な状態のみを制御することを推奨します。 + +特定の状態を制御するには、対応する`state`値と`on[State]Change`関数の両方をテーブルインスタンスに渡す必要があります。 + +フィルタリング、ソート、ページネーションを「手動」のサーバーサイドデータ取得シナリオで例として取り上げます。フィルタリング、ソート、ページネーションの状態は独自のステート管理に保存できますが、APIが関与しないカラム順序や可視性などの状態は除外できます。 + +```jsx +const columnFilters = Qwik.useSignal([]) //デフォルトフィルターなし +const sorting = Qwik.useSignal([{ + id: 'age', + desc: true, //デフォルトで年齢の降順にソート +}]) +const pagination = Qwik.useSignal({ pageIndex: 0, pageSize: 15 }) + +//制御された状態値を使用してデータを取得 +const tableQuery = useQuery({ + queryKey: ['users', columnFilters.value, sorting.value, pagination.value], + queryFn: () => fetchUsers(columnFilters.value, sorting.value, pagination.value), + //... +}) + +const table = useQwikTable({ + columns: columns.value, + data: tableQuery.data, + //... + state: { + columnFilters: columnFilters.value, //制御された状態をテーブルに戻す(内部状態を上書き) + sorting: sorting.value, + pagination: pagination.value, + }, + onColumnFiltersChange: updater => { + columnFilters.value = updater instanceof Function ? updater(columnFilters.value) : updater //columnFilters状態を独自のステート管理に引き上げ + }, + onSortingChange: updater => { + sorting.value = updater instanceof Function ? updater(sorting.value) : updater + }, + onPaginationChange: updater => { + pagination.value = updater instanceof Function ? updater(pagination.value) : updater + }, +}) +//... +``` + +#### 完全に制御されたステート + +代わりに、`onStateChange`テーブルオプションを使用してテーブルステート全体を制御できます。これにより、テーブルステート全体が独自のステート管理システムに引き上げられます。ただし、`columnSizingInfo`状態のように頻繁に変更される状態値をコンポーネントツリーの上位に引き上げるとパフォーマンス問題を引き起こす可能性があるため、このアプローチには注意が必要です。 + +これを機能させるには、さらにいくつかの工夫が必要です。`onStateChange`テーブルオプションを使用する場合、`state`の初期値には、使用するすべての機能に関連する状態値を設定する必要があります。すべての初期状態値を手動で入力するか、以下のように`table.setOptions` APIを特別な方法で使用できます。 + +```jsx +//デフォルト状態値でテーブルインスタンスを作成 +const table = useQwikTable({ + columns, + data, + //... 注: `state`値はまだ渡されていない +}) + + +const sate = Qwik.useSignal({ + ...table.initialState, //テーブルインスタンスからすべてのデフォルト状態値を初期状態に設定 + pagination: { + pageIndex: 0, + pageSize: 15 //オプションで初期ページネーション状態をカスタマイズ + } +}) + +//table.setOptions APIを使用して、完全に制御された状態をテーブルインスタンスにマージ +table.setOptions(prev => ({ + ...prev, //上記で設定した他のオプションを保持 + state: state.value, //完全に制御された状態が内部状態を上書き + onStateChange: updater => { + state.value = updater instanceof Function ? updater(state.value) : updater //状態変更は独自のステート管理に反映 + }, +})) +``` + +### ステート変更コールバック + +これまで、`on[State]Change`および`onStateChange`テーブルオプションがテーブル状態の変更を独自のステート管理に「引き上げる」仕組みを見てきました。ただし、これらのオプションを使用する際に注意すべき点がいくつかあります。 + +#### 1. **ステート変更コールバックには、対応する`state`オプションに状態値が含まれている必要があります**。 + +`on[State]Change`コールバックを指定すると、テーブルインスタンスはこれが制御された状態であると認識します。対応する`state`値を指定しない場合、その状態は初期値で「凍結」されます。 + +```jsx +const sorting = Qwik.useSignal([]) +//... +const table = useQwikTable({ + columns, + data, + //... + state: { + sorting: sorting.value, //`onSortingChange`を使用するため必須 + }, + onSortingChange: updater => { + sorting.value = updater instanceof Function ? updater(sorting) : updater //`state.sorting`を制御 + }, +}) +``` + +#### 2. **アップデータは生の値またはコールバック関数のいずれかです**。 + +`on[State]Change`および`onStateChange`コールバックは、Reactの`setState`関数とまったく同じように機能します。アップデータ値は、新しい状態値または前の状態値を受け取って新しい状態値を返すコールバック関数のいずれかです。 + +これにはどのような意味があるでしょうか? `on[State]Change`コールバックに追加のロジックを含めたい場合、新しいアップデータ値が関数か値かを確認する必要があるということです。 + +これが、上記の例で`updater instanceof Function ? updater(state.value) : updater`というパターンが見られる理由です。このパターンは、アップデータが関数かどうかを確認し、関数の場合は前の状態値を渡して新しい状態値を取得します。 + +### ステートの型 + +TanStack Tableのすべての複雑な状態には、インポートして使用できる独自のTypeScript型があります。これは、制御している状態値に正しいデータ構造とプロパティを使用していることを確認するのに役立ちます。 + +```tsx +import { useQwikTable, type SortingState } from '@tanstack/qwik-table' +//... +const sorting = Qwik.useSignal([ + { + id: 'age', //`id`と`desc`プロパティのオートコンプリートが有効 + desc: true, + } +]) +``` diff --git a/docs/ja/framework/qwik/qwik-table.md b/docs/ja/framework/qwik/qwik-table.md new file mode 100644 index 0000000000..7c952e51e7 --- /dev/null +++ b/docs/ja/framework/qwik/qwik-table.md @@ -0,0 +1,47 @@ +--- +source-updated-at: '2024-05-17T05:10:48.000Z' +translation-updated-at: '2025-05-05T19:23:40.680Z' +title: Qwikテーブルアダプター +--- +`@tanstack/qwik-table`アダプターは、コアのテーブルロジックをラップするものです。その主な役割は、状態管理を「Qwik」の方法で行い、型を提供し、セル/ヘッダー/フッターテンプレートのレンダリング実装を提供することです。 + +## エクスポート + +`@tanstack/qwik-table`は、`@tanstack/table-core`のすべてのAPIと以下のものを再エクスポートします。 + +### `useQwikTable` + +`options`オブジェクトを受け取り、`NoSerialize`を含むQwik Storeからテーブルを返します。 + +```ts +import { useQwikTable } from '@tanstack/qwik-table' + +const table = useQwikTable(options) +// ...テーブルをレンダリング +``` + +### `flexRender` + +セル/ヘッダー/フッターテンプレートを動的な値でレンダリングするためのユーティリティ関数です。 + +例: + +```jsx +import { flexRender } from '@tanstack/qwik-table' +//... +return ( + + {table.getRowModel().rows.map(row => { + return ( + + {row.getVisibleCells().map(cell => ( + + {flexRender(cell.column.columnDef.cell, cell.getContext())} + + ))} + + ) + })} + +); +``` diff --git a/docs/ja/framework/react/guide/table-state.md b/docs/ja/framework/react/guide/table-state.md new file mode 100644 index 0000000000..2fca4c513b --- /dev/null +++ b/docs/ja/framework/react/guide/table-state.md @@ -0,0 +1,205 @@ +--- +source-updated-at: '2025-03-20T21:15:29.000Z' +translation-updated-at: '2025-05-05T19:26:10.916Z' +title: テーブル状態 +--- +## 例 + +実装に直接進みたいですか?以下の例を確認してください: + +- [キッチンシンク](../examples/kitchen-sink) +- [完全に制御された状態](../examples/fully-controlled) + +## テーブル状態 (React) ガイド + +TanStack Tableは、テーブルの状態を保存・管理するためのシンプルな内部状態管理システムを備えています。また、独自の状態管理で管理する必要がある状態を選択的に取り出すことも可能です。このガイドでは、テーブルの状態を操作・管理するさまざまな方法について説明します。 + +### テーブル状態へのアクセス + +テーブル状態を機能させるために特別な設定は必要ありません。`state`、`initialState`、または`on[State]Change`テーブルオプションに何も渡さない場合、テーブルは内部で独自に状態を管理します。この内部状態の任意の部分には、`table.getState()`テーブルインスタンスAPIを使用してアクセスできます。 + +```jsx +const table = useReactTable({ + columns, + data, + //... +}) + +console.log(table.getState()) //内部状態全体にアクセス +console.log(table.getState().rowSelection) //行選択状態のみにアクセス +``` + +### カスタム初期状態 + +特定の状態について初期値をカスタマイズするだけでよい場合、依然として状態を自分で管理する必要はありません。テーブルインスタンスの`initialState`オプションに値を設定するだけで済みます。 + +```jsx +const table = useReactTable({ + columns, + data, + initialState: { + columnOrder: ['age', 'firstName', 'lastName'], //初期カラム順をカスタマイズ + columnVisibility: { + id: false //デフォルトでidカラムを非表示 + }, + expanded: true, //デフォルトですべての行を展開 + sorting: [ + { + id: 'age', + desc: true //デフォルトで年齢の降順にソート + } + ] + }, + //... +}) +``` + +> **注**: `initialState`と`state`の両方に同じ状態を指定しないでください。特定の状態値を`initialState`と`state`の両方に渡すと、`state`で初期化された値が`initialState`の対応する値を上書きします。 + +### 制御された状態 + +アプリケーションの他の部分でテーブル状態に簡単にアクセスする必要がある場合、TanStack Tableでは独自の状態管理システムでテーブル状態の一部または全部を簡単に制御・管理できます。これを行うには、独自の状態と状態管理関数を`state`と`on[State]Change`テーブルオプションに渡します。 + +#### 個別に制御された状態 + +必要な状態のみを制御できます。すべてのテーブル状態を制御する必要はありません。ケースバイケースで必要な状態のみを制御することを推奨します。 + +特定の状態を制御するには、対応する`state`値と`on[State]Change`関数の両方をテーブルインスタンスに渡す必要があります。 + +フィルタリング、ソート、ページネーションを「手動」のサーバーサイドデータ取得シナリオで例として見てみましょう。フィルタリング、ソート、ページネーションの状態を独自の状態管理に保存できますが、APIが関与しないカラム順序やカラム表示状態などは除外できます。 + +```jsx +const [columnFilters, setColumnFilters] = React.useState([]) //デフォルトフィルターなし +const [sorting, setSorting] = React.useState([{ + id: 'age', + desc: true, //デフォルトで年齢の降順にソート +}]) +const [pagination, setPagination] = React.useState({ pageIndex: 0, pageSize: 15 }) + +//制御された状態値を使用してデータを取得 +const tableQuery = useQuery({ + queryKey: ['users', columnFilters, sorting, pagination], + queryFn: () => fetchUsers(columnFilters, sorting, pagination), + //... +}) + +const table = useReactTable({ + columns, + data: tableQuery.data, + //... + state: { + columnFilters, //制御された状態をテーブルに戻す(内部状態を上書き) + sorting, + pagination + }, + onColumnFiltersChange: setColumnFilters, //columnFilters状態を独自の状態管理に引き上げ + onSortingChange: setSorting, + onPaginationChange: setPagination, +}) +//... +``` + +#### 完全に制御された状態 + +あるいは、`onStateChange`テーブルオプションを使用してテーブル状態全体を制御できます。これにより、テーブル状態全体が独自の状態管理システムに引き上げられます。ただし、`columnSizingInfo`状態のように頻繁に変更される状態値をReactツリーの上位に引き上げると、パフォーマンスの問題を引き起こす可能性があるため注意が必要です。 + +これを機能させるには、さらにいくつかの工夫が必要な場合があります。`onStateChange`テーブルオプションを使用する場合、`state`の初期値には、使用したいすべての機能に関連する状態値を設定する必要があります。すべての初期状態値を手動で入力するか、以下のように`table.setOptions` APIを特別な方法で使用できます。 + +```jsx +//デフォルト状態値でテーブルインスタンスを作成 +const table = useReactTable({ + columns, + data, + //... 注: `state`値はまだ渡されていない +}) + + +const [state, setState] = React.useState({ + ...table.initialState, //テーブルインスタンスからすべてのデフォルト状態値を取得して初期状態を設定 + pagination: { + pageIndex: 0, + pageSize: 15 //必要に応じて初期ページネーション状態をカスタマイズ + } +}) + +//table.setOptions APIを使用して、完全に制御された状態をテーブルインスタンスにマージ +table.setOptions(prev => ({ + ...prev, //上記で設定した他のオプションを保持 + state, //完全に制御された状態が内部状態を上書き + onStateChange: setState //状態変更が独自の状態管理に引き上げられる +})) +``` + +### 状態変更コールバック + +これまで、`on[State]Change`および`onStateChange`テーブルオプションが、テーブル状態の変更を独自の状態管理に「引き上げる」仕組みを見てきました。しかし、これらのオプションを使用する際に注意すべき点がいくつかあります。 + +#### 1. **状態変更コールバックには、`state`オプションに対応する状態値が必要です**。 + +`on[State]Change`コールバックを指定すると、テーブルインスタンスはこれが制御された状態であると認識します。対応する`state`値を指定しない場合、その状態は初期値で「凍結」されます。 + +```jsx +const [sorting, setSorting] = React.useState([]) +//... +const table = useReactTable({ + columns, + data, + //... + state: { + sorting, //`onSortingChange`を使用しているため必須 + }, + onSortingChange: setSorting, //`state.sorting`を制御された状態にする +}) +``` + +#### 2. **アップデータは生の値またはコールバック関数のいずれかです**。 + +`on[State]Change`および`onStateChange`コールバックは、Reactの`setState`関数とまったく同じように機能します。アップデータ値は、新しい状態値または前の状態値を受け取って新しい状態値を返すコールバック関数のいずれかです。 + +これにはどのような意味があるのでしょうか?つまり、`on[State]Change`コールバックに追加のロジックを含めたい場合、新しいアップデータ値が関数か値かを確認する必要があるということです。 + +```jsx +const [sorting, setSorting] = React.useState([]) +const [pagination, setPagination] = React.useState({ pageIndex: 0, pageSize: 10 }) + +const table = useReactTable({ + columns, + data, + //... + state: { + pagination, + sorting, + } + //構文1 + onPaginationChange: (updater) => { + setPagination(old => { + const newPaginationValue = updater instanceof Function ? updater(old) : updater + //新しいページネーション値で何かを行う + //... + return newPaginationValue + }) + }, + //構文2 + onSortingChange: (updater) => { + const newSortingValue = updater instanceof Function ? updater(sorting) : updater + //新しいソート値で何かを行う + //... + setSorting(updater) //通常の状態更新 + } +}) +``` + +### 状態の型 + +TanStack Tableのすべての複雑な状態には、インポートして使用できる独自のTypeScript型があります。これは、制御している状態値に対して正しいデータ構造とプロパティを使用していることを確認するのに便利です。 + +```tsx +import { useReactTable, type SortingState } from '@tanstack/react-table' +//... +const [sorting, setSorting] = React.useState([ + { + id: 'age', //`id`と`desc`プロパティのオートコンプリートが可能 + desc: true, + } +]) +``` diff --git a/docs/ja/framework/react/react-table.md b/docs/ja/framework/react/react-table.md new file mode 100644 index 0000000000..fed56e713d --- /dev/null +++ b/docs/ja/framework/react/react-table.md @@ -0,0 +1,22 @@ +--- +source-updated-at: '2024-01-24T21:39:34.000Z' +translation-updated-at: '2025-05-05T19:23:33.923Z' +title: Reactテーブルアダプター +--- +# React Table + +`@tanstack/react-table`アダプターは、コアのテーブルロジックをラップするものです。その主な役割は、状態管理を「React」の方法で行い、セル/ヘッダー/フッターテンプレートの型定義とレンダリング実装を提供することです。 + +## `useReactTable` + +`options`オブジェクトを受け取り、テーブルを返します。 + +```tsx +import { useReactTable } from '@tanstack/react-table' + +function App() { + const table = useReactTable(options) + + // ...テーブルをレンダリング +} +``` diff --git a/docs/ja/framework/solid/guide/table-state.md b/docs/ja/framework/solid/guide/table-state.md new file mode 100644 index 0000000000..8f76332dc0 --- /dev/null +++ b/docs/ja/framework/solid/guide/table-state.md @@ -0,0 +1,222 @@ +--- +source-updated-at: '2024-05-17T05:10:48.000Z' +translation-updated-at: '2025-05-05T19:26:15.799Z' +title: テーブル状態 +--- +## Table State (Solid) ガイド + +TanStack Tableのコアは**フレームワークに依存しない (framework agnostic)** ため、使用するフレームワークに関係なく同じAPIを提供します。各フレームワーク向けのアダプターが用意されており、テーブルコアを簡単に扱えるようになっています。利用可能なアダプターについては、Adaptersメニューを参照してください。 + +### テーブルステートへのアクセス + +テーブルステートを機能させるために特別な設定は必要ありません。`state`、`initialState`、または`on[State]Change`テーブルオプションに何も渡さない場合、テーブルは内部で独自にステートを管理します。この内部ステートには、`table.getState()`テーブルインスタンスAPIを使用してアクセスできます。 + +```jsx +const table = createSolidTable({ + columns, + get data() { + return data() + }, + //... +}) + +console.log(table.getState()) //内部ステート全体にアクセス +console.log(table.getState().rowSelection) //行選択ステートのみにアクセス +``` + +### カスタム初期ステート + +特定のステートについて初期値をカスタマイズするだけでよい場合、ステートを自分で管理する必要はありません。テーブルインスタンスの`initialState`オプションに値を設定するだけで済みます。 + +```jsx +const table = createSolidTable({ + columns, + data, + initialState: { + columnOrder: ['age', 'firstName', 'lastName'], //初期カラム順をカスタマイズ + columnVisibility: { + id: false //デフォルトでidカラムを非表示 + }, + expanded: true, //デフォルトですべての行を展開 + sorting: [ + { + id: 'age', + desc: true //デフォルトで年齢の降順ソート + } + ] + }, + //... +}) +``` + +> **注意**: 各ステートは`initialState`または`state`のいずれか一方でのみ指定してください。両方に同じステート値を渡した場合、`state`で初期化された値が`initialState`の対応する値を上書きします。 + +### 制御されたステート (Controlled State) + +アプリケーションの他の部分でテーブルステートに簡単にアクセスする必要がある場合、TanStack Tableでは任意またはすべてのテーブルステートを独自のステート管理システムで制御・管理できます。これは、`state`と`on[State]Change`テーブルオプションに独自のステートとステート管理関数を渡すことで実現します。 + +#### 個別に制御されたステート + +必要なステートのみを制御できます。すべてのテーブルステートを制御する必要はありません。ケースバイケースで必要なステートのみを制御することを推奨します。 + +特定のステートを制御するには、対応する`state`値と`on[State]Change`関数の両方をテーブルインスタンスに渡す必要があります。 + +「手動」のサーバーサイドデータ取得シナリオで、フィルタリング、ソート、ページネーションを例に挙げましょう。フィルタリング、ソート、ページネーションのステートは独自のステート管理に保存し、APIが関与しないカラム順序や可視性などの他のステートは除外できます。 + +```jsx +const [columnFilters, setColumnFilters] = createSignal([]) //デフォルトフィルターなし +const [sorting, setSorting] = createSignal([{ + id: 'age', + desc: true, //デフォルトで年齢の降順ソート +}]) +const [pagination, setPagination] = createSignal({ pageIndex: 0, pageSize: 15 }) + +//制御されたステート値を使用してデータを取得 +const tableQuery = createQuery({ + queryKey: ['users', columnFilters, sorting, pagination], + queryFn: () => fetchUsers(columnFilters, sorting, pagination), + //... +}) + +const table = createSolidTable({ + columns, + get data() { + return tableQuery.data() + }, + //... + state: { + get columnFilters() { + return columnFilters() //制御されたステートをテーブルに戻す(内部ステートを上書き) + }, + get sorting() { + return sorting() + }, + get pagination() { + return pagination() + }, + }, + onColumnFiltersChange: setColumnFilters, //columnFiltersステートを独自のステート管理に引き上げ + onSortingChange: setSorting, + onPaginationChange: setPagination, +}) +//... +``` + +#### 完全に制御されたステート + +あるいは、`onStateChange`テーブルオプションを使用してテーブルステート全体を制御できます。これにより、テーブルステート全体が独自のステート管理システムに引き上げられます。ただし、`columnSizingInfo`ステートのように頻繁に変更されるステート値をSolidツリーの上位に引き上げると、パフォーマンスの問題が発生する可能性があるため注意が必要です。 + +これを機能させるには、いくつかの追加の工夫が必要です。`onStateChange`テーブルオプションを使用する場合、`state`の初期値には、使用するすべての機能に関連するステート値を設定する必要があります。すべての初期ステート値を手動で入力するか、以下のように`table.setOptions` APIを特別な方法で使用できます。 + +```jsx +//デフォルトステート値でテーブルインスタンスを作成 +const table = createSolidTable({ + columns, + get data() { + return data() + }, + //... 注: `state`値はまだ渡されていない +}) + + +const [state, setState] = createSignal({ + ...table.initialState, //テーブルインスタンスからすべてのデフォルトステート値を初期ステートに設定 + pagination: { + pageIndex: 0, + pageSize: 15 //必要に応じて初期ページネーションステートをカスタマイズ + } +}) + +//table.setOptions APIを使用して、完全に制御されたステートをテーブルインスタンスにマージ +table.setOptions(prev => ({ + ...prev, //上記で設定した他のオプションを保持 + get state() { + return state() //完全に制御されたステートが内部ステートを上書き + }, + onStateChange: setState //ステートの変更は独自のステート管理に反映される +})) +``` + +### ステート変更コールバック + +これまで、`on[State]Change`および`onStateChange`テーブルオプションが、テーブルステートの変更を独自のステート管理に「引き上げる」仕組みを見てきました。ただし、これらのオプションを使用する際に注意すべき点がいくつかあります。 + +#### 1. **ステート変更コールバックには、対応する`state`オプションのステート値が必要** + +`on[State]Change`コールバックを指定すると、テーブルインスタンスはこれが制御されたステートであると認識します。対応する`state`値を指定しない場合、そのステートは初期値で「凍結」されます。 + +```jsx +const [sorting, setSorting] = createSignal([]) +//... +const table = createSolidTable({ + columns, + data, + //... + state: { + get sorting() { + return sorting() //`onSortingChange`を使用するため必須 + }, + }, + onSortingChange: setSorting, //`state.sorting`を制御する +}) +``` + +#### 2. **アップデータは生の値またはコールバック関数のいずれか** + +`on[State]Change`および`onStateChange`コールバックは、React(Solid Setters)の`setState`関数とまったく同じように機能します。アップデータ値は、新しいステート値または前のステート値を受け取って新しいステート値を返すコールバック関数のいずれかです。 + +これにはどのような意味があるのでしょうか?つまり、`on[State]Change`コールバックに追加のロジックを含めたい場合、新しいアップデータ値が関数か値かを確認する必要があるということです。 + +```jsx +const [sorting, setSorting] = createSignal([]) +const [pagination, setPagination] = createSignal({ pageIndex: 0, pageSize: 10 }) + +const table = createSolidTable({ + get columns() { + return columns() + }, + get data() { + return data() + }, + //... + state: { + get pagination() { + return pagination() + }, + get sorting() { + return sorting() + }, + } + //構文1 + onPaginationChange: (updater) => { + setPagination(old => { + const newPaginationValue = updater instanceof Function ? updater(old) : updater + //新しいページネーション値で何かを行う + //... + return newPaginationValue + }) + }, + //構文2 + onSortingChange: (updater) => { + const newSortingValue = updater instanceof Function ? updater(sorting) : updater + //新しいソート値で何かを行う + //... + setSorting(updater) //通常のステート更新 + } +}) +``` + +### ステートの型 + +TanStack Tableのすべての複雑なステートには、インポートして使用できる独自のTypeScript型があります。これは、制御するステート値に正しいデータ構造とプロパティを使用していることを確認するのに役立ちます。 + +```tsx +import { createSolidTable, type SortingState } from '@tanstack/solid-table' +//... +const [sorting, setSorting] = createSignal([ + { + id: 'age', //`id`と`desc`プロパティのオートコンプリートが利用可能 + desc: true, + } +]) +``` diff --git a/docs/ja/framework/solid/solid-table.md b/docs/ja/framework/solid/solid-table.md new file mode 100644 index 0000000000..2242e864fc --- /dev/null +++ b/docs/ja/framework/solid/solid-table.md @@ -0,0 +1,20 @@ +--- +source-updated-at: '2024-01-24T21:39:34.000Z' +translation-updated-at: '2025-05-05T19:23:32.886Z' +title: Solidテーブルアダプター +--- +`@tanstack/solid-table`アダプターは、コアのテーブルロジックをラップするものです。その主な役割は、状態管理を「Solid」の方法で行い、型を提供し、セル/ヘッダー/フッターテンプレートのレンダリング実装を提供することです。 + +## `createSolidTable` + +`options`オブジェクトを受け取り、テーブルを返します。 + +```tsx +import { createSolidTable } from '@tanstack/solid-table' + +function App() { + const table = createSolidTable(options) + + // ...テーブルをレンダリング +} +``` diff --git a/docs/ja/framework/svelte/guide/table-state.md b/docs/ja/framework/svelte/guide/table-state.md new file mode 100644 index 0000000000..17cc9f0d94 --- /dev/null +++ b/docs/ja/framework/svelte/guide/table-state.md @@ -0,0 +1,261 @@ +--- +source-updated-at: '2024-05-17T05:10:48.000Z' +translation-updated-at: '2025-05-05T19:26:25.934Z' +title: テーブル状態 +--- +## テーブルステート (Svelte) ガイド + +TanStack Tableは、テーブルの状態を保存・管理するためのシンプルな内部ステート管理システムを備えています。また、独自のステート管理で管理が必要な状態を選択的に取り出すことも可能です。このガイドでは、テーブルの状態を操作・管理するさまざまな方法を説明します。 + +### テーブルステートへのアクセス + +テーブルステートを機能させるために特別な設定は必要ありません。`state`、`initialState`、または`on[State]Change`テーブルオプションに何も渡さない場合、テーブルは内部で独自に状態を管理します。この内部状態の任意の部分には、テーブルインスタンスAPIの`table.getState()`を使用してアクセスできます。 + +```jsx +const options = writable({ + columns, + data, + //... +}) + +const table = createSvelteTable(options) + +console.log(table.getState()) //内部状態全体にアクセス +console.log(table.getState().rowSelection) //行選択状態のみにアクセス +``` + +### カスタム初期状態 + +特定の状態について初期値をカスタマイズするだけでよい場合、依然としてステートを自分で管理する必要はありません。テーブルインスタンスの`initialState`オプションに値を設定するだけで済みます。 + +```jsx +const options = writable({ + columns, + data, + initialState: { + columnOrder: ['age', 'firstName', 'lastName'], //初期カラム順をカスタマイズ + columnVisibility: { + id: false //デフォルトでidカラムを非表示 + }, + expanded: true, //デフォルトですべての行を展開 + sorting: [ + { + id: 'age', + desc: true //デフォルトで年齢の降順にソート + } + ] + }, + //... +}) + +const table = createSvelteTable(options) +``` + +> **注**: 各状態は`initialState`か`state`のどちらか一方でのみ指定してください。両方に同じ状態値を渡した場合、`state`で初期化された値が`initialState`の対応する値を上書きします。 + +### 制御されたステート + +アプリケーションの他の部分でテーブルステートに簡単にアクセスする必要がある場合、TanStack Tableでは任意またはすべてのテーブルステートを独自のステート管理システムで制御・管理できます。これは、`state`と`on[State]Change`テーブルオプションに独自のステートとステート管理関数を渡すことで実現します。 + +#### 個別に制御されたステート + +必要なステートのみを制御できます。すべてのテーブルステートを制御する必要はありません。ケースバイケースで必要なステートのみを制御することが推奨されます。 + +特定のステートを制御するには、対応する`state`値と`on[State]Change`関数の両方をテーブルインスタンスに渡す必要があります。 + +「手動」なサーバーサイドデータ取得シナリオで、フィルタリング、ソート、ページネーションを例に取りましょう。フィルタリング、ソート、ページネーションの状態を独自のステート管理に保存しつつ、APIが関与しないカラム順序やカラム表示状態などは除外できます。 + +```ts +let sorting = [ + { + id: 'age', + desc: true, //デフォルトで年齢の降順にソート + }, +] +const setSorting = updater => { + if (updater instanceof Function) { + sorting = updater(sorting) + } else { + sorting = updater + } + options.update(old => ({ + ...old, + state: { + ...old.state, + sorting, + }, + })) +} + +let columnFilters = [] //デフォルトのフィルタなし +const setColumnFilters = updater => { + if (updater instanceof Function) { + columnFilters = updater(columnFilters) + } else { + columnFilters = updater + } + options.update(old => ({ + ...old, + state: { + ...old.state, + columnFilters, + }, + })) +} + +let pagination = { pageIndex: 0, pageSize: 15 } //デフォルトのページネーション +const setPagination = updater => { + if (updater instanceof Function) { + pagination = updater(pagination) + } else { + pagination = updater + } + options.update(old => ({ + ...old, + state: { + ...old.state, + pagination, + }, + })) +} + +//制御されたステート値を使用してデータを取得 +const tableQuery = createQuery({ + queryKey: ['users', columnFilters, sorting, pagination], + queryFn: () => fetchUsers(columnFilters, sorting, pagination), + //... +}) + +const options = writable({ + columns, + data: tableQuery.data, + //... + state: { + columnFilters, //制御されたステートをテーブルに戻す(内部状態を上書き) + sorting, + pagination + }, + onColumnFiltersChange: setColumnFilters, //columnFiltersステートを独自のステート管理に引き上げ + onSortingChange: setSorting, + onPaginationChange: setPagination, +}) + +const table = createSvelteTable(options) +//... +``` + +#### 完全に制御されたステート + +代わりに、`onStateChange`テーブルオプションを使用してテーブルステート全体を制御できます。これにより、テーブルステート全体が独自のステート管理システムに引き上げられます。ただし、`columnSizingInfo`ステートのように頻繁に変更される状態値をSvelteツリーに引き上げるとパフォーマンスの問題を引き起こす可能性があるため、このアプローチには注意が必要です。 + +これを機能させるには、さらにいくつかの工夫が必要かもしれません。`onStateChange`テーブルオプションを使用する場合、`state`の初期値には、使用したいすべての機能に関連するステート値をすべて設定する必要があります。すべての初期状態値を手動で入力するか、以下のように`table.setOptions` APIを特別な方法で使用できます。 + +```jsx +//デフォルトの状態値でテーブルインスタンスを作成 +const options = writable({ + columns, + data, + //... 注: `state`値はまだ渡されていない +}) +const table = createSvelteTable(options) + +let state = { + ...table.initialState, //テーブルインスタンスからすべてのデフォルト状態値を取得して初期状態を設定 + pagination: { + pageIndex: 0, + pageSize: 15 //オプションで初期ページネーション状態をカスタマイズ + } +} +const setState = updater => { + if (updater instanceof Function) { + state = updater(state) + } else { + state = updater + } + options.update(old => ({ + ...old, + state, + })) +} + +//table.setOptions APIを使用して、完全に制御されたステートをテーブルインスタンスにマージ +table.setOptions(prev => ({ + ...prev, //上記で設定した他のオプションを保持 + state, //完全に制御されたステートが内部状態を上書き + onStateChange: setState //状態変更は独自のステート管理に引き上げられる +})) +``` + +### ステート変更コールバック + +これまで、`on[State]Change`と`onStateChange`テーブルオプションがテーブルステートの変更を独自のステート管理に「引き上げる」働きを見てきました。しかし、これらのオプションを使用する際に注意すべき点がいくつかあります。 + +#### 1. **ステート変更コールバックには、対応する`state`オプションにステート値が含まれている必要があります**。 + +`on[State]Change`コールバックを指定すると、テーブルインスタンスはこれが制御されたステートであると認識します。対応する`state`値を指定しない場合、その状態は初期値で「凍結」されます。 + +```ts +let sorting = [] +const setSorting = updater => { + if (updater instanceof Function) { + sorting = updater(sorting) + } else { + sorting = updater + } + options.update(old => ({ + ...old, + state: { + ...old.state, + sorting, + }, + })) +} +//... +const options = writable({ + columns, + data, + //... + state: { + sorting, //`onSortingChange`を使用するため必須 + }, + onSortingChange: setSorting, //`state.sorting`を制御する +}) +const table = createSvelteTable(options) +``` + +#### 2. **アップデータは生の値またはコールバック関数のいずれかになります**。 + +`on[State]Change`と`onStateChange`コールバックは、Reactの`setState`関数とまったく同じように機能します。アップデータ値は、新しいステート値か、前のステート値を受け取って新しいステート値を返すコールバック関数のいずれかになります。 + +これにはどのような意味があるのでしょうか?`on[State]Change`コールバックに追加のロジックを含めたい場合、新しいアップデータ値が関数か値かを確認する必要があることを意味します。 + +これが、上記の例の`setState`関数に`if (updater instanceof Function)`チェックがある理由です。 + +### ステートの型 + +TanStack Tableのすべての複雑なステートには、インポートして使用できる独自のTypeScript型があります。これは、制御しているステート値に対して正しいデータ構造とプロパティを使用していることを確認するのに役立ちます。 + +```ts +import { createSvelteTable, type SortingState, type Updater } from '@tanstack/svelte-table' +//... +let sorting: SortingState[] = [ + { + id: 'age', //`id`と`desc`プロパティのオートコンプリートが得られる + desc: true, + } +] +const setSorting = (updater: Updater) => { + if (updater instanceof Function) { + sorting = updater(sorting) + } else { + sorting = updater + } + options.update(old => ({ + ...old, + state: { + ...old.state, + sorting, + }, + })) +} +``` diff --git a/docs/ja/framework/svelte/svelte-table.md b/docs/ja/framework/svelte/svelte-table.md new file mode 100644 index 0000000000..ee08b4fd2b --- /dev/null +++ b/docs/ja/framework/svelte/svelte-table.md @@ -0,0 +1,20 @@ +--- +source-updated-at: '2024-01-24T21:39:34.000Z' +translation-updated-at: '2025-05-05T19:23:43.906Z' +title: Svelteテーブルアダプター +--- +`@tanstack/svelte-table`アダプターは、コアのテーブルロジックをラップするものです。その主な役割は、状態管理を「スベルテ (Svelte)」の方法で行い、型を提供し、セル/ヘッダー/フッターテンプレートのレンダリング実装を提供することです。 + +## `createSvelteTable` + +`options`オブジェクトを受け取り、テーブルを返します。 + +```svelte + +``` diff --git a/docs/ja/framework/vanilla/guide/table-state.md b/docs/ja/framework/vanilla/guide/table-state.md new file mode 100644 index 0000000000..b0a3763cc0 --- /dev/null +++ b/docs/ja/framework/vanilla/guide/table-state.md @@ -0,0 +1,8 @@ +--- +source-updated-at: '2024-03-22T06:50:43.000Z' +translation-updated-at: '2025-05-05T19:25:29.388Z' +title: テーブル状態 +--- +## テーブルステート (Vanilla JS) ガイド + +TanStack Tableのコアは**フレームワーク非依存 (framework agnostic)** です。つまり、使用するフレームワークに関係なくAPIは同じです。各フレームワーク向けのアダプターが提供されており、テーブルコアを簡単に扱えるようになっています。利用可能なアダプターについては、Adaptersメニューを参照してください。 diff --git a/docs/ja/framework/vue/guide/table-state.md b/docs/ja/framework/vue/guide/table-state.md new file mode 100644 index 0000000000..27af39893e --- /dev/null +++ b/docs/ja/framework/vue/guide/table-state.md @@ -0,0 +1,249 @@ +--- +source-updated-at: '2024-08-10T14:15:46.000Z' +translation-updated-at: '2025-05-05T19:26:41.038Z' +title: テーブル状態 +--- +## テーブルステート (Vue) ガイド + +TanStack Tableは、テーブルの状態を保存・管理するためのシンプルな内部ステート管理システムを備えています。また、独自のステート管理で管理する必要がある状態を選択的に取り出すことも可能です。このガイドでは、テーブルの状態を操作・管理するさまざまな方法について説明します。 + +### テーブルステートへのアクセス + +テーブルステートを機能させるために特別な設定は必要ありません。`state`、`initialState`、または`on[State]Change`テーブルオプションに何も渡さない場合、テーブルは内部で独自に状態を管理します。この内部状態の任意の部分には、`table.getState()`テーブルインスタンスAPIを使用してアクセスできます。 + +```ts +const table = useVueTable({ + columns, + data: dataRef, // リアクティブデータのサポート + //... +}) + +console.log(table.getState()) // 内部状態全体にアクセス +console.log(table.getState().rowSelection) // 行選択状態のみにアクセス +``` + +### リアクティブデータの使用 + +> **v8.20.0で新機能追加** + +`useVueTable`フックはリアクティブデータをサポートするようになりました。これにより、Vueの`ref`や`computed`を含むデータを`data`オプションに渡すことができます。テーブルはデータの変更に自動的に反応します。 + +```ts +const columns = [ + { accessor: 'id', Header: 'ID' }, + { accessor: 'name', Header: 'Name' } +] + +const dataRef = ref([ + { id: 1, name: 'John' }, + { id: 2, name: 'Jane' } +]) + +const table = useVueTable({ + columns, + data: dataRef, // リアクティブデータのrefを渡す +}) + +// 後でdataRefを更新すると、テーブルが自動的に更新されます +dataRef.value = [ + { id: 1, name: 'John' }, + { id: 2, name: 'Jane' }, + { id: 3, name: 'Doe' } +] +``` + +> ⚠️ パフォーマンス上の理由から、内部的に`shallowRef`が使用されています。つまり、データは深くリアクティブではなく、`.value`のみがリアクティブです。データを更新するには、データを直接変更する必要があります。 + +```ts +const dataRef = ref([ + { id: 1, name: 'John' }, + { id: 2, name: 'Jane' } +]) + +// これはテーブルを更新しません ❌ +dataRef.value.push({ id: 4, name: 'John' }) + +// これはテーブルを更新します ✅ +dataRef.value = [ + ...dataRef.value, + { id: 4, name: 'John' } +] +``` + +### カスタム初期状態 + +特定の状態に対して初期値をカスタマイズするだけでよい場合、独自に状態を管理する必要はありません。テーブルインスタンスの`initialState`オプションに値を設定するだけで済みます。 + +```jsx +const table = useVueTable({ + columns, + data, + initialState: { + columnOrder: ['age', 'firstName', 'lastName'], // 初期カラム順序をカスタマイズ + columnVisibility: { + id: false // 初期状態でidカラムを非表示 + }, + expanded: true, // 初期状態ですべての行を展開 + sorting: [ + { + id: 'age', + desc: true // 初期状態でageで降順ソート + } + ] + }, + //... +}) +``` + +> **注意**: `initialState`と`state`の両方に同じ状態を指定しないでください。両方に渡した場合、`state`で初期化された状態が`initialState`の対応する値を上書きします。 + +### 制御された状態 + +アプリケーションの他の部分でテーブル状態に簡単にアクセスする必要がある場合、TanStack Tableでは独自のステート管理システムでテーブル状態を簡単に制御・管理できます。これを行うには、独自の状態と状態管理関数を`state`および`on[State]Change`テーブルオプションに渡します。 + +#### 個別に制御された状態 + +簡単にアクセスが必要な状態のみを制御できます。すべてのテーブル状態を制御する必要はありません。必要に応じてケースバイケースで状態を制御することを推奨します。 + +特定の状態を制御するには、対応する`state`値と`on[State]Change`関数の両方をテーブルインスタンスに渡す必要があります。 + +フィルタリング、ソート、ページネーションを「手動」のサーバーサイドデータ取得シナリオの例として取り上げます。フィルタリング、ソート、ページネーションの状態を独自のステート管理に保存できますが、APIが関与しないカラム順序やカラム表示状態などは除外できます。 + +```ts +const columnFilters = ref([]) // デフォルトフィルターなし +const sorting = ref([{ + id: 'age', + desc: true, // デフォルトでageで降順ソート +}]) +const pagination = ref({ pageIndex: 0, pageSize: 15 } + +// 制御された状態値を使用してデータを取得 +const tableQuery = useQuery({ + queryKey: ['users', columnFilters, sorting, pagination], + queryFn: () => fetchUsers(columnFilters, sorting, pagination), + //... +}) + +const table = useVueTable({ + columns, + data: tableQuery.data, + //... + state: { + get columnFilters() { + return columnFilters.value + }, + get sorting() { + return sorting.value + }, + get pagination() { + return pagination.value + } + }, + onColumnFiltersChange: updater => { + columnFilters.value = + updater instanceof Function + ? updater(columnFilters.value) + : updater + }, + onSortingChange: updater => { + sorting.value = + updater instanceof Function + ? updater(sorting.value) + : updater + }, + onPaginationChange: updater => { + pagination.value = + updater instanceof Function + ? updater(pagination.value) + : updater + }, +}) +//... +``` + +#### 完全に制御された状態 + +または、`onStateChange`テーブルオプションを使用してテーブル状態全体を制御できます。これにより、テーブル状態全体が独自のステート管理システムに引き上げられます。ただし、`columnSizingInfo`状態のように頻繁に変更される状態値をReactツリーの上位に引き上げると、パフォーマンスの問題を引き起こす可能性があるため、注意が必要です。 + +これを機能させるには、さらにいくつかの工夫が必要かもしれません。`onStateChange`テーブルオプションを使用する場合、`state`の初期値には、使用したいすべての機能に関連する状態値をすべて設定する必要があります。すべての初期状態値を手動で入力するか、以下のように`table.setOptions` APIを特別な方法で使用できます。 + +```jsx +// デフォルト状態値でテーブルインスタンスを作成 +const table = useVueTable({ + get columns() { + return columns.value + }, + data, + //... 注: `state`値はまだ渡されていません +}) + +const state = ref({ + ...table.initialState, + pagination: { + pageIndex: 0, + pageSize: 15 + } +}) +const setState = updater => { + state.value = updater instanceof Function ? updater(state.value) : updater +} + +// table.setOptions APIを使用して、完全に制御された状態をテーブルインスタンスにマージ +table.setOptions(prev => ({ + ...prev, // 上記で設定した他のオプションを保持 + get state() { + return state.value + }, + onStateChange: setState // 状態変更は独自のステート管理に引き上げられます +})) +``` + +### 状態変更コールバック + +これまで、`on[State]Change`および`onStateChange`テーブルオプションがテーブル状態の変更を独自のステート管理に「引き上げる」仕組みを見てきました。ただし、これらのオプションを使用する際に注意すべき点がいくつかあります。 + +#### 1. **状態変更コールバックには、対応する状態値が`state`オプションに含まれている必要があります**。 + +`on[State]Change`コールバックを指定すると、テーブルインスタンスはこれが制御された状態であると認識します。対応する`state`値を指定しない場合、その状態は初期値で「凍結」されます。 + +```jsx +const sorting = ref([]) +const setSorting = updater => { + sorting.value = updater instanceof Function ? updater(sorting.value) : updater +} +//... +const table = useVueTable({ + columns, + data, + //... + state: { + get sorting() { + return sorting // `onSortingChange`を使用するため必要 + }, + }, + onSortingChange: setSorting, // `state.sorting`を制御します +}) +``` + +#### 2. **アップデータは生の値またはコールバック関数のいずれかになります**。 + +`on[State]Change`および`onStateChange`コールバックは、Reactの`setState`関数とまったく同じように機能します。アップデータ値は、新しい状態値または前の状態値を受け取り新しい状態値を返すコールバック関数のいずれかになります。 + +これにはどのような意味があるでしょうか? `on[State]Change`コールバックに追加のロジックを含めたい場合、新しいアップデータ値が関数か値かを確認する必要があることを意味します。 + +これが、上記の`setState`関数に`updater instanceof Function`チェックがある理由です。このチェックにより、同じ関数内で生の値とコールバック関数の両方を処理できます。 + +### 状態の型 + +TanStack Tableのすべての複雑な状態には、インポートして使用できる独自のTypeScript型があります。これは、制御している状態値に対して正しいデータ構造とプロパティを使用していることを確認するのに便利です。 + +```tsx +import { useVueTable, type SortingState } from '@tanstack/vue-table' +//... +const sorting = ref([ + { + id: 'age', // `id`と`desc`プロパティのオートコンプリートが表示されます + desc: true, + } +]) +``` diff --git a/docs/ja/framework/vue/vue-table.md b/docs/ja/framework/vue/vue-table.md new file mode 100644 index 0000000000..655b77fa0f --- /dev/null +++ b/docs/ja/framework/vue/vue-table.md @@ -0,0 +1,48 @@ +--- +source-updated-at: '2024-05-17T05:10:48.000Z' +translation-updated-at: '2025-05-05T19:23:54.221Z' +title: Vueテーブルアダプター +--- +# Vue Table + +TanStack Tableのコアは**フレームワーク非依存 (framework agnostic)** です。つまり、使用するフレームワークに関係なくAPIは同じです。各フレームワークでテーブルコアを簡単に操作できるように、アダプターが提供されています。利用可能なアダプターについては、Adaptersメニューを参照してください。 + +`@tanstack/vue-table`アダプターは、コアのテーブルロジックをラップするものです。その主な役割は、状態管理を"Vue"の方法で行い、型を提供し、セル/ヘッダー/フッターテンプレートのレンダリング実装を提供することです。 + +## エクスポート + +`@tanstack/vue-table`は`@tanstack/table-core`のすべてのAPIと以下を再エクスポートします: + +### `useVueTable` + +`options`オブジェクトを受け取り、テーブルを返します。 + +```ts +import { useVueTable } from '@tanstack/vue-table' + +const table = useVueTable(options) +// ...テーブルをレンダリング +``` + +### `FlexRender` + +動的な値を持つセル/ヘッダー/フッターテンプレートをレンダリングするためのVueコンポーネントです。 + +例: + +```vue +import { FlexRender } from '@tanstack/vue-table' + + +``` diff --git a/docs/ja/guide/cells.md b/docs/ja/guide/cells.md new file mode 100644 index 0000000000..8345524ee4 --- /dev/null +++ b/docs/ja/guide/cells.md @@ -0,0 +1,87 @@ +--- +source-updated-at: '2025-03-20T21:15:29.000Z' +translation-updated-at: '2025-05-05T19:24:46.938Z' +title: セル +--- +## API + +[Cell API](../api/core/cell) + +## セルガイド + +このクイックガイドでは、TanStack Tableで`cell`オブジェクトを取得および操作するさまざまな方法について説明します。 + +### セルの取得元 + +セルは[行(Rows)](../guide/rows)から取得されます。これで十分ですよね? + +使用している機能に応じて、行インスタンスAPIを使用して適切なセルを取得できます。最も一般的には、`row.getAllCells`または`row.getVisibleCells` APIを使用します(列可視性機能を使用している場合)。ただし、他にもいくつかの類似したAPIが利用可能です。 + +### セルオブジェクト + +各セルオブジェクトは、UI内の``または類似のセル要素に関連付けることができます。`cell`オブジェクトには、テーブルの状態と連携したり、テーブルの状態に基づいてセル値を抽出したりするために使用できるプロパティやメソッドがいくつかあります。 + +#### セルID + +各セルオブジェクトには、テーブルインスタンス内で一意となる`id`プロパティがあります。各`cell.id`は、親行と列のIDをアンダースコアで区切った単純な結合として構築されます。 + +```js +{ id: `${row.id}_${column.id}` } +``` + +グループ化や集計機能を使用している場合、`cell.id`には追加の文字列が付加されます。 + +#### セルの親オブジェクト + +各セルは、親の[行(row)](../guide/rows)と[列(column)](../guide/columns)オブジェクトへの参照を保持しています。 + +#### セル値へのアクセス + +セルからデータ値を取得する推奨方法は、`cell.getValue`または`cell.renderValue` APIを使用することです。これらのAPIを使用すると、アクセサ関数の結果がキャッシュされ、レンダリングが効率的になります。両者の唯一の違いは、`cell.renderValue`は値が未定義の場合に値または`renderFallbackValue`を返すのに対し、`cell.getValue`は値または未定義の場合は`undefined`を返す点です。 + +> 注: `cell.getValue`と`cell.renderValue` APIは、それぞれ`row.getValue`と`row.renderValue` APIのショートカットです。 + +```js +// 任意の列からデータにアクセス +const firstName = cell.getValue('firstName') // firstName列からセル値を取得 +const renderedLastName = cell.renderValue('lastName') // lastName列から値をレンダリング +``` + +#### 任意のセルから他の行データにアクセス + +各セルオブジェクトは親行に関連付けられているため、`cell.row.original`を使用してテーブルで使用している元の行データにアクセスできます。 + +```js +// 別のセルのスコープ内にいても、元の行データにアクセス可能 +const firstName = cell.row.original.firstName // { firstName: 'John', lastName: 'Doe' } +``` + +### その他のセルAPI + +テーブルで使用している機能に応じて、セルを操作するための便利なAPIが数十種類あります。詳細については、各機能の対応するAPIドキュメントまたはガイドを参照してください。 + +### セルのレンダリング + +テーブルのセルをレンダリングするには、`cell.renderValue`または`cell.getValue` APIを使用できます。ただし、これらのAPIは生のセル値(アクセサ関数からの値)のみを出力します。`cell: () => JSX`列定義オプションを使用している場合は、アダプタから`flexRender` APIユーティリティを使用する必要があります。 + +`flexRender` APIを使用すると、セルが追加のマークアップやJSXとともに正しくレンダリングされ、コールバック関数が正しいパラメータで呼び出されます。 + +```jsx +import { flexRender } from '@tanstack/react-table' + +const columns = [ + { + accessorKey: 'fullName', + cell: ({ cell, row }) => { + return
{row.original.firstName} {row.original.lastName}
+ } + //... + } +] +//... + + {row.getVisibleCells().map(cell => { + return {flexRender(cell.column.columnDef.cell, cell.getContext())} + })} + +``` diff --git a/docs/ja/guide/column-defs.md b/docs/ja/guide/column-defs.md new file mode 100644 index 0000000000..3da83e0e8e --- /dev/null +++ b/docs/ja/guide/column-defs.md @@ -0,0 +1,283 @@ +--- +source-updated-at: '2025-03-20T21:15:29.000Z' +translation-updated-at: '2025-05-05T19:25:13.911Z' +title: カラム定義 +--- +## API + +[Column Def](../api/core/column-def) + +## カラム定義ガイド + +> 注: このガイドはテーブルのカラム定義の設定に関するものであり、テーブルインスタンス内で生成される実際の[`column`](../guide/columns)オブジェクトについては扱いません。 + +カラム定義はテーブル構築において最も重要な部分です。これらは以下の役割を担います: + +- ソート、フィルタリング、グループ化などすべての処理に使用される基礎データモデルの構築 +- データモデルをテーブルに表示する形式への変換 +- [ヘッダーグループ](../api/core/header-group)、[ヘッダー](../api/core/header)、[フッター](../api/core/column-def#footer)の作成 +- アクションボタン、チェックボックス、エキスパンダー、スパークラインなど表示専用のカラム作成 + +## カラム定義の種類 + +以下のカラム定義「タイプ」は実際のTypeScriptの型ではなく、カラム定義の全体的なカテゴリを説明するための概念です: + +- `アクセサーカラム (Accessor Columns)` + - データモデルを持つため、ソート、フィルタリング、グループ化などが可能 +- `ディスプレイカラム (Display Columns)` + - データモデルを持たないためソートやフィルタリングは不可だが、テーブルに任意のコンテンツ(行アクションボタン、チェックボックス、エキスパンダーなど)を表示可能 +- `グループ化カラム (Grouping Columns)` + - データモデルを持たないためソートやフィルタリングは不可で、他のカラムをグループ化するために使用。カラムグループのヘッダーやフッターを定義するのが一般的 + +## カラムヘルパー + +カラム定義は結局のところ単なるオブジェクトですが、テーブルコアから`createColumnHelper`関数が公開されています。この関数に行タイプを渡すと、可能な限り型安全な方法で様々なカラム定義タイプを作成するユーティリティが返されます。 + +以下はカラムヘルパーの作成と使用例です: + +```tsx +// 行の形状を定義 +type Person = { + firstName: string + lastName: string + age: number + visits: number + status: string + progress: number +} + +const columnHelper = createColumnHelper() + +// カラムを作成 +const defaultColumns = [ + // ディスプレイカラム + columnHelper.display({ + id: 'actions', + cell: props => , + }), + // グループ化カラム + columnHelper.group({ + header: 'Name', + footer: props => props.column.id, + columns: [ + // アクセサーカラム + columnHelper.accessor('firstName', { + cell: info => info.getValue(), + footer: props => props.column.id, + }), + // アクセサーカラム + columnHelper.accessor(row => row.lastName, { + id: 'lastName', + cell: info => info.getValue(), + header: () => Last Name, + footer: props => props.column.id, + }), + ], + }), + // グループ化カラム + columnHelper.group({ + header: 'Info', + footer: props => props.column.id, + columns: [ + // アクセサーカラム + columnHelper.accessor('age', { + header: () => 'Age', + footer: props => props.column.id, + }), + // グループ化カラム + columnHelper.group({ + header: 'More Info', + columns: [ + // アクセサーカラム + columnHelper.accessor('visits', { + header: () => Visits, + footer: props => props.column.id, + }), + // アクセサーカラム + columnHelper.accessor('status', { + header: 'Status', + footer: props => props.column.id, + }), + // アクセサーカラム + columnHelper.accessor('progress', { + header: 'Profile Progress', + footer: props => props.column.id, + }), + ], + }), + ], + }), +] +``` + +## アクセサーカラムの作成 + +データカラムは、`data`配列の各アイテムからプリミティブ値を抽出するように設定する必要がある点で特殊です。 + +これには3つの方法があります: + +- アイテムが`オブジェクト`の場合、抽出したい値に対応するオブジェクトキーを使用 +- アイテムがネストされた`配列`の場合、抽出したい値に対応する配列インデックスを使用 +- 抽出したい値を返すアクセサー関数を使用 + +## オブジェクトキー + +各アイテムが以下の形状のオブジェクトの場合: + +```tsx +type Person = { + firstName: string + lastName: string + age: number + visits: number + status: string + progress: number +} +``` + +`firstName`値を以下のように抽出できます: + +```tsx +columnHelper.accessor('firstName') + +// または + +{ + accessorKey: 'firstName', +} +``` + +## 深いキー + +各アイテムが以下の形状のオブジェクトの場合: + +```tsx +type Person = { + name: { + first: string + last: string + } + info: { + age: number + visits: number + } +} +``` + +`first`値を以下のように抽出できます: + +```tsx +columnHelper.accessor('name.first', { + id: 'firstName', +}) + +// または + +{ + accessorKey: 'name.first', + id: 'firstName', +} +``` + +## 配列インデックス + +各アイテムが以下の形状の配列の場合: + +```tsx +type Sales = [Date, number] +``` + +`number`値を以下のように抽出できます: + +```tsx +columnHelper.accessor(1) + +// または + +{ + accessorKey: 1, +} +``` + +## アクセサー関数 + +各アイテムが以下の形状のオブジェクトの場合: + +```tsx +type Person = { + firstName: string + lastName: string + age: number + visits: number + status: string + progress: number +} +``` + +計算されたフルネーム値を以下のように抽出できます: + +```tsx +columnHelper.accessor(row => `${row.firstName} ${row.lastName}`, { + id: 'fullName', +}) + +// または + +{ + id: 'fullName', + accessorFn: row => `${row.firstName} ${row.lastName}`, +} +``` + +> 🧠 アクセサー関数が返す値はソートやフィルタリングなどに使用されるため、意味のある操作が可能なプリミティブ値を返すようにしてください。オブジェクトや配列のような非プリミティブ値を返す場合は、適切なフィルター/ソート/グループ化関数を用意するか、独自の関数を提供する必要があります!😬 + +## ユニークなカラムID + +カラムは3つの方法で一意に識別されます: + +- オブジェクトキーまたは配列インデックスでアクセサーカラムを定義する場合、同じ値がカラムの一意識別に使用されます + - オブジェクトキー内のピリオド(`.`)はアンダースコア(`_`)に置換されます +- アクセサー関数でアクセサーカラムを定義する場合 + - カラムの`id`プロパティが一意識別に使用されるか + - プリミティブな`文字列`ヘッダーが提供されている場合、そのヘッダー文字列が一意識別に使用されます + +> 🧠 簡単に覚える方法: アクセサー関数でカラムを定義する場合は、文字列ヘッダーを提供するか、一意の`id`プロパティを提供してください。 + +## カラムのフォーマットとレンダリング + +デフォルトでは、カラムセルはデータモデル値を文字列として表示します。カスタムレンダリング実装を提供することでこの動作を上書きできます。各実装にはセル、ヘッダー、フッターに関する関連情報が提供され、使用するフレームワークアダプターがレンダリングできるもの(JSX/コンポーネント/文字列など)を返します。これは使用するアダプターによって異なります。 + +利用可能なフォーマッター: + +- `cell`: セルのフォーマットに使用 +- `aggregatedCell`: 集約時のセルフォーマットに使用 +- `header`: ヘッダーのフォーマットに使用 +- `footer`: フッターのフォーマットに使用 + +## セルフォーマット + +`cell`プロパティに関数を渡し、`props.getValue()`関数を使用してセルの値にアクセスすることで、カスタムセルフォーマッタを提供できます: + +```tsx +columnHelper.accessor('firstName', { + cell: props => {props.getValue().toUpperCase()}, +}) +``` + +セルフォーマッタには`row`と`table`オブジェクトも渡されるため、セル値だけでなくセルのフォーマットをさらにカスタマイズできます。以下の例では`firstName`をアクセサーとして指定していますが、元の行オブジェクトにあるユーザーIDを接頭辞として表示しています: + +```tsx +columnHelper.accessor('firstName', { + cell: props => ( + {`${props.row.original.id} - ${props.getValue()}`} + ), +}) +``` + +## 集約セルフォーマット + +集約セルの詳細については、[グループ化](../guide/grouping)を参照してください。 + +## ヘッダーとフッターのフォーマット + +ヘッダーとフッターは行データにアクセスできませんが、カスタムコンテンツを表示するための同じ概念を使用します。 diff --git a/docs/ja/guide/column-faceting.md b/docs/ja/guide/column-faceting.md new file mode 100644 index 0000000000..47b227cc1a --- /dev/null +++ b/docs/ja/guide/column-faceting.md @@ -0,0 +1,90 @@ +--- +source-updated-at: '2025-03-20T21:15:29.000Z' +translation-updated-at: '2025-05-05T19:26:51.424Z' +title: カラムファセット +--- +## 例 + +実装に直接進みたいですか?以下の例を確認してください: + +- [filters-faceted](../framework/react/examples/filters-faceted) + +## API + +[Column Faceting API](../api/features/column-faceting) + +## カラムファセットガイド + +カラムファセット (Column Faceting) は、特定のカラムのデータからそのカラムの値のリストを生成できる機能です。例えば、カラム内のすべての行から一意の値のリストを生成し、オートコンプリートフィルターコンポーネントの検索候補として使用できます。または、数値のカラムから最小値と最大値のタプルを生成し、レンジスライダーフィルターコンポーネントの範囲として使用できます。 + +### カラムファセットの行モデル + +カラムファセット機能を使用するには、テーブルオプションに適切な行モデルを含める必要があります。 + +```ts +//必要な行モデルのみをインポート +import { + getCoreRowModel, + getFacetedRowModel, + getFacetedMinMaxValues, //getFacetedRowModelに依存 + getFacetedUniqueValues, //getFacetedRowModelに依存 +} +//... +const table = useReactTable({ + columns, + data, + getCoreRowModel: getCoreRowModel(), + getFacetedRowModel: getFacetedRowModel(), //カラムの値リストが必要な場合(他のファセット行モデルはこれに依存) + getFacetedMinMaxValues: getFacetedMinMaxValues(), //最小/最大値が必要な場合 + getFacetedUniqueValues: getFacetedUniqueValues(), //一意の値リストが必要な場合 + //... +}) +``` + +まず、`getFacetedRowModel` 行モデルを含める必要があります。この行モデルは、指定されたカラムの値リストを生成します。一意の値リストが必要な場合は、`getFacetedUniqueValues` 行モデルを含めてください。最小値と最大値のタプルが必要な場合は、`getFacetedMinMaxValues` 行モデルを含めてください。 + +### ファセット行モデルの使用 + +テーブルオプションに適切な行モデルを含めたら、ファセットカラムインスタンスAPIを使用して、ファセット行モデルによって生成された値リストにアクセスできます。 + +```ts +// オートコンプリートフィルター用の一意の値リスト +const autoCompleteSuggestions = + Array.from(column.getFacetedUniqueValues().keys()) + .sort() + .slice(0, 5000); +``` + +```ts +// レンジフィルター用の最小値と最大値のタプル +const [min, max] = column.getFacetedMinMaxValues() ?? [0, 1]; +``` + +### カスタム(サーバーサイド)ファセット + +組み込みのクライアントサイドファセット機能の代わりに、サーバーサイドで独自のファセットロジックを実装し、ファセットされた値をクライアントサイドに渡すことができます。`getFacetedUniqueValues` および `getFacetedMinMaxValues` テーブルオプションを使用して、サーバーサイドからファセットされた値を解決できます。 + +```ts +const facetingQuery = useQuery( + //... +) + +const table = useReactTable({ + columns, + data, + getCoreRowModel: getCoreRowModel(), + getFacetedRowModel: getFacetedRowModel(), + getFacetedUniqueValues: (table, columnId) => { + const uniqueValueMap = new Map(); + //... + return uniqueValueMap; + }, + getFacetedMinMaxValues: (table, columnId) => { + //... + return [min, max]; + }, + //... +}) +``` + +あるいは、ファセットロジックをTanStack Table APIを通じて一切処理する必要はありません。単にリストを取得し、直接フィルターコンポーネントに渡すこともできます。 diff --git a/docs/ja/guide/column-filtering.md b/docs/ja/guide/column-filtering.md new file mode 100644 index 0000000000..4b916911cc --- /dev/null +++ b/docs/ja/guide/column-filtering.md @@ -0,0 +1,328 @@ +--- +source-updated-at: '2025-03-20T21:15:29.000Z' +translation-updated-at: '2025-05-05T19:28:29.613Z' +title: カラムフィルタリング +--- +## 例 + +実装に直接進みたい場合は、以下の例を参照してください: + +- [列フィルタリング](../framework/react/examples/filters) +- [ファセットフィルタリング](../framework/react/examples/filters-faceted) (オートコンプリートと範囲フィルタ) +- [ファジー検索](../framework/react/examples/filters-fuzzy) (Match Sorter) +- [編集可能なデータ](../framework/react/examples/editable-data) +- [展開](../framework/react/examples/expanding) (サブ行からのフィルタリング) +- [グループ化](../framework/react/examples/grouping) +- [ページネーション](../framework/react/examples/pagination) +- [行選択](../framework/react/examples/row-selection) + +## API + +[列フィルタリング API](../api/features/column-filtering) + +## 列フィルタリングガイド + +フィルタリングには2つの種類があります: 列フィルタリングとグローバルフィルタリングです。 + +このガイドでは、単一列のアクセサ値に適用されるフィルタである列フィルタリングに焦点を当てます。 + +TanStackテーブルはクライアントサイドと手動サーバーサイドの両方のフィルタリングをサポートしています。このガイドでは、両方を実装およびカスタマイズする方法と、どのユースケースに最適かを判断する手助けをします。 + +### クライアントサイド vs サーバーサイドフィルタリング + +大規模なデータセットがある場合、すべてのデータをクライアントのブラウザに読み込んでフィルタリングしたくないかもしれません。その場合、サーバーサイドフィルタリング、ソート、ページネーションなどを実装するのが適切でしょう。 + +ただし、[ページネーションガイド](../guide/pagination#should-you-use-client-side-pagination)でも述べられているように、多くの開発者はクライアントサイドでパフォーマンスに影響を与えずに処理できる行数を過小評価しています。TanStackテーブルの例では、100,000行以上のデータでもクライアントサイドのフィルタリング、ソート、ページネーション、グループ化が十分なパフォーマンスで動作することがよくテストされています。これは必ずしもあなたのアプリがそれだけの行数を処理できるという意味ではありませんが、テーブルが最大でも数千行程度であれば、TanStackテーブルが提供するクライアントサイドのフィルタリング、ソート、ページネーション、グループ化を活用できるかもしれません。 + +> TanStackテーブルは数千行のクライアントサイド処理を良好なパフォーマンスで処理できます。少し考える前にクライアントサイドのフィルタリング、ページネーション、ソートなどを除外しないでください。 + +すべてのユースケースは異なり、テーブルの複雑さ、列の数、各データのサイズなどによって異なります。注意すべき主なボトルネックは以下の通りです: + +1. サーバーがすべてのデータを合理的な時間(およびコスト)でクエリできるか? +2. フェッチするデータの総サイズは?(列が多くない場合、思ったほど悪くスケールしないかもしれません) +3. すべてのデータを一度に読み込むとクライアントのブラウザがメモリを使いすぎるか? + +わからない場合は、まずクライアントサイドのフィルタリングとページネーションから始め、データが増えるにつれて将来サーバーサイドの戦略に切り替えることができます。 + +### 手動サーバーサイドフィルタリング + +組み込みのクライアントサイドフィルタリングではなく、サーバーサイドフィルタリングを実装する必要があると判断した場合、その方法を説明します。 + +手動サーバーサイドフィルタリングには`getFilteredRowModel`テーブルオプションは必要ありません。代わりに、テーブルに渡す`data`は既にフィルタリングされている必要があります。ただし、`getFilteredRowModel`テーブルオプションを渡した場合、`manualFiltering`オプションを`true`に設定することでテーブルにそれをスキップするように指示できます。 + +```jsx +const table = useReactTable({ + data, + columns, + getCoreRowModel: getCoreRowModel(), + // getFilteredRowModel: getFilteredRowModel(), // 手動サーバーサイドフィルタリングには不要 + manualFiltering: true, +}) +``` + +> **注:** 手動フィルタリングを使用する場合、このガイドの残りの部分で説明する多くのオプションは効果がありません。`manualFiltering`が`true`に設定されている場合、テーブルインスタンスは渡された行にフィルタリングロジックを適用しません。代わりに、行は既にフィルタリングされていると仮定し、渡された`data`をそのまま使用します。 + +### クライアントサイドフィルタリング + +組み込みのクライアントサイドフィルタリング機能を使用する場合、まず`getFilteredRowModel`関数をテーブルオプションに渡す必要があります。この関数はテーブルがデータをフィルタリングする必要があるときに呼び出されます。TanStackテーブルからデフォルトの`getFilteredRowModel`関数をインポートするか、独自の関数を作成できます。 + +```jsx +import { useReactTable, getFilteredRowModel } from '@tanstack/react-table' +//... +const table = useReactTable({ + data, + columns, + getCoreRowModel: getCoreRowModel(), + getFilteredRowModel: getFilteredRowModel(), // クライアントサイドフィルタリングに必要 +}) +``` + +### 列フィルタ状態 + +クライアントサイドまたはサーバーサイドのフィルタリングを使用するかどうかにかかわらず、TanStackテーブルが提供する組み込みの列フィルタ状態管理を活用できます。フィルタ状態を変更および操作し、列フィルタ状態を取得するための多くのテーブルおよび列APIがあります。 + +列フィルタ状態は以下の形状のオブジェクトの配列として定義されます: + +```ts +interface ColumnFilter { + id: string + value: unknown +} +type ColumnFiltersState = ColumnFilter[] +``` + +列フィルタ状態はオブジェクトの配列であるため、複数の列フィルタを同時に適用できます。 + +#### 列フィルタ状態へのアクセス + +`table.getState()` APIを使用して、他のテーブル状態と同様にテーブルインスタンスから列フィルタ状態にアクセスできます。 + +```jsx +const table = useReactTable({ + columns, + data, + //... +}) + +console.log(table.getState().columnFilters) // テーブルインスタンスから列フィルタ状態にアクセス +``` + +ただし、テーブルが初期化される前に列フィルタ状態にアクセスする必要がある場合は、以下のように列フィルタ状態を「制御」できます。 + +### 制御された列フィルタ状態 + +列フィルタ状態に簡単にアクセスする必要がある場合は、`state.columnFilters`と`onColumnFiltersChange`テーブルオプションを使用して、独自の状態管理で列フィルタ状態を制御/管理できます。 + +```tsx +const [columnFilters, setColumnFilters] = useState([]) // ここで初期列フィルタ状態を設定可能 +//... +const table = useReactTable({ + columns, + data, + //... + state: { + columnFilters, + }, + onColumnFiltersChange: setColumnFilters, +}) +``` + +#### 初期列フィルタ状態 + +独自の状態管理やスコープで列フィルタ状態を制御する必要がないが、初期列フィルタ状態を設定したい場合は、`state`の代わりに`initialState`テーブルオプションを使用できます。 + +```jsx +const table = useReactTable({ + columns, + data, + //... + initialState: { + columnFilters: [ + { + id: 'name', + value: 'John', // デフォルトでname列を'John'でフィルタ + }, + ], + }, +}) +``` + +> **注**: `initialState.columnFilters`と`state.columnFilters`を同時に使用しないでください。`state.columnFilters`で初期化された状態が`initialState.columnFilters`を上書きします。 + +### フィルタ関数 + +各列は独自のフィルタリングロジックを持つことができます。TanStackテーブルが提供するフィルタ関数から選択するか、独自の関数を作成できます。 + +デフォルトで10の組み込みフィルタ関数が利用可能です: + +- `includesString` - 大文字小文字を区別しない文字列包含 +- `includesStringSensitive` - 大文字小文字を区別する文字列包含 +- `equalsString` - 大文字小文字を区別しない文字列一致 +- `equalsStringSensitive` - 大文字小文字を区別する文字列一致 +- `arrIncludes` - 配列内のアイテム包含 +- `arrIncludesAll` - 配列内のすべてのアイテム包含 +- `arrIncludesSome` - 配列内の一部のアイテム包含 +- `equals` - オブジェクト/参照等価性 `Object.is`/`===` +- `weakEquals` - 弱いオブジェクト/参照等価性 `==` +- `inNumberRange` - 数値範囲包含 + +`filterFn`列オプションまたは`filterFns`テーブルオプションを使用して、カスタムフィルタ関数を定義することもできます。 + +#### カスタムフィルタ関数 + +> **注:** これらのフィルタ関数はクライアントサイドフィルタリング時のみ実行されます。 + +`filterFn`列オプションまたは`filterFns`テーブルオプションでカスタムフィルタ関数を定義する場合、以下のシグネチャを持つ必要があります: + +```ts +const myCustomFilterFn: FilterFn = (row: Row, columnId: string, filterValue: any, addMeta: (meta: any) => void) => boolean +``` + +各フィルタ関数は以下を受け取ります: + +- フィルタする行 +- 行の値を取得するためのcolumnId +- フィルタ値 + +そして、行がフィルタされた行に含まれるべき場合は`true`を、削除されるべき場合は`false`を返す必要があります。 + +```jsx +const columns = [ + { + header: () => '名前', + accessorKey: 'name', + filterFn: 'includesString', // 組み込みフィルタ関数を使用 + }, + { + header: () => '年齢', + accessorKey: 'age', + filterFn: 'inNumberRange', + }, + { + header: () => '誕生日', + accessorKey: 'birthday', + filterFn: 'myCustomFilterFn', // カスタムグローバルフィルタ関数を使用 + }, + { + header: () => 'プロフィール', + accessorKey: 'profile', + // 直接カスタムフィルタ関数を使用 + filterFn: (row, columnId, filterValue) => { + return // カスタムロジックに基づいてtrueまたはfalse + }, + } +] +//... +const table = useReactTable({ + columns, + data, + getCoreRowModel: getCoreRowModel(), + getFilteredRowModel: getFilteredRowModel(), + filterFns: { // カスタムグローバルフィルタ関数を追加 + myCustomFilterFn: (row, columnId, filterValue) => { // ここでインライン定義 + return // カスタムロジックに基づいてtrueまたはfalse + }, + startsWith: startsWithFilterFn, // 別途定義 + }, +}) +``` + +##### フィルタ関数の動作をカスタマイズ + +フィルタ関数にいくつかの追加プロパティをアタッチして動作をカスタマイズできます: + +- `filterFn.resolveFilterValue` - 任意の`filterFn`に追加できるこのオプショナルな「ハンギング」メソッドは、フィルタ値がフィルタ関数に渡される前に変換/サニタイズ/フォーマットすることを許可します。 + +- `filterFn.autoRemove` - 任意の`filterFn`に追加できるこのオプショナルな「ハンギング」メソッドは、フィルタ値がフィルタ状態から削除されるべきかどうかを判断するために使用されます。例えば、ブールスタイルのフィルタは、フィルタ値が`false`に設定されている場合、フィルタ値をテーブル状態から削除したい場合があります。 + +```tsx +const startsWithFilterFn = ( + row: Row, + columnId: string, + filterValue: number | string, //resolveFilterValueはこれを文字列に変換します +) => + row + .getValue(columnId) + .toString() + .toLowerCase() + .trim() + .startsWith(filterValue); // `resolveFilterValue`でフィルタ値をtoString、toLowerCase、trim + +// フィルタ値がfalsy(この場合は空文字列)の場合、フィルタ状態から削除 +startsWithFilterFn.autoRemove = (val: any) => !val; + +// フィルタ値がフィルタ関数に渡される前に変換/サニタイズ/フォーマット +startsWithFilterFn.resolveFilterValue = (val: any) => val.toString().toLowerCase().trim(); +``` + +### 列フィルタリングのカスタマイズ + +列フィルタリング動作をさらにカスタマイズするために使用できる多くのテーブルおよび列オプションがあります。 + +#### 列フィルタリングの無効化 + +デフォルトでは、すべての列で列フィルタリングが有効になっています。`enableColumnFilters`テーブルオプションまたは`enableColumnFilter`列オプションを使用して、すべての列または特定の列で列フィルタリングを無効にできます。また、`enableFilters`テーブルオプションを`false`に設定することで、列フィルタリングとグローバルフィルタリングの両方を無効にできます。 + +列のフィルタリングを無効にすると、その列に対して`column.getCanFilter` APIは`false`を返します。 + +```jsx +const columns = [ + { + header: () => 'ID', + accessorKey: 'id', + enableColumnFilter: false, // この列のフィルタリングを無効化 + }, + //... +] +//... +const table = useReactTable({ + columns, + data, + enableColumnFilters: false, // すべての列のフィルタリングを無効化 +}) +``` + +#### サブ行のフィルタリング(展開) + +展開、グループ化、集計などの機能を使用する際の列フィルタリング動作をカスタマイズするためのいくつかの追加テーブルオプションがあります。 + +##### リーフ行からフィルタリング + +デフォルトでは、フィルタリングは親行から下に向かって行われるため、親行がフィルタリングされると、すべての子サブ行もフィルタリングされます。ユースケースによっては、トップレベルの行のみを検索させ、サブ行は検索させない場合に望ましい動作です。これはまた最もパフォーマンスの高いオプションです。 + +ただし、親行がフィルタリングされているかどうかに関係なく、サブ行をフィルタリングおよび検索できるようにしたい場合は、`filterFromLeafRows`テーブルオプションを`true`に設定できます。このオプションを`true`に設定すると、フィルタリングはリーフ行から上に向かって行われるため、子または孫の行が含まれている限り、親行も含まれます。 + +```jsx +const table = useReactTable({ + columns, + data, + getCoreRowModel: getCoreRowModel(), + getFilteredRowModel: getFilteredRowModel(), + getExpandedRowModel: getExpandedRowModel(), + filterFromLeafRows: true, // サブ行をフィルタリングおよび検索 +}) +``` + +##### 最大リーフ行フィルタ深度 + +デフォルトでは、ツリー内のすべての行に対してフィルタリングが行われます。`maxLeafRowFilterDepth`テーブルオプションを`0`に設定すると、フィルタリングはルートレベルの親行にのみ適用され、すべてのサブ行はフィルタリングされません。同様に、このオプションを`1`に設定すると、フィルタリングは1レベルの深さの子リーフ行にのみ適用されます。 + +親行がフィルタを通過している間、親行のサブ行がフィルタリングされないようにするには、`maxLeafRowFilterDepth: 0`を使用します。 + +```jsx +const table = useReactTable({ + columns, + data, + getCoreRowModel: getCoreRowModel(), + getFilteredRowModel: getFilteredRowModel(), + getExpandedRowModel: getExpandedRowModel(), + maxLeafRowFilterDepth: 0, // ルートレベルの親行のみをフィルタリング +}) +``` + +### 列フィルタAPI + +列フィルタ状態と対話し、UIコンポーネントに接続するために使用できる多くの列およびテーブルAPIがあります。以下は利用可能なAPIとその最も一般的な使用例のリストです: + +- `table.setColumnFilters` - 列フィルタ状態全体を新しい状態で上書きします。 +- `table.resetColumnFilters` - 「すべてクリア/リセット」ボタ diff --git a/docs/ja/guide/column-ordering.md b/docs/ja/guide/column-ordering.md new file mode 100644 index 0000000000..49cc05e401 --- /dev/null +++ b/docs/ja/guide/column-ordering.md @@ -0,0 +1,112 @@ +--- +source-updated-at: '2025-03-20T21:15:29.000Z' +translation-updated-at: '2025-05-05T19:26:21.530Z' +title: カラム順序 +--- +## 例 + +実装に直接進みたいですか?以下の例を確認してください: + +- [column-ordering](../framework/react/examples/column-ordering) +- [column-dnd](../framework/react/examples/column-dnd) + +## API + +[Column Ordering API](../api/features/column-ordering) + +## カラム順序ガイド + +デフォルトでは、カラムは`columns`配列で定義された順序で並びます。ただし、`columnOrder`ステートを使用してカラムの順序を手動で指定できます。カラムピン留めやグループ化などの他の機能もカラムの順序に影響を与えることがあります。 + +### カラム順序に影響する要素 + +カラムの順序を変更する可能性があるテーブル機能は3つあり、以下の順序で適用されます: + +1. [カラムピン留め](../guide/column-pinning) - ピン留めが有効な場合、カラムは左、中央(ピン留めされていない)、右ピン留めカラムに分割されます。 +2. 手動による**カラム順序指定** - 手動で指定されたカラム順序が適用されます。 +3. [グループ化](../guide/grouping) - グループ化が有効で、グループ化ステートがアクティブかつ`tableOptions.groupedColumnMode`が`'reorder' | 'remove'`に設定されている場合、グループ化されたカラムがカラムフローの先頭に並べ替えられます。 + +> **注意:** `columnOrder`ステートは、カラムピン留めと併用する場合、ピン留めされていないカラムにのみ影響します。 + +### カラム順序ステート + +`columnOrder`ステートを指定しない場合、TanStack Tableは`columns`配列のカラム順序を使用します。ただし、`columnOrder`ステートにカラムIDの配列を指定することで、カラムの順序を指定できます。 + +#### デフォルトのカラム順序 + +初期のカラム順序を指定するだけでよい場合は、`initialState`テーブルオプションで`columnOrder`ステートを指定できます。 + +```jsx +const table = useReactTable({ + //... + initialState: { + columnOrder: ['columnId1', 'columnId2', 'columnId3'], + } + //... +}); +``` + +> **注意:** `state`テーブルオプションで`columnOrder`ステートも指定している場合、`initialState`は効果がありません。特定のステートは`initialState`または`state`のいずれかで指定してください。両方で指定しないでください。 + +#### カラム順序ステートの管理 + +カラム順序を動的に変更する必要がある場合、またはテーブル初期化後にカラム順序を設定する必要がある場合は、他のテーブルステートと同様に`columnOrder`ステートを管理できます。 + +```jsx +const [columnOrder, setColumnOrder] = useState(['columnId1', 'columnId2', 'columnId3']); //オプションでカラム順序を初期化 +//... +const table = useReactTable({ + //... + state: { + columnOrder, + //... + } + onColumnOrderChange: setColumnOrder, + //... +}); +``` + +### カラムの並べ替え + +ユーザーがカラムを並べ替えることができるUIをテーブルに実装する場合、ロジックは次のように設定できます: + +```tsx +const [columnOrder, setColumnOrder] = useState(columns.map(c => c.id)); + +//使用するDnDソリューションによっては、このようなステートが必要ない場合もあります +const [movingColumnId, setMovingColumnId] = useState(null); +const [targetColumnId, setTargetColumnId] = useState(null); + +//columnOrder配列をスプライスして並べ替えるユーティリティ関数 +const reorderColumn = ( + movingColumnId: Column, + targetColumnId: Column, +): string[] => { + const newColumnOrder = [...columnOrder]; + newColumnOrder.splice( + newColumnOrder.indexOf(targetColumnId), + 0, + newColumnOrder.splice(newColumnOrder.indexOf(movingColumnId), 1)[0], + ); + setColumnOrder(newColumnOrder); +}; + +const handleDragEnd = (e: DragEvent) => { + if(!movingColumnId || !targetColumnId) return; + setColumnOrder(reorderColumn(movingColumnId, targetColumnId)); +}; + +//任意のDnDソリューションを使用 +``` + +#### ドラッグアンドドロップによるカラム並べ替えの提案(React) + +TanStack Tableと一緒にドラッグアンドドロップ機能を実装する方法は数多くあります。以下は、問題を避けるためのいくつかの提案です: + +1. React 18以降を使用している場合、[`"react-dnd"`](https://react-dnd.github.io/react-dnd/docs/overview)を使用**しないでください**。React DnDはその時代において重要なライブラリでしたが、現在はあまり更新されておらず、特にReact Strict ModeではReact 18との互換性に問題があります。動作させることは可能ですが、より互換性が高く、活発にメンテナンスされている新しい代替手段があります。React DnDのProviderは、アプリ内で試す他のDnDソリューションと競合する可能性もあります。 + +2. [`"@dnd-kit/core"`](https://dndkit.com/)を使用してください。DnD Kitはモダンでモジュール化された軽量なドラッグアンドドロップライブラリで、現代のReactエコシステムと高い互換性があり、セマンティックな``マークアップとよく連携します。公式のTanStack DnD例である[Column DnD](../framework/react/examples/column-dnd)と[Row DnD](../framework/react/examples/row-dnd)は、どちらも現在DnD Kitを使用しています。 + +3. [`"react-beautiful-dnd"`](https://github.com/atlassian/react-beautiful-dnd)などの他のDnDライブラリも検討できますが、バンドルサイズの大きさ、メンテナンス状況、`
`マークアップとの互換性に注意してください。 + +4. 軽量なドラッグアンドドロップ機能を実装するために、ネイティブのブラウザイベントとステート管理を使用することを検討してください。ただし、このアプローチは、適切なタッチイベントを実装しない限り、モバイルユーザーにとって最適ではない可能性があることに注意してください。[Material React Table V2](https://www.material-react-table.com/docs/examples/column-ordering)は、`onDragStart`、`onDragEnd`、`onDragEnter`などのブラウザのドラッグアンドドロップイベントのみを使用してTanStack Tableを実装したライブラリの例です。ソースコードを参照して実装方法を確認してください。 diff --git a/docs/ja/guide/column-pinning.md b/docs/ja/guide/column-pinning.md new file mode 100644 index 0000000000..c03964c475 --- /dev/null +++ b/docs/ja/guide/column-pinning.md @@ -0,0 +1,93 @@ +--- +source-updated-at: '2025-03-20T21:15:29.000Z' +translation-updated-at: '2025-05-05T19:26:18.204Z' +title: カラム固定 +--- +## 実装例 + +実装に直接進みたい場合は、以下の例を参照してください: + +- [column-pinning](../framework/react/examples/column-pinning) +- [sticky-column-pinning](../framework/react/examples/column-pinning-sticky) + +### その他の例 + +- [Svelte column-pinning](../framework/svelte/examples/column-pinning) +- [Vue column-pinning](../framework/vue/examples/column-pinning) + +## API + +[カラムピン固定 API](../api/features/column-pinning) + +## カラムピン固定ガイド + +TanStack Tableは、テーブルUIでカラムピン固定機能を実装するのに役立つ状態とAPIを提供します。カラムピン固定は複数の方法で実装できます。ピン固定されたカラムを別々のテーブルに分割するか、すべてのカラムを同じテーブルに保持しつつ、ピン固定状態を使用してカラムを正しく並べ替え、sticky CSSを使用してカラムを左または右に固定することができます。 + +### カラムピン固定がカラム順序に与える影響 + +カラムの順序を変更する可能性があるテーブル機能は3つあり、以下の順序で実行されます: + +1. **カラムピン固定** - ピン固定が有効な場合、カラムは左、中央(ピン固定なし)、右のピン固定カラムに分割されます。 +2. 手動[カラム順序設定](../guide/column-ordering) - 手動で指定されたカラム順序が適用されます。 +3. [グループ化](../guide/grouping) - グループ化が有効で、グループ化状態がアクティブかつ`tableOptions.groupedColumnMode`が`'reorder' | 'remove'`に設定されている場合、グループ化されたカラムはカラムフローの先頭に再配置されます。 + +ピン固定されたカラムの順序を変更する唯一の方法は、`columnPinning.left`および`columnPinning.right`状態自体です。`columnOrder`状態はピン固定されていない(「中央」の)カラムの順序にのみ影響します。 + +### カラムピン固定状態 + +`columnPinning`状態の管理はオプションであり、通常は永続的な状態機能を追加しない限り必要ありません。TanStack Tableはすでにカラムピン固定状態を追跡しています。必要に応じて、他のテーブル状態と同様に`columnPinning`状態を管理します。 + +```jsx +const [columnPinning, setColumnPinning] = useState({ + left: [], + right: [], +}); +//... +const table = useReactTable({ + //... + state: { + columnPinning, + //... + } + onColumnPinningChange: setColumnPinning, + //... +}); +``` + +### デフォルトでカラムをピン固定する + +非常に一般的なユースケースは、いくつかのカラムをデフォルトでピン固定することです。これは、`columnPinning`状態をピン固定するcolumnIdsで初期化するか、`initialState`テーブルオプションを使用して行うことができます。 + +```jsx +const table = useReactTable({ + //... + initialState: { + columnPinning: { + left: ['expand-column'], + right: ['actions-column'], + }, + //... + } + //... +}); +``` + +### 便利なカラムピン固定API + +> 注: これらのAPIの一部はv8.12.0で新しく追加されました + +カラムピン固定機能を実装するのに役立つ便利なカラムAPIメソッドがいくつかあります: + +- [`column.getCanPin`](../api/features/column-pinning#getcanpin): カラムをピン固定できるかどうかを判断するために使用します。 +- [`column.pin`](../api/features/column-pinning#pin): カラムを左または右にピン固定するために使用します。または、カラムのピン固定を解除するために使用します。 +- [`column.getIsPinned`](../api/features/column-pinning#getispinned): カラムがどこにピン固定されているかを判断するために使用します。 +- [`column.getStart`](../api/features/column-pinning#getstart): ピン固定されたカラムに正しい`left` CSS値を提供するために使用します。 +- [`column.getAfter`](../api/features/column-pinning#getafter): ピン固定されたカラムに正しい`right` CSS値を提供するために使用します。 +- [`column.getIsLastColumn`](../api/features/column-pinning#getislastcolumn): カラムがピン固定グループの最後のカラムかどうかを判断するために使用します。box-shadowを追加するのに便利です。 +- [`column.getIsFirstColumn`](../api/features/column-pinning#getisfirstcolumn): カラムがピン固定グループの最初のカラムかどうかを判断するために使用します。box-shadowを追加するのに便利です。 + +### テーブル分割によるカラムピン固定 + +sticky CSSを使用してカラムをピン固定するだけの場合、ほとんどの場合、`table.getHeaderGroups`および`row.getVisibleCells`メソッドを使用して通常通りテーブルをレンダリングできます。 + +ただし、ピン固定されたカラムを別々のテーブルに分割する場合は、`table.getLeftHeaderGroups`、`table.getCenterHeaderGroups`、`table.getRightHeaderGroups`、`row.getLeftVisibleCells`、`row.getCenterVisibleCells`、および`row.getRightVisibleCells`メソッドを使用して、現在のテーブルに関連するカラムのみをレンダリングできます。 diff --git a/docs/ja/guide/column-sizing.md b/docs/ja/guide/column-sizing.md new file mode 100644 index 0000000000..8fdc2bae21 --- /dev/null +++ b/docs/ja/guide/column-sizing.md @@ -0,0 +1,178 @@ +--- +source-updated-at: '2025-03-20T21:15:29.000Z' +translation-updated-at: '2025-05-05T19:26:50.442Z' +title: カラムサイズ調整 +--- +## 例 + +実装に直接進みたいですか?以下の例を確認してください: + +- [column-sizing](../framework/react/examples/column-sizing) +- [column-resizing-performant](../framework/react/examples/column-resizing-performant) + +## API + +[Column Sizing API](../api/features/column-sizing) + +## カラムサイズ設定ガイド + +カラムサイズ設定機能を使用すると、各カラムの幅(最小幅と最大幅を含む)をオプションで指定できます。また、ユーザーがカラムヘッダーをドラッグするなどして、すべてのカラムの幅を動的に変更することも可能です。 + +### カラム幅 + +デフォルトでは、カラムには以下の測定オプションが設定されています: + +```tsx +export const defaultColumnSizing = { + size: 150, + minSize: 20, + maxSize: Number.MAX_SAFE_INTEGER, +} +``` + +これらのデフォルト値は、`tableOptions.defaultColumn`と個々のカラム定義の両方で上書きできます(この順序で適用されます)。 + +```tsx +const columns = [ + { + accessorKey: 'col1', + size: 270, //このカラムのサイズを設定 + }, + //... +] + +const table = useReactTable({ + //デフォルトのカラムサイズを上書き + defaultColumn: { + size: 200, //開始時のカラムサイズ + minSize: 50, //カラムリサイズ時に適用される最小サイズ + maxSize: 500, //カラムリサイズ時に適用される最大サイズ + }, +}) +``` + +カラムの「サイズ」は数値としてテーブルの状態に保存され、通常はピクセル単位の値として解釈されますが、これらのカラムサイズ値をCSSスタイルに適切に接続することができます。 + +ヘッドレスユーティリティとして、カラムサイズ設定のためのテーブルロジックは、実際にはレイアウトに適用できる状態のコレクションに過ぎません(上記の例では、このロジックを2つのスタイルで実装しています)。これらの幅の測定値をさまざまな方法で適用できます: + +- セマンティックな`table`要素またはテーブルCSSモードで表示される任意の要素 +- `div/span`要素または非テーブルCSSモードで表示される任意の要素 + - 厳密な幅を持つブロックレベル要素 + - 厳密な幅を持つ絶対位置指定要素 + - 緩やかな幅を持つFlexbox配置要素 + - 緩やかな幅を持つGrid配置要素 +- セルの幅をテーブル構造に変換できる任意のレイアウトメカニズム + +これらの各アプローチには、通常はUI/コンポーネントライブラリやデザインシステムが保持する意見である、独自のトレードオフと制限があります。 + +### カラムリサイズ + +TanStack Tableは、組み込みのカラムリサイズ状態とAPIを提供しており、さまざまなUXとパフォーマンスオプションを使用して、テーブルUIに簡単にカラムリサイズを実装できます。 + +#### カラムリサイズの有効化 + +デフォルトでは、`column.getCanResize()` APIはすべてのカラムに対して`true`を返しますが、`enableColumnResizing`テーブルオプションですべてのカラムのリサイズを無効にしたり、`enableResizing`カラムオプションでカラムごとにリサイズを無効にしたりできます。 + +```tsx +const columns = [ + { + accessorKey: 'id', + enableResizing: false, //このカラムのみリサイズを無効化 + size: 200, //開始時のカラムサイズ + }, + //... +] +``` + +#### カラムリサイズモード + +デフォルトでは、カラムリサイズモードは`"onEnd"`に設定されています。これは、`column.getSize()` APIが、ユーザーがカラムのリサイズ(ドラッグ)を終了するまで新しいカラムサイズを返さないことを意味します。通常、ユーザーがカラムをリサイズしている間、小さなUIインジケーターが表示されます。 + +React TanStack Tableアダプターでは、テーブルやウェブページの複雑さによっては、60 fpsのカラムリサイズレンダリングを達成することが難しい場合があります。`"onEnd"`カラムリサイズモードは、ユーザーがカラムをリサイズしている間のカクつきや遅延を避けるための良いデフォルトオプションです。ただし、TanStack React Tableを使用しながら60 fpsのカラムリサイズレンダリングを達成できないわけではありませんが、これを達成するには追加のメモ化やその他のパフォーマンス最適化が必要になる場合があります。 + +> 高度なカラムリサイズのパフォーマンスに関するヒントは、[後述](#advanced-column-resizing-performance)します。 + +即時のカラムリサイズレンダリングのためにカラムリサイズモードを`"onChange"`に変更するには、`columnResizeMode`テーブルオプションを使用します。 + +```tsx +const table = useReactTable({ + //... + columnResizeMode: 'onChange', //カラムリサイズモードを"onChange"に変更 +}) +``` + +#### カラムリサイズの方向 + +デフォルトでは、TanStack Tableはテーブルのマークアップが左から右にレイアウトされていると仮定します。右から左のレイアウトの場合、カラムリサイズの方向を`"rtl"`に変更する必要があるかもしれません。 + +```tsx +const table = useReactTable({ + //... + columnResizeDirection: 'rtl', //特定のロケールのためにカラムリサイズ方向を"rtl"に変更 +}) +``` + +#### カラムリサイズAPIをUIに接続 + +カラムリサイズのドラッグ操作をUIに接続するために使用できる便利なAPIがいくつかあります。 + +##### カラムサイズAPI + +カラムヘッドセル、データセル、またはフッターセルにカラムのサイズを適用するには、以下のAPIを使用できます: + +```ts +header.getSize() +column.getSize() +cell.column.getSize() +``` + +これらのサイズスタイルをマークアップに適用する方法はあなた次第ですが、カラムサイズを適用するためにCSS変数またはインラインスタイルを使用することが一般的です。 + +```tsx + + {table.getRowModel().rows.map((row) => ( + + {/* 通常の行UI */} + + {row.getVisibleCells().map((cell) => ( + + ))} + + {/* 行が展開されている場合、展開UIを単一のセルを持つ別の行としてレンダリングし、テーブルの幅全体に広げます */} + {row.getIsExpanded() && ( + + + + )} + + ))} + +//... +``` + +### 展開行の状態 + +テーブル内の行の展開状態を制御する必要がある場合は、`expanded`状態と`onExpandedChange`オプションを使用して行うことができます。これにより、要件に応じて展開状態を管理できます。 + +```ts +const [expanded, setExpanded] = useState({}) + +const table = useReactTable({ + // 他のオプション... + state: { + expanded: expanded, // 展開状態をテーブルに戻す必要があります + }, + onExpandedChange: setExpanded +}) +``` + +`ExpandedState`型は以下のように定義されています: + +```ts +type ExpandedState = true | Record +``` + +`ExpandedState`が`true`の場合、すべての行が展開されていることを意味します。レコードの場合、レコード内のキーとして存在し、値が`true`に設定されているIDを持つ行のみが展開されます。例えば、展開状態が`{ row1: true, row2: false }`の場合、IDが`row1`の行は展開され、IDが`row2`の行は展開されません。この状態は、テーブルがどの行が展開されているか、およびサブ行(存在する場合)を表示する必要があるかを判断するために使用されます。 + +### 展開行のUIトグルハンドラ + +TanStack Tableは、展開データのトグルハンドラUIをテーブルに自動的に追加しません。ユーザーが行を展開および折りたためることができるように、各行のUI内に手動で追加する必要があります。例えば、列定義内にボタンUIを追加できます。 + +```ts +const columns = [ + { + accessorKey: 'name', + header: '名前', + }, + { + accessorKey: 'age', + header: '年齢', + }, + { + header: '子要素', + cell: ({ row }) => { + return row.getCanExpand() ? + + : ''; + }, + }, +] +``` + +### 展開行のフィルタリング + +デフォルトでは、フィルタリング処理は親行から開始され、下方向に進みます。つまり、親行がフィルタによって除外されると、そのすべての子行も除外されます。ただし、`filterFromLeafRows`オプションを使用してこの動作を変更できます。このオプションを有効にすると、フィルタリング処理はリーフ(子)行から開始され、上方向に進みます。これにより、子または孫行の少なくとも1つがフィルタ条件を満たしている限り、親行がフィルタ結果に含まれるようになります。さらに、`maxLeafRowFilterDepth`オプションを使用して、フィルタ処理が考慮する子階層の深さを制御できます。このオプションでは、フィルタが考慮する子行の最大深度を指定できます。 + +```ts +//... +const table = useReactTable({ + // 他のオプション... + getSubRows: row => row.subRows, + getCoreRowModel: getCoreRowModel(), + getFilteredRowModel: getFilteredRowModel(), + getExpandedRowModel: getExpandedRowModel(), + filterFromLeafRows: true, // 展開行を検索 + maxLeafRowFilterDepth: 1, // 検索される展開行の深度を制限 +}) +``` + +### 展開行のページネーション + +デフォルトでは、展開行はテーブルの他の部分と一緒にページネーションされます(つまり、展開行は複数のページにまたがる可能性があります)。この動作を無効にしたい場合(つまり、展開行は常に親のページにレンダリングされます。これにより、設定されたページサイズよりも多くの行がレンダリングされることも意味します)、`paginateExpandedRows`オプションを使用できます。 + +```ts +const table = useReactTable({ + // 他のオプション... + paginateExpandedRows: false, +}) +``` + +### 展開行のピン留め + +展開行のピン留めは、通常の行のピン留めと同じように機能します。展開行をテーブルの上部または下部にピン留めできます。行のピン留めに関する詳細は、[ピン留めガイド (Pinning Guide)](./pinning.md)を参照してください。 + +### 展開行のソート + +デフォルトでは、展開行はテーブルの他の部分と一緒にソートされます。 + +### 手動展開(サーバーサイド) + +サーバーサイドの展開を行う場合、`manualExpanding`オプションを`true`に設定することで手動行展開を有効にできます。これは、`getExpandedRowModel`が行の展開に使用されず、独自のデータモデルで展開を実行することが期待されることを意味します。 + +```ts +const table = useReactTable({ + // 他のオプション... + manualExpanding: true, +}) +``` diff --git a/docs/ja/guide/fuzzy-filtering.md b/docs/ja/guide/fuzzy-filtering.md new file mode 100644 index 0000000000..dc10849e5d --- /dev/null +++ b/docs/ja/guide/fuzzy-filtering.md @@ -0,0 +1,125 @@ +--- +source-updated-at: '2025-03-20T21:15:29.000Z' +translation-updated-at: '2025-05-05T19:27:07.952Z' +title: ファジーフィルタリング +--- +## サンプル + +実装に直接進みたいですか?以下のサンプルを確認してください: + +- [filters-fuzzy](../framework/react/examples/filters-fuzzy) + +## API + +[フィルターAPI](../api/features/filters) + +## ファジーフィルタリングガイド + +ファジーフィルタリング (fuzzy filtering) は、近似一致に基づいてデータをフィルタリングする技術です。これは、完全一致ではなく、指定された値に類似したデータを検索したい場合に便利です。 + +カスタムフィルター関数を定義することで、クライアントサイドのファジーフィルタリングを実装できます。この関数は行、columnId、フィルター値を引数に取り、その行をフィルタリングされたデータに含めるかどうかを示すブール値を返します。 + +ファジーフィルタリングは主にグローバルフィルタリングで使用されますが、個々の列にも適用できます。両方のケースでの実装方法について説明します。 + +> **注:** ファジーフィルタリングを使用するには、`@tanstack/match-sorter-utils`ライブラリをインストールする必要があります。 +> TanStack Match Sorter Utils は、Kent C. Dodds の [match-sorter](https://github.com/kentcdodds/match-sorter) のフォークです。TanStack Tableの行ごとのフィルタリングアプローチにより適切に動作するようにフォークされました。 + +match-sorterライブラリの使用は任意ですが、TanStack Match Sorter Utilsライブラリは、ファジーフィルタリングと、返されるランク情報によるソートの両方を可能にする優れた方法を提供します。これにより、検索クエリに最も近い一致順に行をソートできます。 + +### カスタムファジーフィルター関数の定義 + +以下はカスタムファジーフィルター関数の例です: + +```typescript +import { rankItem } from '@tanstack/match-sorter-utils'; +import { FilterFn } from '@tanstack/table'; + +const fuzzyFilter: FilterFn = (row, columnId, value, addMeta) => { + // アイテムをランク付け + const itemRank = rankItem(row.getValue(columnId), value) + + // itemRank情報を保存 + addMeta({ itemRank }) + + // アイテムをフィルタリングするかどうかを返す + return itemRank.passed +} +``` + +この関数では、@tanstack/match-sorter-utilsライブラリのrankItem関数を使用してアイテムをランク付けしています。その後、ランキング情報を行のメタデータに保存し、アイテムがランキング基準を通過したかどうかを返します。 + +### グローバルフィルタリングでのファジーフィルタリングの使用 + +グローバルフィルタリングでファジーフィルタリングを使用するには、テーブルインスタンスのglobalFilterFnオプションでファジーフィルター関数を指定します: + +```typescript +const table = useReactTable({ // または使用するフレームワークの同等関数 + columns, + data, + filterFns: { + fuzzy: fuzzyFilter, //カラム定義で使用できるフィルター関数として定義 + }, + globalFilterFn: 'fuzzy', //グローバルフィルターにファジーフィルターを適用(ファジーフィルターの最も一般的な使用例) + getCoreRowModel: getCoreRowModel(), + getFilteredRowModel: getFilteredRowModel(), //クライアントサイドフィルタリング + getSortedRowModel: getSortedRowModel(), //ソートも使用する場合はクライアントサイドソートが必要 +}) +``` + +### カラムフィルタリングでのファジーフィルタリングの使用 + +カラムフィルタリングでファジーフィルタリングを使用するには、まずテーブルインスタンスのfilterFnsオプションでファジーフィルター関数を定義します。その後、カラム定義のfilterFnオプションでファジーフィルター関数を指定できます: + +```typescript +const column = [ + { + accessorFn: row => `${row.firstName} ${row.lastName}`, + id: 'fullName', + header: 'Full Name', + cell: info => info.getValue(), + filterFn: 'fuzzy', //カスタムファジーフィルター関数を使用 + }, + // 他のカラム... +]; +``` + +この例では、データのfirstNameフィールドとlastNameフィールドを結合したカラムにファジーフィルターを適用しています。 + +#### ファジーフィルタリングでのソート + +カラムフィルタリングでファジーフィルタリングを使用する場合、ランキング情報に基づいてデータをソートすることもできます。これはカスタムソート関数を定義することで実現できます: + +```typescript +import { compareItems } from '@tanstack/match-sorter-utils' +import { sortingFns } from '@tanstack/table' + +const fuzzySort: SortingFn = (rowA, rowB, columnId) => { + let dir = 0 + + // カラムにランキング情報がある場合のみランクでソート + if (rowA.columnFiltersMeta[columnId]) { + dir = compareItems( + rowA.columnFiltersMeta[columnId]?.itemRank!, + rowB.columnFiltersMeta[columnId]?.itemRank! + ) + } + + // ランクが等しい場合の英数字フォールバックを提供 + return dir === 0 ? sortingFns.alphanumeric(rowA, rowB, columnId) : dir +} +``` + +この関数では、2つの行のランキング情報を比較しています。ランクが等しい場合は、英数字ソートにフォールバックします。 + +このソート関数は、カラム定義のsortFnオプションで指定できます: + +```typescript +{ + accessorFn: row => `${row.firstName} ${row.lastName}`, + id: 'fullName', + header: 'Full Name', + cell: info => info.getValue(), + filterFn: 'fuzzy', //カスタムファジーフィルター関数を使用 + sortFn: 'fuzzySort', //カスタムファジーソート関数を使用 +} +``` diff --git a/docs/ja/guide/global-faceting.md b/docs/ja/guide/global-faceting.md new file mode 100644 index 0000000000..a9c5f8af5b --- /dev/null +++ b/docs/ja/guide/global-faceting.md @@ -0,0 +1,80 @@ +--- +source-updated-at: '2025-03-20T21:15:29.000Z' +translation-updated-at: '2025-05-05T19:27:02.204Z' +title: グローバルファセット +--- +## 例 + +実装に直接進みたいですか?以下の例を確認してください: + +- [filters-faceted](../framework/react/examples/filters) + +## API + +[グローバルファセットAPI](../api/features/global-faceting) + +## グローバルファセットガイド + +グローバルファセットを使用すると、テーブルのデータからすべての列の値リストを生成できます。例えば、テーブル内のすべての行と列からユニークな値のリストを生成し、オートコンプリートフィルターコンポーネントの検索候補として使用できます。または、数値テーブルから最小値と最大値のタプルを生成し、レンジスライダーフィルターコンポーネントの範囲として使用できます。 + +### グローバルファセット行モデル + +グローバルファセット機能を使用するには、テーブルオプションに適切な行モデルを含める必要があります。 + +```ts +//必要な行モデルのみインポート +import { + getCoreRowModel, + getFacetedRowModel, + getFacetedMinMaxValues, //getFacetedRowModelに依存 + getFacetedUniqueValues, //getFacetedRowModelに依存 +} from '@tanstack/react-table' +//... +const table = useReactTable({ + // その他のオプション... + getCoreRowModel: getCoreRowModel(), + getFacetedRowModel: getFacetedRowModel(), //クライアントサイドファセット用モデル(他のファセットメソッドはこのモデルに依存) + getFacetedMinMaxValues: getFacetedMinMaxValues(), //最小値/最大値が必要な場合 + getFacetedUniqueValues: getFacetedUniqueValues(), //ユニーク値リストが必要な場合 + //... +}) +``` + +### グローバルファセット行モデルの使用 + +テーブルオプションに適切な行モデルを含めたら、ファセットテーブルインスタンスAPIを使用して、ファセット行モデルによって生成された値リストにアクセスできます。 + +```ts +// オートコンプリートフィルター用のユニーク値リスト +const autoCompleteSuggestions = + Array.from(table.getGlobalFacetedUniqueValues().keys()) + .sort() + .slice(0, 5000); +``` + +```ts +// レンジフィルター用の最小値と最大値のタプル +const [min, max] = table.getGlobalFacetedMinMaxValues() ?? [0, 1]; +``` + +### カスタムグローバル(サーバーサイド)ファセット + +組み込みのクライアントサイドファセット機能の代わりに、サーバーサイドで独自のファセットロジックを実装し、ファセット値をクライアントサイドに渡すことができます。`getGlobalFacetedUniqueValues`および`getGlobalFacetedMinMaxValues`テーブルオプションを使用して、サーバーサイドからファセット値を解決できます。 + +```ts +const facetingQuery = useQuery( + 'faceting', + async () => { + const response = await fetch('/api/faceting'); + return response.json(); + }, + { + onSuccess: (data) => { + table.getGlobalFacetedUniqueValues = () => data.uniqueValues; + table.getGlobalFacetedMinMaxValues = () => data.minMaxValues; + }, + } +); +``` + +この例では、`react-query`の`useQuery`フックを使用してサーバーからファセットデータを取得しています。データが取得されると、`getGlobalFacetedUniqueValues`および`getGlobalFacetedMinMaxValues`テーブルオプションを設定し、サーバー応答からファセット値を返します。これにより、テーブルはサーバーサイドのファセットデータを使用してオートコンプリート候補とレンジフィルターを生成できます。 diff --git a/docs/ja/guide/global-filtering.md b/docs/ja/guide/global-filtering.md new file mode 100644 index 0000000000..019308a35b --- /dev/null +++ b/docs/ja/guide/global-filtering.md @@ -0,0 +1,198 @@ +--- +source-updated-at: '2025-03-20T21:15:29.000Z' +translation-updated-at: '2025-05-05T19:27:41.889Z' +title: グローバルフィルタリング +--- +## サンプル + +実装に直接進みたいですか?以下のサンプルを確認してください: + +- [グローバルフィルター](../framework/react/examples/filters-global) + +## API + +[グローバルフィルタリング API](../api/features/global-filtering) + +## グローバルフィルタリングガイド + +フィルタリングには2つの種類があります: カラムフィルタリングとグローバルフィルタリングです。 + +このガイドでは、すべてのカラムに適用されるフィルターであるグローバルフィルタリングに焦点を当てます。 + +### クライアントサイド vs サーバーサイドフィルタリング + +大規模なデータセットがある場合、フィルタリングするためにすべてのデータをクライアントのブラウザに読み込みたくないかもしれません。その場合、サーバーサイドフィルタリング、ソート、ページネーションなどを実装する必要があるでしょう。 + +ただし、[ページネーションガイド](../guide/pagination#should-you-use-client-side-pagination)でも説明されているように、多くの開発者はパフォーマンスに影響を与えずにクライアントサイドで読み込める行数を過小評価しています。TanStackテーブルのサンプルは、多くの場合、最大100,000行以上のクライアントサイドフィルタリング、ソート、ページネーション、グループ化を適切なパフォーマンスで処理できるようにテストされています。これは必ずしもあなたのアプリがそれだけの行数を処理できることを意味するわけではありませんが、テーブルが最大でも数千行しか持たない場合は、TanStackテーブルが提供するクライアントサイドフィルタリング、ソート、ページネーション、グループ化を活用できるかもしれません。 + +> TanStackテーブルは、数千行のクライアントサイド処理を良好なパフォーマンスで処理できます。クライアントサイドフィルタリング、ページネーション、ソートなどを最初に検討せずに除外しないでください。 + +各ユースケースは異なり、テーブルの複雑さ、カラムの数、各データのサイズなどによって異なります。主に注意すべきボトルネックは以下の通りです: + +1. サーバーがすべてのデータを合理的な時間(およびコスト)でクエリできるか? +2. フェッチの総サイズは?(カラムが多くない場合、思ったほどスケールしないかもしれません。) +3. すべてのデータを一度に読み込んだ場合、クライアントのブラウザが使用するメモリが多すぎないか? + +わからない場合は、最初にクライアントサイドフィルタリングとページネーションから始め、データが増えるにつれて将来サーバーサイド戦略に切り替えることができます。 + +### 手動サーバーサイドグローバルフィルタリング + +組み込みのクライアントサイドグローバルフィルタリングを使用する代わりに、サーバーサイドグローバルフィルタリングを実装する必要があると判断した場合の方法です。 + +手動サーバーサイドグローバルフィルタリングには、`getFilteredRowModel`テーブルオプションは必要ありません。代わりに、テーブルに渡す`data`はすでにフィルタリングされている必要があります。ただし、`getFilteredRowModel`テーブルオプションを渡した場合は、`manualFiltering`オプションを`true`に設定することでテーブルにスキップするように指示できます。 + +```jsx +const table = useReactTable({ + data, + columns, + // getFilteredRowModel: getFilteredRowModel(), // 手動サーバーサイドグローバルフィルタリングには不要 + manualFiltering: true, +}) +``` + +注: 手動グローバルフィルタリングを使用する場合、このガイドの残りの部分で説明されている多くのオプションは効果がありません。`manualFiltering`が`true`に設定されている場合、テーブルインスタンスは渡された行にグローバルフィルタリングロジックを適用しません。代わりに、行がすでにフィルタリングされていると仮定し、渡されたデータをそのまま使用します。 + +### クライアントサイドグローバルフィルタリング + +組み込みのクライアントサイドグローバルフィルタリングを使用する場合、まず`getFilteredRowModel`関数をテーブルオプションに渡す必要があります。 + +```jsx +import { useReactTable, getFilteredRowModel } from '@tanstack/react-table' +//... +const table = useReactTable({ + // その他のオプション... + getCoreRowModel: getCoreRowModel(), + getFilteredRowModel: getFilteredRowModel(), // クライアントサイドグローバルフィルタリングに必要 +}) +``` + +### グローバルフィルター関数 + +`globalFilterFn`オプションを使用すると、グローバルフィルタリングに使用するフィルター関数を指定できます。フィルター関数は、組み込みのフィルター関数を参照する文字列、`tableOptions.filterFns`オプションを介して提供されるカスタムフィルター関数を参照する文字列、またはカスタムフィルター関数そのものです。 + +```jsx +const table = useReactTable({ + data, + columns, + getCoreRowModel: getCoreRowModel(), + getFilteredRowModel: getFilteredRowModel(), + globalFilterFn: 'text' // 組み込みフィルター関数 +}) +``` + +デフォルトで10の組み込みフィルター関数が用意されています: + +- includesString - 大文字小文字を区別しない文字列包含 +- includesStringSensitive - 大文字小文字を区別する文字列包含 +- equalsString - 大文字小文字を区別しない文字列一致 +- equalsStringSensitive - 大文字小文字を区別する文字列一致 +- arrIncludes - 配列内のアイテム包含 +- arrIncludesAll - 配列内のすべてのアイテム包含 +- arrIncludesSome - 配列内の一部のアイテム包含 +- equals - オブジェクト/参照等価性 Object.is/=== +- weakEquals - 弱いオブジェクト/参照等価性 == +- inNumberRange - 数値範囲包含 + +また、`globalFilterFn`テーブルオプションとしてカスタムフィルター関数を定義することもできます。 + +### グローバルフィルター状態 + +グローバルフィルター状態はテーブルの内部状態に保存され、`table.getState().globalFilter`プロパティを介してアクセスできます。グローバルフィルター状態をテーブルの外部で保持したい場合は、`onGlobalFilterChange`オプションを使用して、グローバルフィルター状態が変更されるたびに呼び出されるコールバック関数を提供できます。 + +```jsx +const [globalFilter, setGlobalFilter] = useState([]) + +const table = useReactTable({ + // その他のオプション... + state: { + globalFilter, + }, + onGlobalFilterChange: setGlobalFilter +}) +``` + +グローバルフィルタリング状態は以下の形状のオブジェクトとして定義されます: + +```jsx +interface GlobalFilter { + globalFilter: any +} +``` + +### UIへのグローバルフィルター入力の追加 + +TanStackテーブルはグローバルフィルター入力UIをテーブルに自動的に追加しません。ユーザーがテーブルをフィルタリングできるように、手動でUIに追加する必要があります。たとえば、テーブルの上に入力UIを追加して、ユーザーが検索語を入力できるようにすることができます。 + +```jsx +return ( +
+ table.setGlobalFilter(String(e.target.value))} + placeholder="検索..." + /> +
+) +``` + +### カスタムグローバルフィルター関数 + +カスタムグローバルフィルター関数を使用したい場合は、関数を定義して`globalFilterFn`オプションに渡すことができます。 + +> **注:** グローバルフィルタリングにファジーフィルタリング関数を使用するのは一般的なアイデアです。これについては[ファジーフィルタリングガイド](./fuzzy-filtering.md)で説明されています。 + +```jsx +const customFilterFn = (rows, columnId, filterValue) => { + // カスタムフィルターロジック +} + +const table = useReactTable({ + // その他のオプション... + globalFilterFn: customFilterFn +}) +``` + +### 初期グローバルフィルター状態 + +テーブルが初期化されたときに初期グローバルフィルター状態を設定したい場合は、`initialState`オプションの一部としてグローバルフィルター状態を渡すことができます。 + +ただし、`state.globalFilter`オプションで初期グローバルフィルター状態を指定することもできます。 + +```jsx +const [globalFilter, setGlobalFilter] = useState("検索語") // ここでglobalFilter状態を初期化することを推奨 + +const table = useReactTable({ + // その他のオプション... + initialState: { + globalFilter: '検索語', // globalFilter状態を管理しない場合、ここで初期状態を設定 + } + state: { + globalFilter, // 管理されたglobalFilter状態をテーブルに渡す + } +}) +``` + +> 注意: `initialState.globalFilter`と`state.globalFilter`を同時に使用しないでください。`state.globalFilter`で初期化された状態が`initialState.globalFilter`を上書きします。 + +### グローバルフィルタリングの無効化 + +デフォルトでは、すべてのカラムでグローバルフィルタリングが有効になっています。`enableGlobalFilter`テーブルオプションを使用して、すべてのカラムのグローバルフィルタリングを無効にできます。また、`enableFilters`テーブルオプションを`false`に設定することで、カラムフィルタリングとグローバルフィルタリングの両方を無効にすることもできます。 + +グローバルフィルタリングを無効にすると、`column.getCanGlobalFilter` APIはそのカラムに対して`false`を返します。 + +```jsx +const columns = [ + { + header: () => 'ID', + accessorKey: 'id', + enableGlobalFilter: false, // このカラムのグローバルフィルタリングを無効化 + }, + //... +] +//... +const table = useReactTable({ + // その他のオプション... + columns, + enableGlobalFilter: false, // すべてのカラムのグローバルフィルタリングを無効化 +}) +``` diff --git a/docs/ja/guide/grouping.md b/docs/ja/guide/grouping.md new file mode 100644 index 0000000000..221cdf5076 --- /dev/null +++ b/docs/ja/guide/grouping.md @@ -0,0 +1,148 @@ +--- +source-updated-at: '2025-03-20T21:15:29.000Z' +translation-updated-at: '2025-05-05T19:27:29.079Z' +title: グループ化 +--- +## サンプル + +実装にすぐに進みたいですか?以下のサンプルを確認してください: + +- [グルーピング](../framework/react/examples/grouping) + +## API + +[グルーピング API](../api/features/grouping) + +## グルーピングガイド + +列の並べ替えを行うテーブル機能は3つあり、以下の順序で実行されます: + +1. [列の固定 (Column Pinning)](../guide/column-pinning) - 固定する場合、列は左、中央(固定なし)、右固定列に分割されます。 +2. 手動[列の並べ替え (Column Ordering)](../guide/column-ordering) - 手動で指定された列順が適用されます。 +3. **グルーピング** - グルーピングが有効で、グルーピング状態がアクティブかつ `tableOptions.groupedColumnMode` が `'reorder' | 'remove'` に設定されている場合、グルーピングされた列が列フローの先頭に並べ替えられます。 + +TanStack Tableのグルーピングは列に適用される機能で、特定の列に基づいてテーブル行を分類・整理できます。大量のデータがあり、特定の基準でグループ化したい場合に便利です。 + +グルーピング機能を使用するには、グルーピングされた行モデルを使用する必要があります。このモデルはグルーピング状態に基づいて行をグループ化します。 + +```tsx +import { getGroupedRowModel } from '@tanstack/react-table' + +const table = useReactTable({ + // その他のオプション... + getGroupedRowModel: getGroupedRowModel(), +}) +``` + +グルーピング状態がアクティブな場合、テーブルは一致する行をサブ行としてグループ化された行に追加します。グループ化された行は、最初に一致した行と同じインデックスでテーブル行に追加されます。一致した行はテーブル行から削除されます。 +ユーザーがグループ化された行を展開/折りたたみできるようにするには、展開機能を使用できます。 + +```tsx +import { getGroupedRowModel, getExpandedRowModel} from '@tanstack/react-table' + +const table = useReactTable({ + // その他のオプション... + getGroupedRowModel: getGroupedRowModel(), + getExpandedRowModel: getExpandedRowModel(), +}) +``` + +### グルーピング状態 + +グルーピング状態は文字列の配列で、各文字列はグループ化する列のIDです。配列内の文字列の順序がグループ化の順序を決定します。例えば、グルーピング状態が ['column1', 'column2'] の場合、テーブルは最初にcolumn1でグループ化し、次に各グループ内でcolumn2でグループ化します。setGrouping関数を使用してグルーピング状態を制御できます: + +```tsx +table.setGrouping(['column1', 'column2']); +``` + +resetGrouping関数を使用してグルーピング状態を初期状態にリセットすることもできます: + +```tsx +table.resetGrouping(); +``` + +デフォルトでは、列がグループ化されるとテーブルの先頭に移動します。この動作はgroupedColumnModeオプションで制御できます。'reorder'に設定すると、グループ化された列がテーブルの先頭に移動します。'remove'に設定すると、グループ化された列がテーブルから削除されます。falseに設定すると、グループ化された列は移動も削除もされません。 + +```tsx +const table = useReactTable({ + // その他のオプション... + groupedColumnMode: 'reorder', +}) +``` + +### 集計 + +行がグループ化されている場合、aggregationFnオプションを使用して列ごとにグループ化された行のデータを集計できます。これは集計関数のIDである文字列です。aggregationFnsオプションを使用して集計関数を定義できます。 + +```tsx +const column = columnHelper.accessor('key', { + aggregationFn: 'sum', +}) +``` + +上記の例では、sum集計関数がグループ化された行のデータを集計するために使用されます。 +デフォルトでは、数値列はsum集計関数を使用し、非数値列はcount集計関数を使用します。列定義でaggregationFnオプションを指定することでこの動作を上書きできます。 + +使用できる組み込みの集計関数は以下の通りです: + +- sum - グループ化された行の値を合計します。 +- count - グループ化された行の数をカウントします。 +- min - グループ化された行の最小値を見つけます。 +- max - グループ化された行の最大値を見つけます。 +- extent - グループ化された行の値の範囲(最小値と最大値)を見つけます。 +- mean - グループ化された行の値の平均を見つけます。 +- median - グループ化された行の値の中央値を見つけます。 +- unique - グループ化された行の一意の値の配列を返します。 +- uniqueCount - グループ化された行の一意の値の数をカウントします。 + +#### カスタム集計 + +行がグループ化されている場合、aggregationFnsオプションを使用してグループ化された行のデータを集計できます。これは、キーが集計関数のIDで、値が集計関数自体のレコードです。これらの集計関数は、列のaggregationFnオプションで参照できます。 + +```tsx +const table = useReactTable({ + // その他のオプション... + aggregationFns: { + myCustomAggregation: (columnId, leafRows, childRows) => { + // 集計値を返す + }, + }, +}) +``` + +上記の例では、myCustomAggregationは、列ID、リーフ行、子行を受け取り、集計値を返すカスタム集計関数です。この集計関数は、列のaggregationFnオプションで使用できます: + +```tsx +const column = columnHelper.accessor('key', { + aggregationFn: 'myCustomAggregation', +}) +``` + +### 手動グルーピング + +サーバーサイドグルーピングと集計を行う場合、manualGroupingオプションを使用して手動グルーピングを有効にできます。このオプションがtrueに設定されている場合、テーブルはgetGroupedRowModel()を使用して自動的に行をグループ化せず、代わりに行を手動でグループ化してテーブルに渡すことを期待します。 + +```tsx +const table = useReactTable({ + // その他のオプション... + manualGrouping: true, +}) +``` + +> **注:** 現在、TanStack Tableでサーバーサイドグルーピングを行う簡単な方法は多く知られていません。これを機能させるには、多くのカスタムセルレンダリングを行う必要があります。 + +### グルーピング変更ハンドラ + +グルーピング状態を自分で管理したい場合は、onGroupingChangeオプションを使用できます。このオプションは、グルーピング状態が変更されたときに呼び出される関数です。管理された状態をtableOptions.state.groupingオプションを介してテーブルに戻すことができます。 + +```tsx +const [grouping, setGrouping] = useState([]) + +const table = useReactTable({ + // その他のオプション... + state: { + grouping: grouping, + }, + onGroupingChange: setGrouping +}) +``` diff --git a/docs/ja/guide/header-groups.md b/docs/ja/guide/header-groups.md new file mode 100644 index 0000000000..fd71584072 --- /dev/null +++ b/docs/ja/guide/header-groups.md @@ -0,0 +1,50 @@ +--- +source-updated-at: '2025-03-20T21:15:29.000Z' +translation-updated-at: '2025-05-05T19:24:50.264Z' +title: ヘッダーグループ +--- +## API + +[Header Group API](../api/core/header-group) + +## ヘッダーグループガイド + +このクイックガイドでは、TanStack Tableでヘッダーグループオブジェクトを取得および操作するさまざまな方法について説明します。 + +### ヘッダーグループとは? + +ヘッダーグループは、単純にヘッダーの「行」です。名前が紛らわしいかもしれませんが、実はとてもシンプルです。ほとんどのテーブルは1行のヘッダー(単一のヘッダーグループ)しか持ちませんが、[Column Groupsの例](../framework/react/examples/column-groups)のようにネストした列構造を定義すると、複数行のヘッダー(複数のヘッダーグループ)を持つことができます。 + +### ヘッダーグループの取得方法 + +テーブルインスタンスからヘッダーグループを取得するには、複数の`table`インスタンスAPIを使用できます。`table.getHeaderGroups`が最も一般的に使用されるAPIですが、使用している機能によっては、他のAPIを使用する必要がある場合があります。例えば、カラムピニング機能を使用している場合は、`table.get[Left/Center/Right]HeaderGroups`などのAPIを使用する必要があります。 + +### ヘッダーグループオブジェクト + +ヘッダーグループオブジェクトは[Row](../guide/rows)オブジェクトと似ていますが、ボディ行ほど複雑ではないため、よりシンプルです。 + +デフォルトでは、ヘッダーグループには次の3つのプロパティしかありません: + +- `id`: ヘッダーグループの深さ(インデックス)から生成される一意の識別子。Reactコンポーネントのキーとして有用です。 +- `depth`: ヘッダーグループの深さで、ゼロベースのインデックスです。これはすべてのヘッダー行における行インデックスと考えることができます。 +- `headers`: このヘッダーグループ(行)に属する[Header](../guide/headers)セルオブジェクトの配列。 + +### ヘッダーセルへのアクセス + +ヘッダーグループ内のヘッダーセルをレンダリングするには、ヘッダーグループオブジェクトの`headers`配列をマッピングします。 + +```jsx +
+ {table.getHeaderGroups().map(headerGroup => { + return ( + + {headerGroup.headers.map(header => ( // headerGroupのheaders配列をマッピング + + ))} + + ) + })} + +``` diff --git a/docs/ja/guide/headers.md b/docs/ja/guide/headers.md new file mode 100644 index 0000000000..1b1f0c2016 --- /dev/null +++ b/docs/ja/guide/headers.md @@ -0,0 +1,86 @@ +--- +source-updated-at: '2025-03-20T21:15:29.000Z' +translation-updated-at: '2025-05-05T19:25:20.567Z' +title: ヘッダー +--- +## API + +[Header API](../api/core/header) + +## ヘッダーガイド + +このクイックガイドでは、TanStack Tableで`header`オブジェクトを取得および操作するさまざまな方法について説明します。 + +ヘッダーはセルに相当しますが、``セクションではなく``セクション向けに設計されています。 + +### ヘッダーの取得元 + +ヘッダーは[Header Groups](../guide/header-groups)から取得されます。ヘッダーグループは行に相当しますが、``セクションではなく``セクション向けに設計されています。 + +#### ヘッダーグループのヘッダー + +ヘッダーグループ内では、ヘッダーは`headerGroup.headers`プロパティの配列として格納されています。通常はこの配列をマップしてヘッダーをレンダリングします。 + +```jsx + + {table.getHeaderGroups().map(headerGroup => { + return ( + + {headerGroup.headers.map(header => ( // headerGroup.headers配列をマップ + + ))} + + ) + })} + +``` + +#### ヘッダーテーブルインスタンスAPI + +使用する機能に応じて、ヘッダーのリストを取得するための複数の`table`インスタンスAPIが利用可能です。最も一般的なAPIは`table.getFlatHeaders`で、テーブル内のすべてのヘッダーのフラットリストを返しますが、カラム可視性やカラムピニング機能と併用するのに便利なAPIが他にも十数種類あります。`table.getLeftLeafHeaders`や`table.getRightFlatHeaders`などのAPIは、ユースケースに応じて便利です。 + +### ヘッダーオブジェクト + +ヘッダーオブジェクトは[Cell](../guide/cells)オブジェクトと似ていますが、``セクションではなく``セクション向けに設計されています。各ヘッダーオブジェクトはUI内の` +))} +``` diff --git a/docs/ja/guide/migrating.md b/docs/ja/guide/migrating.md new file mode 100644 index 0000000000..24ac0a98b7 --- /dev/null +++ b/docs/ja/guide/migrating.md @@ -0,0 +1,194 @@ +--- +source-updated-at: '2024-12-30T21:50:15.000Z' +translation-updated-at: '2025-05-05T19:24:54.984Z' +title: V8への移行 +--- +## V8への移行ガイド + +TanStack Table V8は、React Table v7をTypeScriptで一から書き直したメジャーリニューアル版です。マークアップやCSSの全体的な構造/構成は大きく変わりませんが、多くのAPIが改名または置き換えられています。 + +### 主な変更点 + +- TypeScriptによる完全な書き直し(基本パッケージに型定義を含む) +- プラグインシステムの廃止(代わりに制御の反転を採用) +- 大幅に拡張・改善されたAPI(ピン留めなどの新機能を含む) +- より優れた制御状態管理 +- サーバーサイド操作 (server-side operations) のサポート強化 +- 完全な(ただしオプションの)データパイプライン制御 +- フレームワークに依存しないコア (agnostic core) とReact、Solid、Svelte、Vue用アダプター(将来的にさらに追加予定) +- 新しい開発者ツール (Dev Tools) + +### 新しいバージョンのインストール + +TanStack Tableの新バージョンは`@tanstack`スコープで公開されています。お好きなパッケージマネージャーを使って新しいパッケージをインストールしてください: + +```bash +npm uninstall react-table @types/react-table +npm install @tanstack/react-table +``` + +```tsx +- import { useTable } from 'react-table' // [!code --] ++ import { useReactTable } from '@tanstack/react-table' // [!code ++] +``` + +型定義は基本パッケージに含まれるようになったため、`@types/react-table`パッケージは削除できます。 + +> 必要に応じて、古い`react-table`パッケージをインストールしたままにし、コードを段階的に移行することも可能です。別々のテーブルで両方のパッケージを同時に使用しても問題ありません。 + +### テーブルオプションの更新 + +- `useTable`を`useReactTable`に改名 +- 古いフックとプラグインシステムは廃止され、各機能ごとにtree-shaking可能な行モデルインポートに置き換えられました。 + +```tsx +- import { useTable, usePagination, useSortBy } from 'react-table'; // [!code --] ++ import { // [!code ++] ++ useReactTable, // [!code ++] ++ getCoreRowModel, // [!code ++] ++ getPaginationRowModel, // [!code ++] ++ getSortedRowModel // [!code ++] ++ } from '@tanstack/react-table'; // [!code ++] + +// ... + +- const tableInstance = useTable( // [!code --] +- { columns, data }, // [!code --] +- useSortBy, // [!code --] +- usePagination, //order of hooks used to matter // [!code --] +- // etc. // [!code --] +- ); // [!code --] ++ const tableInstance = useReactTable({ // [!code ++] ++ columns, // [!code ++] ++ data, // [!code ++] ++ getCoreRowModel: getCoreRowModel(), // [!code ++] ++ getPaginationRowModel: getPaginationRowModel(), // [!code ++] ++ getSortedRowModel: getSortedRowModel(), //order doesn't matter anymore! // [!code ++] ++ // etc. // [!code ++] ++ }); // [!code ++] +``` + +- すべての`disable*`テーブルオプションは`enable*`テーブルオプションに改名されました(例:`disableSortBy`は`enableSorting`に、`disableGroupBy`は`enableGrouping`に変更など) +- ... + +### カラム定義の更新 + +- accessorは`accessorKey`または`accessorFn`に改名されました(文字列か関数かによって使い分け) +- width、minWidth、maxWidthはsize、minSize、maxSizeに改名 +- オプションで、より良いTypeScriptヒントを得るために、新しい`createColumnHelper`関数を各カラム定義で使用できます(従来通りカラム定義の配列を使用することも可能) + - 第一引数はアクセサ関数またはアクセサ文字列 + - 第二引数はカラムオプションのオブジェクト + +```tsx +const columns = [ +- { // [!code --] +- accessor: 'firstName', // [!code --] +- Header: 'First Name', // [!code --] +- }, // [!code --] +- { // [!code --] +- accessor: row => row.lastName, // [!code --] +- Header: () => Last Name, // [!code --] +- }, // [!code --] + +// TypeScriptで最適な開発体験(特に後で`cell.getValue()`を使用する場合) ++ columnHelper.accessor('firstName', { //accessorKey // [!code ++] ++ header: 'First Name', // [!code ++] ++ }), // [!code ++] ++ columnHelper.accessor(row => row.lastName, { //accessorFn // [!code ++] ++ header: () => Last Name, // [!code ++] ++ }), // [!code ++] + +// または(従来のスタイルを希望する場合) ++ { // [!code ++] ++ accessorKey: 'firstName', // [!code ++] ++ header: 'First Name', // [!code ++] ++ }, // [!code ++] ++ { // [!code ++] ++ accessorFn: row => row.lastName, // [!code ++] ++ header: () => Last Name, // [!code ++] ++ }, // [!code ++] +] +``` + +> 注意:コンポーネント内でカラムを定義する場合、カラム定義に安定した識別性を持たせるようにしてください。パフォーマンス向上と不要な再レンダリングを防ぐために、カラム定義を`useMemo`または`useState`フックに保存します。 + +- カラムオプション名の変更 + - `Header`は`header`に改名 + - `Cell`は`cell`に改名(セルレンダリング関数も変更あり。下記参照) + - `Footer`は`footer`に改名 + - すべての`disable*`カラムオプションは`enable*`カラムオプションに改名(例:`disableSortBy`は`enableSorting`に、`disableGroupBy`は`enableGrouping`に変更など) + - `sortType`は`sortingFn`に改名 + - ... + +- カスタムセルレンダラーの変更 + - `value`は`getValue`に改名(値は直接提供されるのではなく、`getValue`関数を通じて評価されるようになりました。この変更により、`getValue()`が呼び出された時点で値が評価されキャッシュされるため、パフォーマンスが向上します) + - `cell: { isGrouped, isPlaceholder, isAggregated }`は`cell: { getIsGrouped, getIsPlaceholder, getIsAggregated }`に変更 + - `column`: ベースレベルのプロパティはRT固有のものになりました。定義時にオブジェクトに追加した値は、`columnDef`の1階層下に移動しました。 + - `table`: `useTable`フックに渡されたプロパティは`options`の下に表示されます。 + +### テーブルマークアップの移行 + +- `cell.render('Cell')`や`column.render('Header')`などの代わりに`flexRender()`を使用 +- `getHeaderProps`、`getFooterProps`、`getCellProps`、`getRowProps`などはすべて非推奨 (deprecated) になりました + - TanStack Tableはデフォルトの`style`や`role`などのアクセシビリティ属性を提供しなくなりました。これらは依然として重要ですが、フレームワークに依存しないようにするために削除されました。 + - `onClick`ハンドラを手動で定義する必要がありますが、新しい`get*Handler`ヘルパー関数でシンプルに記述できます。 + - `key`プロパティを手動で定義する必要があります + - グループ化ヘッダーや集計などの機能を使用する場合は、`colSpan`プロパティを手動で定義する必要があります + +```tsx +- // [!code --] ++ // [!code ++] +``` + +```tsx +- // [!code --] ++ // [!code ++] +``` + +```tsx +// このケースでのカラム定義内 +- Header: ({ getToggleAllRowsSelectedProps }) => ( // [!code --] +- // [!code --] +- ), // [!code --] +- Cell: ({ row }) => ( // [!code --] +- // [!code --] +- ), // [!code --] ++ header: ({ table }) => ( // [!code ++] ++ // [!code ++] ++ ), // [!code ++] ++ cell: ({ row }) => ( // [!code ++] ++ // [!code ++] ++ ), // [!code ++] +``` + +### その他の変更点 + +- カスタム`filterTypes`(現在は`filterFns`)は、行を含めるかどうかのブール値のみを返す新しい関数シグネチャになりました + +```tsx +- (rows: Row[], id: string, filterValue: any) => Row[] // [!code --] ++ (row: Row, id: string, filterValue: any) => boolean // [!code ++] +``` + +- ... + +> このガイドは現在進行中の作業です。時間があればぜひ貢献をお願いします! diff --git a/docs/ja/guide/pagination.md b/docs/ja/guide/pagination.md new file mode 100644 index 0000000000..c94e4402ec --- /dev/null +++ b/docs/ja/guide/pagination.md @@ -0,0 +1,223 @@ +--- +source-updated-at: '2025-03-20T21:15:29.000Z' +translation-updated-at: '2025-05-05T19:28:23.394Z' +title: ページネーション +--- +## 例 + +実装に直接進みたいですか?以下の例を確認してください: + +- [ページネーション](../framework/react/examples/pagination) +- [ページネーション(制御付き、React Query使用)](../framework/react/examples/pagination-controlled) +- [編集可能データ](../framework/react/examples/editable-data) +- [展開](../framework/react/examples/expanding) +- [フィルター](../framework/react/examples/filters) +- [完全制御](../framework/react/examples/fully-controlled) +- [行選択](../framework/react/examples/row-selection) + +## API + +[ページネーションAPI](../api/features/pagination) + +## ページネーションガイド + +TanStack Tableはクライアントサイドとサーバーサイドの両方のページネーションをサポートしています。このガイドでは、テーブルにページネーションを実装するさまざまな方法を説明します。 + +### クライアントサイドページネーション + +クライアントサイドページネーションを使用すると、フェッチする`data`にはテーブルの***すべて***の行が含まれ、テーブルインスタンスがフロントエンドでページネーションロジックを処理します。 + +#### クライアントサイドページネーションを使用すべきか? + +クライアントサイドページネーションは、TanStack Tableを使用する際にページネーションを実装する最も簡単な方法ですが、非常に大きなデータセットには実用的ではない場合があります。 + +ただし、多くの人がクライアントサイドで処理できるデータ量を過小評価しています。テーブルが数千行以下であれば、クライアントサイドページネーションはまだ有効な選択肢です。TanStack Tableは、ページネーション、フィルタリング、ソート、グループ化において、数万行まで良好なパフォーマンスでスケールアップできるように設計されています。[公式のページネーション例](../framework/react/examples/pagination)では10万行を読み込んでも良好なパフォーマンスを発揮しています(ただし、列数は少ない場合です)。 + +各ユースケースは異なり、テーブルの複雑さ、列の数、データの大きさなどによって異なります。主に注意すべきボトルネックは以下の通りです: + +1. サーバーがすべてのデータを合理的な時間(とコスト)でクエリできるか? +2. フェッチの総サイズは?(列が多くない場合、思ったほどスケールしないかもしれません) +3. すべてのデータを一度に読み込むと、クライアントのブラウザがメモリを使いすぎるか? + +わからない場合は、まずクライアントサイドページネーションから始めて、データが増えたら後でサーバーサイドページネーションに切り替えることもできます。 + +#### 代わりに仮想化を使用すべきか? + +ページネーションの代わりに、大きなデータセットのすべての行を同じページにレンダリングし、ビューポートに表示されている行のみをブラウザのリソースを使ってレンダリングする方法もあります。この戦略は「仮想化」または「ウィンドウ化」と呼ばれることがあります。TanStackには[TalStack Virtual](https://tanstack.com/virtual/latest)という仮想化ライブラリがあり、TanStack Tableとうまく連携できます。仮想化とページネーションのUI/UXにはそれぞれトレードオフがあるので、ユースケースに最適なものを選択してください。 + +#### ページネーション行モデル + +TanStack Tableの組み込みクライアントサイドページネーションを利用するには、まずページネーション行モデルを渡す必要があります。 + +```jsx +import { useReactTable, getCoreRowModel, getPaginationRowModel } from '@tanstack/react-table'; +//... +const table = useReactTable({ + columns, + data, + getCoreRowModel: getCoreRowModel(), + getPaginationRowModel: getPaginationRowModel(), //クライアントサイドページネーションコードを読み込む +}); +``` + +### 手動サーバーサイドページネーション + +サーバーサイドページネーションを使用する必要がある場合、以下のように実装できます。 + +サーバーサイドページネーションにはページネーション行モデルは必要ありませんが、他のテーブルで必要な場合に共有コンポーネントで提供している場合は、`manualPagination`オプションを`true`に設定することでクライアントサイドページネーションをオフにできます。`manualPagination`オプションを`true`に設定すると、テーブルインスタンスは内部的に`table.getPrePaginationRowModel`行モデルを使用し、渡された`data`が既にページネーションされていると仮定します。 + +#### ページ数と行数 + +テーブルインスタンスは、バックエンドに合計で何行/何ページあるかを知る方法がないため、明示的に伝える必要があります。`rowCount`または`pageCount`テーブルオプションを提供して、テーブルインスタンスに合計ページ数を伝えます。`rowCount`を提供すると、テーブルインスタンスは`rowCount`と`pageSize`から内部的に`pageCount`を計算します。既に`pageCount`を持っている場合は、直接提供することもできます。ページ数がわからない場合は、`pageCount`に`-1`を渡すことができますが、この場合`getCanNextPage`と`getCanPreviousPage`行モデル関数は常に`true`を返します。 + +```jsx +import { useReactTable, getCoreRowModel, getPaginationRowModel } from '@tanstack/react-table'; +//... +const table = useReactTable({ + columns, + data, + getCoreRowModel: getCoreRowModel(), + // getPaginationRowModel: getPaginationRowModel(), //サーバーサイドページネーションには不要 + manualPagination: true, //クライアントサイドページネーションをオフにする + rowCount: dataQuery.data?.rowCount, //合計行数を渡してテーブルにページ数を伝える(pageCountが提供されていない場合は内部的に計算) + // pageCount: dataQuery.data?.pageCount, //代わりに直接pageCountを渡すことも可能 +}); +``` + +> **注**: `manualPagination`オプションを`true`に設定すると、テーブルインスタンスは渡された`data`が既にページネーションされていると仮定します。 + +### ページネーション状態 + +クライアントサイドまたは手動サーバーサイドページネーションのどちらを使用する場合でも、組み込みの`pagination`状態とAPIを使用できます。 + +`pagination`状態は以下のプロパティを含むオブジェクトです: + +- `pageIndex`: 現在のページインデックス(0ベース)。 +- `pageSize`: 現在のページサイズ。 + +`pagination`状態は、テーブルインスタンスの他の状態と同様に管理できます。 + +```jsx +import { useReactTable, getCoreRowModel, getPaginationRowModel } from '@tanstack/react-table'; +//... +const [pagination, setPagination] = useState({ + pageIndex: 0, //初期ページインデックス + pageSize: 10, //デフォルトページサイズ +}); + +const table = useReactTable({ + columns, + data, + getCoreRowModel: getCoreRowModel(), + getPaginationRowModel: getPaginationRowModel(), + onPaginationChange: setPagination, //内部APIがページネーション状態を変更したときに更新 + state: { + //... + pagination, + }, +}); +``` + +あるいは、`pagination`状態を自身のスコープで管理する必要がなく、`pageIndex`と`pageSize`に異なる初期値を設定したい場合は、`initialState`オプションを使用できます。 + +```jsx +const table = useReactTable({ + columns, + data, + getCoreRowModel: getCoreRowModel(), + getPaginationRowModel: getPaginationRowModel(), + initialState: { + pagination: { + pageIndex: 2, //カスタム初期ページインデックス + pageSize: 25, //カスタムデフォルトページサイズ + }, + }, +}); +``` + +> **注**: `pagination`状態を`state`と`initialState`の両方に渡さないでください。`state`は`initialState`を上書きします。どちらか一方のみを使用してください。 + +### ページネーションオプション + +手動サーバーサイドページネーションに有用な`manualPagination`、`pageCount`、`rowCount`オプション([上記](#manual-server-side-pagination)で説明)に加えて、理解しておくと便利なテーブルオプションがもう1つあります。 + +#### ページインデックスの自動リセット + +デフォルトでは、`data`が更新されたり、フィルターが変更されたり、グループ化が変更されたりなど、ページに影響を与える状態変更が発生すると、`pageIndex`は`0`にリセットされます。この動作は`manualPagination`がtrueの場合は自動的に無効になりますが、`autoResetPageIndex`テーブルオプションに明示的にブール値を割り当てることで上書きできます。 + +```jsx +const table = useReactTable({ + columns, + data, + getCoreRowModel: getCoreRowModel(), + getPaginationRowModel: getPaginationRowModel(), + autoResetPageIndex: false, //pageIndexの自動リセットをオフにする +}); +``` + +ただし、`autoResetPageIndex`をオフにした場合、空のページを表示しないようにするために、`pageIndex`を自分でリセットするロジックを追加する必要があるかもしれないことに注意してください。 + +### ページネーションAPI + +ページネーションUIコンポーネントを接続するのに便利な、いくつかのページネーションテーブルインスタンスAPIがあります。 + +#### ページネーションボタンAPI + +- `getCanPreviousPage`: 最初のページにいる場合に「前のページ」ボタンを無効にするのに便利。 +- `getCanNextPage`: これ以上ページがない場合に「次のページ」ボタンを無効にするのに便利。 +- `previousPage`: 前のページに移動するのに便利(ボタンクリックハンドラ)。 +- `nextPage`: 次のページに移動するのに便利(ボタンクリックハンドラ)。 +- `firstPage`: 最初のページに移動するのに便利(ボタンクリックハンドラ)。 +- `lastPage`: 最後のページに移動するのに便利(ボタンクリックハンドラ)。 +- `setPageIndex`: 「ページに移動」入力に便利。 +- `resetPageIndex`: テーブル状態を元のページインデックスにリセットするのに便利。 +- `setPageSize`: 「ページサイズ」入力/選択に便利。 +- `resetPageSize`: テーブル状態を元のページサイズにリセットするのに便利。 +- `setPagination`: ページネーション状態を一度にすべて設定するのに便利。 +- `resetPagination`: テーブル状態を元のページネーション状態にリセットするのに便利。 + +> **注**: これらのAPIの一部は`v8.13.0`で新しく追加されました。 + +```jsx + + + + + +``` + +#### ページネーション情報API + +- `getPageCount`: 合計ページ数を表示するのに便利。 +- `getRowCount`: 合計行数を表示するのに便利。 diff --git a/docs/ja/guide/row-models.md b/docs/ja/guide/row-models.md new file mode 100644 index 0000000000..985ddab767 --- /dev/null +++ b/docs/ja/guide/row-models.md @@ -0,0 +1,113 @@ +--- +source-updated-at: '2024-04-24T03:41:47.000Z' +translation-updated-at: '2025-05-05T19:24:59.286Z' +title: 行モデル +--- +## 行モデル (Row Models) ガイド + +TanStack Tableの最も基本的な例を見ると、次のようなコードスニペットがあります: + +```ts +import { getCoreRowModel, useReactTable } from '@tanstack/react-table' + +function Component() { + const table = useReactTable({ + data, + columns, + getCoreRowModel: getCoreRowModel(), //row model + }) +} +``` + +この`getCoreRowModel`関数とは何でしょうか?そして、なぜTanStack Tableからインポートしただけで、それをそのまま渡す必要があるのでしょうか? + +その答えは、TanStack Tableがモジュール型のライブラリであることにあります。すべての機能のコードがデフォルトでcreateTable関数/フックに含まれているわけではありません。使用する機能に基づいて行を正しく生成するために必要なコードのみをインポートして含める必要があります。 + +### 行モデル (Row Models) とは? + +行モデルはTanStack Tableの内部で動作し、フィルタリング、ソート、グループ化、展開、ページネーションなどのデータグリッド機能に必要な有用な方法で元のデータを変換します。画面上に生成されてレンダリングされる行は、必ずしもテーブルに渡した元のデータと1:1で対応するわけではありません。ソート、フィルタリング、ページネーションなどが適用される可能性があります。 + +### 行モデルのインポート + +必要な行モデルのみをインポートする必要があります。以下は利用可能なすべての行モデルです: + +```ts +//必要な行モデルのみをインポート +import { + getCoreRowModel, + getExpandedRowModel, + getFacetedMinMaxValues, + getFacetedRowModel, + getFacetedUniqueValues, + getFilteredRowModel, + getGroupedRowModel, + getPaginationRowModel, + getSortedRowModel, +} +//... +const table = useReactTable({ + columns, + data, + getCoreRowModel: getCoreRowModel(), + getExpandedRowModel: getExpandedRowModel(), + getFacetedMinMaxValues: getFacetedMinMaxValues(), + getFacetedRowModel: getFacetedRowModel(), + getFacetedUniqueValues: getFacetedUniqueValues(), + getFilteredRowModel: getFilteredRowModel(), + getGroupedRowModel: getGroupedRowModel(), + getPaginationRowModel: getPaginationRowModel(), + getSortedRowModel: getSortedRowModel(), +}) +``` + +### 行モデルのカスタマイズ/フォーク + +TanStack Tableが提供する正確な行モデルを使用する必要はありません。特定の行モデルに高度なカスタマイズが必要な場合は、カスタマイズしたい行モデルの[ソースコード](https://github.com/TanStack/table/tree/main/packages/table-core/src/utils)をコピーして、必要に応じて変更してください。 + +### 行モデルの使用 + +テーブルインスタンスが作成されると、必要なすべての行モデルにテーブルインスタンスから直接アクセスできます。インポートしたもの以外にも、さらに多くの派生行モデルが利用可能です。 + +通常のレンダリングユースケースでは、おそらく`table.getRowModel()`メソッドのみを使用すれば十分です。この行モデルは、有効または無効にした機能に応じて、他のすべて/任意の行モデルを使用します。他のすべての行モデルは、テーブルで行われている基礎的なデータ変換を「掘り下げる」ために利用できます。 + +### テーブルインスタンスで利用可能な行モデル + +- **`getRowModel`** - これはテーブル行のマークアップをレンダリングするために使用する主要な行モデルです。他のすべての行モデルを使用して、テーブル行をレンダリングするために使用する最終的な行モデルを生成します。 + +- `getCoreRowModel` - テーブルに渡された元のデータと1:1で対応する基本的な行モデルを返します。 + +- `getFilteredRowModel` - カラムフィルタリングとグローバルフィルタリングを考慮した行モデルを返します。 +- `getPreFilteredRowModel` - カラムフィルタリングとグローバルフィルタリングが適用される前の行モデルを返します。 + +- `getGroupedRowModel` - データにグループ化と集約を適用し、サブ行を作成する行モデルを返します。 +- `getPreGroupedRowModel` - グループ化と集約が適用される前の行モデルを返します。 + +- `getSortedRowModel` - ソートが適用された行モデルを返します。 +- `getPreSortedRowModel` - ソートが適用される前の行モデルを返します(行は元の順序です)。 + +- `getExpandedRowModel` - 展開/非表示のサブ行を考慮した行モデルを返します。 +- `getPreExpandedRowModel` - 展開されたサブ行を含まないルートレベルの行のみを含む行モデルを返します。ソートは含まれます。 + +- `getPaginationRowModel` - ページネーション状態に基づいて現在のページに表示されるべき行のみを含む行モデルを返します。 +- `getPrePaginationRowModel` - ページネーションが適用されていない行モデルを返します(すべての行を含みます)。 + +- `getSelectedRowModel` - 選択されたすべての行の行モデルを返します(ただし、テーブルに渡されたデータに基づきます)。getCoreRowModelの後に実行されます。 +- `getPreSelectedRowModel` - 行選択が適用される前の行モデルを返します(getCoreRowModelを返します)。 +- `getGroupedSelectedRowModel` - グループ化後に選択された行の行モデルを返します。getFilteredRowModelの後に実行されるgetGroupedRowModelの後に実行されるgetSortedRowModelの後に実行されます。 +- `getFilteredSelectedRowModel` - カラムフィルタリングとグローバルフィルタリング後に選択された行の行モデルを返します。getFilteredRowModelの後に実行されます。 + +### 行モデル実行の順序 + +TanStack Tableが内部的に行を処理する方法を知ることは、内部で何が起こっているかをよりよく理解し、発生する可能性のある問題をデバッグするのに役立ちます。 + +内部的には、それぞれの行モデルがデータに適用される順序は次のとおりです(それぞれの機能が有効になっている場合): + +`getCoreRowModel` -> `getFilteredRowModel` -> `getGroupedRowModel` -> `getSortedRowModel` -> `getExpandedRowModel` -> `getPaginationRowModel` -> `getRowModel` + +いずれの場合でも、それぞれの機能が無効になっているか、`"manual*"`テーブルオプションでオフになっている場合、そのプロセスのステップでは代わりに`getPre*RowModel`が使用されます。 + +上記のように、最初にデータがフィルタリングされ、次にグループ化され、ソートされ、展開され、最後にページネーションが最終ステップとして適用されます。 + +### 行モデルのデータ構造 + +各 diff --git a/docs/ja/guide/row-pinning.md b/docs/ja/guide/row-pinning.md new file mode 100644 index 0000000000..28cbfcfbcd --- /dev/null +++ b/docs/ja/guide/row-pinning.md @@ -0,0 +1,21 @@ +--- +source-updated-at: '2025-03-20T21:15:29.000Z' +translation-updated-at: '2025-05-05T19:26:55.943Z' +title: 行固定 +--- +## 例 + +実装に直接進みたいですか?以下の例を確認してください: + +- [行の固定 (row-pinning)](../framework/react/examples/row-pinning) + +## API + +[行の固定API (Row Pinning API)](../api/features/row-pinning) + +## 行の固定ガイド (Row Pinning Guide) + +テーブルには行の順序を変更する2つの機能があり、以下の順序で処理されます: + +1. **行の固定 (Row Pinning)** - 行を固定する場合、行は上部固定、中央(固定なし)、下部固定の行に分割されます。 +2. [ソート (Sorting)](../guide/sorting) diff --git a/docs/ja/guide/row-selection.md b/docs/ja/guide/row-selection.md new file mode 100644 index 0000000000..a358a5528a --- /dev/null +++ b/docs/ja/guide/row-selection.md @@ -0,0 +1,185 @@ +--- +source-updated-at: '2025-03-20T21:15:29.000Z' +translation-updated-at: '2025-05-05T19:28:03.173Z' +title: 行選択 +--- +## 実装例 + +実装に直接進みたいですか?以下の例を確認してください: + +- [React 行選択](../framework/react/examples/row-selection) +- [Vue 行選択](../framework/vue/examples/row-selection) +- [React 展開](../framework/react/examples/expanding) + +## API + +[行選択 API](../api/features/row-selection) + +## 行選択ガイド + +行選択機能は、どの行が選択されているかを追跡し、さまざまな方法で行の選択を切り替えることができます。一般的な使用例を見ていきましょう。 + +### 行選択状態へのアクセス + +テーブルインスタンスはすでに行選択状態を管理しています(ただし、以下で見るように、行選択状態を独自のスコープで管理した方が便利な場合があります)。いくつかのAPIから内部の行選択状態または選択された行にアクセスできます。 + +- `getState().rowSelection` - 内部の行選択状態を返す +- `getSelectedRowModel()` - 選択された行を返す +- `getFilteredSelectedRowModel()` - フィルタリング後の選択行を返す +- `getGroupedSelectedRowModel()` - グループ化とソート後の選択行を返す + +```ts +console.log(table.getState().rowSelection) //行選択状態を取得 - { 1: true, 2: false, etc... } +console.log(table.getSelectedRowModel().rows) //クライアント側の選択行全体を取得 +console.log(table.getFilteredSelectedRowModel().rows) //フィルタリングされたクライアント側の選択行を取得 +console.log(table.getGroupedSelectedRowModel().rows) //グループ化されたクライアント側の選択行を取得 +``` + +> 注意: `manualPagination`を使用している場合、`getSelectedRowModel` APIは現在のページの選択行のみを返します。テーブルの行モデルは渡された`data`に基づいてのみ行を生成できるためです。ただし、行選択状態は`data`配列に存在しない行IDを含むことができます。 + +### 行選択状態の管理 + +テーブルインスタンスが行選択状態を管理しますが、API呼び出しやその他のアクションに使用できる選択行IDに簡単にアクセスするために、通常は独自のスコープで状態を管理する方が便利です。 + +`onRowSelectionChange`テーブルオプションを使用して、行選択状態を独自のスコープに引き上げます。次に、`state`テーブルオプションを使用して行選択状態をテーブルインスタンスに戻します。 + +```ts +const [rowSelection, setRowSelection] = useState({}) //独自の行選択状態を管理 + +const table = useReactTable({ + //... + onRowSelectionChange: setRowSelection, //行選択状態を独自のスコープに引き上げる + state: { + rowSelection, //行選択状態をテーブルインスタンスに戻す + }, +}) +``` + +### 有用な行ID + +デフォルトでは、各行の行IDは単に`row.index`です。行選択機能を使用している場合、行選択状態が行IDでキー付けされるため、より有用な行識別子を使用する必要があります。`getRowId`テーブルオプションを使用して、各行の一意の行IDを返す関数を指定できます。 + +```ts +const table = useReactTable({ + //... + getRowId: row => row.uuid, //データベースの行のuuidを行IDとして使用 +}) +``` + +これで、行が選択されると、行選択状態は次のようになります: + +```json +{ + "13e79140-62a8-4f9c-b087-5da737903b76": true, + "f3e2a5c0-5b7a-4d8a-9a5c-9c9b8a8e5f7e": false + //... +} +``` + +この代わりに: + +```json +{ + "0": true, + "1": false + //... +} +``` + +### 条件付きで行選択を有効化 + +行選択はデフォルトですべての行に対して有効になっています。特定の行に対して条件付きで行選択を有効にするか、すべての行に対して行選択を無効にするには、`enableRowSelection`テーブルオプションを使用します。このオプションは、ブール値またはより詳細な制御のための関数を受け入れます。 + +```ts +const table = useReactTable({ + //... + enableRowSelection: row => row.original.age > 18, //成人のみ行選択を有効化 +}) +``` + +UIで行が選択可能かどうかを強制するには、チェックボックスまたは他の選択UIに`row.getCanSelect()` APIを使用できます。 + +### 単一行選択 + +デフォルトでは、テーブルは複数の行を同時に選択できます。ただし、一度に1つの行のみを選択できるようにしたい場合は、`enableMultiRowSelection`テーブルオプションを`false`に設定して複数行選択を無効にするか、行のサブ行に対して条件付きで複数行選択を無効にする関数を渡します。 + +これは、チェックボックスの代わりにラジオボタンを持つテーブルを作成する場合に便利です。 + +```ts +const table = useReactTable({ + //... + enableMultiRowSelection: false, //一度に1つの行のみ選択可能 + // enableMultiRowSelection: row => row.original.age > 18, //成人に対してのみ1つの行を選択可能 +}) +``` + +### サブ行選択 + +デフォルトでは、親行を選択するとそのすべてのサブ行が選択されます。自動サブ行選択を無効にしたい場合は、`enableSubRowSelection`テーブルオプションを`false`に設定してサブ行選択を無効にするか、行のサブ行に対して条件付きでサブ行選択を無効にする関数を渡します。 + +```ts +const table = useReactTable({ + //... + enableSubRowSelection: false, //サブ行選択を無効化 + // enableSubRowSelection: row => row.original.age > 18, //成人に対してサブ行選択を無効化 +}) +``` + +### 行選択UIのレンダリング + +TanStackテーブルは、行選択UIをどのようにレンダリングするかを規定しません。チェックボックス、ラジオボタンを使用するか、単に行自体にクリックイベントをフックできます。テーブルインスタンスは、行選択UIをレンダリングするのに役立ついくつかのAPIを提供します。 + +#### チェックボックス入力に行選択APIを接続 + +TanStackテーブルは、行選択を切り替えるためにチェックボックス入力に直接接続できるいくつかのハンドラ関数を提供します。これらの関数は、行選択状態を更新し、テーブルを再レンダリングするために他の内部APIを自動的に呼び出します。 + +`row.getToggleSelectedHandler()` APIを使用して、行の選択を切り替えるためにチェックボックス入力に接続します。 + +`table.getToggleAllRowsSelectedHandler()`または`table.getToggleAllPageRowsSelectedHandler` APIを使用して、「すべて選択」チェックボックス入力に接続し、すべての行の選択を切り替えます。 + +これらの関数ハンドラをより詳細に制御する必要がある場合は、常に`row.toggleSelected()`または`table.toggleAllRowsSelected()` APIを直接使用できます。または、他の状態更新プログラムと同様に、`table.setRowSelection()` APIを直接呼び出して行選択状態を設定することもできます。これらのハンドラ関数は単なる便利機能です。 + +```tsx +const columns = [ + { + id: 'select-col', + header: ({ table }) => ( + + ), + cell: ({ row }) => ( + + ), + }, + //... その他の列定義... +] +``` + +#### UIに行選択APIを接続 + +よりシンプルな行選択UIが必要な場合は、行自体にクリックイベントをフックするだけです。`row.getToggleSelectedHandler()` APIはこの使用例にも役立ちます。 + +```tsx + + {table.getRowModel().rows.map(row => { + return ( + + {row.getVisibleCells().map(cell => { + return + })} + + ) + })} + +``` diff --git a/docs/ja/guide/rows.md b/docs/ja/guide/rows.md new file mode 100644 index 0000000000..3caebb611b --- /dev/null +++ b/docs/ja/guide/rows.md @@ -0,0 +1,98 @@ +--- +source-updated-at: '2025-03-20T21:15:29.000Z' +translation-updated-at: '2025-05-05T19:24:41.808Z' +title: 行 +--- +## API + +[行 API](../api/core/row) + +## 行ガイド + +このクイックガイドでは、TanStack Table で行オブジェクトを取得および操作するさまざまな方法について説明します。 + +### 行の取得方法 + +テーブルインスタンスから行を取得するために使用できる複数の `table` インスタンス API があります。 + +#### table.getRow + +特定の行を `id` でアクセスする必要がある場合は、`table.getRow` テーブルインスタンス API を使用できます。 + +```js +const row = table.getRow(rowId) +``` + +#### 行モデル + +`table` インスタンスは `row` オブジェクトを生成し、それらを ["行モデル"](../guide/row-models) と呼ばれる便利な配列に格納します。これについては [行モデルガイド](../guide/row-models) で詳しく説明されていますが、ここでは行モデルにアクセスする最も一般的な方法を紹介します。 + +##### 行のレンダリング + +```jsx + + {table.getRowModel().rows.map(row => ( + + {/* ... */} + + ))} + +``` + +##### 選択された行の取得 + +```js +const selectedRows = table.getSelectedRowModel().rows +``` + +### 行オブジェクト + +各行オブジェクトには行データと、テーブルの状態と対話したり、テーブルの状態に基づいて行からセルを抽出したりするための多くの API が含まれています。 + +#### 行 ID + +各行オブジェクトには、テーブルインスタンス内で一意となる `id` プロパティがあります。デフォルトでは、`row.id` は行モデルで作成された `row.index` と同じです。ただし、行のデータから一意の識別子を使用して各行の `id` をオーバーライドすると便利な場合があります。これを行うには、`getRowId` テーブルオプションを使用できます。 + +```js +const table = useReactTable({ + columns, + data, + getRowId: originalRow => originalRow.uuid, // 行のデータから uuid を使用して row.id をオーバーライド +}) +``` + +> 注: グループ化や展開などの一部の機能では、`row.id` に追加の文字列が付加されます。 + +#### 行の値へのアクセス + +行からデータ値を取得する推奨方法は、`row.getValue` または `row.renderValue` API を使用することです。これらの API のいずれかを使用すると、アクセサー関数の結果がキャッシュされ、レンダリングが効率的になります。両者の唯一の違いは、`row.renderValue` は値が undefined の場合に値または `renderFallbackValue` を返すのに対し、`row.getValue` は値または undefined を返す点です。 + +```js +// 任意の列からデータにアクセス +const firstName = row.getValue('firstName') // firstName 列から行の値を読み取る +const renderedLastName = row.renderValue('lastName') // lastName 列から値をレンダリング +``` + +> 注: `cell.getValue` と `cell.renderValue` は、それぞれ `row.getValue` と `row.renderValue` API のショートカットです。 + +#### 元の行データへのアクセス + +各行オブジェクトに対して、`row.original` プロパティを介してテーブルインスタンスに渡された元の対応する `data` にアクセスできます。`row.original` 内のデータは、列定義のアクセサーによって変更されていないため、アクセサーで何らかのデータ変換を行っていた場合、それらは `row.original` オブジェクトには反映されません。 + +```js +// 元の行から任意のデータにアクセス +const firstName = row.original.firstName // { firstName: 'John', lastName: 'Doe' } +``` + +### サブ行 + +グループ化または展開機能を使用している場合、行にはサブ行または親行参照が含まれることがあります。これについては [展開ガイド](../guide/expanding) で詳しく説明されていますが、ここではサブ行を操作するための便利なプロパティとメソッドの概要を紹介します。 + +- `row.subRows`: 行のサブ行の配列。 +- `row.depth`: 行の深さ(ネストまたはグループ化されている場合)をルート行配列からの相対値で示します。ルートレベルの行は 0、子行は 1、孫行は 2 など。 +- `row.parentId`: 行の親行の一意の ID(この行をその subRows 配列に含む行)。 +- `row.getParentRow`: 存在する場合、行の親行を返します。 + +### その他の行 API + +テーブルで使用している機能に応じて、行と対話するための数十の便利な API があります。詳細については、各機能の対応する API ドキュメントまたはガイドを参照してください。 diff --git a/docs/ja/guide/sorting.md b/docs/ja/guide/sorting.md new file mode 100644 index 0000000000..74c925ff1b --- /dev/null +++ b/docs/ja/guide/sorting.md @@ -0,0 +1,359 @@ +--- +source-updated-at: '2025-03-20T21:15:29.000Z' +translation-updated-at: '2025-05-05T19:29:13.756Z' +title: ソート +--- +## 例 + +実装に直接進みたいですか?以下の例を確認してください: + +- [ソート](../framework/react/examples/sorting) +- [フィルター](../framework/react/examples/filters) + +## API + +[ソート API](../api/features/sorting) + +## ソートガイド + +TanStack Tableは、あらゆるソートユースケースに対応するソリューションを提供します。このガイドでは、組み込みのクライアントサイドソート機能をカスタマイズするためのさまざまなオプションと、手動のサーバーサイドソートを優先してクライアントサイドソートをオプトアウトする方法について説明します。 + +### ソート状態 + +ソート状態は以下の形状のオブジェクトの配列として定義されます: + +```tsx +type ColumnSort = { + id: string + desc: boolean +} +type SortingState = ColumnSort[] +``` + +ソート状態は配列であるため、複数の列で同時にソートすることが可能です。[下記](#multi-sorting)でマルチソートのカスタマイズについて詳しく説明します。 + +#### ソート状態へのアクセス + +`table.getState()` APIを使用して、他の状態と同様にソート状態に直接アクセスできます。 + +```tsx +const table = useReactTable({ + columns, + data, + //... +}) + +console.log(table.getState().sorting) // テーブルインスタンスからソート状態にアクセス +``` + +ただし、テーブルが初期化される前にソート状態にアクセスする必要がある場合は、以下のようにソート状態を「制御」できます。 + +#### 制御されたソート状態 + +ソート状態に簡単にアクセスする必要がある場合は、`state.sorting`と`onSortingChange`テーブルオプションを使用して、独自の状態管理でソート状態を制御/管理できます。 + +```tsx +const [sorting, setSorting] = useState([]) // ここで初期ソート状態を設定可能 +//... +// ソート状態を使用してサーバーからデータを取得するなど... +//... +const table = useReactTable({ + columns, + data, + //... + state: { + sorting, + }, + onSortingChange: setSorting, +}) +``` + +#### 初期ソート状態 + +独自の状態管理やスコープでソート状態を制御する必要がないが、初期ソート状態を設定したい場合は、`state`の代わりに`initialState`テーブルオプションを使用できます。 + +```jsx +const table = useReactTable({ + columns, + data, + //... + initialState: { + sorting: [ + { + id: 'name', + desc: true, // デフォルトで名前で降順ソート + }, + ], + }, +}) +``` + +> **注意**: `initialState.sorting`と`state.sorting`を同時に使用しないでください。`state.sorting`で初期化された状態が`initialState.sorting`を上書きします。 + +### クライアントサイド vs サーバーサイドソート + +クライアントサイドソートとサーバーサイドソートのどちらを使用すべきかは、クライアントサイドまたはサーバーサイドのページネーションやフィルタリングを使用しているかどうかによって完全に異なります。一貫性を保つようにしてください。クライアントサイドソートをサーバーサイドページネーションやフィルタリングと一緒に使用すると、現在ロードされているデータのみがソートされ、データセット全体はソートされません。 + +### 手動サーバーサイドソート + +バックエンドロジックで独自のサーバーサイドソートを使用する予定の場合、ソートされた行モデルを提供する必要はありません。ただし、ソート行モデルを提供しているが無効にしたい場合は、`manualSorting`テーブルオプションを使用できます。 + +```jsx +const [sorting, setSorting] = useState([]) +//... +const table = useReactTable({ + columns, + data, + getCoreRowModel: getCoreRowModel(), + //getSortedRowModel: getSortedRowModel(), // 手動ソートには不要 + manualSorting: true, // ソート済み行モデルの代わりに事前ソート済み行モデルを使用 + state: { + sorting, + }, + onSortingChange: setSorting, +}) +``` + +> **注意**: `manualSorting`が`true`に設定されている場合、テーブルは提供されたデータが既にソートされていると見なし、それにソートを適用しません。 + +### クライアントサイドソート + +クライアントサイドソートを実装するには、まずソート行モデルをテーブルに提供する必要があります。TanStack Tableから`getSortedRowModel`関数をインポートすると、行をソート済み行に変換するために使用されます。 + +```jsx +import { useReactTable } from '@tanstack/react-table' +//... +const table = useReactTable({ + columns, + data, + getCoreRowModel: getCoreRowModel(), + getSortedRowModel: getSortedRowModel(), // ソート行モデルを提供 +}) +``` + +### ソート関数 + +すべての列のデフォルトのソート関数は、列のデータ型から推測されます。ただし、特にデータがnull許容型である場合や標準的なデータ型でない場合、特定の列に使用する正確なソート関数を定義すると便利です。 + +`sortingFn`列オプションを使用して、列ごとにカスタムソート関数を決定できます。 + +デフォルトでは、6つの組み込みソート関数から選択できます: + +- `alphanumeric` - 大文字小文字を区別せずに英数字混合値をソート。遅いですが、文字列に自然にソートする必要がある数字が含まれている場合により正確です。 +- `alphanumericCaseSensitive` - 大文字小文字を区別して英数字混合値をソート。遅いですが、文字列に自然にソートする必要がある数字が含まれている場合により正確です。 +- `text` - 大文字小文字を区別せずにテキスト/文字列値をソート。高速ですが、文字列に自然にソートする必要がある数字が含まれている場合に精度が低くなります。 +- `textCaseSensitive` - 大文字小文字を区別してテキスト/文字列値をソート。高速ですが、文字列に自然にソートする必要がある数字が含まれている場合に精度が低くなります。 +- `datetime` - 時間でソート。値が`Date`オブジェクトの場合に使用します。 +- `basic` - 基本的/標準的な`a > b ? 1 : a < b ? -1 : 0`比較を使用してソート。最も高速なソート関数ですが、最も正確ではない場合があります。 + +`sortingFn`列オプションとして、または`sortingFns`テーブルオプションを使用してグローバルソート関数として、独自のカスタムソート関数を定義することもできます。 + +#### カスタムソート関数 + +`sortingFns`テーブルオプションまたは`sortingFn`列オプションでカスタムソート関数を定義する場合、以下のシグネチャを持つ必要があります: + +```tsx +// 必要に応じてSortingFnを使用してパラメータ型を推論 +const myCustomSortingFn: SortingFn = (rowA: Row, rowB: Row, columnId: string) => { + return // -1, 0, または1 - rowA.originalとrowB.originalを使用して任意の行データにアクセス +} +``` + +> 注意: 比較関数は、列が降順または昇順であるかどうかを考慮する必要はありません。行モデルがそのロジックを処理します。`sortingFn`関数は一貫した比較を提供するだけでよいです。 + +すべてのソート関数は2つの行と列IDを受け取り、列IDを使用して2つの行を比較し、昇順で`-1`、`0`、または`1`を返すことが期待されます。以下はチートシートです: + +| 戻り値 | 昇順 | +| ------ | ---------- | +| `-1` | `a < b` | +| `0` | `a === b` | +| `1` | `a > b` | + +```jsx +const columns = [ + { + header: () => '名前', + accessorKey: 'name', + sortingFn: 'alphanumeric', // 名前で組み込みソート関数を使用 + }, + { + header: () => '年齢', + accessorKey: 'age', + sortingFn: 'myCustomSortingFn', // カスタムグローバルソート関数を使用 + }, + { + header: () => '誕生日', + accessorKey: 'birthday', + sortingFn: 'datetime', // 日付列に推奨 + }, + { + header: () => 'プロフィール', + accessorKey: 'profile', + // 直接カスタムソート関数を使用 + sortingFn: (rowA, rowB, columnId) => { + return rowA.original.someProperty - rowB.original.someProperty + }, + } +] +//... +const table = useReactTable({ + columns, + data, + getCoreRowModel: getCoreRowModel(), + getSortedRowModel: getSortedRowModel(), + sortingFns: { // カスタムソート関数を追加 + myCustomSortingFn: (rowA, rowB, columnId) => { + return rowA.original[columnId] > rowB.original[columnId] ? 1 : rowA.original[columnId] < rowB.original[columnId] ? -1 : 0 + }, + }, +}) +``` + +### ソートのカスタマイズ + +ソートのUXと動作をさらにカスタマイズするために、多くのテーブルおよび列オプションを使用できます。 + +#### ソートの無効化 + +`enableSorting`列オプションまたはテーブルオプションを使用して、特定の列またはテーブル全体のソートを無効にできます。 + +```jsx +const columns = [ + { + header: () => 'ID', + accessorKey: 'id', + enableSorting: false, // この列のソートを無効化 + }, + { + header: () => '名前', + accessorKey: 'name', + }, + //... +] +//... +const table = useReactTable({ + columns, + data, + enableSorting: false, // テーブル全体のソートを無効化 +}) +``` + +#### ソート方向 + +デフォルトでは、`toggleSorting` APIを使用して列のソートを循環する際の最初のソート方向は、文字列列の場合は昇順、数値列の場合は降順です。`sortDescFirst`列オプションまたはテーブルオプションを使用してこの動作を変更できます。 + +```jsx +const columns = [ + { + header: () => '名前', + accessorKey: 'name', + sortDescFirst: true, // 名前で最初に降順ソート(文字列列のデフォルトは昇順) + }, + { + header: () => '年齢', + accessorKey: 'age', + sortDescFirst: false, // 年齢で最初に昇順ソート(数値列のデフォルトは降順) + }, + //... +] +//... +const table = useReactTable({ + columns, + data, + sortDescFirst: true, // すべての列で最初に降順ソート(文字列列のデフォルトは昇順、数値列のデフォルトは降順) +}) +``` + +> **注意**: null許容値を持つ列には、明示的に`sortDescFirst`列オプションを設定することをお勧めします。null許容値が含まれている場合、テーブルは列が数値か文字列かを正しく判断できない場合があります。 + +#### ソートの反転 + +ソートの反転は、デフォルトのソート方向の変更と同じではありません。列オプション`invertSorting`が`true`の場合、"desc/asc"ソート状態は通常通り循環しますが、行の実際のソートは反転されます。これは、低い数字が良いことを示す逆のベスト/ワーストスケールを持つ値(例: ランキング(1位、2位、3位)やゴルフのようなスコアリング)に役立ちます。 + +```jsx +const columns = [ + { + header: () => 'ランク', + accessorKey: 'rank', + invertSorting: true, // この列のソートを反転。"desc"ソートが適用されていても1位 -> 2位 -> 3位 -> ... + }, + //... +] +``` + +#### 未定義値のソート + +未定義の値は、`sortUndefined`列オプションまたはテーブルオプションに基づいてリストの先頭または末尾にソートされます。特定のユースケースに合わせてこの動作をカスタマイズできます。 + +指定されていない場合、`sortUndefined`のデフォルト値は`1`で、未定義の値は優先度が低い(降順)としてソートされます。昇順の場合、未定義はリストの末尾に表示されます。 + +- `'first'` - 未定義の値はリストの先頭にプッシュされます +- `'last'` - 未定義の値はリストの末尾にプッシュされます +- `false` - 未定義の値は同点と見なされ、次の列フィルターまたは元のインデックスでソートする必要があります(適用可能な場合) +- `-1` - 未定義の値は優先度が高い(昇順)としてソートされます(昇順の場合、未定義はリストの先頭に表示されます) +- `1` - 未定義の値は優先度が低い(降順)としてソートされます(昇順の場合、未定義はリストの末尾に表示されます) + +> 注意: `'first'`および`'last'`オプションはv8.16.0で新しく追加されました + +```jsx +const columns = [ + { + header: () => 'ランク', + accessorKey: 'rank', + sortUndefined: -1, // 'first' | 'last' | 1 | -1 | false + }, +] +``` + +#### ソートの削除 + +デフォルトでは、列のソート状態を循環する際にソートを削除する機能が有効になっています。`enableSortingRemoval`テーブルオプションを使用してこの動作を無効にできます。この動作は、少なくとも1つの列が常にソートされていることを保証したい場合に便利です。 + +`getToggleSortingHandler`または`toggleSorting` APIを使用する場合のデフォルトの動作は、次のようにソート状態を循環します: + +`'none' -> 'desc' -> 'asc' -> 'none' -> 'desc' -> 'asc' -> ...` + +ソート削除を無効にすると、動作は次のようになります: + +`'none' -> 'desc' -> 'asc' -> 'desc' -> 'asc' -> ...` + +一度列がソートされ、`enableSortingRemoval`が`false`の場合、その列のソートを切り替えてもソートが削除されることはありません。ただし、ユーザーが別の列でソートし、それがマルチソートイベントでない場合、前の列のソートは削除され、新しい列にのみ適用されます。 + +> 少なくとも1つの列が常にソートされていることを保証したい場合は、`enableSortingRemoval`を`false`に設定します。 + +```jsx +const table = useReactTable({ + columns, + data, + enableSortingRemoval: false, // 列のソート削除機能を無効化(常に none -> asc -> desc -> asc) +}) +``` + +#### マルチソート + +`column.getToggleSortingHandler` APIを使用している場合、デフォルトで複数列での同時ソートが有効になっています。ユーザーが`Shift`キーを押しながら列ヘッダーをクリックすると、テーブルはその列と既にソートされている列を追加でソートします。`column.toggleSorting` APIを使用する場合は、マルチソートを使用するかどうかを手動で渡す必要があります(`column.toggleSorting(desc, multi)`)。 + +##### マルチソートの無効化 + +`enableMultiSort`列オプションまたはテーブルオプションを使用して、特定の列またはテーブル全体のマルチソートを無効にできます。特定の列のマルチソートを無効にすると、既存のすべてのソートが新しい列のソートに置き換えられます。 + +```jsx +const columns = [ + { + header: () => '作成日', + accessorKey: 'createdAt', + enableMultiSort: false, // この列でソートする場合は常にこの列のみでソート + }, + //... +] +//... +const table = useReactTable({ + columns, + data, + enableMultiSort: false, // テーブル全体のマルチソートを無効化 +}) +``` + +##### マルチソートトリガーのカスタマイズ + +デフォルトでは、`Shift`キーがマルチソートのトリガーとして使用されます。`isMultiSortEvent`テーブルオプションを使用してこの動作を変更できます。カスタム関数から`true`を返すことで、すべてのソートイベントがマルチソートをトリガーするように指定することもできます diff --git a/docs/ja/guide/tables.md b/docs/ja/guide/tables.md new file mode 100644 index 0000000000..f5aba24a51 --- /dev/null +++ b/docs/ja/guide/tables.md @@ -0,0 +1,102 @@ +--- +source-updated-at: '2025-03-20T21:15:29.000Z' +translation-updated-at: '2025-05-05T19:24:53.275Z' +title: テーブルインスタンス +--- +## API + +[Table API](../api/core/table) + +## テーブルインスタンスガイド + +TanStack TableはヘッドレスUIライブラリです。`table` または「テーブルインスタンス」について話す場合、実際の`
+``` + +ただし、[高度なカラムリサイズのパフォーマンスセクション](#advanced-column-resizing-performance)で説明したように、マークアップにカラムサイズを適用するためにCSS変数を使用することを検討することをお勧めします。 + +##### カラムリサイズAPI + +TanStack Tableは、ドラッグ操作を簡単に実装するための事前構築済みのイベントハンドラーを提供します。これらのイベントハンドラーは、カラムサイズ設定状態を更新し、テーブルを再レンダリングするために他の内部APIを呼び出す便利な関数です。`header.getResizeHandler()`を使用して、マウスイベントとタッチイベントの両方に対してカラムリサイズのドラッグ操作に接続します。 + +```tsx + +``` + +##### ColumnSizingInfoStateを使用したカラムリサイズインジケーター + +TanStack Tableは、`columnSizingInfo`という状態オブジェクトを追跡しており、これを使用してカラムリサイズインジケーターUIをレンダリングできます。 + +```jsx + +``` + +#### 高度なカラムリサイズのパフォーマンス + +大規模または複雑なテーブルを作成している場合(そしてReactを使用している場合😉)、レンダリングロジックに適切なメモ化を追加しないと、ユーザーがカラムをリサイズしている間にパフォーマンスの低下が発生する可能性があります。 + +[パフォーマンスの高いカラムリサイズの例](../framework/react/examples/column-resizing-performant)を作成しました。この例では、それ以外の場合にはレンダリングが遅くなる可能性のある複雑なテーブルで60 fpsのカラムリサイズレンダリングを達成する方法を示しています。この例を見てどのように行われているかを確認することをお勧めしますが、基本的に留意すべき点は以下の通りです: + +1. すべてのヘッダーとすべてのデータセルで`column.getSize()`を使用しないでください。代わりに、すべてのカラム幅を一度に事前に計算し、**メモ化**します! +2. リサイズが進行中の間、テーブルボディをメモ化します。 +3. CSS変数を使用して、カラム幅をテーブルセルに伝達します。 + +これらの手順に従うと、カラムのリサイズ中のパフォーマンスが大幅に向上するはずです。 + +Reactを使用せず、代わりにSvelte、Vue、またはSolidアダプターを使用している場合、これほど心配する必要はないかもしれませんが、同様の原則が適用されます。 diff --git a/docs/ja/guide/column-visibility.md b/docs/ja/guide/column-visibility.md new file mode 100644 index 0000000000..bb4efd4083 --- /dev/null +++ b/docs/ja/guide/column-visibility.md @@ -0,0 +1,132 @@ +--- +source-updated-at: '2025-03-20T21:15:29.000Z' +translation-updated-at: '2025-05-05T19:26:46.830Z' +title: カラム表示/非表示 +--- +## 例 + +実装に直接進みたいですか?以下の例を確認してください: + +- [column-visibility](../framework/react/examples/column-visibility) +- [column-ordering](../framework/react/examples/column-ordering) +- [sticky-column-pinning](../framework/react/examples/column-pinning-sticky) + +### その他の例 + +- [SolidJS column-visibility](../framework/solid/examples/column-visibility) +- [Svelte column-visibility](../framework/svelte/examples/column-visibility) + +## API + +[Column Visibility API](../api/features/column-visibility) + +## カラム可視性ガイド + +カラム可視性機能を使用すると、テーブルのカラムを動的に表示/非表示にできます。以前のバージョンのreact-tableでは、この機能はカラムの静的プロパティでしたが、v8では専用の`columnVisibility`ステートとAPIが用意され、カラムの可視性を動的に管理できるようになりました。 + +### カラム可視性ステート + +`columnVisibility`ステートは、カラムIDとブール値のマップです。カラムIDがマップ内に存在し、値が`false`の場合、そのカラムは非表示になります。カラムIDがマップ内に存在しないか、値が`true`の場合、カラムは表示されます。 + +```jsx +const [columnVisibility, setColumnVisibility] = useState({ + columnId1: true, + columnId2: false, //このカラムはデフォルトで非表示 + columnId3: true, +}); + +const table = useReactTable({ + //... + state: { + columnVisibility, + //... + }, + onColumnVisibilityChange: setColumnVisibility, +}); +``` + +または、テーブルの外部でカラム可視性ステートを管理する必要がない場合は、`initialState`オプションを使用して初期のデフォルトカラム可視性ステートを設定することもできます。 + +> **注**: `columnVisibility`が`initialState`と`state`の両方に提供される場合、`state`の初期化が優先され、`initialState`は無視されます。`columnVisibility`を`initialState`と`state`の両方に提供しないでください。どちらか一方のみに提供してください。 + +```jsx +const table = useReactTable({ + //... + initialState: { + columnVisibility: { + columnId1: true, + columnId2: false, //このカラムはデフォルトで非表示 + columnId3: true, + }, + //... + }, +}); +``` + +### カラムの非表示を無効化 + +デフォルトでは、すべてのカラムを非表示または表示できます。特定のカラムを非表示にできないようにするには、それらのカラムに対して`enableHiding`カラムオプションを`false`に設定します。 + +```jsx +const columns = [ + { + header: 'ID', + accessorKey: 'id', + enableHiding: false, // このカラムの非表示を無効化 + }, + { + header: '名前', + accessor: 'name', // 非表示に可能 + }, +]; +``` + +### カラム可視性トグルAPI + +UIでカラム可視性トグルをレンダリングする際に便利なカラムAPIメソッドがいくつかあります。 + +- `column.getCanHide` - `enableHiding`が`false`に設定されているカラムの可視性トグルを無効にするのに便利です。 +- `column.getIsVisible` - 可視性トグルの初期状態を設定するのに便利です。 +- `column.toggleVisibility` - カラムの可視性をトグルするのに便利です。 +- `column.getToggleVisibilityHandler` - `column.toggleVisibility`メソッドをUIイベントハンドラに接続するショートカットです。 + +```jsx +{table.getAllColumns().map((column) => ( + +))} +``` + +### カラム可視性を考慮したテーブルAPI + +ヘッダー、ボディ、フッターセルをレンダリングする際、多くのAPIオプションが利用可能です。`table.getAllLeafColumns`や`row.getAllCells`のようなAPIを見かけることがありますが、これらのAPIを使用すると、カラム可視性が考慮されません。代わりに、`table.getVisibleLeafColumns`や`row.getVisibleCells`などの「可視」バリアントのAPIを使用する必要があります。 + +```jsx + + + + {table.getVisibleLeafColumns().map((column) => ( // カラム可視性を考慮 + // + ))} + + + + {table.getRowModel().rows.map((row) => ( + + {row.getVisibleCells().map((cell) => ( // カラム可視性を考慮 + // + ))} + + ))} + +
+``` + +ヘッダーグループAPIを使用している場合、これらはすでにカラム可視性を考慮しています。 diff --git a/docs/ja/guide/columns.md b/docs/ja/guide/columns.md new file mode 100644 index 0000000000..9231158a07 --- /dev/null +++ b/docs/ja/guide/columns.md @@ -0,0 +1,73 @@ +--- +source-updated-at: '2025-03-20T21:15:29.000Z' +translation-updated-at: '2025-05-05T19:25:28.522Z' +title: カラム +--- +## API + +[Column API](../api/core/column) + +## カラムガイド + +> 注: このガイドは、テーブルインスタンス内で生成される実際の `column` オブジェクトに関するものであり、テーブルの[カラム定義](../guide/column-defs)を設定する方法に関するものではありません。 + +このクイックガイドでは、TanStack Tableで `column` オブジェクトを取得および操作するさまざまな方法について説明します。 + +### カラムの取得方法 + +`column` オブジェクトは多くの場所で見つけることができます。それらはしばしば関連付けられています。 + +#### ヘッダーとセルオブジェクト + +`table` インスタンスAPIのいずれかにアクセスする前に、実際に `columns` ではなく[ヘッダー](../guide/headers)または[セル](../guide/cells)を取得する必要があるかどうかを検討してください。テーブルのマークアップをレンダリングする場合、ほとんどの場合、カラムではなくヘッダーまたはセルを返すAPIを使用することになります。カラムオブジェクト自体はヘッダーやセルをレンダリングするためのものではありませんが、`header` および `cell` オブジェクトにはこれらの `column` オブジェクトへの参照が含まれており、そこからUIをレンダリングするために必要な情報を取得できます。 + +```js +const column = cell.column; // セルからカラムを取得 +const column = header.column; // ヘッダーからカラムを取得 +``` + +#### カラムテーブルインスタンスAPI + +テーブルインスタンスからカラムを取得するために使用できる数十の `table` インスタンスAPIがあります。どのAPIを使用するかは、テーブルで使用している機能とユースケースに完全に依存します。 + +##### カラムの取得 + +IDで単一のカラムを取得する必要がある場合は、`table.getColumn` APIを使用できます。 + +```js +const column = table.getColumn('firstName'); +``` + +##### カラムの一覧取得 + +最もシンプルなカラムAPIは `table.getAllColumns` で、テーブル内のすべてのカラムのリストを返します。ただし、このAPIと一緒に使用する可能性のある、他の機能やテーブルの状態に影響を受ける数十の他のカラムAPIがあります。`table.getAllFlatColumns`、`table.getAllLeafColumns`、`getCenterLeafColumns`、`table.getLeftVisibleLeafColumns` は、カラムの可視性やカラムピン留め機能と併用する可能性のある他のカラムAPIのほんの一例です。 + +### カラムオブジェクト + +カラムオブジェクトは、実際にはテーブルUIを直接レンダリングするためのものではないため、テーブルの `
` または `` 要素と1対1で関連付けられていません。しかし、テーブルの状態を操作するために使用できる多くの便利なプロパティとメソッドが含まれています。 + +#### カラムID + +すべてのカラムには、関連する[カラム定義](../guide/column-defs)で定義された一意の `id` が必要です。通常、この `id` は自分で定義するか、カラム定義の `accessorKey` または `header` プロパティから派生します。 + +#### ColumnDef + +カラムの作成に使用された元の `columnDef` オブジェクトへの参照は、常にカラムオブジェクトで利用可能です。 + +#### ネストされたグループ化カラムのプロパティ + +`column` オブジェクトには、カラムがネストまたはグループ化されたカラム構造の一部である場合にのみ有用ないくつかのプロパティがあります。これらのプロパティには以下が含まれます: + +- `columns`: グループカラムに属する子カラムの配列。 +- `depth`: カラムグループが属するヘッダーグループの「行インデックス」。 +- `parent`: カラムの親カラム。カラムがトップレベルの場合、これは `undefined` になります。 + +### その他のカラムAPI + +テーブルの状態を操作し、テーブルの状態に基づいてテーブルからセル値を抽出するために使用できる数十のカラムAPIがあります。詳細については、各機能のカラムAPIドキュメントを参照してください。 + +### カラムのレンダリング + +必ずしも `column` オブジェクトを使用して `headers` や `cells` を直接レンダリングしないでください。代わりに、上で説明したように[`header`](../guide/headers) および [`cell`](../guide/cells) オブジェクトを使用してください。 + +ただし、カラム可視性メニューのようなUIの他の部分でカラムのリストをレンダリングするだけの場合は、カラムの配列をマッピングして通常どおりUIをレンダリングできます。 diff --git a/docs/ja/guide/custom-features.md b/docs/ja/guide/custom-features.md new file mode 100644 index 0000000000..4c646ebd80 --- /dev/null +++ b/docs/ja/guide/custom-features.md @@ -0,0 +1,262 @@ +--- +source-updated-at: '2025-03-20T21:15:29.000Z' +translation-updated-at: '2025-05-05T19:29:28.276Z' +title: カスタム機能 +--- +```markdown +## サンプル + +実装に直接進みたいですか?以下のサンプルをチェックしてください: + +- [custom-features](../framework/react/examples/custom-features) + +## カスタム機能ガイド + +このガイドでは、TanStack Tableをカスタム機能で拡張する方法を説明します。その過程で、TanStack Table v8のコードベースの構造や動作についても詳しく学びます。 + +### TanStack Tableは軽量であることを目指す + +TanStack Tableには、ソート、フィルタリング、ページネーションなど、ライブラリに組み込まれたコア機能セットがあります。多くのリクエストや、時にはよく考えられたPRが、さらに多くの機能をライブラリに追加するために寄せられます。ライブラリの改善には常にオープンですが、TanStack Tableがほとんどのユースケースで使用されないような肥大化やコードを含まない、軽量なライブラリであり続けることも重要です。すべてのPRがコアライブラリに受け入れられるわけではなく、また受け入れるべきでもありません。たとえそれが実際の問題を解決するものであってもです。これは、TanStack Tableがユースケースの90%を解決するが、もう少し制御が必要な開発者にとってはフラストレーションの原因になるかもしれません。 + +TanStack Tableは、少なくともv7以降、高度に拡張可能な方法で構築されています。使用しているフレームワークアダプター(`useReactTable`、`useVueTable`など)から返される`table`インスタンスは、追加のプロパティやAPIを追加できるプレーンなJavaScriptオブジェクトです。コンポジションを使用して、テーブルインスタンスにカスタムロジック、状態、APIを追加することは常に可能でした。[Material React Table](https://github.com/KevinVandy/material-react-table/blob/v2/packages/material-react-table/src/hooks/useMRT_TableInstance.ts)のようなライブラリは、単に`useReactTable`フックの周りにカスタムラッパーフックを作成し、テーブルインスタンスをカスタム機能で拡張しています。 + +しかし、バージョン8.14.0から、TanStack Tableは新しい`_features`テーブルオプションを公開し、組み込みのテーブル機能とまったく同じ方法でカスタムコードをテーブルインスタンスに統合できるようにしました。 + +> TanStack Table v8.14.0では、テーブルインスタンスにカスタム機能を追加できる新しい`_features`オプションが導入されました。 + +この新しい統合により、より複雑なカスタム機能をテーブルに簡単に追加でき、コミュニティと共有することも可能になります。今後の展開を見守りましょう。将来的なv9リリースでは、すべての機能をオプトインにすることでTanStack Tableのバンドルサイズをさらに削減するかもしれませんが、これはまだ検討中です。 + +### TanStack Tableの機能の動作 + +TanStack Tableのソースコードは、ある意味シンプルです(少なくとも私たちはそう考えています)。各機能のコードは、初期状態、デフォルトのテーブルおよびカラムオプション、`table`、`header`、`column`、`row`、`cell`インスタンスに追加できるAPIメソッドを持つ独自のオブジェクト/ファイルに分割されています。 + +機能オブジェクトのすべての機能は、TanStack Tableからエクスポートされる`TableFeature`型で記述できます。この型は、機能を作成するために必要な機能オブジェクトの形状を記述するTypeScriptインターフェースです。 + +```ts +export interface TableFeature { + createCell?: ( + cell: Cell, + column: Column, + row: Row, + table: Table + ) => void + createColumn?: (column: Column, table: Table) => void + createHeader?: (header: Header, table: Table) => void + createRow?: (row: Row, table: Table) => void + createTable?: (table: Table) => void + getDefaultColumnDef?: () => Partial> + getDefaultOptions?: ( + table: Table + ) => Partial> + getInitialState?: (initialState?: InitialTableState) => Partial +} +``` + +少し混乱するかもしれませんので、これらのメソッドのそれぞれが何をするのかを分解してみましょう: + +#### デフォルトオプションと初期状態 + +
+ +##### getDefaultOptions + +テーブル機能の`getDefaultOptions`メソッドは、その機能のデフォルトテーブルオプションを設定する責任があります。例えば、[Column Sizing](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/ColumnSizing.ts)機能では、`getDefaultOptions`メソッドがデフォルトの`columnResizeMode`オプションを`"onEnd"`というデフォルト値で設定します。 + +
+ +##### getDefaultColumnDef + +テーブル機能の`getDefaultColumnDef`メソッドは、その機能のデフォルトカラムオプションを設定する責任があります。例えば、[Sorting](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/RowSorting.ts)機能では、`getDefaultColumnDef`メソッドがデフォルトの`sortUndefined`カラムオプションを`1`というデフォルト値で設定します。 + +
+ +##### getInitialState + +テーブル機能の`getInitialState`メソッドは、その機能のデフォルト状態を設定する責任があります。例えば、[Pagination](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/RowPagination.ts)機能では、`getInitialState`メソッドがデフォルトの`pageSize`状態を`10`、`pageIndex`状態を`0`に設定します。 + +#### APIクリエーター + +
+ +##### createTable + +テーブル機能の`createTable`メソッドは、`table`インスタンスにメソッドを追加する責任があります。例えば、[Row Selection](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/RowSelection.ts)機能では、`createTable`メソッドが`toggleAllRowsSelected`、`getIsAllRowsSelected`、`getIsSomeRowsSelected`などの多くのテーブルインスタンスAPIメソッドを追加します。したがって、`table.toggleAllRowsSelected()`を呼び出すとき、`RowSelection`機能によってテーブルインスタンスに追加されたメソッドを呼び出しています。 + +
+ +##### createHeader + +テーブル機能の`createHeader`メソッドは、`header`インスタンスにメソッドを追加する責任があります。例えば、[Column Sizing](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/ColumnSizing.ts)機能では、`createHeader`メソッドが`getStart`などの多くのヘッダーインスタンスAPIメソッドを追加します。したがって、`header.getStart()`を呼び出すとき、`ColumnSizing`機能によってヘッダーインスタンスに追加されたメソッドを呼び出しています。 + +
+ +##### createColumn + +テーブル機能の`createColumn`メソッドは、`column`インスタンスにメソッドを追加する責任があります。例えば、[Sorting](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/RowSorting.ts)機能では、`createColumn`メソッドが`getNextSortingOrder`、`toggleSorting`などの多くのカラムインスタンスAPIメソッドを追加します。したがって、`column.toggleSorting()`を呼び出すとき、`RowSorting`機能によってカラムインスタンスに追加されたメソッドを呼び出しています。 + +
+ +##### createRow + +テーブル機能の`createRow`メソッドは、`row`インスタンスにメソッドを追加する責任があります。例えば、[Row Selection](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/RowSelection.ts)機能では、`createRow`メソッドが`toggleSelected`、`getIsSelected`などの多くの行インスタンスAPIメソッドを追加します。したがって、`row.toggleSelected()`を呼び出すとき、`RowSelection`機能によって行インスタンスに追加されたメソッドを呼び出しています。 + +
+ +##### createCell + +テーブル機能の`createCell`メソッドは、`cell`インスタンスにメソッドを追加する責任があります。例えば、[Column Grouping](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/ColumnGrouping.ts)機能では、`createCell`メソッドが`getIsGrouped`、`getIsAggregated`などの多くのセルインスタンスAPIメソッドを追加します。したがって、`cell.getIsGrouped()`を呼び出すとき、`ColumnGrouping`機能によってセルインスタンスに追加されたメソッドを呼び出しています。 + +### カスタム機能の追加 + +仮想的なユースケースのためにカスタムテーブル機能を作成する手順を見ていきましょう。ユーザーがテーブルの「密度」(セルのパディング)を変更できる機能をテーブルインスタンスに追加したいとします。 + +完全な実装については、[custom-features](../framework/react/examples/custom-features)サンプルを確認してください。ここでは、カスタム機能を作成する手順を詳しく見ていきます。 + +#### ステップ1:TypeScriptの型を設定 + +TanStack Tableの組み込み機能と同じ完全な型安全性が必要な場合、新しい機能のためのTypeScriptの型をすべて設定しましょう。新しいテーブルオプション、状態、テーブルインスタンスAPIメソッドの型を作成します。 + +これらの型はTanStack Table内部で使用されている命名規則に従っていますが、好きな名前を付けることができます。これらの型をTanStack Tableにまだ追加していませんが、次のステップで行います。 + +```ts +// 新しい機能のカスタム状態の型を定義 +export type DensityState = 'sm' | 'md' | 'lg' +export interface DensityTableState { + density: DensityState +} + +// 新しい機能のテーブルオプションの型を定義 +export interface DensityOptions { + enableDensity?: boolean + onDensityChange?: OnChangeFn +} + +// 新しい機能のテーブルAPIの型を定義 +export interface DensityInstance { + setDensity: (updater: Updater) => void + toggleDensity: (value?: DensityState) => void +} +``` + +#### ステップ2:宣言マージを使用して新しい型をTanStack Tableに追加 + +TypeScriptに、TanStack Tableからエクスポートされる型を変更して、新しい機能の型を含めるように指示できます。これは「宣言マージ」と呼ばれ、TypeScriptの強力な機能です。これにより、新しい機能のコードやアプリケーションコードで`as unknown as CustomTable`や`// @ts-ignore`のようなTypeScriptのハックを使用する必要がなくなります。 + +```ts +// 宣言マージを使用して、新しい機能のAPIと状態の型をTanStack Tableの既存の型に追加 +declare module '@tanstack/react-table' { // または使用しているフレームワークアダプター + // 新しい機能の状態を既存のテーブル状態にマージ + interface TableState extends DensityTableState {} + // 新しい機能のオプションを既存のテーブルオプションにマージ + interface TableOptionsResolved + extends DensityOptions {} + // 新しい機能のインスタンスAPIを既存のテーブルインスタンスAPIにマージ + interface Table extends DensityInstance {} + // セルインスタンスAPIを追加する必要がある場合... + // interface Cell extends DensityCell + // 行インスタンスAPIを追加する必要がある場合... + // interface Row extends DensityRow + // カラムインスタンスAPIを追加する必要がある場合... + // interface Column extends DensityColumn + // ヘッダーインスタンスAPIを追加する必要がある場合... + // interface Header extends DensityHeader + + // 注:`ColumnDef`に対する宣言マージは、複雑な型でありインターフェースではないため不可能です。 + // ただし、`ColumnDef.meta`に対しては宣言マージを使用できます。 +} +``` + +これを正しく行えば、新しい機能のコードを作成し、アプリケーションで使用しようとするときにTypeScriptエラーが発生しなくなります。 + +##### 宣言マージの注意点 + +宣言マージの注意点の1つは、コードベース内のすべてのテーブルのTanStack Tableの型に影響を与えることです。アプリケーション内のすべてのテーブルに同じ機能セットをロードする予定であれば問題ありませんが、一部のテーブルが追加機能をロードし、一部がロードしない場合は問題になる可能性があります。あるいは、TanStack Tableの型を拡張して新しい機能を追加したカスタム型をたくさん作ることもできます。これは、[Material React Table](https://github.com/KevinVandy/material-react-table/blob/v2/packages/material-react-table/src/types.ts)が、通常のTanStack Tableテーブルの型に影響を与えないようにするために行っている方法ですが、少し面倒で、特定の時点で多くの型キャストが必要になります。 + +#### ステップ3:機能オブジェクトを作成 + +すべてのTypeScriptの設定が完了したら、新しい機能の機能オブジェクトを作成できます。ここで、テーブルインスタンスに追加されるすべてのメソッドを定義します。 + +`TableFeature`型を使用して、機能オブジェクトを正しく作成していることを確認します。TypeScriptの型が正しく設定されていれば、新しい状態、オプション、インスタンスAPIで機能オブジェクトを作成するときにTypeScriptエラーが発生しません。 + +```ts +export const DensityFeature: TableFeature = { // TableFeature型を使用!! + // 新しい機能の初期状態を定義 + getInitialState: (state): DensityTableState => { + return { + density: 'md', + ...state, + } + }, + + // 新しい機能のデフォルトオプションを定義 + getDefaultOptions: ( + table: Table + ): DensityOptions => { + return { + enableDensity: true, + onDensityChange: makeStateUpdater('density', table), + } as DensityOptions + }, + // デフォルトのカラム定義を追加する必要がある場合... + // getDefaultColumnDef: (): Partial> => { + // return { meta: {} } // カラムDefに直接追加する代わりにmetaを使用して、回避が難しいTypeScriptの問題を避ける + // }, + + // 新しい機能のテーブルインスタンスメソッドを定義 + createTable: (table: Table): void => { + table.setDensity = updater => { + const safeUpdater: Updater = old => { + let newState = functionalUpdate(updater, old) + return newState + } + return table.options.onDensityChange?.(safeUpdater) + } + table.toggleDensity = value => { + table.setDensity(old => { + if (value) return value + return old === 'lg' ? 'md' : old === 'md' ? 'sm' : 'lg' // 3つのオプションを循環 + }) + } + }, + + // 行インスタンスAPIを追加する必要がある場合... + // createRow: (row, table): void => {}, + // セルインスタンスAPIを追加する必要がある場合... + // createCell: (cell, column, row, table): void => {}, + // カラムインスタンスAPIを追加する必要がある場合... + // createColumn: (column, table): void => {}, + // ヘッダーインスタンスAPIを追加する必要がある場合... + // createHeader: (header, table): void => {}, +} +``` + +#### ステップ4:機能をテーブルに追加 + +機能オブジェクトができたので、テーブルインスタンスを作成するときに`_features`オプションに渡すことで、テーブルインスタンスに追加できます。 + +```ts +const table = useReactTable({ + _features: [DensityFeature], // 新しい機能を組み込み機能とマージして渡す + columns, + data, + //.. +}) +``` + +#### ステップ5:アプリケーションで機能を使用 + +機能がテーブルインスタンスに追加されたので、アプリケーションで新しいインスタンスAPI、オプション、状態を使用できます。 + +```tsx +const table = useReactTable({ + _features: [DensityFeature], // テーブル作成時にインスタンス化するためにカスタム機能を渡す + columns, + data, + //... + state: { + density, // 密度状態をテーブルに渡す、TSはまだ満足 :) + }, + onDensityChange: setDensity, // 新しいonDensityChangeオプションを使用、TSはまだ満足 :) +}) +//... +const { density } = table diff --git a/docs/ja/guide/data.md b/docs/ja/guide/data.md new file mode 100644 index 0000000000..6b3487c193 --- /dev/null +++ b/docs/ja/guide/data.md @@ -0,0 +1,251 @@ +--- +source-updated-at: '2025-03-20T21:15:29.000Z' +translation-updated-at: '2025-05-05T19:25:22.255Z' +title: データ +--- +## データガイド + +テーブルはデータから始まります。列定義と行はデータの形状に依存します。TanStack TableにはTypeScriptの機能があり、タイプセーフな体験を提供しながらテーブルコードを作成するのに役立ちます。データと型を正しく設定すれば、TanStack Tableはデータの形状を推論し、列定義が正しく作成されるように強制できます。 + +### TypeScript + +TanStack Tableパッケージを使用するためにTypeScriptは必須ではありません... ***しかし***、TanStack TableはTypeScriptの優れた体験をライブラリの主な売りの1つとして感じられるように書かれ、構成されています。TypeScriptを使用していない場合、開発時間を短縮し、コードのバグを減らす多くの優れたオートコンプリートや型チェック機能を逃すことになります。 + +#### TypeScriptジェネリクス + +TypeScriptジェネリクスが何であり、どのように機能するかを基本的に理解していると、このガイドをよりよく理解するのに役立ちますが、進めながら簡単に習得できるはずです。公式の[TypeScriptジェネリクスドキュメント](https://www.typescriptlang.org/docs/handbook/2/generics.html)は、TypeScriptにまだ慣れていない人にとって役立つかもしれません。 + +### データ型の定義 + +`data`はテーブルの行に変換されるオブジェクトの配列です。配列内の各オブジェクトは(通常の状況では)データの行を表します。TypeScriptを使用している場合、通常はデータの形状に対して型を定義します。この型は、他のすべてのテーブル、列、行、セルインスタンスのジェネリック型として使用されます。このジェネリックは、TanStack Tableの型とAPI全体で通常`TData`と呼ばれます。 + +例えば、次のようなユーザーのリストを表示するテーブルがある場合: + +```json +[ + { + "firstName": "Tanner", + "lastName": "Linsley", + "age": 33, + "visits": 100, + "progress": 50, + "status": "Married" + }, + { + "firstName": "Kevin", + "lastName": "Vandy", + "age": 27, + "visits": 200, + "progress": 100, + "status": "Single" + } +] +``` + +次のようにUser(TData)型を定義できます: + +```ts +//TData +type User = { + firstName: string + lastName: string + age: number + visits: number + progress: number + status: string +} +``` + +この型で`data`配列を定義すると、TanStack Tableは後で列、行、セルなどで多くの型をインテリジェントに推論できるようになります。これは`data`型が文字通り`TData`ジェネリック型として定義されているためです。`data`テーブルオプションに渡すものは、テーブルインスタンスの残りの部分の`TData`型になります。後で列定義を行う際に、`data`型と同じ`TData`型を使用するようにしてください。 + +```ts +//注: 無限再レンダリングを防ぐため、dataは「安定した」参照が必要 +const data: User[] = [] +//または +const [data, setData] = React.useState([]) +//または +const data = ref([]) //vue +//など... +``` + +#### 深いキーを持つデータ + +データがフラットなオブジェクトの配列でなくても問題ありません!列を定義する際に、アクセサーで深くネストされたデータにアクセスするための戦略があります。 + +`data`が次のような場合: + +```json +[ + { + "name": { + "first": "Tanner", + "last": "Linsley" + }, + "info": { + "age": 33, + "visits": 100, + } + }, + { + "name": { + "first": "Kevin", + "last": "Vandy" + }, + "info": { + "age": 27, + "visits": 200, + } + } +] +``` + +次のように型を定義できます: + +```ts +type User = { + name: { + first: string + last: string + } + info: { + age: number + visits: number + } +} +``` + +そして、列定義で`accessorKey`のドット表記または`accessorFn`を使用してデータにアクセスできます。 + +```ts +const columns = [ + { + header: 'First Name', + accessorKey: 'name.first', + }, + { + header: 'Last Name', + accessorKey: 'name.last', + }, + { + header: 'Age', + accessorFn: row => row.info.age, + }, + //... +] +``` + +これについての詳細は[列定義ガイド](../guide/column-defs)で説明されています。 + +> 注: jsonデータの「キー」は通常何でも構いませんが、キーにピリオドが含まれている場合、深いキーとして解釈され、エラーが発生する可能性があります。 + +#### ネストされたサブ行データ + +展開機能を使用している場合、データにネストされたサブ行があることが一般的です。これにより、少し異なる再帰型が生じます。 + +データが次のような場合: + +```json +[ + { + "firstName": "Tanner", + "lastName": "Linsley", + "subRows": [ + { + "firstName": "Kevin", + "lastName": "Vandy", + }, + { + "firstName": "John", + "lastName": "Doe", + "subRows": [ + //... + ] + } + ] + }, + { + "firstName": "Jane", + "lastName": "Doe", + } +] +``` + +次のように型を定義できます: + +```ts +type User = { + firstName: string + lastName: string + subRows?: User[] //「subRows」という名前でなくてもよい、任意の名前を付けられる +} +``` + +ここで`subRows`は`User`オブジェクトのオプションの配列です。これについての詳細は[展開ガイド](../guide/expanding)で説明されています。 + +### データに「安定した」参照を与える + +テーブルインスタンスに渡す`data`配列は、無限再レンダリング(特にReactで)を引き起こすバグを防ぐために***必ず***「安定した」参照を持っている必要があります。 + +これは使用するフレームワークアダプターによって異なりますが、Reactでは`React.useState`、`React.useMemo`、または類似の方法を使用して、`data`と`columns`テーブルオプションの両方が安定した参照を持つようにする必要があります。 + +```tsx +const fallbackData = [] + +export default function MyComponent() { + //✅ 良い: `columns`は安定した参照なので、無限再レンダリングループを引き起こさない + const columns = useMemo(() => [ + // ... + ], []); + + //✅ 良い: `data`は安定した参照なので、無限再レンダリングループを引き起こさない + const [data, setData] = useState(() => [ + // ... + ]); + + // 列とデータは安定した参照で定義されているため、無限ループを引き起こさない! + const table = useReactTable({ + columns, + data ?? fallbackData, //コンポーネントの外で定義されたフォールバック配列を使用するのも良い(安定した参照) + }); + + return ...
; +} +``` + +`React.useState`と`React.useMemo`だけがデータに安定した参照を与える方法ではありません。コンポーネントの外でデータを定義したり、Redux、Zustand、TanStack Queryなどのサードパーティの状態管理ライブラリを使用することもできます。 + +主に避けるべきは、`useReactTable`呼び出しと同じスコープ内で`data`配列を定義することです。これにより、`data`配列が毎回のレンダリングで再定義され、無限再レンダリングループが発生します。 + +```tsx +export default function MyComponent() { + //😵 悪い: `columns`が毎回のレンダリングで新しい配列として再定義されるため、無限再レンダリングループを引き起こす! + const columns = [ + // ... + ]; + + //😵 悪い: `data`が毎回のレンダリングで新しい配列として再定義されるため、無限再レンダリングループを引き起こす! + const data = [ + // ... + ]; + + //❌ 列とデータが安定した参照なしで`useReactTable`と同じスコープ内で定義されているため、無限ループを引き起こす! + const table = useReactTable({ + columns, + data ?? [], //❌ フォールバック配列が毎回のレンダリングで再作成されるため、これも悪い + }); + + return ...
; +} +``` + +### TanStack Tableがデータを変換する方法 + +これらのドキュメントの他の部分では、TanStack Tableがテーブルに渡した`data`を処理し、テーブルを作成するために使用される行とセルオブジェクトを生成する方法を見ていきます。テーブルに渡す`data`はTanStack Tableによって変更されることはありませんが、行とセルの実際の値は、列定義のアクセサーや[行モデル](../guide/row-models)によるグループ化や集計などの他の機能によって変換される場合があります。 + +### TanStack Tableが処理できるデータ量 + +信じられないかもしれませんが、TanStack Tableは実際にクライアント側で数十万行のデータを処理できるように構築されています。これは各列のデータのサイズや列数によって常に可能というわけではありませんが、ソート、フィルタリング、ページネーション、グループ化機能はすべて大規模なデータセットを考慮してパフォーマンスを意識して構築されています。 + +データグリッドを構築する開発者のデフォルトの考え方は、大規模なデータセットに対してサーバーサイドのページネーション、ソート、フィルタリングを実装することです。これはまだ通常良いアイデアですが、多くの開発者は現代のブラウザと適切な最適化があれば、実際にクライアント側で処理できるデータ量を過小評価しています。テーブルが数千行を超えることがない場合、サーバー側で自分で実装する代わりに、TanStack Tableのクライアント側機能を利用できる可能性があります。もちろん、TanStack Tableのクライアント側機能に大規模なデータセットを処理させる前に、実際のデータでテストして、ニーズに十分なパフォーマンスが得られるか確認する必要があります。 + +これについての詳細は[ページネーションガイド](../guide/pagination#should-you-use-client-side-pagination)で説明されています。 diff --git a/docs/ja/guide/expanding.md b/docs/ja/guide/expanding.md new file mode 100644 index 0000000000..e764303e09 --- /dev/null +++ b/docs/ja/guide/expanding.md @@ -0,0 +1,230 @@ +--- +source-updated-at: '2025-03-20T21:15:29.000Z' +translation-updated-at: '2025-05-05T19:27:55.773Z' +title: 展開 +--- +## サンプル + +実装の詳細を確認したいですか?以下のサンプルを参照してください: + +- [展開 (expanding)](../framework/react/examples/expanding) +- [グループ化 (grouping)](../framework/react/examples/grouping) +- [サブコンポーネント (sub-components)](../framework/react/examples/sub-components) + +## API + +[展開 API (Expanding API)](../api/features/expanding) + +## 展開機能ガイド + +展開機能は、特定の行に関連する追加のデータ行を表示または非表示にする機能です。階層構造を持つデータがあり、ユーザーが上位レベルからデータを掘り下げられるようにしたい場合や、行に関連する追加情報を表示したい場合に便利です。 + +### 展開機能のさまざまなユースケース + +TanStack Tableにおける展開機能には、以下のような複数のユースケースがあります。 + +1. サブ行の展開(子行、集計行など) +2. カスタムUIの展開(詳細パネル、サブテーブルなど) + +### クライアントサイド展開の有効化 + +クライアントサイドの展開機能を使用するには、テーブルオプションで`getExpandedRowModel`関数を定義する必要があります。この関数は、展開された行モデルを返す役割を担います。 + +```ts +const table = useReactTable({ + // 他のオプション... + getExpandedRowModel: getExpandedRowModel(), +}) +``` + +展開データには、テーブル行または表示したい任意のデータを含めることができます。このガイドでは、両方のケースの扱い方について説明します。 + +### 展開データとしてのテーブル行 + +展開行は基本的に親行と同じ列構造を継承する子行です。データオブジェクトに既にこれらの展開行データが含まれている場合、`getSubRows`関数を使用してこれらの子行を指定できます。データオブジェクトに展開行データが含まれていない場合、それらはカスタム展開データとして扱うことができます(次のセクションで説明します)。 + +例えば、以下のようなデータオブジェクトがある場合: + +```ts +type Person = { + id: number + name: string + age: number + children?: Person[] | undefined +} + +const data: Person[] = [ + { id: 1, + name: 'John', + age: 30, + children: [ + { id: 2, name: 'Jane', age: 5 }, + { id: 5, name: 'Jim', age: 10 } + ] + }, + { id: 3, + name: 'Doe', + age: 40, + children: [ + { id: 4, name: 'Alice', age: 10 } + ] + }, +] +``` + +`getSubRows`関数を使用して、各行の`children`配列を展開行として返すことができます。これにより、テーブルインスタンスは各行のサブ行をどこで探すべきかを理解します。 + +```ts +const table = useReactTable({ + // 他のオプション... + getSubRows: (row) => row.children, // children配列をサブ行として返す + getCoreRowModel: getCoreRowModel(), + getExpandedRowModel: getExpandedRowModel(), +}) +``` + +> **注意:** 複雑な`getSubRows`関数を定義することもできますが、この関数はすべての行とサブ行に対して実行されるため、最適化されていないとパフォーマンスに影響を与える可能性があります。非同期関数はサポートされていません。 + +### カスタム展開UI + +場合によっては、テーブルデータオブジェクトの一部であるかどうかにかかわらず、行の展開データなど、追加の詳細や情報を表示したいことがあります。この種の展開行UIは、「展開可能な行 (expandable rows)」、「詳細パネル (detail panels)」、「サブコンポーネント (sub-components)」など、さまざまな名前で呼ばれてきました。 + +デフォルトでは、`row.getCanExpand()`行インスタンスAPIは、行に`subRows`が見つからない限りfalseを返します。これは、テーブルインスタンスオプションで独自の`getRowCanExpand`関数を実装することで上書きできます。 + +```ts +//... +const table = useReactTable({ + // 他のオプション... + getRowCanExpand: (row) => true, // 行が展開可能かどうかを決定するロジックを追加。trueはすべての行に展開データが含まれることを意味します + getCoreRowModel: getCoreRowModel(), + getExpandedRowModel: getExpandedRowModel(), +}) +//... +
+ +
// 親行と同じ列を共有しない展開データの場合にスパンする列の数 + // カスタムUIをここに配置 +
+ {/* */} +
+ {/* */} +
`または類似のセル要素に関連付けることができます。`header`オブジェクトには、テーブルの状態とやり取りしたり、テーブルの状態に基づいてセル値を抽出したりするために使用できるいくつかのプロパティとメソッドがあります。 + +#### ヘッダーID + +各ヘッダーオブジェクトには、テーブルインスタンス内で一意の`id`プロパティがあります。通常、この`id`はReactのキーとしての一意識別子、または[パフォーマンスの良いカラムリサイズ例](../framework/react/examples/column-resizing-performant)に従う場合にのみ必要です。 + +高度なネストやグループ化されたヘッダーロジックがない単純なヘッダーの場合、`header.id`は親の`column.id`と同じになります。ただし、ヘッダーがグループカラムまたはプレースホルダーセルの一部である場合、ヘッダーファミリー、深さ/ヘッダー行インデックス、カラムID、ヘッダーグループIDから構築されたより複雑なIDになります。 + +#### ネストされたグループヘッダーのプロパティ + +ヘッダーがネストまたはグループ化されたヘッダー構造の一部である場合にのみ有用ないくつかのプロパティが`header`オブジェクトにあります。これらのプロパティには以下が含まれます: + +- `colspan`: ヘッダーがまたがるべきカラム数。``要素の`colSpan`属性をレンダリングする際に便利です。 +- `rowSpan`: ヘッダーがまたがるべき行数。``要素の`rowSpan`属性をレンダリングする際に便利です(現在、デフォルトのTanStack Tableでは実装されていません)。 +- `depth`: ヘッダーグループが属する「行インデックス」。 +- `isPlaceholder`: ヘッダーがプレースホルダーヘッダーである場合にtrueとなるブールフラグ。プレースホルダーヘッダーは、カラムが非表示の場合やグループカラムの一部である場合の隙間を埋めるために使用されます。 +- `placeholderId`: プレースホルダーヘッダーの一意識別子。 +- `subHeaders`: このヘッダーに属するサブ/子ヘッダーの配列。ヘッダーがリーフヘッダーの場合は空になります。 + +> 注: `header.index`はヘッダーグループ(ヘッダーの行)内でのインデックス、つまり左から右への位置を指します。ヘッダーグループの「行インデックス」を指す`header.depth`とは異なります。 + +#### ヘッダーの親オブジェクト + +各ヘッダーは、その親[column](../guide/columns)オブジェクトと親[header group](../guide/header-groups)オブジェクトへの参照を保持しています。 + +### その他のヘッダーAPI + +ヘッダーには、テーブルの状態とやり取りするのに便利なAPIがいくつか追加されています。そのほとんどはカラムサイズ変更機能に関連しています。詳細は[Column Sizing Guide](../guide/column-sizing)を参照してください。 + +### ヘッダーのレンダリング + +定義した`header`カラムオプションは文字列、JSX、またはそれらを返す関数のいずれかであるため、ヘッダーをレンダリングする最良の方法は、アダプターから`flexRender`ユーティリティを使用することです。これにより、すべてのケースが処理されます。 + +```jsx +{headerGroup.headers.map(header => ( + + {/* `header`のすべての可能なカラム定義シナリオを処理 */} + {flexRender(header.column.columnDef.header, header.getContext())} + {cell.render('Header')} // [!code ++] ++ {flexRender( // [!code ++] ++ header.column.columnDef.header, // [!code ++] ++ header.getContext() // [!code ++] ++ )} // [!code ++] ++ {cell.render('Cell')} // [!code ++] ++ {flexRender( // [!code ++] ++ cell.column.columnDef.cell, // [!code ++] ++ cell.getContext() // [!code ++] ++ )} // [!code ++] ++
{/* */}
`要素を指しているのではありません。代わりに、テーブルの状態とAPIを含むコアテーブルオブジェクトを指しています。`table`インスタンスは、アダプターの`createTable`関数(例:`useReactTable`、`useVueTable`、`createSolidTable`、`createSvelteTable`、`createAngularTable`、`useQwikTable`)を呼び出すことで作成されます。 + +フレームワークアダプターから返される`table`インスタンスは、テーブルの状態を読み取り、変更するためにやり取りする主要なオブジェクトです。TanStack Tableではすべてがこの`table`インスタンスを中心に行われます。UIをレンダリングする段階では、この`table`インスタンスのAPIを使用します。 + +### テーブルインスタンスの作成 + +テーブルインスタンスを作成するには、3つの`options`が必要です:`columns`、`data`、および`getCoreRowModel`の実装です。他にも多くのテーブルオプションがありますが、これら3つは必須です。 + +#### データの定義 + +データは安定した参照を持つオブジェクトの配列として定義します。`data`はAPIレスポンスやコード内で静的に定義されたものなど、どこからでも取得できますが、無限再レンダリングを防ぐために安定した参照を持つ必要があります。TypeScriptを使用する場合、データに与える型は`TData`ジェネリックとして使用されます。詳細は[データガイド](../guide/data)を参照してください。 + +#### カラムの定義 + +カラム定義については、前のセクションの[カラム定義ガイド](../guide/column-defs)で詳しく説明しています。ただし、カラムの型を定義する際には、データに使用したのと同じ`TData`型を使用する必要があることに注意してください。 + +```ts +const columns: ColumnDef[] = [] //User型をジェネリックTData型として渡す +//または +const columnHelper = createColumnHelper() //User型をジェネリックTData型として渡す +``` + +カラム定義では、`accessorKey`または`accessorFn`を使用して、各カラムが行データにどのようにアクセスまたは変換するかをTanStack Tableに指示します。詳細は[カラム定義ガイド](../guide/column-defs#creating-accessor-columns)を参照してください。 + +#### 行モデルの指定 + +これについては[行モデルガイド](../guide/row-models)で詳しく説明されていますが、ここではTanStack Tableから`getCoreRowModel`関数をインポートし、テーブルオプションとして渡すだけです。使用予定の機能によっては、後で追加の行モデルを渡す必要がある場合があります。 + +```ts +import { getCoreRowModel } from '@tanstack/[framework]-table' + +const table = createTable({ columns, data, getCoreRowModel: getCoreRowModel() }) +``` + +#### テーブルインスタンスの初期化 + +`columns`、`data`、`getCoreRowModel`を定義したら、他のテーブルオプションと共に基本的なテーブルインスタンスを作成できます。 + +```ts +//vanilla js +const table = createTable({ columns, data, getCoreRowModel: getCoreRowModel() }) + +//angular +this.table = createAngularTable({ columns: this.columns, data: this.data(), getCoreRowModel: getCoreRowModel() }) + +//lit +const table = this.tableController.table({ columns, data, getCoreRowModel: getCoreRowModel() }) + +//qwik +const table = useQwikTable({ columns, data, getCoreRowModel: getCoreRowModel() }) + +//react +const table = useReactTable({ columns, data, getCoreRowModel: getCoreRowModel() }) + +//solid +const table = createSolidTable({ columns, get data() { return data() }, getCoreRowModel: getCoreRowModel() }) + +//svelte +const table = createSvelteTable({ columns, data, getCoreRowModel: getCoreRowModel() }) + +//vue +const table = useVueTable({ columns, data, getCoreRowModel: getCoreRowModel() }) +``` + +では、`table`インスタンスには何が含まれているのでしょうか?テーブルインスタンスとのインタラクションを見てみましょう。 + +### テーブルの状態 + +テーブルインスタンスにはすべてのテーブルの状態が含まれており、`table.getState()` APIを通じてアクセスできます。各テーブル機能は、テーブルの状態にさまざまな状態を登録します。例えば、行選択機能は`rowSelection`状態を、ページネーション機能は`pagination`状態を登録します。 + +各機能には、テーブルインスタンス上に対応する状態設定APIと状態リセットAPIもあります。例えば、行選択機能には`setRowSelection` APIと`resetRowSelection`があります。 + +```ts +table.getState().rowSelection //行選択状態を読み取る +table.setRowSelection((old) => ({...old})) //行選択状態を設定する +table.resetRowSelection() //行選択状態をリセットする +``` + +詳細は[テーブル状態ガイド](../framework/react/guide/table-state)で説明されています。 + +### テーブルAPI + +各機能によって作成された数十のテーブルAPIがあり、さまざまな方法でテーブルの状態を読み取ったり変更したりするのに役立ちます。 + +コアテーブルインスタンスおよび他のすべての機能APIのAPIリファレンスドキュメントは、APIドキュメント全体に記載されています。 + +例えば、コアテーブルインスタンスのAPIドキュメントはこちらで確認できます:[Table API](../api/core/table#table-api) + +### テーブル行モデル + +テーブルインスタンスから行を読み取るための特別なAPIセットがあり、行モデルと呼ばれます。TanStack Tableには、生成される行が最初に渡した`data`の配列と大きく異なる場合がある高度な機能があります。テーブルオプションとして渡せるさまざまな行モデルの詳細については、[行モデルガイド](../guide/row-models)を参照してください。 diff --git a/docs/ja/guide/virtualization.md b/docs/ja/guide/virtualization.md new file mode 100644 index 0000000000..1bc10c1fc4 --- /dev/null +++ b/docs/ja/guide/virtualization.md @@ -0,0 +1,21 @@ +--- +source-updated-at: '2025-03-20T21:15:29.000Z' +translation-updated-at: '2025-05-05T19:27:09.342Z' +title: 仮想化 +--- +## サンプル + +実装をすぐに確認したいですか?以下のサンプルをチェックしてください: + +- [仮想化された列 (virtualized-columns)](../framework/react/examples/virtualized-columns) +- [仮想化された行 (動的な行の高さ) (virtualized-rows (dynamic row height))](../framework/react/examples/virtualized-rows) +- [仮想化された行 (固定の行の高さ) (virtualized-rows (fixed row height))](../../../../virtual/v3/docs/framework/react/examples/table) +- [仮想化された無限スクロール (virtualized-infinite-scrolling)](../framework/react/examples/virtualized-infinite-scrolling) + +## API + +[TanStack Virtual Virtualizer API](../../../../virtual/v3/docs/api/virtualizer) + +## 仮想化ガイド + +TanStack Tableのパッケージには、仮想化APIや機能が組み込まれていませんが、TanStack Tableは[react-window](https://www.npmjs.com/package/react-window)やTanStack独自の[TanStack Virtual](https://tanstack.com/virtual/v3)などの他の仮想化ライブラリと簡単に連携できます。このガイドでは、TanStack TableとTanStack Virtualを併用するためのいくつかの戦略を紹介します。 diff --git a/docs/ja/installation.md b/docs/ja/installation.md new file mode 100644 index 0000000000..e5672ab19d --- /dev/null +++ b/docs/ja/installation.md @@ -0,0 +1,82 @@ +--- +source-updated-at: '2024-05-19T21:37:34.000Z' +translation-updated-at: '2025-05-05T19:23:57.032Z' +title: インストール +--- +APIの詳細に入る前に、まずはセットアップをしましょう! + +お気に入りのnpmパッケージマネージャーを使用して、テーブルアダプターを依存関係としてインストールします。 + +_以下のパッケージのうち、1つだけをインストールしてください:_ + +## React Table + +```bash +npm install @tanstack/react-table +``` + +`@tanstack/react-table`パッケージは、React 16.8、React 17、React 18、およびReact 19で動作します。 + +> 注意: ReactアダプターはReact 19で動作しますが、React 19と同時にリリースされる新しいReactコンパイラでは動作しない可能性があります。これは今後のTanStack Tableのアップデートで修正される予定です。 + +## Vue Table + +```bash +npm install @tanstack/vue-table +``` + +`@tanstack/vue-table`パッケージはVue 3で動作します。 + +## Solid Table + +```bash +npm install @tanstack/solid-table +``` + +`@tanstack/solid-table`パッケージはSolid-JS 1で動作します。 + +## Svelte Table + +```bash +npm install @tanstack/svelte-table +``` + +`@tanstack/svelte-table`パッケージはSvelte 3およびSvelte 4で動作します。 + +> 注意: 現時点ではSvelte 5用の組み込みアダプターはありませんが、`@tanstack/table-core`パッケージをインストールし、コミュニティ製のカスタムアダプターを使用することで、TanStack TableをSvelte 5で利用できます。この[PR](https://github.com/TanStack/table/pull/5403)を参考にしてください。 + +## Qwik Table + +```bash +npm install @tanstack/qwik-table +``` + +`@tanstack/qwik-table`パッケージはQwik 1で動作します。 + +> 注意: 近い将来、Qwik 2をサポートするための「破壊的変更」を含むリリースが予定されています。これはマイナーバージョンアップとしてリリースされますが、ドキュメントに記載されます。Qwik 2自体には破壊的変更はありませんが、npmレジストリ上の名前が変更され、異なるピア依存関係が必要になります。 + +> 注意: 現在のqwikアダプターはCSR(クライアントサイドレンダリング)のみに対応しています。さらなる改善は今後のテーブルバージョンまで利用できない可能性があります。 + +## Angular Table + +```bash +npm install @tanstack/angular-table +``` + +`@tanstack/angular-table`パッケージはAngular 17で動作します。Angularアダプターは新しいAngular Signal実装を使用しています。 + +## Lit Table + +```bash +npm install @tanstack/lit-table +``` + +`@tanstack/lit-table`パッケージはLit 3で動作します。 + +## Table Core (フレームワーク不要) + +```bash +npm install @tanstack/table-core +``` + +お気に入りのフレームワーク(またはフレームワークの特定バージョン)がリストにありませんか?`@tanstack/table-core`パッケージを使用して、独自のコードベースでアダプターを構築することもできます。通常、特定のフレームワーク向けに状態管理とレンダリングを処理するための薄いラッパーのみが必要です。他のすべてのアダプターの[ソースコード](https://github.com/TanStack/table/tree/main/packages)を参照して、その動作を確認してください。 diff --git a/docs/ja/introduction.md b/docs/ja/introduction.md new file mode 100644 index 0000000000..80a196150b --- /dev/null +++ b/docs/ja/introduction.md @@ -0,0 +1,70 @@ +--- +source-updated-at: '2024-03-22T01:02:38.000Z' +translation-updated-at: '2025-05-05T19:24:08.572Z' +title: イントロダクション +--- +TanStack Tableは、TS/JS、React、Vue、Solid、Qwik、Svelte向けの強力なテーブルとデータグリッドを構築するための**ヘッドレスUI (Headless UI)**ライブラリです。 + +## 「ヘッドレス」UIとは? + +**ヘッドレスUI (Headless UI)**とは、UI要素とインタラクションのためのロジック、状態管理、処理、APIを提供するが、**マークアップ、スタイル、または事前に構築された実装は提供しない**ライブラリやユーティリティを指す用語です。まだピンときていませんか?😉 ヘッドレスUIにはいくつかの主な目的があります: + +複雑なUI構築で最も難しい部分は、通常、状態管理、イベント処理、副作用、データの計算/管理に関わるものです。これらの懸念事項をマークアップ、スタイル、実装の詳細から切り離すことで、ロジックとコンポーネントをよりモジュール化し、再利用可能にすることができます。 + +UI構築は、デザインシステムを選択したりデザイン仕様に準拠したりする場合でも、非常にブランド化されたカスタム体験です。このカスタム体験をサポートするため、コンポーネントベースのUIライブラリは、マークアップとスタイルのカスタマイズに関して大規模(そして一見無限の)APIサーフェスをサポートする必要があります。ヘッドレスUIライブラリは、ロジックとUIを分離します。 + +ヘッドレスUIライブラリを使用すると、**データ処理、状態管理、ビジネスロジック**といった複雑なタスクはライブラリが処理するため、実装やユースケースごとに異なるより高次の意思決定に集中できます。 + +> さらに深く知りたいですか?[ヘッドレスUIについて詳しく読む](https://www.merrickchristensen.com/articles/headless-user-interface-components/)。 + +## コンポーネントベースライブラリ vs ヘッドレスライブラリ + +テーブル/データグリッドライブラリのエコシステムには、主に2つのカテゴリがあります: + +- コンポーネントベースのテーブルライブラリ +- ヘッドレステーブルライブラリ + +### どの種類のテーブルライブラリを使うべきか? + +それぞれのアプローチには微妙なトレードオフがあります。これらの微妙な違いを理解することで、アプリケーションとチームに適した判断ができるようになります。 + +### コンポーネントベースのテーブルライブラリ + +コンポーネントベースのテーブルライブラリは通常、機能豊富な即戦力ソリューションと、スタイル/テーマが組み込まれたすぐに使えるコンポーネント/マークアップを提供します。[AG Grid](https://ag-grid.com/react-data-grid/?utm_source=reacttable&utm_campaign=githubreacttable)はこのタイプのテーブルライブラリの良い例です。 + +**利点:** + +- すぐに使えるマークアップ/スタイルが付属 +- セットアップがほとんど不要 +- すぐに使える体験 + +**欠点:** + +- マークアップに対する制御が少ない +- カスタムスタイルは通常テーマベース +- バンドルサイズが大きい +- フレームワークアダプターやプラットフォームに強く依存 + +**すぐに使えるテーブルが必要で、デザイン/バンドルサイズが厳しい要件でない場合**、コンポーネントベースのテーブルライブラリの使用を検討すべきです。 + +世の中には多くのコンポーネントベースのテーブルライブラリがありますが、[AG Grid](https://ag-grid.com/react-data-grid/?utm_source=reacttable&utm_campaign=githubreacttable)がゴールドスタンダードであり、私たちのお気に入りのグリッド仲間です(他のライブラリには内緒です🤫)。 + +### ヘッドレステーブルライブラリ + +ヘッドレステーブルライブラリは通常、独自のテーブルマークアップを構築したり、既存のテーブルマークアップにアタッチしたりするための関数、状態管理、ユーティリティ、イベントリスナーを提供します。 + +**利点:** + +- マークアップとスタイルの完全な制御 +- すべてのスタイリングパターン(CSS、CSS-in-JS、UIライブラリなど)をサポート +- バンドルサイズが小さい +- 移植性が高い。JSが動作する場所ならどこでも実行可能! + +**欠点:** + +- より多くのセットアップが必要 +- マークアップ、スタイル、テーマは提供されない + +**より軽量なテーブルが必要な場合、またはデザインを完全に制御したい場合**、ヘッドレステーブルライブラリの使用を検討すべきです。 + +世の中には非常に少ないヘッドレステーブルライブラリしかありませんが、もちろん**TanStack Table**が私たちのお気に入りです! diff --git a/docs/ja/overview.md b/docs/ja/overview.md new file mode 100644 index 0000000000..8ee0a5ec3a --- /dev/null +++ b/docs/ja/overview.md @@ -0,0 +1,66 @@ +--- +source-updated-at: '2024-05-12T19:19:51.000Z' +translation-updated-at: '2025-05-05T19:24:27.877Z' +title: 概要 +--- +# 概要 + +TanStack Tableのコアは**フレームワーク非依存 (framework agnostic)** であり、使用するフレームワークに関係なくAPIは同じです。各フレームワークに対応するアダプターが提供されており、テーブルコアを簡単に扱えるようになっています。利用可能なアダプターについては、Adaptersメニューを参照してください。 + +## TypeScript + +TanStack Tableは[TypeScript](https://www.typescriptlang.org/)で書かれていますが、アプリケーションでTypeScriptを使用することはオプションです(ただし、コードベースと開発者双方に優れた利点をもたらすため、使用を推奨します)。 + +TypeScriptを使用する場合、すべてのテーブルAPIと状態に対して最高レベルの型安全性とエディタのオートコンプリート機能が得られます。 + +## ヘッドレス (Headless) + +[イントロダクション](../introduction)セクションで詳しく説明されているように、TanStack Tableは**ヘッドレス (headless)** です。つまり、DOM要素をレンダリングせず、代わりにUI/UX開発者であるあなたがテーブルのマークアップとスタイルを提供する必要があります。これは、React、Vue、Solid、Svelte、Qwik、AngularなどのUIフレームワークや、React NativeのようなJS-to-ネイティブプラットフォームでも使用できるテーブルを構築する優れた方法です。 + +## 非依存性 (Agnostic) + +TanStack TableはヘッドレスでバニラJavaScriptコア上で動作するため、次の点で非依存性を持っています: + +1. **フレームワーク非依存 (Framework Agnostic)** - 任意のJavaScriptフレームワーク(またはライブラリ)で使用できます。TanStack TableはReact、Vue、Solid、Svelte、Qwik向けのすぐに使えるアダプターを提供していますが、必要に応じて独自のアダプターを作成することも可能です。 +2. **CSS/コンポーネントライブラリ非依存 (CSS / Component Library Agnostic)** - 任意のCSS戦略やコンポーネントライブラリと一緒にTanStack Tableを使用できます。TanStack Table自体はテーブルのマークアップやスタイルをレンダリングしません。あなた自身でそれらを用意します!TailwindやShadCNを使いたいですか?問題ありません!Material UIやBootstrapを使いたいですか?問題ありません!独自のデザインシステムを持っていますか?TanStack Tableはあなたのために作られています! + +## コアオブジェクトと型 + +テーブルコアでは、アダプターによって一般的に公開される以下の抽象化が使用されます: + +- [データ (Data)](../guide/data) - テーブルに提供するコアデータ配列 +- [カラム定義 (Column Defs)](../guide/column-defs): カラムとそのデータモデル、表示テンプレートなどを設定するためのオブジェクト +- [テーブルインスタンス (Table Instance)](../guide/tables): 状態とAPIを含むコアテーブルオブジェクト +- [行モデル (Row Models)](../guide/row-models): 使用する機能に応じて`data`配列が有用な行に変換される方法 +- [行 (Rows)](../guide/rows): 各行は対応する行データを反映し、行固有のAPIを提供 +- [セル (Cells)](../guide/cells): 各セルは対応する行-列の交差点を反映し、セル固有のAPIを提供 +- [ヘッダーグループ (Header Groups)](../guide/header-groups): ヘッダーグループはネストされたヘッダーレベルの計算されたスライスで、各グループにはヘッダーのグループが含まれる +- [ヘッダー (Headers)](../guide/headers): 各ヘッダーはカラム定義に直接関連付けられているか、そこから派生し、ヘッダー固有のAPIを提供 +- [カラム (Columns)](../guide/columns): 各カラムは対応するカラム定義を反映し、カラム固有のAPIも提供 + +## 機能 + +TanStack Tableを使えば、想像できるほぼあらゆるタイプのテーブルを構築できます。以下の機能に対して組み込みの状態とAPIが用意されています: + +- [カラムファセット (Column Faceting)](../guide/column-faceting) - カラム値の一意なリストやカラムの最小/最大値をリスト表示 +- [カラムフィルタリング (Column Filtering)](../guide/column-filtering) - カラムの検索値に基づいて行をフィルタリング +- [カラムグループ化 (Column Grouping)](../guide/grouping) - カラムをグループ化し、集計などを実行 +- [カラム順序変更 (Column Ordering)](../guide/column-ordering) - カラムの順序を動的に変更 +- [カラム固定 (Column Pinning)](../guide/column-pinning) - カラムをテーブルの左または右に固定(フリーズ) +- [カラムサイズ変更 (Column Sizing)](../guide/column-sizing) - カラムのサイズを動的に変更(カラムリサイズハンドル) +- [カラム表示/非表示 (Column Visibility)](../guide/column-visibility) - カラムを表示/非表示 +- [グローバルファセット (Global Faceting)](../guide/global-faceting) - テーブル全体のカラム値の一意なリストや最小/最大値をリスト表示 +- [グローバルフィルタリング (Global Filtering)](../guide/global-filtering) - テーブル全体の検索値に基づいて行をフィルタリング +- [行展開 (Row Expanding)](../guide/expanding) - 行を展開/折りたたみ(サブ行) +- [行ページネーション (Row Pagination)](../guide/pagination) - 行をページ分割 +- [行固定 (Row Pinning)](../guide/row-pinning) - 行をテーブルの上部または下部に固定(フリーズ) +- [行選択 (Row Selection)](../guide/row-selection) - 行を選択/選択解除(チェックボックス) +- [行ソート (Row Sorting)](../guide/sorting) - カラム値で行をソート + +これらはTanStack Tableで構築できる機能の一部にすぎません。組み込み機能と併用して追加できる多くの機能が存在します。 + +[仮想化 (Virtualization)](../guide/virtualization)は、TanStack Tableに組み込まれていない機能の一例ですが、[TanStack Virtual](https://tanstack.com/virtual/v3)のような別のライブラリを使用し、他のテーブルレンダリングロジックと一緒に追加することで実現できます。 + +TanStack Tableはまた、[カスタム機能 (Custom Features)](../guide/custom-features)(プラグイン)をサポートしており、テーブルインスタンスを変更して、より統合された方法で独自のカスタムロジックをテーブルに追加できます。 + +もちろん、テーブルに必要な他の機能を追加するために、独自の状態やフックを書くこともできます。TanStack Tableコアの機能は、パフォーマンスと開発者体験 (DX) に重点を置いた、構築のための強固な基盤にすぎません。 diff --git a/docs/ja/vanilla.md b/docs/ja/vanilla.md new file mode 100644 index 0000000000..c7919e0e4d --- /dev/null +++ b/docs/ja/vanilla.md @@ -0,0 +1,16 @@ +--- +source-updated-at: '2024-01-24T21:39:34.000Z' +translation-updated-at: '2025-05-05T19:23:58.945Z' +title: Vanilla JS (フレームワークなし) +--- +`@tanstack/table-core` ライブラリには、TanStack Table のコアロジックが含まれています。非標準のフレームワークを使用している場合やフレームワークにアクセスできない場合は、TypeScript または JavaScript を介して直接コアライブラリを使用できます。 + +## `createTable` + +`options` オブジェクトを受け取り、テーブルを返します。 + +```tsx +import { createTable } from '@tanstack/table-core' + +const table = createTable(options) +``` diff --git a/docs/ru/config.json b/docs/ru/config.json new file mode 100644 index 0000000000..917ab530f7 --- /dev/null +++ b/docs/ru/config.json @@ -0,0 +1,790 @@ +{ + "$schema": "https://raw.githubusercontent.com/TanStack/tanstack.com/main/tanstack-docs-config.schema.json", + "docSearch": { + "appId": "74SF5EKVW9", + "apiKey": "9fc015a3310be6669ed66c6c459f319f", + "indexName": "tanstack-table" + }, + "sections": [ + { + "label": "Начало работы", + "children": [ + { + "label": "Введение", + "to": "introduction" + }, + { + "label": "Обзор", + "to": "overview" + }, + { + "label": "Установка", + "to": "installation" + }, + { + "label": "Миграция на V8", + "to": "guide/migrating" + }, + { + "label": "Часто задаваемые вопросы", + "to": "faq" + } + ], + "frameworks": [ + { + "label": "angular", + "children": [ + { + "label": "Адаптер таблицы для Angular", + "to": "framework/angular/angular-table" + } + ] + }, + { + "label": "lit", + "children": [ + { + "label": "Адаптер таблицы для Lit", + "to": "framework/lit/lit-table" + } + ] + }, + { + "label": "qwik", + "children": [ + { + "label": "Адаптер таблицы для Qwik", + "to": "framework/qwik/qwik-table" + } + ] + }, + { + "label": "react", + "children": [ + { + "label": "Адаптер таблицы для React", + "to": "framework/react/react-table" + } + ] + }, + { + "label": "solid", + "children": [ + { + "label": "Адаптер таблицы для Solid", + "to": "framework/solid/solid-table" + } + ] + }, + { + "label": "svelte", + "children": [ + { + "label": "Адаптер таблицы для Svelte", + "to": "framework/svelte/svelte-table" + } + ] + }, + { + "label": "vue", + "children": [ + { + "label": "Адаптер таблицы для Vue", + "to": "framework/vue/vue-table" + } + ] + }, + { + "label": "vanilla", + "children": [ + { + "label": "Vanilla JS (без фреймворка)", + "to": "vanilla" + } + ] + } + ] + }, + { + "label": "Основные руководства", + "children": [ + { + "label": "Данные", + "to": "guide/data" + }, + { + "label": "Определения колонок", + "to": "guide/column-defs" + }, + { + "label": "Экземпляр таблицы", + "to": "guide/tables" + }, + { + "label": "Модели строк", + "to": "guide/row-models" + }, + { + "label": "Строки", + "to": "guide/rows" + }, + { + "label": "Ячейки", + "to": "guide/cells" + }, + { + "label": "Группы заголовков", + "to": "guide/header-groups" + }, + { + "label": "Заголовки", + "to": "guide/headers" + }, + { + "label": "Колонки", + "to": "guide/columns" + } + ], + "frameworks": [ + { + "label": "angular", + "children": [ + { + "label": "Состояние таблицы", + "to": "framework/angular/guide/table-state" + } + ] + }, + { + "label": "lit", + "children": [ + { + "label": "Состояние таблицы", + "to": "framework/lit/guide/table-state" + } + ] + }, + { + "label": "qwik", + "children": [ + { + "label": "Состояние таблицы", + "to": "framework/qwik/guide/table-state" + } + ] + }, + { + "label": "react", + "children": [ + { + "label": "Состояние таблицы", + "to": "framework/react/guide/table-state" + } + ] + }, + { + "label": "solid", + "children": [ + { + "label": "Состояние таблицы", + "to": "framework/solid/guide/table-state" + } + ] + }, + { + "label": "svelte", + "children": [ + { + "label": "Состояние таблицы", + "to": "framework/svelte/guide/table-state" + } + ] + }, + { + "label": "vue", + "children": [ + { + "label": "Состояние таблицы", + "to": "framework/vue/guide/table-state" + } + ] + }, + { + "label": "vanilla", + "children": [ + { + "label": "Состояние таблицы", + "to": "framework/vanilla/guide/table-state" + } + ] + } + ] + }, + { + "label": "Руководства по функциям", + "children": [ + { + "label": "Порядок колонок", + "to": "guide/column-ordering" + }, + { + "label": "Закрепление колонок", + "to": "guide/column-pinning" + }, + { + "label": "Размер колонок", + "to": "guide/column-sizing" + }, + { + "label": "Видимость колонок", + "to": "guide/column-visibility" + }, + { + "label": "Фильтрация колонок", + "to": "guide/column-filtering" + }, + { + "label": "Глобальная фильтрация", + "to": "guide/global-filtering" + }, + { + "label": "Нечеткая фильтрация", + "to": "guide/fuzzy-filtering" + }, + { + "label": "Фасеты колонок", + "to": "guide/column-faceting" + }, + { + "label": "Глобальные фасеты", + "to": "guide/global-faceting" + }, + { + "label": "Группировка", + "to": "guide/grouping" + }, + { + "label": "Раскрытие", + "to": "guide/expanding" + }, + { + "label": "Пагинация", + "to": "guide/pagination" + }, + { + "label": "Закрепление строк", + "to": "guide/row-pinning" + }, + { + "label": "Выбор строк", + "to": "guide/row-selection" + }, + { + "label": "Сортировка", + "to": "guide/sorting" + }, + { + "label": "Виртуализация", + "to": "guide/virtualization" + }, + { + "label": "Пользовательские функции", + "to": "guide/custom-features" + } + ] + }, + { + "label": "Основные API", + "children": [ + { + "label": "Определение колонки", + "to": "api/core/column-def" + }, + { + "label": "Таблица", + "to": "api/core/table" + }, + { + "label": "Колонка", + "to": "api/core/column" + }, + { + "label": "Группа заголовков", + "to": "api/core/header-group" + }, + { + "label": "Заголовок", + "to": "api/core/header" + }, + { + "label": "Строка", + "to": "api/core/row" + }, + { + "label": "Ячейка", + "to": "api/core/cell" + } + ] + }, + { + "label": "API функций", + "children": [ + { + "label": "Фильтрация колонок", + "to": "api/features/column-filtering" + }, + { + "label": "Фасеты колонок", + "to": "api/features/column-faceting" + }, + { + "label": "Порядок колонок", + "to": "api/features/column-ordering" + }, + { + "label": "Закрепление колонок", + "to": "api/features/column-pinning" + }, + { + "label": "Размер колонок", + "to": "api/features/column-sizing" + }, + { + "label": "Видимость колонок", + "to": "api/features/column-visibility" + }, + { + "label": "Глобальные фасеты", + "to": "api/features/global-faceting" + }, + { + "label": "Глобальная фильтрация", + "to": "api/features/global-filtering" + }, + { + "label": "Сортировка", + "to": "api/features/sorting" + }, + { + "label": "Группировка", + "to": "api/features/grouping" + }, + { + "label": "Раскрытие", + "to": "api/features/expanding" + }, + { + "label": "Пагинация", + "to": "api/features/pagination" + }, + { + "label": "Закрепление строк", + "to": "api/features/row-pinning" + }, + { + "label": "Выбор строк", + "to": "api/features/row-selection" + } + ] + }, + { + "label": "Enterprise", + "children": [ + { + "label": "AG Grid", + "to": "enterprise/ag-grid" + } + ] + }, + { + "label": "Примеры", + "children": [], + "frameworks": [ + { + "label": "angular", + "children": [ + { + "to": "framework/angular/examples/basic", + "label": "Базовый" + }, + { + "to": "framework/angular/examples/grouping", + "label": "Группировка колонок" + }, + { + "to": "framework/angular/examples/column-ordering", + "label": "Порядок колонок" + }, + { + "to": "framework/angular/examples/column-pinning", + "label": "Закрепление колонок" + }, + { + "to": "framework/angular/examples/column-pinning-sticky", + "label": "Липкое закрепление колонок" + }, + { + "to": "framework/angular/examples/column-visibility", + "label": "Видимость колонок" + }, + { + "to": "framework/angular/examples/filters", + "label": "Фильтры колонок" + }, + { + "to": "framework/angular/examples/row-selection", + "label": "Выбор строк" + }, + { + "to": "framework/angular/examples/expanding", + "label": "Раскрытие" + }, + { + "to": "framework/angular/examples/sub-components", + "label": "Дочерние компоненты" + }, + { + "to": "framework/angular/examples/signal-input", + "label": "Signal Input" + }, + { + "to": "framework/angular/examples/editable", + "label": "Редактируемые данные" + }, + { + "to": "framework/angular/examples/row-dnd", + "label": "Перетаскивание строк" + }, + { + "to": "framework/angular/examples/column-resizing-performant", + "label": "Производительное изменение размера колонок" + } + ] + }, + { + "label": "lit", + "children": [ + { + "to": "framework/lit/examples/basic", + "label": "Базовый" + }, + { + "to": "framework/lit/examples/column-sizing", + "label": "Размер колонок" + }, + { + "to": "framework/lit/examples/filters", + "label": "Фильтры" + }, + { + "to": "framework/lit/examples/row-selection", + "label": "Выбор строк" + }, + { + "to": "framework/lit/examples/sorting", + "label": "Сортировка" + }, + { + "to": "framework/lit/examples/virtualized-rows", + "label": "Виртуализация строк" + } + ] + }, + { + "label": "qwik", + "children": [ + { + "to": "framework/qwik/examples/basic", + "label": "Базовый" + }, + { + "to": "framework/qwik/examples/filters", + "label": "Фильтры" + }, + { + "to": "framework/qwik/examples/row-selection", + "label": "Выбор строк" + }, + { + "to": "framework/qwik/examples/sorting", + "label": "Сортировка" + } + ] + }, + { + "label": "react", + "children": [ + { + "to": "framework/react/examples/basic", + "label": "Базовый" + }, + { + "to": "framework/react/examples/column-groups", + "label": "Группы заголовков" + }, + { + "to": "framework/react/examples/filters", + "label": "Фильтры колонок" + }, + { + "to": "framework/react/examples/filters-faceted", + "label": "Фильтры колонок (фасеты)" + }, + { + "to": "framework/react/examples/filters-fuzzy", + "label": "Нечеткие фильтры" + }, + { + "to": "framework/react/examples/column-ordering", + "label": "Порядок колонок" + }, + { + "to": "framework/react/examples/column-dnd", + "label": "Порядок колонок (перетаскивание)" + }, + { + "to": "framework/react/examples/column-pinning", + "label": "Закрепление колонок" + }, + { + "to": "framework/react/examples/column-pinning-sticky", + "label": "Липкое закрепление колонок" + }, + { + "to": "framework/react/examples/column-sizing", + "label": "Размер колонок" + }, + { + "to": "framework/react/examples/column-resizing-performant", + "label": "Производительное изменение размера колонок" + }, + { + "to": "framework/react/examples/column-visibility", + "label": "Видимость колонок" + }, + { + "to": "framework/react/examples/editable-data", + "label": "Редактируемые данные" + }, + { + "to": "framework/react/examples/expanding", + "label": "Раскрытие" + }, + { + "to": "framework/react/examples/sub-components", + "label": "Дочерние компоненты" + }, + { + "to": "framework/react/examples/fully-controlled", + "label": "Полностью контролируемый" + }, + { + "to": "framework/react/examples/grouping", + "label": "Группировка" + }, + { + "to": "framework/react/examples/pagination", + "label": "Пагинация" + }, + { + "to": "framework/react/examples/pagination-controlled", + "label": "Контролируемая пагинация" + }, + { + "to": "framework/react/examples/row-dnd", + "label": "Перетаскивание строк" + }, + { + "to": "framework/react/examples/row-pinning", + "label": "Закрепление строк" + }, + { + "to": "framework/react/examples/row-selection", + "label": "Выбор строк" + }, + { + "to": "framework/react/examples/sorting", + "label": "Сортировка" + }, + { + "to": "framework/react/examples/virtualized-columns", + "label": "Виртуализация колонок" + }, + { + "to": "framework/react/examples/virtualized-columns-experimental", + "label": "Виртуализация колонок (экспериментальная)" + }, + { + "to": "framework/react/examples/virtualized-rows", + "label": "Виртуализация строк" + }, + { + "to": "framework/react/examples/virtualized-rows-experimental", + "label": "Виртуализация строк (экспериментальная)" + }, + { + "to": "framework/react/examples/virtualized-infinite-scrolling", + "label": "Бесконечная прокрутка" + }, + { + "to": "framework/react/examples/kitchen-sink", + "label": "Кухонная раковина" + }, + { + "to": "framework/react/examples/bootstrap", + "label": "React Bootstrap" + }, + { + "to": "framework/react/examples/material-ui-pagination", + "label": "Пагинация Material UI" + }, + { + "to": "framework/react/examples/full-width-table", + "label": "Таблица на всю ширину" + }, + { + "to": "framework/react/examples/full-width-resizable-table", + "label": "Таблица на всю ширину с изменяемым размером" + }, + { + "to": "framework/react/examples/custom-features", + "label": "Пользовательские функции" + }, + { + "to": "framework/react/examples/query-router-search-params", + "label": "Параметры поиска Query Router" + } + ] + }, + { + "label": "solid", + "children": [ + { + "to": "framework/solid/examples/basic", + "label": "Базовый" + }, + { + "to": "framework/solid/examples/column-groups", + "label": "Группы колонок" + }, + { + "to": "framework/solid/examples/column-ordering", + "label": "Порядок колонок" + }, + { + "to": "framework/solid/examples/column-visibility", + "label": "Видимость колонок" + }, + { + "to": "framework/solid/examples/filters", + "label": "Фильтры" + }, + { + "to": "framework/solid/examples/sorting", + "label": "Сортировка" + }, + { + "to": "framework/solid/examples/bootstrap", + "label": "Solid Bootstrap" + } + ] + }, + { + "label": "svelte", + "children": [ + { + "to": "framework/svelte/examples/basic", + "label": "Базовый" + }, + { + "to": "framework/svelte/examples/column-groups", + "label": "Группы колонок" + }, + { + "to": "framework/svelte/examples/column-ordering", + "label": "Порядок колонок" + }, + { + "to": "framework/svelte/examples/column-pinning", + "label": "Закрепление колонок" + }, + { + "to": "framework/svelte/examples/column-visibility", + "label": "Видимость колонок" + }, + { + "to": "framework/svelte/examples/filtering", + "label": "Фильтрация" + }, + { + "to": "framework/svelte/examples/sorting", + "label": "Сортировка" + } + ] + }, + { + "label": "vue", + "children": [ + { + "to": "framework/vue/examples/basic", + "label": "Базовый" + }, + { + "to": "framework/vue/examples/column-ordering", + "label": "Порядок колонок" + }, + { + "to": "framework/vue/examples/column-pinning", + "label": "Закрепление колонок" + }, + { + "to": "framework/vue/examples/pagination", + "label": "Пагинация" + }, + { + "to": "framework/vue/examples/row-selection", + "label": "Выбор строк" + }, + { + "to": "framework/vue/examples/sorting", + "label": "Сортировка" + }, + { + "to": "framework/vue/examples/sub-components", + "label": "Дочерние компоненты" + }, + { + "to": "framework/vue/examples/filters", + "label": "Фильтры колонок" + }, + { + "to": "framework/vue/examples/virtualized-rows", + "label": "Виртуализация строк" + }, + { + "to": "framework/vue/examples/grouping", + "label": "Группировка" + } + ] + }, + { + "label": "vanilla", + "children": [ + { + "to": "framework/vanilla/examples/basic", + "label": "Базовый" + }, + { + "to": "framework/vanilla/examples/pagination", + "label": "Пагинация" + }, + { + "to": "framework/vanilla/examples/sorting", + "label": "Сортировка" + } + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/docs/zh-hans/api/core/cell.md b/docs/zh-hans/api/core/cell.md new file mode 100644 index 0000000000..4816b6b729 --- /dev/null +++ b/docs/zh-hans/api/core/cell.md @@ -0,0 +1,69 @@ +--- +source-updated-at: '2025-03-20T21:15:29.000Z' +translation-updated-at: '2025-05-02T17:32:33.600Z' +title: 单元格 +--- +以下是所有单元格的核心选项和 API 属性。更多选项和 API 属性可在其他[表格功能](../guide/features)中找到。 + +## 单元格 API + +所有单元格对象都具有以下属性: + +### `id` + +```tsx +id: string +``` + +该单元格在整个表格中的唯一标识符。 + +### `getValue` + +```tsx +getValue: () => any +``` + +通过关联列的访问器键或访问器函数获取单元格的值并返回。 + +### `renderValue` + +```tsx +renderValue: () => any +``` + +与 `getValue` 相同的方式渲染单元格的值,但如果未找到值,则会返回 `renderFallbackValue`。 + +### `row` + +```tsx +row: Row +``` + +该单元格关联的行对象。 + +### `column` + +```tsx +column: Column +``` + +该单元格关联的列对象。 + +### `getContext` + +```tsx +getContext: () => { + table: Table + column: Column + row: Row + cell: Cell + getValue: () => TTValue + renderValue: () => TTValue | null +} +``` + +返回基于单元格的组件(如单元格和聚合单元格)的渲染上下文(或属性)。使用这些属性配合您框架的 `flexRender` 工具函数,按需渲染模板: + +```tsx +flexRender(cell.column.columnDef.cell, cell.getContext()) +``` diff --git a/docs/zh-hans/api/core/column-def.md b/docs/zh-hans/api/core/column-def.md new file mode 100644 index 0000000000..8fdd3bdc47 --- /dev/null +++ b/docs/zh-hans/api/core/column-def.md @@ -0,0 +1,108 @@ +--- +source-updated-at: '2024-03-22T01:02:38.000Z' +translation-updated-at: '2025-05-02T17:29:32.771Z' +title: 列定义 +--- +列定义 (ColumnDef) 是包含以下选项的普通对象: + +## 选项 + +### `id` + +```tsx +id: string +``` + +该列的唯一标识符。 + +> � 在以下情况下列 ID 是可选的: +> +> - 当使用对象键访问器 (accessor) 创建访问器列时 +> - 当列标题定义为字符串时 + +### `accessorKey` + +```tsx +accessorKey?: string & typeof TData +``` + +用于从行对象中提取列值时使用的键名。 + +### `accessorFn` + +```tsx +accessorFn?: (originalRow: TData, index: number) => any +``` + +用于从每行数据中提取列值的访问器函数。 + +### `columns` + +```tsx +columns?: ColumnDef[] +``` + +包含在分组列中的子列定义。 + +### `header` + +```tsx +header?: + | string + | ((props: { + table: Table + header: Header + column: Column + }) => unknown) +``` + +为该列显示的标题。如果传入字符串,则可作为列 ID 的默认值。如果传入函数,则会接收标题的属性对象,并应返回渲染后的标题值(具体类型取决于所使用的适配器)。 + +### `footer` + +```tsx +footer?: + | string + | ((props: { + table: Table + header: Header + column: Column + }) => unknown) +``` + +为该列显示的页脚。如果传入函数,则会接收页脚的属性对象,并应返回渲染后的页脚值(具体类型取决于所使用的适配器)。 + +### `cell` + +```tsx +cell?: + | string + | ((props: { + table: Table + row: Row + column: Column + cell: Cell + getValue: () => any + renderValue: () => any + }) => unknown) +``` + +为该列每行数据显示的单元格。如果传入函数,则会接收单元格的属性对象,并应返回渲染后的单元格值(具体类型取决于所使用的适配器)。 + +### `meta` + +```tsx +meta?: ColumnMeta // 此接口可通过声明合并扩展。见下文! +``` + +与该列关联的元数据。当列可用时,我们可以通过 `column.columnDef.meta` 在任何地方访问它。此类型对所有表格都是全局的,可以像这样扩展: + +```tsx +import '@tanstack/react-table' // 或 vue, svelte, solid, qwik 等 + +declare module '@tanstack/react-table' { + interface ColumnMeta { + foo: string + } +} +``` diff --git a/docs/zh-hans/api/core/column.md b/docs/zh-hans/api/core/column.md new file mode 100644 index 0000000000..4762be14d9 --- /dev/null +++ b/docs/zh-hans/api/core/column.md @@ -0,0 +1,78 @@ +--- +source-updated-at: '2025-03-20T21:15:29.000Z' +translation-updated-at: '2025-05-06T01:25:22.796Z' +title: 列 +--- +以下是所有列的核心选项和 API 属性。更多选项和 API 属性可用于其他[表格功能](../guide/features)。 + +## 列 API (Column API) + +所有列对象都具有以下属性: + +### `id` + +```tsx +id: string +``` + +解析出的唯一标识符,按以下优先级确定: + +- 列定义中手动指定的 `id` 属性 +- 列定义中的访问器键 (accessor key) +- 列定义中的表头字符串 + +### `depth` + +```tsx +depth: number +``` + +列的分组深度 (如果已分组),相对于根列定义数组。 + +### `accessorFn` + +```tsx +accessorFn?: AccessorFn +``` + +解析出的访问器函数,用于从每行中提取该列的值。仅当列定义中定义了有效的访问器键或函数时才会存在。 + +### `columnDef` + +```tsx +columnDef: ColumnDef +``` + +用于创建列的原始列定义。 + +### `columns` + +```tsx +type columns = ColumnDef[] +``` + +子列数组 (如果该列是分组列)。如果列不是分组列,则为空数组。 + +### `parent` + +```tsx +parent?: Column +``` + +该列的父列。如果是根列则为 undefined。 + +### `getFlatColumns` + +```tsx +type getFlatColumns = () => Column[] +``` + +返回该列及其所有子列/孙列组成的扁平化数组。 + +### `getLeafColumns` + +```tsx +type getLeafColumns = () => Column[] +``` + +返回该列的所有叶子节点列数组。如果列没有子列,则它本身被视为唯一的叶子节点列。 diff --git a/docs/zh-hans/api/core/header-group.md b/docs/zh-hans/api/core/header-group.md new file mode 100644 index 0000000000..59871d0ff3 --- /dev/null +++ b/docs/zh-hans/api/core/header-group.md @@ -0,0 +1,34 @@ +--- +source-updated-at: '2025-03-20T21:15:29.000Z' +translation-updated-at: '2025-05-02T17:31:11.271Z' +title: 表头分组 +--- +以下是适用于所有表头组 (header groups) 的**核心**选项和 API 属性。更多选项和 API 属性可能适用于其他[表格功能](../guide/features)。 + +## 表头组 API (Header Group API) + +所有表头组对象都具有以下属性: + +### `id` + +```tsx +id: string +``` + +表头组的唯一标识符。 + +### `depth` + +```tsx +depth: number +``` + +表头组的深度,从零开始计数 (zero-indexed)。 + +### `headers` + +```tsx +type headers = Header[] +``` + +属于该表头组的[表头 (Header)](../api/core/header) 对象数组。 diff --git a/docs/zh-hans/api/core/header.md b/docs/zh-hans/api/core/header.md new file mode 100644 index 0000000000..61d72a3cba --- /dev/null +++ b/docs/zh-hans/api/core/header.md @@ -0,0 +1,244 @@ +--- +source-updated-at: '2025-03-20T21:15:29.000Z' +translation-updated-at: '2025-05-02T17:31:55.565Z' +title: 表头 +--- +以下是所有表头 (header) 的**核心**选项和 API 属性。更多选项和 API 属性可能适用于其他[表格功能](../guide/features)。 + +## 表头 API (Header API) + +所有表头对象都具有以下属性: + +### `id` + +```tsx +id: string +``` + +表头的唯一标识符。 + +### `index` + +```tsx +index: number +``` + +表头在表头组中的索引。 + +### `depth` + +```tsx +depth: number +``` + +表头的深度,从零开始计数。 + +### `column` + +```tsx +column: Column +``` + +表头关联的[列 (Column)](../api/core/column) 对象。 + +### `headerGroup` + +```tsx +headerGroup: HeaderGroup +``` + +表头关联的[表头组 (HeaderGroup)](../api/core/header-group) 对象。 + +### `subHeaders` + +```tsx +type subHeaders = Header[] +``` + +表头的层级子表头。如果表头关联的列是叶子列 (leaf-column),则此数组为空。 + +### `colSpan` + +```tsx +colSpan: number +``` + +表头的列跨度 (col-span)。 + +### `rowSpan` + +```tsx +rowSpan: number +``` + +表头的行跨度 (row-span)。 + +### `getLeafHeaders` + +```tsx +type getLeafHeaders = () => Header[] +``` + +返回此表头层级下嵌套的所有叶子表头。 + +### `isPlaceholder` + +```tsx +isPlaceholder: boolean +``` + +标识表头是否为占位表头的布尔值。 + +### `placeholderId` + +```tsx +placeholderId?: string +``` + +如果表头是占位表头,此属性将提供一个唯一的表头 ID,确保不与表格中其他表头冲突。 + +### `getContext` + +```tsx +getContext: () => { + table: Table + header: Header + column: Column +} +``` + +返回用于表头、页脚和过滤器等基于列的组件的渲染上下文(或属性)。将这些属性与框架的 `flexRender` 工具一起使用,以按所选模板渲染这些组件: + +```tsx +flexRender(header.column.columnDef.header, header.getContext()) +``` + +## 表格 API (Table API) + +### `getHeaderGroups` + +```tsx +type getHeaderGroups = () => HeaderGroup[] +``` + +返回表格的所有表头组。 + +### `getLeftHeaderGroups` + +```tsx +type getLeftHeaderGroups = () => HeaderGroup[] +``` + +如果启用了固定列 (pinning),返回左侧固定列的表头组。 + +### `getCenterHeaderGroups` + +```tsx +type getCenterHeaderGroups = () => HeaderGroup[] +``` + +如果启用了固定列,返回未固定列的表头组。 + +### `getRightHeaderGroups` + +```tsx +type getRightHeaderGroups = () => HeaderGroup[] +``` + +如果启用了固定列,返回右侧固定列的表头组。 + +### `getFooterGroups` + +```tsx +type getFooterGroups = () => HeaderGroup[] +``` + +返回表格的所有页脚组。 + +### `getLeftFooterGroups` + +```tsx +type getLeftFooterGroups = () => HeaderGroup[] +``` + +如果启用了固定列,返回左侧固定列的页脚组。 + +### `getCenterFooterGroups` + +```tsx +type getCenterFooterGroups = () => HeaderGroup[] +``` + +如果启用了固定列,返回未固定列的页脚组。 + +### `getRightFooterGroups` + +```tsx +type getRightFooterGroups = () => HeaderGroup[] +``` + +如果启用了固定列,返回右侧固定列的页脚组。 + +### `getFlatHeaders` + +```tsx +type getFlatHeaders = () => Header[] +``` + +返回表格中所有列的表头,包括父表头。 + +### `getLeftFlatHeaders` + +```tsx +type getLeftFlatHeaders = () => Header[] +``` + +如果启用了固定列,返回表格中所有左侧固定列的表头,包括父表头。 + +### `getCenterFlatHeaders` + +```tsx +type getCenterFlatHeaders = () => Header[] +``` + +如果启用了固定列,返回表格中所有未固定列的表头,包括父表头。 + +### `getRightFlatHeaders` + +```tsx +type getRightFlatHeaders = () => Header[] +``` + +如果启用了固定列,返回表格中所有右侧固定列的表头,包括父表头。 + +### `getLeafHeaders` + +```tsx +type getLeafHeaders = () => Header[] +``` + +返回表格中所有叶子列的表头(不包括父表头)。 + +### `getLeftLeafHeaders` + +```tsx +type getLeftLeafHeaders = () => Header[] +``` + +如果启用了固定列,返回表格中所有左侧固定叶子列的表头(不包括父表头)。 + +### `getCenterLeafHeaders` + +```tsx +type getCenterLeafHeaders = () => Header[] +``` + +如果启用了固定列,返回表格中所有未固定列的表头(不包括父表头)。 + +### `getRightLeafHeaders` + +```tsx +type getRightLeafHeaders = () => Header[] +``` + +如果启用了固定列,返回表格中所有右侧固定叶子列的表头(不包括父表头)。 diff --git a/docs/zh-hans/api/core/row.md b/docs/zh-hans/api/core/row.md new file mode 100644 index 0000000000..c8c4f414c3 --- /dev/null +++ b/docs/zh-hans/api/core/row.md @@ -0,0 +1,110 @@ +--- +source-updated-at: '2025-03-20T21:15:29.000Z' +translation-updated-at: '2025-05-02T17:32:18.576Z' +title: 行 +--- +以下是所有行的**核心**选项和 API 属性。更多选项和 API 属性可用于其他[表格功能](../guide/features)。 + +## 行 (Row) API + +所有行对象都具有以下属性: + +### `id` + +```tsx +id: string +``` +通过 `options.getRowId` 选项解析出的唯一标识符。默认为行的索引(如果是子行则为相对索引)。 + +### `depth` + +```tsx +depth: number +``` +行相对于根行数组的深度(如果是嵌套或分组行)。 + +### `index` + +```tsx +index: number +``` +行在其父数组(或根数据数组)中的索引。 + +### `original` + +```tsx +original: TData +``` +提供给表格的原始行对象。 + +> 🧠 如果行是分组行,原始行对象将是组中的第一个原始行。 + +### `parentId` + +```tsx +parentId?: string +``` +如果是嵌套行,此行父行的 ID。 + +### `getValue` + +```tsx +getValue: (columnId: string) => TValue +``` +返回行中指定列 ID 的值。 + +### `renderValue` + +```tsx +renderValue: (columnId: string) => TValue +``` +渲染行中指定列 ID 的值,但如果未找到值,将返回 `renderFallbackValue`。 + +### `getUniqueValues` + +```tsx +getUniqueValues: (columnId: string) => TValue[] +``` +返回行中指定列 ID 的唯一值数组。 + +### `subRows` + +```tsx +type subRows = Row[] +``` +由 `options.getSubRows` 选项返回和创建的行子行数组。 + +### `getParentRow` + +```tsx +type getParentRow = () => Row | undefined +``` +返回行的父行(如果存在)。 + +### `getParentRows` + +```tsx +type getParentRows = () => Row[] +``` +返回行的所有父行,直到根行。 + +### `getLeafRows` + +```tsx +type getLeafRows = () => Row[] +``` +返回行的所有叶子行,不包括任何父行。 + +### `originalSubRows` + +```tsx +originalSubRows?: TData[] +``` +由 `options.getSubRows` 选项返回的原始子行数组。 + +### `getAllCells` + +```tsx +type getAllCells = () => Cell[] +``` +返回行中所有的[单元格 (Cell)](../api/core/cell)。 diff --git a/docs/zh-hans/api/core/table.md b/docs/zh-hans/api/core/table.md new file mode 100644 index 0000000000..bf4f0dc2a5 --- /dev/null +++ b/docs/zh-hans/api/core/table.md @@ -0,0 +1,386 @@ +--- +source-updated-at: '2025-03-20T21:15:29.000Z' +translation-updated-at: '2025-05-02T17:31:02.769Z' +title: 表格 +--- +## `createAngularTable` / `useReactTable` / `createSolidTable` / `useQwikTable` / `useVueTable` / `createSvelteTable` + +```tsx +type useReactTable = ( + options: TableOptions +) => Table +``` + +这些函数用于创建表格实例,具体使用哪一个取决于你所采用的框架适配器。 + +## 选项参数 + +以下是表格的**核心**选项和 API 属性。更多选项和 API 属性可参见其他 [表格功能](../guide/features)。 + +### `data` + +```tsx +data: TData[] +``` + +表格需要展示的数据数组。该数组理论上可以是任意类型,但通常建议与 `table.setRowType<...>` 指定的类型匹配。常见情况下数组中的每个元素是键值对对象(但非强制要求),列可以通过字符串/索引或函数访问器来获取这些数据。 + +当 `data` 选项的引用发生变化时(通过 `Object.is` 比较),表格会重新处理数据。任何依赖核心数据模型的其他数据处理(如分组、排序、筛选等)也会随之重新执行。 + +> 🧠 确保仅在需要表格重新处理数据时才更新 `data` 选项。如果每次渲染时都内联传入 `[]` 或新建数据数组,会导致大量不必要的重复处理。在小型表格中可能不易察觉,但在大型表格中会明显影响性能。 + +### `columns` + +```tsx +type columns = ColumnDef[] +``` + +用于表格的列定义数组。创建列定义的详细信息请参阅 [列定义指南](../../docs/guide/column-defs)。 + +### `defaultColumn` + +```tsx +defaultColumn?: Partial> +``` + +为所有列定义提供默认配置选项。适用于设置默认的单元格/表头/表尾渲染器、排序/筛选/分组选项等。传入 `options.columns` 的所有列定义都会与此默认配置合并生成最终列定义。 + +### `initialState` + +```tsx +initialState?: Partial< + VisibilityTableState & + ColumnOrderTableState & + ColumnPinningTableState & + FiltersTableState & + SortingTableState & + ExpandedTableState & + GroupingTableState & + ColumnSizingTableState & + PaginationTableState & + RowSelectionTableState +> +``` + +通过此选项可选择性传入表格的初始状态。该状态会在重置表格时被使用(例如通过 `options.autoResetPageIndex` 自动重置,或调用 `table.resetRowSelection()` 等方法)。大多数重置函数允许传递标志位来重置为空白/默认状态而非初始状态。 + +> 🧠 此对象变化时不会触发表格状态重置,因此初始状态对象无需保持稳定引用。 + +### `autoResetAll` + +```tsx +autoResetAll?: boolean +``` + +设置此选项可覆盖所有 `autoReset...` 功能选项。 + +### `meta` + +```tsx +meta?: TableMeta // 此接口可通过声明合并扩展,见下文! +``` + +可通过 `options.meta` 传递任意对象,并在表格实例可访问的任何地方通过 `table.options.meta` 获取。该类型全局作用于所有表格,扩展方式如下: + +```tsx +declare module '@tanstack/table-core' { + interface TableMeta { + foo: string + } +} +``` + +> 🧠 可将此选项视为表格的任意"上下文"。这是在不污染其他接口的情况下,向表格传递任意数据或函数的理想方式。典型用例包括传递本地化对象用于格式化日期/数字,或像 [可编辑数据示例](../framework/react/examples/editable-data) 中那样传递更新函数。 + +### `state` + +```tsx +state?: Partial< + VisibilityTableState & + ColumnOrderTableState & + ColumnPinningTableState & + FiltersTableState & + SortingTableState & + ExpandedTableState & + GroupingTableState & + ColumnSizingTableState & + PaginationTableState & + RowSelectionTableState +> +``` + +通过 `state` 选项可以选择性_控制_部分或全部表格状态。此处传入的状态会与表格内部自动管理的状态合并,并覆盖后者形成最终状态。同时可通过 `onStateChange` 选项监听状态变化。 + +### `onStateChange` + +```tsx +onStateChange: (updater: Updater) => void +``` + +此选项用于选择性监听表格内部状态变化。若提供此选项,则需要自行控制和更新表格状态,并通过 `state` 选项将状态回传给表格。 + +### `debugAll` + +> ⚠️ 调试功能仅在开发模式下可用。 + +```tsx +debugAll?: boolean +``` + +设为 true 可将所有调试信息输出到控制台。 + +### `debugTable` + +> ⚠️ 调试功能仅在开发模式下可用。 + +```tsx +debugTable?: boolean +``` + +设为 true 可输出表格调试信息到控制台。 + +### `debugHeaders` + +> ⚠️ 调试功能仅在开发模式下可用。 + +```tsx +debugHeaders?: boolean +``` + +设为 true 可输出表头调试信息到控制台。 + +### `debugColumns` + +> ⚠️ 调试功能仅在开发模式下可用。 + +```tsx +debugColumns?: boolean +``` + +设为 true 可输出列调试信息到控制台。 + +### `debugRows` + +> ⚠️ 调试功能仅在开发模式下可用。 + +```tsx +debugRows?: boolean +``` + +设为 true 可输出行调试信息到控制台。 + +### `_features` + +```tsx +_features?: TableFeature[] +``` + +可添加到表格实例的额外功能数组。 + +### `render` + +> ⚠️ 此选项仅在你实现表格适配器时需要。 + +```tsx +type render = (template: Renderable, props: TProps) => any +``` + +`render` 选项为表格提供渲染器实现,用于将表头和单元格模板转换为用户框架支持的输出结果。 + +### `mergeOptions` + +> ⚠️ 此选项仅在你实现表格适配器时需要。 + +```tsx +type mergeOptions = (defaultOptions: T, options: Partial) => T +``` + +此选项用于实现表格选项的合并逻辑。某些框架(如 solid-js)使用代理追踪响应式和使用情况,需要谨慎处理响应式对象的合并。此选项将合并过程的控制权交给适配器。 + +### `getCoreRowModel` + +```tsx +getCoreRowModel: (table: Table) => () => RowModel +``` + +此必选项是用于计算并返回表格核心行模型的工厂函数。每个表格实例仅调用**一次**,应返回一个**新函数**用于计算和返回行模型。 + +各表格适配器通过 `{ getCoreRowModel }` 导出提供默认实现。 + +### `getSubRows` + +```tsx +getSubRows?: ( + originalRow: TData, + index: number +) => undefined | TData[] +``` + +此可选函数用于获取任意行的子行数据。若使用嵌套行结构,需通过此函数从行数据中返回子行数组(或 undefined)。 + +### `getRowId` + +```tsx +getRowId?: ( + originalRow: TData, + index: number, + parent?: Row +) => string +``` + +此可选函数用于派生行的唯一 ID。未提供时默认使用行索引(嵌套行通过祖先行索引用 `.` 连接,如 `index.index.index`)。若需要标识来自服务端的行数据,建议使用此函数返回具有业务意义的 ID(如 userId、taskId 或数据库 ID 字段等)。 + +## 表格 API + +表格实例上可用的属性和方法: + +### `initialState` + +```tsx +initialState: VisibilityTableState & + ColumnOrderTableState & + ColumnPinningTableState & + FiltersTableState & + SortingTableState & + ExpandedTableState & + GroupingTableState & + ColumnSizingTableState & + PaginationTableState & + RowSelectionTableState +``` + +表格解析后的初始状态。 + +### `reset` + +```tsx +reset: () => void +``` + +调用此函数可将表格状态重置为初始状态。 + +### `getState` + +```tsx +getState: () => TableState +``` + +获取表格当前状态。建议使用此函数及其返回的状态(尤其在手动管理表格状态时),这与表格内部用于所有功能和逻辑的状态完全一致。 + +> 🧠 返回的状态是自动管理的内部状态与通过 `options.state` 传入的手动管理状态的浅合并结果。 + +### `setState` + +```tsx +setState: (updater: Updater) => void +``` + +更新表格状态。建议传入更新函数 `(prevState) => newState`,但也可直接传入状态对象。 + +> 🧠 若提供了 `options.onStateChange`,此函数触发时会调用该回调并传入新状态。 + +### `options` + +```tsx +options: TableOptions +``` + +表格当前选项的只读引用。 + +> ⚠️ 此属性通常供内部或适配器使用。可通过传入新选项更新(具体方式因适配器而异)。适配器必须通过 `setOptions` 函数更新选项。 + +### `setOptions` + +```tsx +setOptions: (newOptions: Updater>) => void +``` + +> ⚠️ 此函数通常由适配器用于更新表格选项。虽然可直接调用,但通常不建议绕过适配器的选项更新策略。 + +### `getCoreRowModel` + +```tsx +getCoreRowModel: () => { + rows: Row[], + flatRows: Row[], + rowsById: Record>, +} +``` + +返回未经任何处理的原始行模型。 + +### `getRowModel` + +```tsx +getRowModel: () => { + rows: Row[], + flatRows: Row[], + rowsById: Record>, +} +``` + +返回经过所有功能处理后的最终行模型。 + +### `getAllColumns` + +```tsx +type getAllColumns = () => Column[] +``` + +返回表格中所有规范化且保持嵌套结构的列(与传入的列定义结构一致)。 + +### `getAllFlatColumns` + +```tsx +type getAllFlatColumns = () => Column[] +``` + +返回所有平铺到单层级的列(包含层次结构中的父列对象)。 + +### `getAllLeafColumns` + +```tsx +type getAllLeafColumns = () => Column[] +``` + +返回所有平铺到单层级的叶子节点列(不包含父列)。 + +### `getColumn` + +```tsx +type getColumn = (id: string) => Column | undefined +``` + +根据 ID 返回单个列。 + +### `getHeaderGroups` + +```tsx +type getHeaderGroups = () => HeaderGroup[] +``` + +返回表格的表头组。 + +### `getFooterGroups` + +```tsx +type getFooterGroups = () => HeaderGroup[] +``` + +返回表格的表尾组。 + +### `getFlatHeaders` + +```tsx +type getFlatHeaders = () => Header[] +``` + +返回平铺的表头对象数组(包含父表头)。 + +### `getLeafHeaders` + +```tsx +type getLeafHeaders = () => Header[] +``` + +返回平铺的叶子节点表头对象数组。 diff --git a/docs/zh-hans/api/features/column-faceting.md b/docs/zh-hans/api/features/column-faceting.md new file mode 100644 index 0000000000..e04ce819c3 --- /dev/null +++ b/docs/zh-hans/api/features/column-faceting.md @@ -0,0 +1,47 @@ +--- +source-updated-at: '2024-03-27T23:32:27.000Z' +translation-updated-at: '2025-05-02T17:34:18.262Z' +title: 列分面 +id: column-faceting +--- +## 列 API (Column API) + +### `getFacetedRowModel` + +```tsx +type getFacetedRowModel = () => RowModel +``` + +> ⚠️ 需要向 `options.facetedRowModel` 传递有效的 `getFacetedRowModel` 函数。默认实现可通过导出的 `getFacetedRowModel` 函数获取。 + +返回应用了其他所有列筛选器(不包括自身筛选器)的行模型 (row model)。适用于展示分面结果计数。 + +### `getFacetedUniqueValues` + +```tsx +getFacetedUniqueValues: () => Map +``` + +> ⚠️ 需要向 `options.getFacetedUniqueValues` 传递有效的 `getFacetedUniqueValues` 函数。默认实现可通过导出的 `getFacetedUniqueValues` 函数获取。 + +该函数会**计算并返回**从 `column.getFacetedRowModel` 派生出的唯一值及其出现次数的 `Map`。适用于展示分面结果值。 + +### `getFacetedMinMaxValues` + +```tsx +getFacetedMinMaxValues: () => Map +``` + +> ⚠️ 需要向 `options.getFacetedMinMaxValues` 传递有效的 `getFacetedMinMaxValues` 函数。默认实现可通过导出的 `getFacetedMinMaxValues` 函数获取。 + +该函数会**计算并返回**从 `column.getFacetedRowModel` 派生出的最小/最大元组。适用于展示分面结果值。 + +## 表格选项 (Table Options) + +### `getColumnFacetedRowModel` + +```tsx +getColumnFacetedRowModel: (columnId: string) => RowModel +``` + +返回指定 columnId 的分面行模型 (faceted row model)。 diff --git a/docs/zh-hans/api/features/column-filtering.md b/docs/zh-hans/api/features/column-filtering.md new file mode 100644 index 0000000000..451791795f --- /dev/null +++ b/docs/zh-hans/api/features/column-filtering.md @@ -0,0 +1,400 @@ +--- +source-updated-at: '2024-03-27T23:32:27.000Z' +translation-updated-at: '2025-05-02T17:34:01.844Z' +title: 列过滤 +id: column-filtering +--- +## 列过滤 API + +## 可过滤性 (Can-Filter) + +列是否支持**列过滤**由以下条件决定: + +- 列定义时提供了有效的 `accessorKey`/`accessorFn` +- `column.enableColumnFilter` 未设置为 `false` +- `options.enableColumnFilters` 未设置为 `false` +- `options.enableFilters` 未设置为 `false` + +## 状态 (State) + +过滤状态以以下形式存储在表格中: + +```tsx +export interface ColumnFiltersTableState { + columnFilters: ColumnFiltersState +} + +export type ColumnFiltersState = ColumnFilter[] + +export interface ColumnFilter { + id: string + value: unknown +} +``` + +## 过滤函数 (Filter Functions) + +表格核心内置了以下过滤函数: + +- `includesString` + - 不区分大小写的字符串包含 +- `includesStringSensitive` + - 区分大小写的字符串包含 +- `equalsString` + - 不区分大小写的字符串相等 +- `equalsStringSensitive` + - 区分大小写的字符串相等 +- `arrIncludes` + - 数组中包含某项 +- `arrIncludesAll` + - 数组中包含所有项 +- `arrIncludesSome` + - 数组中包含某些项 +- `equals` + - 对象/引用相等 `Object.is`/`===` +- `weakEquals` + - 弱对象/引用相等 `==` +- `inNumberRange` + - 数值范围包含 + +每个过滤函数接收: + +- 要过滤的行 +- 用于获取行值的列 ID +- 过滤值 + +如果行应包含在过滤结果中则返回 `true`,否则返回 `false`。 + +以下是所有过滤函数的类型签名: + +```tsx +export type FilterFn = { + ( + row: Row, + columnId: string, + filterValue: any, + addMeta: (meta: any) => void + ): boolean + resolveFilterValue?: TransformFilterValueFn + autoRemove?: ColumnFilterAutoRemoveTestFn + addMeta?: (meta?: any) => void +} + +export type TransformFilterValueFn = ( + value: any, + column?: Column +) => unknown + +export type ColumnFilterAutoRemoveTestFn = ( + value: any, + column?: Column +) => boolean + +export type CustomFilterFns = Record< + string, + FilterFn +> +``` + +### `filterFn.resolveFilterValue` + +此可选方法允许过滤函数在接收过滤值前对其进行转换/清理/格式化。 + +### `filterFn.autoRemove` + +此可选方法接收过滤值,若该值应从过滤状态中移除则返回 `true`。例如,某些布尔型过滤可能在过滤值为 `false` 时希望从表格状态中移除该值。 + +#### 使用过滤函数 + +可通过以下方式使用/引用/定义过滤函数: + +- 引用内置过滤函数的 `string` +- 直接提供给 `columnDefinition.filterFn` 的函数 + +`columnDef.filterFn` 可用的最终过滤函数列表使用以下类型: + +```tsx +export type FilterFnOption = + | 'auto' + | BuiltInFilterFn + | FilterFn +``` + +#### 过滤元数据 (Filter Meta) + +过滤数据时常会暴露可用于后续操作的额外信息。典型例子是类似 [`match-sorter`](https://github.com/kentcdodds/match-sorter) 的排名系统,它能同时排名、过滤和排序数据。虽然此类工具在单维度过滤+排序任务中很实用,但表格的分离式过滤/排序架构使其难以高效使用。 + +为实现排名/过滤/排序系统,`filterFn` 可选择性地用**过滤元数据**标记结果,供后续排序/分组等操作使用。这是通过调用传给自定义 `filterFn` 的 `addMeta` 函数实现的。 + +以下示例使用 `match-sorter-utils` 包对数据进行排名、过滤和排序: + +```tsx +import { sortingFns } from '@tanstack/react-table' + +import { rankItem, compareItems } from '@tanstack/match-sorter-utils' + +const fuzzyFilter = (row, columnId, value, addMeta) => { + // 对项目进行排名 + const itemRank = rankItem(row.getValue(columnId), value) + + // 存储排名信息 + addMeta(itemRank) + + // 返回是否应保留该项目 + return itemRank.passed +} + +const fuzzySort = (rowA, rowB, columnId) => { + let dir = 0 + + // 仅在列有排名信息时排序 + if (rowA.columnFiltersMeta[columnId]) { + dir = compareItems( + rowA.columnFiltersMeta[columnId]!, + rowB.columnFiltersMeta[columnId]! + ) + } + + // 当排名相同时提供字母数字回退 + return dir === 0 ? sortingFns.alphanumeric(rowA, rowB, columnId) : dir +} +``` + +## 列定义选项 (Column Def Options) + +### `filterFn` + +```tsx +filterFn?: FilterFn | keyof FilterFns | keyof BuiltInFilterFns +``` + +用于此列的过滤函数。 + +选项: + +- 引用[内置过滤函数](#filter-functions)的 `string` +- [自定义过滤函数](#filter-functions) + +### `enableColumnFilter` + +```tsx +enableColumnFilter?: boolean +``` + +启用/禁用此列的**列过滤**功能。 + +## 列 API (Column API) + +### `getCanFilter` + +```tsx +getCanFilter: () => boolean +``` + +返回列是否支持**列过滤**。 + +### `getFilterIndex` + +```tsx +getFilterIndex: () => number +``` + +返回列过滤在表格 `state.columnFilters` 数组中的索引(包含 `-1`)。 + +### `getIsFiltered` + +```tsx +getIsFiltered: () => boolean +``` + +返回列当前是否被过滤。 + +### `getFilterValue` + +```tsx +getFilterValue: () => unknown +``` + +返回列的当前过滤值。 + +### `setFilterValue` + +```tsx +setFilterValue: (updater: Updater) => void +``` + +设置列的当前过滤值。可传递值或更新函数以实现不可变操作。 + +### `getAutoFilterFn` + +```tsx +getAutoFilterFn: (columnId: string) => FilterFn | undefined +``` + +根据列的第一个已知值返回自动计算的过滤函数。 + +### `getFilterFn` + +```tsx +getFilterFn: (columnId: string) => FilterFn | undefined +``` + +返回指定列 ID 的过滤函数(用户定义或自动生成,取决于配置)。 + +## 行 API (Row API) + +### `columnFilters` + +```tsx +columnFilters: Record +``` + +行的列过滤映射。此对象跟踪行是否通过特定列 ID 的过滤。 + +### `columnFiltersMeta` + +```tsx +columnFiltersMeta: Record +``` + +行的列过滤元数据映射。此对象跟踪过滤过程中可选提供的任何元数据。 + +## 表格选项 (Table Options) + +### `filterFns` + +```tsx +filterFns?: Record +``` + +此选项允许定义自定义过滤函数,可通过键名在列的 `filterFn` 选项中引用。 + +示例: + +```tsx +declare module '@tanstack/[adapter]-table' { + interface FilterFns { + myCustomFilter: FilterFn + } +} + +const column = columnHelper.data('key', { + filterFn: 'myCustomFilter', +}) + +const table = useReactTable({ + columns: [column], + filterFns: { + myCustomFilter: (rows, columnIds, filterValue) => { + // 返回过滤后的行 + }, + }, +}) +``` + +### `filterFromLeafRows` + +```tsx +filterFromLeafRows?: boolean +``` + +默认情况下,过滤从父行向下进行(若父行被过滤,其所有子行也会被过滤)。设为 `true` 时,过滤从叶子行向上进行(只要子行或孙行被包含,父行也会被包含)。 + +### `maxLeafRowFilterDepth` + +```tsx +maxLeafRowFilterDepth?: number +``` + +默认情况下,所有行(最大深度 100)都会参与过滤。设为 `0` 时仅过滤根级父行,子行不受影响;设为 `1` 时仅过滤一级子行,以此类推。 + +这在需要保持行完整子层级可见的场景中很有用。 + +### `enableFilters` + +```tsx +enableFilters?: boolean +``` + +启用/禁用表格的所有过滤功能。 + +### `manualFiltering` + +```tsx +manualFiltering?: boolean +``` + +禁用使用 `getFilteredRowModel` 过滤数据。在需要动态支持客户端和服务器端过滤时很有用。 + +### `onColumnFiltersChange` + +```tsx +onColumnFiltersChange?: OnChangeFn +``` + +若提供,当 `state.columnFilters` 变化时会调用此函数。这会覆盖默认的内部状态管理,因此需在表格外部完全或部分持久化状态变更。 + +### `enableColumnFilters` + +```tsx +enableColumnFilters?: boolean +``` + +启用/禁用表格的所有列过滤功能。 + +### `getFilteredRowModel` + +```tsx +getFilteredRowModel?: ( + table: Table +) => () => RowModel +``` + +若提供,此函数会被调用一次,并应返回一个新函数来计算和返回过滤后的行模型。 + +- 服务器端过滤无需此函数 +- 客户端过滤需要此函数。各表格适配器通过 `{ getFilteredRowModel }` 导出默认实现 + +示例: + +```tsx +import { getFilteredRowModel } from '@tanstack/[adapter]-table' + + + getFilteredRowModel: getFilteredRowModel(), +}) +``` + +## 表格 API (Table API) + +### `setColumnFilters` + +```tsx +setColumnFilters: (updater: Updater) => void +``` + +设置或更新 `state.columnFilters` 状态。 + +### `resetColumnFilters` + +```tsx +resetColumnFilters: (defaultState?: boolean) => void +``` + +将**columnFilters**状态重置为 `initialState.columnFilters`,或传递 `true` 强制重置为默认空数组 `[]`。 + +### `getPreFilteredRowModel` + +```tsx +getPreFilteredRowModel: () => RowModel +``` + +返回应用**列过滤**前的行模型。 + +### `getFilteredRowModel` + +```tsx +getFilteredRowModel: () => RowModel +``` + +返回应用**列过滤**后的行模型。 diff --git a/docs/zh-hans/api/features/column-ordering.md b/docs/zh-hans/api/features/column-ordering.md new file mode 100644 index 0000000000..c75183a476 --- /dev/null +++ b/docs/zh-hans/api/features/column-ordering.md @@ -0,0 +1,71 @@ +--- +source-updated-at: '2024-02-18T00:06:36.000Z' +translation-updated-at: '2025-05-02T17:34:36.978Z' +title: 列排序 +id: column-ordering +--- +## 状态 (State) + +列的排序状态 (column ordering) 通过以下结构存储在表格中: + +```tsx +export type ColumnOrderTableState = { + columnOrder: ColumnOrderState +} + +export type ColumnOrderState = string[] +``` + +## 表格选项 (Table Options) + +### `onColumnOrderChange` + +```tsx +onColumnOrderChange?: OnChangeFn +``` + +如果提供此函数,当 `state.columnOrder` 发生变化时会调用该函数并传入 `updaterFn`。这将覆盖默认的内部状态管理,因此您需要在表格外部完全或部分持久化状态变更。 + +## 表格 API (Table API) + +### `setColumnOrder` + +```tsx +setColumnOrder: (updater: Updater) => void +``` + +设置或更新 `state.columnOrder` 状态。 + +### `resetColumnOrder` + +```tsx +resetColumnOrder: (defaultState?: boolean) => void +``` + +将 **columnOrder** 状态重置为 `initialState.columnOrder`,或传入 `true` 强制重置为默认空状态 `[]`。 + +## 列 API (Column API) + +### `getIndex` + +```tsx +getIndex: (position?: ColumnPinningPosition) => number +``` + +返回当前列在可见列顺序中的索引。可选传入 `position` 参数以获取列在表格子分区中的索引。 + +### `getIsFirstColumn` + +```tsx +getIsFirstColumn: (position?: ColumnPinningPosition) => boolean +``` + +如果当前列在可见列顺序中处于首位则返回 `true`。可选传入 `position` 参数以检查列是否在表格子分区的首位。 + +### `getIsLastColumn` + +```tsx +getIsLastColumn: (position?: ColumnPinningPosition) => boolean +``` + +如果当前列在可见列顺序中处于末位则返回 `true`。可选传入 `position` 参数以检查列是否在表格子分区的末位。 diff --git a/docs/zh-hans/api/features/column-pinning.md b/docs/zh-hans/api/features/column-pinning.md new file mode 100644 index 0000000000..f95b27e128 --- /dev/null +++ b/docs/zh-hans/api/features/column-pinning.md @@ -0,0 +1,267 @@ +--- +source-updated-at: '2024-03-10T17:31:15.000Z' +translation-updated-at: '2025-05-02T17:35:26.448Z' +title: 列固定 +id: column-pinning +--- +## 列固定 (Column Pinning) 能力 + +列是否可被**固定**取决于以下条件: + +- `options.enablePinning` 未设置为 `false` +- `options.enableColumnPinning` 未设置为 `false` +- `columnDefinition.enablePinning` 未设置为 `false` + +## 状态 (State) + +固定状态通过以下结构存储在表格中: + +```tsx +export type ColumnPinningPosition = false | 'left' | 'right' + +export type ColumnPinningState = { + left?: string[] + right?: string[] +} + + +export type ColumnPinningTableState = { + columnPinning: ColumnPinningState +} +``` + +## 表格选项 (Table Options) + +### `enableColumnPinning` + +```tsx +enableColumnPinning?: boolean +``` + +启用/禁用表格中所有列的固定功能。 + +### `onColumnPinningChange` + +```tsx +onColumnPinningChange?: OnChangeFn +``` + +如果提供,当 `state.columnPinning` 发生变化时,此函数会接收一个 `updaterFn` 被调用。这将覆盖默认的内部状态管理,因此您需要从自行管理的状态中提供 `state.columnPinning`。 + +## 列定义选项 (Column Def Options) + +### `enablePinning` + +```tsx +enablePinning?: boolean +``` + +启用/禁用该列的固定功能。 + +## 表格 API (Table API) + +### `setColumnPinning` + +```tsx +setColumnPinning: (updater: Updater) => void +``` + +设置或更新 `state.columnPinning` 状态。 + +### `resetColumnPinning` + +```tsx +resetColumnPinning: (defaultState?: boolean) => void +``` + +将 **columnPinning** 状态重置为 `initialState.columnPinning`,或传入 `true` 强制重置为默认空状态 `{ left: [], right: [], }`。 + +### `getIsSomeColumnsPinned` + +```tsx +getIsSomeColumnsPinned: (position?: ColumnPinningPosition) => boolean +``` + +返回是否有任何列被固定。可指定仅检查 `left` 或 `right` 位置的固定列。 + +_注意:不考虑列的可见性_ + +### `getLeftHeaderGroups` + +```tsx +getLeftHeaderGroups: () => HeaderGroup[] +``` + +返回表格中左侧固定的表头组。 + +### `getCenterHeaderGroups` + +```tsx +getCenterHeaderGroups: () => HeaderGroup[] +``` + +返回表格中未固定/居中的表头组。 + +### `getRightHeaderGroups` + +```tsx +getRightHeaderGroups: () => HeaderGroup[] +``` + +返回表格中右侧固定的表头组。 + +### `getLeftFooterGroups` + +```tsx +getLeftFooterGroups: () => HeaderGroup[] +``` + +返回表格中左侧固定的表尾组。 + +### `getCenterFooterGroups` + +```tsx +getCenterFooterGroups: () => HeaderGroup[] +``` + +返回表格中未固定/居中的表尾组。 + +### `getRightFooterGroups` + +```tsx +getRightFooterGroups: () => HeaderGroup[] +``` + +返回表格中右侧固定的表尾组。 + +### `getLeftFlatHeaders` + +```tsx +getLeftFlatHeaders: () => Header[] +``` + +返回表格中左侧固定的平铺表头数组,包括父表头。 + +### `getCenterFlatHeaders` + +```tsx +getCenterFlatHeaders: () => Header[] +``` + +返回表格中未固定/居中的平铺表头数组,包括父表头。 + +### `getRightFlatHeaders` + +```tsx +getRightFlatHeaders: () => Header[] +``` + +返回表格中右侧固定的平铺表头数组,包括父表头。 + +### `getLeftLeafHeaders` + +```tsx +getLeftLeafHeaders: () => Header[] +``` + +返回表格中左侧固定的叶子节点表头平铺数组。 + +### `getCenterLeafHeaders` + +```tsx +getCenterLeafHeaders: () => Header[] +``` + +返回表格中未固定/居中的叶子节点表头平铺数组。 + +### `getRightLeafHeaders` + +```tsx +getRightLeafHeaders: () => Header[] +``` + +返回表格中右侧固定的叶子节点表头平铺数组。 + +### `getLeftLeafColumns` + +```tsx +getLeftLeafColumns: () => Column[] +``` + +返回所有左侧固定的叶子列。 + +### `getRightLeafColumns` + +```tsx +getRightLeafColumns: () => Column[] +``` + +返回所有右侧固定的叶子列。 + +### `getCenterLeafColumns` + +```tsx +getCenterLeafColumns: () => Column[] +``` + +返回所有居中固定(未固定)的叶子列。 + +## 列 API (Column API) + +### `getCanPin` + +```tsx +getCanPin: () => boolean +``` + +返回该列是否可被固定。 + +### `getPinnedIndex` + +```tsx +getPinnedIndex: () => number +``` + +返回列在固定列组中的数字索引。 + +### `getIsPinned` + +```tsx +getIsPinned: () => ColumnPinningPosition +``` + +返回列的固定位置。(`'left'`、`'right'` 或 `false`) + +### `pin` + +```tsx +pin: (position: ColumnPinningPosition) => void +``` + +将列固定到 `'left'` 或 `'right'`,或传入 `false` 取消固定到居中位置。 + +## 行 API (Row API) + +### `getLeftVisibleCells` + +```tsx +getLeftVisibleCells: () => Cell[] +``` + +返回行中所有左侧固定的叶子单元格。 + +### `getRightVisibleCells` + +```tsx +getRightVisibleCells: () => Cell[] +``` + +返回行中所有右侧固定的叶子单元格。 + +### `getCenterVisibleCells` + +```tsx +getCenterVisibleCells: () => Cell[] +``` + +返回行中所有居中固定(未固定)的叶子单元格。 diff --git a/docs/zh-hans/api/features/column-sizing.md b/docs/zh-hans/api/features/column-sizing.md new file mode 100644 index 0000000000..292a1f6ff3 --- /dev/null +++ b/docs/zh-hans/api/features/column-sizing.md @@ -0,0 +1,254 @@ +--- +source-updated-at: '2024-02-18T00:06:36.000Z' +translation-updated-at: '2025-05-02T17:36:21.001Z' +title: 列尺寸调整 +id: column-sizing +--- +## 状态 (State) + +列尺寸调整的状态以以下形式存储在表格中: + +```tsx +export type ColumnSizingTableState = { + columnSizing: ColumnSizing + columnSizingInfo: ColumnSizingInfoState +} + +export type ColumnSizing = Record + +export type ColumnSizingInfoState = { + startOffset: null | number + startSize: null | number + deltaOffset: null | number + deltaPercentage: null | number + isResizingColumn: false | string + columnSizingStart: [string, number][] +} +``` + +## 列定义选项 (Column Def Options) + +### `enableResizing` + +```tsx +enableResizing?: boolean +``` + +启用或禁用该列的尺寸调整功能。 + +### `size` + +```tsx +size?: number +``` + +该列的期望尺寸。 + +### `minSize` + +```tsx +minSize?: number +``` + +该列允许的最小尺寸。 + +### `maxSize` + +```tsx +maxSize?: number +``` + +该列允许的最大尺寸。 + +## 列 API (Column API) + +### `getSize` + +```tsx +getSize: () => number +``` + +返回该列的当前尺寸。 + +### `getStart` + +```tsx +getStart: (position?: ColumnPinningPosition) => number +``` + +返回该列沿行轴(通常是标准表格的 x 轴)的偏移量测量值,测量的是所有前列的尺寸之和。 + +适用于列的粘性定位或绝对定位(例如 `left` 或 `transform`)。 + +### `getAfter` + +```tsx +getAfter: (position?: ColumnPinningPosition) => number +``` + +返回该列沿行轴(通常是标准表格的 x 轴)的偏移量测量值,测量的是所有后列的尺寸之和。 + +适用于列的粘性定位或绝对定位(例如 `right` 或 `transform`)。 + +### `getCanResize` + +```tsx +getCanResize: () => boolean +``` + +如果该列可以调整尺寸,则返回 `true`。 + +### `getIsResizing` + +```tsx +getIsResizing: () => boolean +``` + +如果该列当前正在调整尺寸,则返回 `true`。 + +### `resetSize` + +```tsx +resetSize: () => void +``` + +将该列的尺寸重置为其初始尺寸。 + +## 表头 API (Header API) + +### `getSize` + +```tsx +getSize: () => number +``` + +返回表头的尺寸,通过计算属于它的所有叶子列的尺寸之和得出。 + +### `getStart` + +```tsx +getStart: (position?: ColumnPinningPosition) => number +``` + +返回表头沿行轴(通常是标准表格的 x 轴)的偏移量测量值。这实际上是所有前列偏移量测量值的总和。 + +### `getResizeHandler` + +```tsx +getResizeHandler: () => (event: unknown) => void +``` + +返回一个事件处理函数,可用于调整表头尺寸。它可以用作: + +- `onMouseDown` 处理程序 +- `onTouchStart` 处理程序 + +拖拽和释放事件会自动处理。 + +## 表格选项 (Table Options) + +### `enableColumnResizing` + +```tsx +enableColumnResizing?: boolean +``` + +为**所有列**启用或禁用列尺寸调整功能。 + +### `columnResizeMode` + +```tsx +columnResizeMode?: 'onChange' | 'onEnd' +``` + +决定何时更新 columnSizing 状态。`onChange` 在用户拖拽调整尺寸手柄时更新状态,`onEnd` 在用户释放调整尺寸手柄时更新状态。 + +### `columnResizeDirection` + +```tsx +columnResizeDirection?: 'ltr' | 'rtl' +``` + +启用或禁用从右到左的列尺寸调整支持,默认为 'ltr'。 + +### `onColumnSizingChange` + +```tsx +onColumnSizingChange?: OnChangeFn +``` + +当 columnSizing 状态变化时,此可选函数会被调用。如果提供此函数,您需要自行管理其状态。可以通过 `state.columnSizing` 表格选项将此状态传回表格。 + +### `onColumnSizingInfoChange` + +```tsx +onColumnSizingInfoChange?: OnChangeFn +``` + +当 columnSizingInfo 状态变化时,此可选函数会被调用。如果提供此函数,您需要自行管理其状态。可以通过 `state.columnSizingInfo` 表格选项将此状态传回表格。 + +## 表格 API (Table API) + +### `setColumnSizing` + +```tsx +setColumnSizing: (updater: Updater) => void +``` + +使用更新函数或值设置列尺寸调整状态。如果向表格选项传递了 `onColumnSizingChange` 函数,则会触发该函数,否则状态将由表格自动管理。 + +### `setColumnSizingInfo` + +```tsx +setColumnSizingInfo: (updater: Updater) => void +``` + +使用更新函数或值设置列尺寸调整信息状态。如果向表格选项传递了 `onColumnSizingInfoChange` 函数,则会触发该函数,否则状态将由表格自动管理。 + +### `resetColumnSizing` + +```tsx +resetColumnSizing: (defaultState?: boolean) => void +``` + +将列尺寸调整重置为其初始状态。如果 `defaultState` 为 `true`,则会使用表格的默认状态而非提供的初始值。 + +### `resetHeaderSizeInfo` + +```tsx +resetHeaderSizeInfo: (defaultState?: boolean) => void +``` + +将列尺寸调整信息重置为其初始状态。如果 `defaultState` 为 `true`,则会使用表格的默认状态而非提供的初始值。 + +### `getTotalSize` + +```tsx +getTotalSize: () => number +``` + +通过计算所有叶子列的尺寸之和,返回表格的总尺寸。 + +### `getLeftTotalSize` + +```tsx +getLeftTotalSize: () => number +``` + +如果启用了固定列,则通过计算所有左侧叶子列的尺寸之和,返回表格左侧部分的总尺寸。 + +### `getCenterTotalSize` + +```tsx +getCenterTotalSize: () => number +``` + +如果启用了固定列,则通过计算所有未固定/中间叶子列的尺寸之和,返回表格中间部分的总尺寸。 + +### `getRightTotalSize` + +```tsx +getRightTotalSize: () => number +``` + +如果启用了固定列,则通过计算所有右侧叶子列的尺寸之和,返回表格右侧部分的总尺寸。 diff --git a/docs/zh-hans/api/features/column-visibility.md b/docs/zh-hans/api/features/column-visibility.md new file mode 100644 index 0000000000..abad37bbc2 --- /dev/null +++ b/docs/zh-hans/api/features/column-visibility.md @@ -0,0 +1,179 @@ +--- +source-updated-at: '2024-02-18T00:06:36.000Z' +translation-updated-at: '2025-05-02T17:36:53.359Z' +title: 列可见性 +id: column-visibility +--- +## 状态 (State) + +列的可见性状态 (visibility state) 以如下形式存储在表格中: + +```tsx +export type VisibilityState = Record + +export type VisibilityTableState = { + columnVisibility: VisibilityState +} +``` + +## 列定义选项 (Column Def Options) + +### `enableHiding` + +```tsx +enableHiding?: boolean +``` + +启用/禁用列的隐藏功能 + +## 列 API (Column API) + +### `getCanHide` + +```tsx +getCanHide: () => boolean +``` + +返回该列是否可被隐藏 + +### `getIsVisible` + +```tsx +getIsVisible: () => boolean +``` + +返回该列当前是否可见 + +### `toggleVisibility` + +```tsx +toggleVisibility: (value?: boolean) => void +``` + +切换列的可见性状态 + +### `getToggleVisibilityHandler` + +```tsx +getToggleVisibilityHandler: () => (event: unknown) => void +``` + +返回一个用于切换列可见性的函数。该函数可用于将事件处理器绑定到复选框上。 + +## 表格选项 (Table Options) + +### `onColumnVisibilityChange` + +```tsx +onColumnVisibilityChange?: OnChangeFn +``` + +当 `state.columnVisibility` 发生变化时,此回调函数会接收一个 `updaterFn`。这会覆盖默认的内部状态管理,因此您需要在表格外部完全或部分持久化状态变更。 + +### `enableHiding` + +```tsx +enableHiding?: boolean +``` + +启用/禁用所有列的隐藏功能 + +## 表格 API (Table API) + +### `getVisibleFlatColumns` + +```tsx +getVisibleFlatColumns: () => Column[] +``` + +返回包含父列在内的所有可见列的扁平数组 + +### `getVisibleLeafColumns` + +```tsx +getVisibleLeafColumns: () => Column[] +``` + +返回所有可见叶子节点列的扁平数组 + +### `getLeftVisibleLeafColumns` + +```tsx +getLeftVisibleLeafColumns: () => Column[] +``` + +如果启用了列固定 (column pinning),返回左侧可见叶子节点列的扁平数组 + +### `getRightVisibleLeafColumns` + +```tsx +getRightVisibleLeafColumns: () => Column[] +``` + +如果启用了列固定 (column pinning),返回右侧可见叶子节点列的扁平数组 + +### `getCenterVisibleLeafColumns` + +```tsx +getCenterVisibleLeafColumns: () => Column[] +``` + +如果启用了列固定 (column pinning),返回未固定/中间区域可见叶子节点列的扁平数组 + +### `setColumnVisibility` + +```tsx +setColumnVisibility: (updater: Updater) => void +``` + +通过更新函数或值来更新列的可见性状态 + +### `resetColumnVisibility` + +```tsx +resetColumnVisibility: (defaultState?: boolean) => void +``` + +将列的可见性状态重置为初始状态。如果提供了 `defaultState`,状态将被重置为 `{}` + +### `toggleAllColumnsVisible` + +```tsx +toggleAllColumnsVisible: (value?: boolean) => void +``` + +切换所有列的可见性状态 + +### `getIsAllColumnsVisible` + +```tsx +getIsAllColumnsVisible: () => boolean +``` + +返回是否所有列都可见 + +### `getIsSomeColumnsVisible` + +```tsx +getIsSomeColumnsVisible: () => boolean +``` + +返回是否部分列可见 + +### `getToggleAllColumnsVisibilityHandler` + +```tsx +getToggleAllColumnsVisibilityHandler: () => ((event: unknown) => void) +``` + +返回用于切换所有列可见性的处理器函数,通常绑定到 `input[type=checkbox]` 元素上 + +## 行 API (Row API) + +### `getVisibleCells` + +```tsx +getVisibleCells: () => Cell[] +``` + +返回该行中考虑列可见性后的单元格数组 diff --git a/docs/zh-hans/api/features/expanding.md b/docs/zh-hans/api/features/expanding.md new file mode 100644 index 0000000000..ccd508abea --- /dev/null +++ b/docs/zh-hans/api/features/expanding.md @@ -0,0 +1,209 @@ +--- +source-updated-at: '2024-02-18T00:06:36.000Z' +translation-updated-at: '2025-05-02T17:41:33.285Z' +title: 展开 +id: expanding +--- +## 展开状态 (Expanded State) + +展开状态 (expanded state) 以如下形式存储在表格中: + +```tsx +export type ExpandedState = true | Record + +export type ExpandedTableState = { + expanded: ExpandedState +} +``` + +## 行 API (Row API) + +### `toggleExpanded` + +```tsx +toggleExpanded: (expanded?: boolean) => void +``` + +切换行的展开状态(如果提供了 `expanded` 参数则直接设置该状态)。 + +### `getIsExpanded` + +```tsx +getIsExpanded: () => boolean +``` + +返回当前行是否处于展开状态。 + +### `getIsAllParentsExpanded` + +```tsx +getIsAllParentsExpanded: () => boolean +``` + +返回该行的所有父行是否均已展开。 + +### `getCanExpand` + +```tsx +getCanExpand: () => boolean +``` + +返回该行是否允许被展开。 + +### `getToggleExpandedHandler` + +```tsx +getToggleExpandedHandler: () => () => void +``` + +返回一个用于切换行展开状态的函数。该函数可用于绑定按钮的事件处理程序。 + +## 表格选项 (Table Options) + +### `manualExpanding` + +```tsx +manualExpanding?: boolean +``` + +启用手动行展开。若设为 `true`,将不会使用 `getExpandedRowModel` 来展开行,而是需要你在自己的数据模型中处理展开逻辑。适用于服务端展开 (server-side expansion) 场景。 + +### `onExpandedChange` + +```tsx +onExpandedChange?: OnChangeFn +``` + +当表格的 `expanded` 状态变化时调用此函数。如果提供了该函数,你需要自行管理此状态。要将托管状态传回表格,需使用 `tableOptions.state.expanded` 选项。 + +### `autoResetExpanded` + +```tsx +autoResetExpanded?: boolean +``` + +启用此设置可在展开状态变化时自动重置表格的展开状态。 + +### `enableExpanding` + +```tsx +enableExpanding?: boolean +``` + +为所有行启用/禁用展开功能。 + +### `getExpandedRowModel` + +```tsx +getExpandedRowModel?: (table: Table) => () => RowModel +``` + +该函数负责返回展开后的行模型。若未提供,表格将不会展开行。可使用默认导出的 `getExpandedRowModel` 函数获取展开行模型,或自行实现。 + +### `getIsRowExpanded` + +```tsx +getIsRowExpanded?: (row: Row) => boolean +``` + +如果提供,可覆盖默认的行展开状态判断逻辑。 + +### `getRowCanExpand` + +```tsx +getRowCanExpand?: (row: Row) => boolean +``` + +如果提供,可覆盖默认的行可展开性判断逻辑。 + +### `paginateExpandedRows` + +```tsx +paginateExpandedRows?: boolean +``` + +设为 `true` 时,展开的行会与其他行一起参与分页(意味着展开的行可能跨越多页)。 + +设为 `false` 时,展开的行不参与分页(意味着展开的行始终会渲染在其父级所在页面,这会导致实际渲染的行数可能超过设定的页面大小)。 + +## 表格 API (Table API) + +### `setExpanded` + +```tsx +setExpanded: (updater: Updater) => void +``` + +通过更新函数或值来更新表格的展开状态。 + +### `toggleAllRowsExpanded` + +```tsx +toggleAllRowsExpanded: (expanded?: boolean) => void +``` + +切换所有行的展开状态。可选提供参数来直接设置展开状态。 + +### `resetExpanded` + +```tsx +resetExpanded: (defaultState?: boolean) => void +``` + +将表格的展开状态重置为初始状态。若提供 `defaultState` 参数,展开状态会被重置为 `{}`。 + +### `getCanSomeRowsExpand` + +```tsx +getCanSomeRowsExpand: () => boolean +``` + +返回是否存在任何可展开的行。 + +### `getToggleAllRowsExpandedHandler` + +```tsx +getToggleAllRowsExpandedHandler: () => (event: unknown) => void +``` + +返回一个可用于切换所有行展开状态的处理器。该处理器设计用于 `input[type=checkbox]` 元素。 + +### `getIsSomeRowsExpanded` + +```tsx +getIsSomeRowsExpanded: () => boolean +``` + +返回是否存在任何已展开的行。 + +### `getIsAllRowsExpanded` + +```tsx +getIsAllRowsExpanded: () => boolean +``` + +返回是否所有行当前均已展开。 + +### `getExpandedDepth` + +```tsx +getExpandedDepth: () => number +``` + +返回已展开行的最大深度。 + +### `getExpandedRowModel` + +```tsx +getExpandedRowModel: () => RowModel +``` + +返回应用展开操作后的行模型。 + +### `getPreExpandedRowModel` + +```tsx +getPreExpandedRowModel: () => RowModel +``` + +返回应用展开操作前的原始行模型。 diff --git a/docs/zh-hans/api/features/filters.md b/docs/zh-hans/api/features/filters.md new file mode 100644 index 0000000000..0d36b3939b --- /dev/null +++ b/docs/zh-hans/api/features/filters.md @@ -0,0 +1,14 @@ +--- +source-updated-at: '2025-03-20T21:15:29.000Z' +translation-updated-at: '2025-05-06T01:25:13.326Z' +title: Filter APIs +id: filters +--- + + +筛选 API 文档现已拆分为多个 API 文档页面: + +- [列多面筛选 (Column Faceting)](../api/features/column-faceting) +- [全局多面筛选 (Global Faceting)](../api/features/global-faceting) +- [列筛选 (Column Filtering)](../api/features/column-filtering) +- [全局筛选 (Global Filtering)](../api/features/global-filtering) diff --git a/docs/zh-hans/api/features/global-faceting.md b/docs/zh-hans/api/features/global-faceting.md new file mode 100644 index 0000000000..54400e8f56 --- /dev/null +++ b/docs/zh-hans/api/features/global-faceting.md @@ -0,0 +1,31 @@ +--- +source-updated-at: '2024-03-27T23:32:27.000Z' +translation-updated-at: '2025-05-02T17:37:01.678Z' +title: 全局分面 +id: global-faceting +--- +## 表格 API (Table API) + +### `getGlobalFacetedRowModel` + +```tsx +getGlobalFacetedRowModel: () => RowModel +``` + +返回全局筛选器 (global filter) 的分面行模型 (faceted row model)。 + +### `getGlobalFacetedUniqueValues` + +```tsx +getGlobalFacetedUniqueValues: () => Map +``` + +返回全局筛选器 (global filter) 的分面唯一值 (faceted unique values)。 + +### `getGlobalFacetedMinMaxValues` + +```tsx +getGlobalFacetedMinMaxValues: () => [number, number] +``` + +返回全局筛选器 (global filter) 的分面最小值和最大值 (faceted min and max values)。 diff --git a/docs/zh-hans/api/features/global-filtering.md b/docs/zh-hans/api/features/global-filtering.md new file mode 100644 index 0000000000..8996cb81c8 --- /dev/null +++ b/docs/zh-hans/api/features/global-filtering.md @@ -0,0 +1,289 @@ +--- +source-updated-at: '2025-03-20T21:15:29.000Z' +translation-updated-at: '2025-05-02T17:38:15.249Z' +title: 全局过滤 +id: global-filtering +--- +## 可全局过滤 (Can-Filter) + +列是否支持**全局**过滤由以下条件决定: + +- 列已定义有效的 `accessorKey`/`accessorFn` +- 如果提供了 `options.getColumnCanGlobalFilter`,则需对指定列返回 `true`;若未提供,则当首行值为 `string` 或 `number` 类型时默认该列可全局过滤 +- `column.enableColumnFilter` 未设为 `false` +- `options.enableColumnFilters` 未设为 `false` +- `options.enableFilters` 未设为 `false` + +## 状态 (State) + +过滤状态以如下形式存储在表格中: + +```tsx +export interface GlobalFilterTableState { + globalFilter: any +} +``` + +## 过滤函数 (Filter Functions) + +全局过滤可使用与列过滤相同的过滤函数。详见[列过滤 API](../api/features/column-filtering)了解过滤函数详情。 + +#### 使用过滤函数 (Using Filter Functions) + +通过以下方式向 `options.globalFilterFn` 传递参数来使用/引用/定义过滤函数: +- 引用内置过滤函数的 `string` 字符串 +- 直接提供给 `options.globalFilterFn` 的函数 + +`tableOptions.globalFilterFn` 可用的最终过滤函数列表使用以下类型: + +```tsx +export type FilterFnOption = + | 'auto' + | BuiltInFilterFn + | FilterFn +``` + +#### 过滤元数据 (Filter Meta) + +过滤数据时通常会暴露数据的附加信息,这些信息可用于辅助后续操作。典型例子是类似 [`match-sorter`](https://github.com/kentcdodds/match-sorter) 的排名系统,它能同时实现排名、过滤和排序。虽然此类工具在单维度过滤+排序场景中很实用,但表格解耦的过滤/排序架构会导致使用效率低下。 + +为实现排名/过滤/排序系统与表格的协同工作,`filterFn` 可选择用**过滤元数据 (filter meta)** 标记结果,这些元数据后续可用于按需排序/分组等操作。具体实现方式是在自定义 `filterFn` 中调用提供的 `addMeta` 函数。 + +以下示例使用我们自己的 `match-sorter-utils` 包(`match-sorter` 的工具分支)对数据进行排名、过滤和排序: + +```tsx +import { sortingFns } from '@tanstack/[adapter]-table' + +import { rankItem, compareItems } from '@tanstack/match-sorter-utils' + +const fuzzyFilter = (row, columnId, value, addMeta) => { + // 对项目进行排名 + const itemRank = rankItem(row.getValue(columnId), value) + + // 存储排名信息 + addMeta(itemRank) + + // 返回该项目是否应被保留 + return itemRank.passed +} + +const fuzzySort = (rowA, rowB, columnId) => { + let dir = 0 + + // 仅在列有排名信息时进行排序 + if (rowA.columnFiltersMeta[columnId]) { + dir = compareItems( + rowA.columnFiltersMeta[columnId]!, + rowB.columnFiltersMeta[columnId]! + ) + } + + // 当排名相同时提供字母数字回退方案 + return dir === 0 ? sortingFns.alphanumeric(rowA, rowB, columnId) : dir +} +``` + +## 列定义选项 (Column Def Options) + +### `enableGlobalFilter` + +```tsx +enableGlobalFilter?: boolean +``` + +启用/禁用该列的**全局**过滤功能。 + +## 列 API (Column API) + +### `getCanGlobalFilter` + +```tsx +getCanGlobalFilter: () => boolean +``` + +返回该列是否可**全局**过滤。设为 `false` 可禁止在全局过滤时扫描该列。 + +## 行 API (Row API) + +### `columnFiltersMeta` + +```tsx +columnFiltersMeta: Record +``` + +该行的列过滤元数据映射。此对象跟踪过滤过程中可选提供的行过滤元数据。 + +## 表格选项 (Table Options) + +### `filterFns` + +```tsx +filterFns?: Record +``` + +此选项允许定义自定义过滤函数,可通过键名在列的 `filterFn` 选项中引用。 +示例: + +```tsx +declare module '@tanstack/table-core' { + interface FilterFns { + myCustomFilter: FilterFn + } +} + +const column = columnHelper.data('key', { + filterFn: 'myCustomFilter', +}) + +const table = useReactTable({ + columns: [column], + filterFns: { + myCustomFilter: (rows, columnIds, filterValue) => { + // 返回过滤后的行 + }, + }, +}) +``` + +### `filterFromLeafRows` + +```tsx +filterFromLeafRows?: boolean +``` + +默认情况下,过滤从父行向下执行(若父行被过滤,其所有子行也会被过滤)。将此选项设为 `true` 会使过滤从叶子行向上执行(只要某个子行或孙行被包含,其父行就会被包含)。 + +### `maxLeafRowFilterDepth` + +```tsx +maxLeafRowFilterDepth?: number +``` + +默认情况下,所有行都会参与过滤(最大深度100),无论它们是根级父行还是子行。设为 `0` 时仅过滤根级父行,所有子行保持未过滤状态;设为 `1` 时仅过滤1层深度的子行,以此类推。 + +这在需要保持行子层级可见性的场景中非常有用。 + +### `enableFilters` + +```tsx +enableFilters?: boolean +``` + +启用/禁用表格的所有过滤功能。 + +### `manualFiltering` + +```tsx +manualFiltering?: boolean +``` + +禁用使用 `getFilteredRowModel` 进行数据过滤。当表格需要动态支持客户端和服务器端过滤时非常有用。 + +### `getFilteredRowModel` + +```tsx +getFilteredRowModel?: ( + table: Table +) => () => RowModel +``` + +若提供,此函数每个表格调用**一次**,应返回**新函数**用于计算并返回过滤后的行模型。 + +- 服务器端过滤场景无需此函数 +- 客户端过滤场景必须提供此函数。各适配器通过 `{ getFilteredRowModel }` 导出默认实现 + +示例: + +```tsx +import { getFilteredRowModel } from '@tanstack/[adapter]-table' + + getFilteredRowModel: getFilteredRowModel(), +}) +``` + +### `globalFilterFn` + +```tsx +globalFilterFn?: FilterFn | keyof FilterFns | keyof BuiltInFilterFns +``` + +用于全局过滤的过滤函数。 + +选项: +- 引用[内置过滤函数](#filter-functions)的 `string` +- 引用通过 `tableOptions.filterFns` 提供的自定义过滤函数的 `string` +- [自定义过滤函数](#filter-functions) + +### `onGlobalFilterChange` + +```tsx +onGlobalFilterChange?: OnChangeFn +``` + +若提供,当 `state.globalFilter` 变化时会使用 `updaterFn` 调用此函数。这将覆盖默认的内部状态管理,因此需在表格外部完全或部分持久化状态变更。 + +### `enableGlobalFilter` + +```tsx +enableGlobalFilter?: boolean +``` + +启用/禁用表格的全局过滤功能。 + +### `getColumnCanGlobalFilter` + +```tsx +getColumnCanGlobalFilter?: (column: Column) => boolean +``` + +若提供,此函数会被传入列对象并返回 `true` 或 `false` 以指示该列是否应用于全局过滤。当列可能包含非 `string` 或 `number` 数据(如 `undefined`)时非常有用。 + +## 表格 API (Table API) + +### `getPreFilteredRowModel` + +```tsx +getPreFilteredRowModel: () => RowModel +``` + +返回在应用任何**列**过滤前的表格行模型。 + +### `getFilteredRowModel` + +```tsx +getFilteredRowModel: () => RowModel +``` + +返回应用**列**过滤后的表格行模型。 + +### `setGlobalFilter` + +```tsx +setGlobalFilter: (updater: Updater) => void +``` + +设置或更新 `state.globalFilter` 状态。 + +### `resetGlobalFilter` + +```tsx +resetGlobalFilter: (defaultState?: boolean) => void +``` + +将 **globalFilter** 状态重置为 `initialState.globalFilter`,或传入 `true` 强制重置为默认空状态 `undefined`。 + +### `getGlobalAutoFilterFn` + +```tsx +getGlobalAutoFilterFn: (columnId: string) => FilterFn | undefined +``` + +当前此函数返回内置的 `includesString` 过滤函数。未来版本中可能根据数据特性返回更动态的过滤函数。 + +### `getGlobalFilterFn` + +```tsx +getGlobalFilterFn: (columnId: string) => FilterFn | undefined +``` + +返回表格的全局过滤函数(根据配置可能是用户定义或自动选择的函数)。 diff --git a/docs/zh-hans/api/features/grouping.md b/docs/zh-hans/api/features/grouping.md new file mode 100644 index 0000000000..806e346414 --- /dev/null +++ b/docs/zh-hans/api/features/grouping.md @@ -0,0 +1,354 @@ +--- +source-updated-at: '2024-02-18T00:06:36.000Z' +translation-updated-at: '2025-05-02T17:40:52.107Z' +title: 分组 +id: grouping +--- +## 分组状态 (Grouping State) + +分组状态 (grouping state) 以如下形式存储在表格中: + +```tsx +export type GroupingState = string[] + +export type GroupingTableState = { + grouping: GroupingState +} +``` + +## 聚合函数 (Aggregation Functions) + +表格核心内置了以下聚合函数 (aggregation functions): + +- `sum` + - 对一组行的值进行求和 +- `min` + - 找出一组行的最小值 +- `max` + - 找出一组行的最大值 +- `extent` + - 找出一组行的最小值和最大值 +- `mean` + - 计算一组行的平均值 +- `median` + - 找出一组行的中位数 +- `unique` + - 找出一组行的唯一值 +- `uniqueCount` + - 计算一组行中唯一值的数量 +- `count` + - 计算一组行的数量 + +每个聚合函数都会接收: + +- 一个用于获取分组行叶子值 (leaf values) 的函数 +- 一个用于获取分组行直接子值 (immediate-child values) 的函数 + +并应返回一个值(通常是原始值)来构建聚合行模型 (aggregated row model)。 + +以下是所有聚合函数的类型签名: + +```tsx +export type AggregationFn = ( + getLeafRows: () => Row[], + getChildRows: () => Row[] +) => any +``` + +#### 使用聚合函数 (Using Aggregation Functions) + +可以通过以下方式使用/引用/定义聚合函数,并将其传递给 `columnDefinition.aggregationFn`: + +- 引用内置聚合函数的 `string` +- 引用通过 `tableOptions.aggregationFns` 选项提供的自定义聚合函数的 `string` +- 直接提供给 `columnDefinition.aggregationFn` 选项的函数 + +`columnDef.aggregationFn` 可用的最终聚合函数列表使用以下类型: + +```tsx +export type AggregationFnOption = + | 'auto' + | keyof AggregationFns + | BuiltInAggregationFn + | AggregationFn +``` + +## 列定义选项 (Column Def Options) + +### `aggregationFn` + +```tsx +aggregationFn?: AggregationFn | keyof AggregationFns | keyof BuiltInAggregationFns +``` + +用于此列的聚合函数。 + +选项: + +- 引用[内置聚合函数](#聚合函数-aggregation-functions)的 `string` +- [自定义聚合函数](#聚合函数-aggregation-functions) + +### `aggregatedCell` + +```tsx +aggregatedCell?: Renderable< + { + table: Table + row: Row + column: Column + cell: Cell + getValue: () => any + renderValue: () => any + } +> +``` + +如果单元格是聚合单元格,则为该列每行显示的单元格。如果传入函数,则会传入包含单元格上下文的 props 对象,并应返回适配器所需的属性类型(具体类型取决于使用的适配器)。 + +### `enableGrouping` + +```tsx +enableGrouping?: boolean +``` + +启用/禁用此列的分组功能。 + +### `getGroupingValue` + +```tsx +getGroupingValue?: (row: TData) => any +``` + +指定用于在此列上分组行的值。如果未指定此选项,则将使用从 `accessorKey` / `accessorFn` 派生的值。 + +## 列 API (Column API) + +### `aggregationFn` + +```tsx +aggregationFn?: AggregationFnOption +``` + +列解析后的聚合函数。 + +### `getCanGroup` + +```tsx +getCanGroup: () => boolean +``` + +返回列是否可以分组。 + +### `getIsGrouped` + +```tsx +getIsGrouped: () => boolean +``` + +返回列当前是否已分组。 + +### `getGroupedIndex` + +```tsx +getGroupedIndex: () => number +``` + +返回列在分组状态 (grouping state) 中的索引。 + +### `toggleGrouping` + +```tsx +toggleGrouping: () => void +``` + +切换列的分组状态。 + +### `getToggleGroupingHandler` + +```tsx +getToggleGroupingHandler: () => () => void +``` + +返回一个切换列分组状态的函数。这对于传递给按钮的 `onClick` 属性非常有用。 + +### `getAutoAggregationFn` + +```tsx +getAutoAggregationFn: () => AggregationFn | undefined +``` + +返回列自动推断的聚合函数。 + +### `getAggregationFn` + +```tsx +getAggregationFn: () => AggregationFn | undefined +``` + +返回列的聚合函数。 + +## 行 API (Row API) + +### `groupingColumnId` + +```tsx +groupingColumnId?: string +``` + +如果此行已分组,则为该行分组依据的列 ID。 + +### `groupingValue` + +```tsx +groupingValue?: any +``` + +如果此行已分组,则为该组所有行在 `groupingColumnId` 上的唯一/共享值。 + +### `getIsGrouped` + +```tsx +getIsGrouped: () => boolean +``` + +返回行当前是否已分组。 + +### `getGroupingValue` + +```tsx +getGroupingValue: (columnId: string) => unknown +``` + +返回任何行和列(包括叶子行)的分组值。 + +## 表格选项 (Table Options) + +### `aggregationFns` + +```tsx +aggregationFns?: Record +``` + +此选项允许您定义自定义聚合函数,可以通过键在列的 `aggregationFn` 选项中引用。 +示例: + +```tsx +declare module '@tanstack/table-core' { + interface AggregationFns { + myCustomAggregation: AggregationFn + } +} + +const column = columnHelper.data('key', { + aggregationFn: 'myCustomAggregation', +}) + +const table = useReactTable({ + columns: [column], + aggregationFns: { + myCustomAggregation: (columnId, leafRows, childRows) => { + // 返回聚合值 + }, + }, +}) +``` + +### `manualGrouping` + +```tsx +manualGrouping?: boolean +``` + +启用手动分组。如果此选项设置为 `true`,表格将不会自动使用 `getGroupedRowModel()` 分组行,而是期望您在将行传递给表格之前手动分组。这对于进行服务端分组和聚合非常有用。 + +### `onGroupingChange` + +```tsx +onGroupingChange?: OnChangeFn +``` + +如果提供了此函数,当分组状态发生变化时会调用它,您需要自行管理状态。您可以通过 `tableOptions.state.grouping` 选项将托管状态传递回表格。 + +### `enableGrouping` + +```tsx +enableGrouping?: boolean +``` + +启用/禁用所有列的分组功能。 + +### `getGroupedRowModel` + +```tsx +getGroupedRowModel?: (table: Table) => () => RowModel +``` + +返回分组完成后的行模型,但不进行进一步处理。 + +### `groupedColumnMode` + +```tsx +groupedColumnMode?: false | 'reorder' | 'remove' // 默认: `reorder` +``` + +分组列默认会自动重新排序到列列表的开头。如果您希望删除它们或保持原样,请在此处设置适当的模式。 + +## 表格 API (Table API) + +### `setGrouping` + +```tsx +setGrouping: (updater: Updater) => void +``` + +设置或更新 `state.grouping` 状态。 + +### `resetGrouping` + +```tsx +resetGrouping: (defaultState?: boolean) => void +``` + +将**分组**状态重置为 `initialState.grouping`,或者可以传递 `true` 强制重置为默认空白状态 `[]`。 + +### `getPreGroupedRowModel` + +```tsx +getPreGroupedRowModel: () => RowModel +``` + +返回应用任何分组之前的表格行模型。 + +### `getGroupedRowModel` + +```tsx +getGroupedRowModel: () => RowModel +``` + +返回应用分组后的表格行模型。 + +## 单元格 API (Cell API) + +### `getIsAggregated` + +```tsx +getIsAggregated: () => boolean +``` + +返回单元格当前是否为聚合单元格。 + +### `getIsGrouped` + +```tsx +getIsGrouped: () => boolean +``` + +返回单元格当前是否为分组单元格。 + +### `getIsPlaceholder` + +```tsx +getIsPlaceholder: () => boolean +``` + +返回单元格当前是否为占位符单元格。 diff --git a/docs/zh-hans/api/features/pagination.md b/docs/zh-hans/api/features/pagination.md new file mode 100644 index 0000000000..38fa3de0a0 --- /dev/null +++ b/docs/zh-hans/api/features/pagination.md @@ -0,0 +1,208 @@ +--- +source-updated-at: '2024-02-27T21:03:18.000Z' +translation-updated-at: '2025-05-02T17:42:17.326Z' +title: 分页 +id: pagination +--- +## 分页状态 (Pagination State) + +分页状态以如下结构存储在表格中: + +```tsx +export type PaginationState = { + pageIndex: number + pageSize: number +} + +export type PaginationTableState = { + pagination: PaginationState +} + +export type PaginationInitialTableState = { + pagination?: Partial +} +``` + +## 表格选项 (Table Options) + +### `manualPagination` + +```tsx +manualPagination?: boolean +``` + +启用手动分页。若设为 `true`,表格不会自动使用 `getPaginationRowModel()` 分页行数据,而是期望你在传入数据前手动完成分页。适用于服务端分页 (server-side pagination) 和聚合场景。 + +### `pageCount` + +```tsx +pageCount?: number +``` + +在手动控制分页时,如果已知总页数可传入此值。若页数未知可设为 `-1`。替代方案是提供 `rowCount` 值,表格会据此内部计算 `pageCount`。 + +### `rowCount` + +```tsx +rowCount?: number +``` + +在手动控制分页时,如果已知总行数可传入此值。`pageCount` 将根据 `rowCount` 和 `pageSize` 内部计算得出。 + +### `autoResetPageIndex` + +```tsx +autoResetPageIndex?: boolean +``` + +设为 `true` 时,当发生影响分页的状态变更(如 `data` 更新、筛选条件变化、分组变化等),分页将重置到第一页。 + +> 🧠 注意:若 `manualPagination` 为 `true`,此选项默认为 `false` + +### `onPaginationChange` + +```tsx +onPaginationChange?: OnChangeFn +``` + +提供此函数后,分页状态变化时会调用该函数,此时需自行管理状态。可通过 `tableOptions.state.pagination` 将管理后的状态传回表格。 + +### `getPaginationRowModel` + +```tsx +getPaginationRowModel?: (table: Table) => () => RowModel +``` + +返回仅经过分页处理后的行模型 (row model)。 + +默认情况下分页列会自动重排到列列表开头。若需保留原顺序或移除分页列,可在此设置对应模式。 + +## 表格 API (Table API) + +### `setPagination` + +```tsx +setPagination: (updater: Updater) => void +``` + +设置或更新 `state.pagination` 状态。 + +### `resetPagination` + +```tsx +resetPagination: (defaultState?: boolean) => void +``` + +将分页状态重置为 `initialState.pagination`,传入 `true` 可强制重置为默认空状态 `[]`。 + +### `setPageIndex` + +```tsx +setPageIndex: (updater: Updater) => void +``` + +使用指定函数或值更新当前页码 (page index)。 + +### `resetPageIndex` + +```tsx +resetPageIndex: (defaultState?: boolean) => void +``` + +重置页码至初始状态。若 `defaultState` 为 `true`,无论初始状态如何都会重置为 `0`。 + +### `setPageSize` + +```tsx +setPageSize: (updater: Updater) => void +``` + +使用指定函数或值更新每页大小 (page size)。 + +### `resetPageSize` + +```tsx +resetPageSize: (defaultState?: boolean) => void +``` + +重置每页大小至初始状态。若 `defaultState` 为 `true`,无论初始状态如何都会重置为 `10`。 + +### `getPageOptions` + +```tsx +getPageOptions: () => number[] +``` + +返回基于当前每页大小的页码选项数组(从零开始索引)。 + +### `getCanPreviousPage` + +```tsx +getCanPreviousPage: () => boolean +``` + +返回表格是否能跳转到上一页。 + +### `getCanNextPage` + +```tsx +getCanNextPage: () => boolean +``` + +返回表格是否能跳转到下一页。 + +### `previousPage` + +```tsx +previousPage: () => void +``` + +将当前页码减一(如果允许)。 + +### `nextPage` + +```tsx +nextPage: () => void +``` + +将当前页码加一(如果允许)。 + +### `firstPage` + +```tsx +firstPage: () => void +``` + +跳转到第一页(页码设为 `0`)。 + +### `lastPage` + +```tsx +lastPage: () => void +``` + +跳转到最后一页。 + +### `getPageCount` + +```tsx +getPageCount: () => number +``` + +返回总页数。如果是手动分页或控制分页状态,此值直接来自 `options.pageCount` 选项,否则会根据总行数和当前每页大小计算得出。 + +### `getPrePaginationRowModel` + +```tsx +getPrePaginationRowModel: () => RowModel +``` + +返回未应用分页前的原始行模型。 + +### `getPaginationRowModel` + +```tsx +getPaginationRowModel: () => RowModel +``` + +返回应用分页处理后的行模型。 diff --git a/docs/zh-hans/api/features/pinning.md b/docs/zh-hans/api/features/pinning.md new file mode 100644 index 0000000000..557d0409be --- /dev/null +++ b/docs/zh-hans/api/features/pinning.md @@ -0,0 +1,12 @@ +--- +source-updated-at: '2025-03-20T21:15:29.000Z' +translation-updated-at: '2025-05-06T01:25:11.923Z' +title: Pinning APIs +id: pinning +--- + + +固定 (Pinning) API 现已拆分为多个 API 页面: + +- [列固定 (Column Pinning)](../api/features/column-pinning) +- [行固定 (Row Pinning)](../api/features/row-pinning) diff --git a/docs/zh-hans/api/features/row-pinning.md b/docs/zh-hans/api/features/row-pinning.md new file mode 100644 index 0000000000..957a6a0080 --- /dev/null +++ b/docs/zh-hans/api/features/row-pinning.md @@ -0,0 +1,141 @@ +--- +source-updated-at: '2024-06-30T17:39:45.000Z' +translation-updated-at: '2025-05-02T17:42:47.963Z' +title: 行固定 +id: row-pinning +--- +## 行固定 (Row Pinning) API + +## 能否固定 (Can-Pin) + +行的**固定**能力由以下条件决定: + +- `options.enableRowPinning` 解析为 `true` +- `options.enablePinning` 未设置为 `false` + +## 状态 (State) + +固定状态以以下形式存储在表格中: + +```tsx +export type RowPinningPosition = false | 'top' | 'bottom' + +export type RowPinningState = { + top?: string[] + bottom?: string[] +} + +export type RowPinningRowState = { + rowPinning: RowPinningState +} +``` + +## 表格选项 (Table Options) + +### `enableRowPinning` + +```tsx +enableRowPinning?: boolean | ((row: Row) => boolean) +``` + +启用/禁用表格中所有行的固定功能。 + +### `keepPinnedRows` + +```tsx +keepPinnedRows?: boolean +``` + +当值为 `false` 时,如果固定行被过滤或分页移出表格,它们将不可见。当值为 `true` 时,固定行将始终可见,不受过滤或分页影响。默认为 `true`。 + +### `onRowPinningChange` + +```tsx +onRowPinningChange?: OnChangeFn +``` + +如果提供此函数,当 `state.rowPinning` 发生变化时,将调用该函数并传入 `updaterFn`。这会覆盖默认的内部状态管理,因此您还需要从自己管理的状态中提供 `state.rowPinning`。 + +## 表格 API (Table API) + +### `setRowPinning` + +```tsx +setRowPinning: (updater: Updater) => void +``` + +设置或更新 `state.rowPinning` 状态。 + +### `resetRowPinning` + +```tsx +resetRowPinning: (defaultState?: boolean) => void +``` + +将 **rowPinning** 状态重置为 `initialState.rowPinning`,或者可以传递 `true` 强制重置为默认空状态 `{}`。 + +### `getIsSomeRowsPinned` + +```tsx +getIsSomeRowsPinned: (position?: RowPinningPosition) => boolean +``` + +返回是否有任何行被固定。可选指定仅检查 `top` 或 `bottom` 位置的固定行。 + +### `getTopRows` + +```tsx +getTopRows: () => Row[] +``` + +返回所有固定在顶部的行。 + +### `getBottomRows` + +```tsx +getBottomRows: () => Row[] +``` + +返回所有固定在底部的行。 + +### `getCenterRows` + +```tsx +getCenterRows: () => Row[] +``` + +返回所有未固定在顶部或底部的行。 + +## 行 API (Row API) + +### `pin` + +```tsx +pin: (position: RowPinningPosition) => void +``` + +将行固定在 `'top'` 或 `'bottom'`,如果传入 `false` 则取消固定到中间位置。 + +### `getCanPin` + +```tsx +getCanPin: () => boolean +``` + +返回该行是否可以被固定。 + +### `getIsPinned` + +```tsx +getIsPinned: () => RowPinningPosition +``` + +返回行的固定位置(`'top'`、`'bottom'` 或 `false`)。 + +### `getPinnedIndex` + +```tsx +getPinnedIndex: () => number +``` + +返回行在固定行组中的数字索引位置。 diff --git a/docs/zh-hans/api/features/row-selection.md b/docs/zh-hans/api/features/row-selection.md new file mode 100644 index 0000000000..a490b81064 --- /dev/null +++ b/docs/zh-hans/api/features/row-selection.md @@ -0,0 +1,231 @@ +--- +source-updated-at: '2025-03-20T21:15:29.000Z' +translation-updated-at: '2025-05-02T17:43:33.690Z' +title: 行选择 +id: row-selection +--- +## 状态 (State) + +行选择状态 (Row Selection) 在表格中使用以下结构存储: + +```tsx +export type RowSelectionState = Record + +export type RowSelectionTableState = { + rowSelection: RowSelectionState +} +``` + +默认情况下,行选择状态使用每行的索引作为行标识符。也可以通过向表格传入自定义的 [getRowId](../core/table.md#getrowid) 函数,使用自定义的唯一行 ID 来跟踪行选择状态。 + +## 表格选项 (Table Options) + +### `enableRowSelection` + +```tsx +enableRowSelection?: boolean | ((row: Row) => boolean) +``` + +- 启用/禁用表格中所有行的行选择功能,或 +- 一个接收行数据并返回是否启用该行选择功能的函数 + +### `enableMultiRowSelection` + +```tsx +enableMultiRowSelection?: boolean | ((row: Row) => boolean) +``` + +- 启用/禁用表格中所有行的多行选择功能,或 +- 一个接收行数据并返回是否启用该行的子行/孙行多行选择功能的函数 + +### `enableSubRowSelection` + +```tsx +enableSubRowSelection?: boolean | ((row: Row) => boolean) +``` + +启用/禁用当父行被选中时自动选择子行的功能,或一个为每行启用/禁用自动子行选择功能的函数。 + +(需与展开或分组功能结合使用) + +### `onRowSelectionChange` + +```tsx +onRowSelectionChange?: OnChangeFn +``` + +如果提供,当 `state.rowSelection` 发生变化时,此函数将被调用并传入一个 `updaterFn`。这会覆盖默认的内部状态管理,因此您需要在表格外部完全或部分地持久化状态变更。 + +## 表格 API (Table API) + +### `getToggleAllRowsSelectedHandler` + +```tsx +getToggleAllRowsSelectedHandler: () => (event: unknown) => void +``` + +返回一个可用于切换表格中所有行选择状态的处理器。 + +### `getToggleAllPageRowsSelectedHandler` + +```tsx +getToggleAllPageRowsSelectedHandler: () => (event: unknown) => void +``` + +返回一个可用于切换当前页所有行选择状态的处理器。 + +### `setRowSelection` + +```tsx +setRowSelection: (updater: Updater) => void +``` + +设置或更新 `state.rowSelection` 状态。 + +### `resetRowSelection` + +```tsx +resetRowSelection: (defaultState?: boolean) => void +``` + +将 **rowSelection** 状态重置为 `initialState.rowSelection`,或传入 `true` 强制重置为默认空状态 `{}`。 + +### `getIsAllRowsSelected` + +```tsx +getIsAllRowsSelected: () => boolean +``` + +返回表格中所有行是否均被选中。 + +### `getIsAllPageRowsSelected` + +```tsx +getIsAllPageRowsSelected: () => boolean +``` + +返回当前页所有行是否均被选中。 + +### `getIsSomeRowsSelected` + +```tsx +getIsSomeRowsSelected: () => boolean +``` + +返回表格中是否有任意行被选中。 + +注意:如果所有行均被选中则返回 `false`。 + +### `getIsSomePageRowsSelected` + +```tsx +getIsSomePageRowsSelected: () => boolean +``` + +返回当前页是否有任意行被选中。 + +### `toggleAllRowsSelected` + +```tsx +toggleAllRowsSelected: (value: boolean) => void +``` + +选中/取消选中表格中所有行。 + +### `toggleAllPageRowsSelected` + +```tsx +toggleAllPageRowsSelected: (value: boolean) => void +``` + +选中/取消选中当前页所有行。 + +### `getPreSelectedRowModel` + +```tsx +getPreSelectedRowModel: () => RowModel +``` + +### `getSelectedRowModel` + +```tsx +getSelectedRowModel: () => RowModel +``` + +### `getFilteredSelectedRowModel` + +```tsx +getFilteredSelectedRowModel: () => RowModel +``` + +### `getGroupedSelectedRowModel` + +```tsx +getGroupedSelectedRowModel: () => RowModel +``` + +## 行 API (Row API) + +### `getIsSelected` + +```tsx +getIsSelected: () => boolean +``` + +返回该行是否被选中。 + +### `getIsSomeSelected` + +```tsx +getIsSomeSelected: () => boolean +``` + +返回该行的部分子行是否被选中。 + +### `getIsAllSubRowsSelected` + +```tsx +getIsAllSubRowsSelected: () => boolean +``` + +返回该行的所有子行是否均被选中。 + +### `getCanSelect` + +```tsx +getCanSelect: () => boolean +``` + +返回该行是否可被选中。 + +### `getCanMultiSelect` + +```tsx +getCanMultiSelect: () => boolean +``` + +返回该行是否支持多选。 + +### `getCanSelectSubRows` + +```tsx +getCanSelectSubRows: () => boolean +``` + +返回当父行被选中时是否自动选择子行。 + +### `toggleSelected` + +```tsx +toggleSelected: (value?: boolean) => void +``` + +选中/取消选中该行。 + +### `getToggleSelectedHandler` + +```tsx +getToggleSelectedHandler: () => (event: unknown) => void +``` + +返回一个可用于切换该行选择状态的处理器。 diff --git a/docs/zh-hans/api/features/sorting.md b/docs/zh-hans/api/features/sorting.md new file mode 100644 index 0000000000..d970d9dabd --- /dev/null +++ b/docs/zh-hans/api/features/sorting.md @@ -0,0 +1,386 @@ +--- +source-updated-at: '2024-04-13T00:46:18.000Z' +translation-updated-at: '2025-05-02T17:39:40.057Z' +title: 排序 +id: sorting +--- +## 排序状态 (Sorting State) + +排序状态以以下形式存储在表格中: + +```tsx +export type SortDirection = 'asc' | 'desc' + +export type ColumnSort = { + id: string + desc: boolean +} + +export type SortingState = ColumnSort[] + +export type SortingTableState = { + sorting: SortingState +} +``` + +## 排序函数 (Sorting Functions) + +表格核心内置了以下排序函数: + +- `alphanumeric` + - 不区分大小写地按字母数字混合值排序。速度较慢,但如果字符串中包含需要自然排序的数字会更准确。 +- `alphanumericCaseSensitive` + - 区分大小写地按字母数字混合值排序。速度较慢,但如果字符串中包含需要自然排序的数字会更准确。 +- `text` + - 不区分大小写地按文本/字符串值排序。速度较快,但如果字符串中包含需要自然排序的数字则准确性较低。 +- `textCaseSensitive` + - 区分大小写地按文本/字符串值排序。速度较快,但如果字符串中包含需要自然排序的数字则准确性较低。 +- `datetime` + - 按时间排序,如果值是 `Date` 对象请使用此函数。 +- `basic` + - 使用基本的 `a > b ? 1 : a < b ? -1 : 0` 比较进行排序。这是最快的排序函数,但可能不是最准确的。 + +每个排序函数接收 2 行数据和一个列 ID,并需要通过列 ID 比较这两行数据,在升序排列时返回 `-1`、`0` 或 `1`。以下是速查表: + +| 返回值 | 升序排列 | +| ------ | --------------- | +| `-1` | `a < b` | +| `0` | `a === b` | +| `1` | `a > b` | + +所有排序函数的类型签名如下: + +```tsx +export type SortingFn = { + (rowA: Row, rowB: Row, columnId: string): number +} +``` + +#### 使用排序函数 (Using Sorting Functions) + +可以通过以下方式在 `columnDefinition.sortingFn` 中使用/引用/定义排序函数: + +- 引用内置排序函数的 `string` +- 通过 `tableOptions.sortingFns` 选项提供的自定义排序函数的 `string` 引用 +- 直接提供给 `columnDefinition.sortingFn` 选项的函数 + +`columnDef.sortingFn` 可用的最终排序函数列表使用以下类型: + +```tsx +export type SortingFnOption = + | 'auto' + | SortingFns + | BuiltInSortingFns + | SortingFn +``` + +## 列定义选项 (Column Def Options) + +### `sortingFn` + +```tsx +sortingFn?: SortingFn | keyof SortingFns | keyof BuiltInSortingFns +``` + +用于此列的排序函数。 + +选项: + +- 引用[内置排序函数](#排序函数-sorting-functions)的 `string` +- [自定义排序函数](#排序函数-sorting-functions) + +### `sortDescFirst` + +```tsx +sortDescFirst?: boolean +``` + +设置为 `true` 时,此列的排序切换将首先按降序方向进行。 + +### `enableSorting` + +```tsx +enableSorting?: boolean +``` + +启用/禁用此列的排序功能。 + +### `enableMultiSort` + +```tsx +enableMultiSort?: boolean +``` + +启用/禁用此列的多列排序功能。 + +### `invertSorting` + +```tsx +invertSorting?: boolean +``` + +反转此列的排序顺序。适用于具有反向最佳/最差比例的值,其中较小的数字更好,例如排名(第1、第2、第3)或类似高尔夫球的计分。 + +### `sortUndefined` + +```tsx +sortUndefined?: 'first' | 'last' | false | -1 | 1 // 默认为 1 +``` + +- `'first'` + - 未定义的值将被推到列表的开头 +- `'last'` + - 未定义的值将被推到列表的末尾 +- `false` + - 未定义的值将被视为并列,需要通过下一个列过滤器或原始索引进行排序(视情况而定) +- `-1` + - 未定义的值将以更高的优先级排序(升序)(如果升序,未定义的值将出现在列表的开头) +- `1` + - 未定义的值将以较低的优先级排序(降序)(如果升序,未定义的值将出现在列表的末尾) + +> 注意:`'first'` 和 `'last'` 选项在 v8.16.0 中新增 + +## 列 API (Column API) + +### `getAutoSortingFn` + +```tsx +getAutoSortingFn: () => SortingFn +``` + +返回基于列值自动推断出的排序函数。 + +### `getAutoSortDir` + +```tsx +getAutoSortDir: () => SortDirection +``` + +返回基于列值自动推断出的排序方向。 + +### `getSortingFn` + +```tsx +getSortingFn: () => SortingFn +``` + +返回用于此列的解析后的排序函数。 + +### `getNextSortingOrder` + +```tsx +getNextSortingOrder: () => SortDirection | false +``` + +返回下一个排序顺序。 + +### `getCanSort` + +```tsx +getCanSort: () => boolean +``` + +返回此列是否可以排序。 + +### `getCanMultiSort` + +```tsx +getCanMultiSort: () => boolean +``` + +返回此列是否可以多列排序。 + +### `getSortIndex` + +```tsx +getSortIndex: () => number +``` + +返回此列在排序状态中的索引位置。 + +### `getIsSorted` + +```tsx +getIsSorted: () => false | SortDirection +``` + +返回此列是否已排序。 + +### `getFirstSortDir` + +```tsx +getFirstSortDir: () => SortDirection +``` + +返回排序此列时应使用的第一个方向。 + +### `clearSorting` + +```tsx +clearSorting: () => void +``` + +从表格的排序状态中移除此列。 + +### `toggleSorting` + +```tsx +toggleSorting: (desc?: boolean, isMulti?: boolean) => void +``` + +切换此列的排序状态。如果提供了 `desc`,将强制排序方向为该值。如果提供了 `isMulti`,将以累加方式多列排序该列(如果已排序则切换)。 + +### `getToggleSortingHandler` + +```tsx +getToggleSortingHandler: () => undefined | ((event: unknown) => void) +``` + +返回一个可用于切换此列排序状态的函数。这对于将点击处理程序附加到列标题很有用。 + +## 表格选项 (Table Options) + +### `sortingFns` + +```tsx +sortingFns?: Record +``` + +此选项允许您定义自定义排序函数,可以通过其键在列的 `sortingFn` 选项中引用。 +示例: + +```tsx +declare module '@tanstack/table-core' { + interface SortingFns { + myCustomSorting: SortingFn + } +} + +const column = columnHelper.data('key', { + sortingFn: 'myCustomSorting', +}) + +const table = useReactTable({ + columns: [column], + sortingFns: { + myCustomSorting: (rowA: any, rowB: any, columnId: any): number => + rowA.getValue(columnId).value < rowB.getValue(columnId).value ? 1 : -1, + }, +}) +``` + +### `manualSorting` + +```tsx +manualSorting?: boolean +``` + +启用表格的手动排序。如果为 `true`,您需要在将数据传递给表格之前自行排序。这对于服务器端排序很有用。 + +### `onSortingChange` + +```tsx +onSortingChange?: OnChangeFn +``` + +如果提供,当 `state.sorting` 发生变化时,将使用 `updaterFn` 调用此函数。这会覆盖默认的内部状态管理,因此您需要在表格外部完全或部分持久化状态更改。 + +### `enableSorting` + +```tsx +enableSorting?: boolean +``` + +启用/禁用表格的排序功能。 + +### `enableSortingRemoval` + +```tsx +enableSortingRemoval?: boolean +``` + +启用/禁用移除表格排序的功能。 +- 如果为 `true`,则排序顺序将循环如下:'无' -> '降序' -> '升序' -> '无' -> ... +- 如果为 `false`,则排序顺序将循环如下:'无' -> '降序' -> '升序' -> '降序' -> '升序' -> ... + +### `enableMultiRemove` + +```tsx +enableMultiRemove?: boolean +``` + +启用/禁用移除多列排序的功能。 + +### `enableMultiSort` + +```tsx +enableMultiSort?: boolean +``` + +启用/禁用表格的多列排序功能。 + +### `sortDescFirst` + +```tsx +sortDescFirst?: boolean +``` + +如果为 `true`,所有排序将默认以降序作为其第一个切换状态。 + +### `getSortedRowModel` + +```tsx +getSortedRowModel?: (table: Table) => () => RowModel +``` + +此函数用于获取排序后的行模型。如果使用服务器端排序,则不需要此函数。要使用客户端排序,请将适配器导出的 `getSortedRowModel()` 传递给表格或自行实现。 + +### `maxMultiSortColCount` + +```tsx +maxMultiSortColCount?: number +``` + +设置可以多列排序的最大列数。 + +### `isMultiSortEvent` + +```tsx +isMultiSortEvent?: (e: unknown) => boolean +``` + +传递一个自定义函数,用于确定是否应触发多列排序事件。它接收排序切换处理程序的事件,如果事件应触发多列排序,则应返回 `true`。 + +## 表格 API (Table API) + +### `setSorting` + +```tsx +setSorting: (updater: Updater) => void +``` + +设置或更新 `state.sorting` 状态。 + +### `resetSorting` + +```tsx +resetSorting: (defaultState?: boolean) => void +``` + +将**排序**状态重置为 `initialState.sorting`,或传递 `true` 强制重置为默认的空状态 `[]`。 + +### `getPreSortedRowModel` + +```tsx +getPreSortedRowModel: () => RowModel +``` + +返回在应用任何排序之前的表格行模型。 + +### `getSortedRowModel` + +```tsx +getSortedRowModel: () => RowModel +``` + +返回应用排序后的表格行模型。 diff --git a/docs/zh-hans/config.json b/docs/zh-hans/config.json new file mode 100644 index 0000000000..563967e939 --- /dev/null +++ b/docs/zh-hans/config.json @@ -0,0 +1,790 @@ +{ + "$schema": "https://raw.githubusercontent.com/TanStack/tanstack.com/main/tanstack-docs-config.schema.json", + "docSearch": { + "appId": "74SF5EKVW9", + "apiKey": "9fc015a3310be6669ed66c6c459f319f", + "indexName": "tanstack-table" + }, + "sections": [ + { + "label": "入门指南", + "children": [ + { + "label": "简介", + "to": "introduction" + }, + { + "label": "概述", + "to": "overview" + }, + { + "label": "安装", + "to": "installation" + }, + { + "label": "迁移至 V8", + "to": "guide/migrating" + }, + { + "label": "常见问题解答", + "to": "faq" + } + ], + "frameworks": [ + { + "label": "angular", + "children": [ + { + "label": "Angular 表格适配器", + "to": "framework/angular/angular-table" + } + ] + }, + { + "label": "lit", + "children": [ + { + "label": "Lit 表格适配器", + "to": "framework/lit/lit-table" + } + ] + }, + { + "label": "qwik", + "children": [ + { + "label": "Qwik 表格适配器", + "to": "framework/qwik/qwik-table" + } + ] + }, + { + "label": "react", + "children": [ + { + "label": "React 表格适配器", + "to": "framework/react/react-table" + } + ] + }, + { + "label": "solid", + "children": [ + { + "label": "Solid 表格适配器", + "to": "framework/solid/solid-table" + } + ] + }, + { + "label": "svelte", + "children": [ + { + "label": "Svelte 表格适配器", + "to": "framework/svelte/svelte-table" + } + ] + }, + { + "label": "vue", + "children": [ + { + "label": "Vue 表格适配器", + "to": "framework/vue/vue-table" + } + ] + }, + { + "label": "vanilla", + "children": [ + { + "label": "原生 JS (无框架)", + "to": "vanilla" + } + ] + } + ] + }, + { + "label": "核心指南", + "children": [ + { + "label": "数据", + "to": "guide/data" + }, + { + "label": "列定义", + "to": "guide/column-defs" + }, + { + "label": "表格实例", + "to": "guide/tables" + }, + { + "label": "行模型", + "to": "guide/row-models" + }, + { + "label": "行", + "to": "guide/rows" + }, + { + "label": "单元格", + "to": "guide/cells" + }, + { + "label": "表头分组", + "to": "guide/header-groups" + }, + { + "label": "表头", + "to": "guide/headers" + }, + { + "label": "列", + "to": "guide/columns" + } + ], + "frameworks": [ + { + "label": "angular", + "children": [ + { + "label": "表格状态", + "to": "framework/angular/guide/table-state" + } + ] + }, + { + "label": "lit", + "children": [ + { + "label": "表格状态", + "to": "framework/lit/guide/table-state" + } + ] + }, + { + "label": "qwik", + "children": [ + { + "label": "表格状态", + "to": "framework/qwik/guide/table-state" + } + ] + }, + { + "label": "react", + "children": [ + { + "label": "表格状态", + "to": "framework/react/guide/table-state" + } + ] + }, + { + "label": "solid", + "children": [ + { + "label": "表格状态", + "to": "framework/solid/guide/table-state" + } + ] + }, + { + "label": "svelte", + "children": [ + { + "label": "表格状态", + "to": "framework/svelte/guide/table-state" + } + ] + }, + { + "label": "vue", + "children": [ + { + "label": "表格状态", + "to": "framework/vue/guide/table-state" + } + ] + }, + { + "label": "vanilla", + "children": [ + { + "label": "表格状态", + "to": "framework/vanilla/guide/table-state" + } + ] + } + ] + }, + { + "label": "功能指南", + "children": [ + { + "label": "列排序", + "to": "guide/column-ordering" + }, + { + "label": "列固定", + "to": "guide/column-pinning" + }, + { + "label": "列尺寸调整", + "to": "guide/column-sizing" + }, + { + "label": "列可见性", + "to": "guide/column-visibility" + }, + { + "label": "列过滤", + "to": "guide/column-filtering" + }, + { + "label": "全局过滤", + "to": "guide/global-filtering" + }, + { + "label": "模糊过滤", + "to": "guide/fuzzy-filtering" + }, + { + "label": "列分面", + "to": "guide/column-faceting" + }, + { + "label": "全局分面", + "to": "guide/global-faceting" + }, + { + "label": "分组", + "to": "guide/grouping" + }, + { + "label": "展开", + "to": "guide/expanding" + }, + { + "label": "分页", + "to": "guide/pagination" + }, + { + "label": "行固定", + "to": "guide/row-pinning" + }, + { + "label": "行选择", + "to": "guide/row-selection" + }, + { + "label": "排序", + "to": "guide/sorting" + }, + { + "label": "虚拟化", + "to": "guide/virtualization" + }, + { + "label": "自定义功能", + "to": "guide/custom-features" + } + ] + }, + { + "label": "核心 API", + "children": [ + { + "label": "列定义", + "to": "api/core/column-def" + }, + { + "label": "表格", + "to": "api/core/table" + }, + { + "label": "列", + "to": "api/core/column" + }, + { + "label": "表头分组", + "to": "api/core/header-group" + }, + { + "label": "表头", + "to": "api/core/header" + }, + { + "label": "行", + "to": "api/core/row" + }, + { + "label": "单元格", + "to": "api/core/cell" + } + ] + }, + { + "label": "功能 API", + "children": [ + { + "label": "列过滤", + "to": "api/features/column-filtering" + }, + { + "label": "列分面", + "to": "api/features/column-faceting" + }, + { + "label": "列排序", + "to": "api/features/column-ordering" + }, + { + "label": "列固定", + "to": "api/features/column-pinning" + }, + { + "label": "列尺寸调整", + "to": "api/features/column-sizing" + }, + { + "label": "列可见性", + "to": "api/features/column-visibility" + }, + { + "label": "全局分面", + "to": "api/features/global-faceting" + }, + { + "label": "全局过滤", + "to": "api/features/global-filtering" + }, + { + "label": "排序", + "to": "api/features/sorting" + }, + { + "label": "分组", + "to": "api/features/grouping" + }, + { + "label": "展开", + "to": "api/features/expanding" + }, + { + "label": "分页", + "to": "api/features/pagination" + }, + { + "label": "行固定", + "to": "api/features/row-pinning" + }, + { + "label": "行选择", + "to": "api/features/row-selection" + } + ] + }, + { + "label": "企业版", + "children": [ + { + "label": "AG Grid", + "to": "enterprise/ag-grid" + } + ] + }, + { + "label": "示例", + "children": [], + "frameworks": [ + { + "label": "angular", + "children": [ + { + "to": "framework/angular/examples/basic", + "label": "基础" + }, + { + "to": "framework/angular/examples/grouping", + "label": "列分组" + }, + { + "to": "framework/angular/examples/column-ordering", + "label": "列排序" + }, + { + "to": "framework/angular/examples/column-pinning", + "label": "列固定" + }, + { + "to": "framework/angular/examples/column-pinning-sticky", + "label": "粘性列固定" + }, + { + "to": "framework/angular/examples/column-visibility", + "label": "列可见性" + }, + { + "to": "framework/angular/examples/filters", + "label": "列过滤" + }, + { + "to": "framework/angular/examples/row-selection", + "label": "行选择" + }, + { + "to": "framework/angular/examples/expanding", + "label": "展开" + }, + { + "to": "framework/angular/examples/sub-components", + "label": "子组件" + }, + { + "to": "framework/angular/examples/signal-input", + "label": "信号输入" + }, + { + "to": "framework/angular/examples/editable", + "label": "可编辑数据" + }, + { + "to": "framework/angular/examples/row-dnd", + "label": "行拖放" + }, + { + "to": "framework/angular/examples/column-resizing-performant", + "label": "高性能列调整" + } + ] + }, + { + "label": "lit", + "children": [ + { + "to": "framework/lit/examples/basic", + "label": "基础" + }, + { + "to": "framework/lit/examples/column-sizing", + "label": "列尺寸调整" + }, + { + "to": "framework/lit/examples/filters", + "label": "过滤" + }, + { + "to": "framework/lit/examples/row-selection", + "label": "行选择" + }, + { + "to": "framework/lit/examples/sorting", + "label": "排序" + }, + { + "to": "framework/lit/examples/virtualized-rows", + "label": "虚拟化行" + } + ] + }, + { + "label": "qwik", + "children": [ + { + "to": "framework/qwik/examples/basic", + "label": "基础" + }, + { + "to": "framework/qwik/examples/filters", + "label": "过滤" + }, + { + "to": "framework/qwik/examples/row-selection", + "label": "行选择" + }, + { + "to": "framework/qwik/examples/sorting", + "label": "排序" + } + ] + }, + { + "label": "react", + "children": [ + { + "to": "framework/react/examples/basic", + "label": "基础" + }, + { + "to": "framework/react/examples/column-groups", + "label": "表头分组" + }, + { + "to": "framework/react/examples/filters", + "label": "列过滤" + }, + { + "to": "framework/react/examples/filters-faceted", + "label": "列过滤 (分面)" + }, + { + "to": "framework/react/examples/filters-fuzzy", + "label": "模糊搜索过滤" + }, + { + "to": "framework/react/examples/column-ordering", + "label": "列排序" + }, + { + "to": "framework/react/examples/column-dnd", + "label": "列排序 (拖放)" + }, + { + "to": "framework/react/examples/column-pinning", + "label": "列固定" + }, + { + "to": "framework/react/examples/column-pinning-sticky", + "label": "粘性列固定" + }, + { + "to": "framework/react/examples/column-sizing", + "label": "列尺寸调整" + }, + { + "to": "framework/react/examples/column-resizing-performant", + "label": "高性能列调整" + }, + { + "to": "framework/react/examples/column-visibility", + "label": "列可见性" + }, + { + "to": "framework/react/examples/editable-data", + "label": "可编辑数据" + }, + { + "to": "framework/react/examples/expanding", + "label": "展开" + }, + { + "to": "framework/react/examples/sub-components", + "label": "子组件" + }, + { + "to": "framework/react/examples/fully-controlled", + "label": "完全受控" + }, + { + "to": "framework/react/examples/grouping", + "label": "分组" + }, + { + "to": "framework/react/examples/pagination", + "label": "分页" + }, + { + "to": "framework/react/examples/pagination-controlled", + "label": "受控分页" + }, + { + "to": "framework/react/examples/row-dnd", + "label": "行拖放" + }, + { + "to": "framework/react/examples/row-pinning", + "label": "行固定" + }, + { + "to": "framework/react/examples/row-selection", + "label": "行选择" + }, + { + "to": "framework/react/examples/sorting", + "label": "排序" + }, + { + "to": "framework/react/examples/virtualized-columns", + "label": "虚拟化列" + }, + { + "to": "framework/react/examples/virtualized-columns-experimental", + "label": "虚拟化列 (实验性)" + }, + { + "to": "framework/react/examples/virtualized-rows", + "label": "虚拟化行" + }, + { + "to": "framework/react/examples/virtualized-rows-experimental", + "label": "虚拟化行 (实验性)" + }, + { + "to": "framework/react/examples/virtualized-infinite-scrolling", + "label": "虚拟化无限滚动" + }, + { + "to": "framework/react/examples/kitchen-sink", + "label": "综合示例" + }, + { + "to": "framework/react/examples/bootstrap", + "label": "React Bootstrap" + }, + { + "to": "framework/react/examples/material-ui-pagination", + "label": "Material UI 分页" + }, + { + "to": "framework/react/examples/full-width-table", + "label": "React 全宽表格" + }, + { + "to": "framework/react/examples/full-width-resizable-table", + "label": "React 全宽可调整表格" + }, + { + "to": "framework/react/examples/custom-features", + "label": "自定义功能" + }, + { + "to": "framework/react/examples/query-router-search-params", + "label": "查询路由搜索参数" + } + ] + }, + { + "label": "solid", + "children": [ + { + "to": "framework/solid/examples/basic", + "label": "基础" + }, + { + "to": "framework/solid/examples/column-groups", + "label": "列分组" + }, + { + "to": "framework/solid/examples/column-ordering", + "label": "列排序" + }, + { + "to": "framework/solid/examples/column-visibility", + "label": "列可见性" + }, + { + "to": "framework/solid/examples/filters", + "label": "过滤" + }, + { + "to": "framework/solid/examples/sorting", + "label": "排序" + }, + { + "to": "framework/solid/examples/bootstrap", + "label": "Solid Bootstrap" + } + ] + }, + { + "label": "svelte", + "children": [ + { + "to": "framework/svelte/examples/basic", + "label": "基础" + }, + { + "to": "framework/svelte/examples/column-groups", + "label": "列分组" + }, + { + "to": "framework/svelte/examples/column-ordering", + "label": "列排序" + }, + { + "to": "framework/svelte/examples/column-pinning", + "label": "列固定" + }, + { + "to": "framework/svelte/examples/column-visibility", + "label": "列可见性" + }, + { + "to": "framework/svelte/examples/filtering", + "label": "过滤" + }, + { + "to": "framework/svelte/examples/sorting", + "label": "排序" + } + ] + }, + { + "label": "vue", + "children": [ + { + "to": "framework/vue/examples/basic", + "label": "基础" + }, + { + "to": "framework/vue/examples/column-ordering", + "label": "列排序" + }, + { + "to": "framework/vue/examples/column-pinning", + "label": "列固定" + }, + { + "to": "framework/vue/examples/pagination", + "label": "分页" + }, + { + "to": "framework/vue/examples/row-selection", + "label": "行选择" + }, + { + "to": "framework/vue/examples/sorting", + "label": "排序" + }, + { + "to": "framework/vue/examples/sub-components", + "label": "子组件" + }, + { + "to": "framework/vue/examples/filters", + "label": "列过滤" + }, + { + "to": "framework/vue/examples/virtualized-rows", + "label": "虚拟化行" + }, + { + "to": "framework/vue/examples/grouping", + "label": "分组" + } + ] + }, + { + "label": "vanilla", + "children": [ + { + "to": "framework/vanilla/examples/basic", + "label": "基础" + }, + { + "to": "framework/vanilla/examples/pagination", + "label": "分页" + }, + { + "to": "framework/vanilla/examples/sorting", + "label": "排序" + } + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/docs/zh-hans/enterprise/ag-grid.md b/docs/zh-hans/enterprise/ag-grid.md new file mode 100644 index 0000000000..72da300281 --- /dev/null +++ b/docs/zh-hans/enterprise/ag-grid.md @@ -0,0 +1,44 @@ +--- +source-updated-at: '2023-12-17T15:54:46.000Z' +translation-updated-at: '2025-05-02T17:44:03.619Z' +title: AG Grid +--- +

+ + + +

+ +虽然我们显然热爱 TanStack Table,但我们承认它并非一个"开箱即用"的产品,也不包含客户支持和企业级打磨。我们意识到部分用户可能需要这些功能!为此,我们想向您介绍 AG Grid —— 一个企业级数据表格解决方案,其丰富的功能集和强劲性能能为您的应用赋能。尽管 TanStack Table 同样是实现数据表格的强大选择,我们坚信应为用户提供多样化的选择来满足特定需求。AG Grid 正是这样一个选项,我们很高兴为您展示其能力。 + +## 为何选择 [AG Grid](https://ag-grid.com/react-data-grid/?utm_source=reacttable&utm_campaign=githubreacttable)? + +以下是考虑在下一个项目中使用 AG Grid 的充分理由: + +### 全面的功能集 + +AG Grid 提供广泛的功能集,使其成为多功能且强大的数据表格解决方案。通过 AG Grid,您可以获得满足复杂企业应用需求的各种功能。从高级排序、筛选和分组能力,到列固定、多级表头和支持树形数据结构,AG Grid 为您提供创建动态交互式数据表格的工具,满足应用的独特需求。 + +### 高性能 + +在处理大型数据集和实现卓越性能方面,AG Grid 表现出色。它采用高度优化的渲染技术、高效的数据更新和虚拟化技术,确保即使处理数千或数百万行数据时也能流畅滚动和快速响应。AG Grid 的性能优化使其成为需要高速数据操作和可视化应用的绝佳选择。 + +### 定制与扩展性 + +AG Grid 设计为高度可定制和可扩展,允许您根据特定需求调整表格。它提供丰富的 API 和事件集,使您能无缝集成自定义功能。您可以定义自定义单元格渲染器、编辑器、过滤器和聚合器来增强表格行为和外观。AG Grid 还支持多种主题,使表格视觉风格与应用设计相匹配。 + +### 支持企业需求 + +作为面向企业的解决方案,AG Grid 满足复杂业务应用的需求。它提供企业级功能,如行分组、列固定、服务端行模型、主/从表格和丰富的编辑能力。AG Grid 还能很好地与其他企业框架和库集成,是大型项目的可靠选择。 + +### 活跃的开发与社区支持 + +AG Grid 受益于活跃的开发和繁荣的开发者社区。AG Grid 背后的团队持续引入新功能和改进,确保产品发展以满足行业变化的需求。社区支持强大,论坛、文档和示例随时可用,帮助您充分发挥 AG Grid 的潜力。 + +## 结论 + +尽管 TanStack Table 仍是实现数据表格的强大灵活选择,我们理解不同项目有不同的需求。AG Grid 提供了一个引人注目的企业级解决方案,可能特别适合您的需求。其全面的功能集、高性能、定制选项和对企业需求的专注,使 AG Grid 成为需要健壮且可扩展数据表格解决方案项目的绝佳选择。 + +我们鼓励您访问 AG Grid 网站并试用演示版来进一步探索。请记住,TanStack Table 和 AG Grid 各有独特的优势和考量。我们坚信应为用户提供选择,使您能做出明智决策,为特定用例选择最佳方案。 + +访问 [AG Grid 官网](https://www.ag-grid.com)。 diff --git a/docs/zh-hans/faq.md b/docs/zh-hans/faq.md new file mode 100644 index 0000000000..d522f5dfab --- /dev/null +++ b/docs/zh-hans/faq.md @@ -0,0 +1,167 @@ +--- +source-updated-at: '2024-03-28T21:06:30.000Z' +translation-updated-at: '2025-05-02T16:50:14.598Z' +title: 常见问题解答 +--- +## 如何避免无限渲染循环? + +如果你在使用 React,有一个常见的陷阱会导致无限渲染。如果你未能为 `columns`、`data` 或 `state` 提供稳定的引用,React 会在表格状态发生任何变化时进入无限重新渲染循环。 + +为什么会这样?这是 TanStack Table 的 bug 吗?**不是**。*这是 React 的基本工作原理*,正确管理你的列、数据和状态可以避免这个问题。 + +TanStack Table 的设计会在传入表格的 `data` 或 `columns` 发生变化时,或表格的任何状态发生变化时触发重新渲染。 + +> 未能为 `columns` 或 `data` 提供稳定的引用会导致无限重新渲染循环。 + +### 陷阱 1:在每次渲染时创建新的列或数据 + +```js +export default function MyComponent() { + //😵 错误:这将导致无限重新渲染循环,因为 `columns` 在每次渲染时被重新定义为一个新数组! + const columns = [ + // ... + ]; + + //😵 错误:这将导致无限重新渲染循环,因为 `data` 在每次渲染时被重新定义为一个新数组! + const data = [ + // ... + ]; + + //❌ 列和数据在 `useReactTable` 的同一作用域内定义且没有稳定引用,会导致无限循环! + const table = useReactTable({ + columns, + data, + }); + + return
...
; +} +``` + +### 解决方案 1:使用 useMemo 或 useState 提供稳定引用 + +在 React 中,你可以通过将变量定义在组件外部/上方,或使用 `useMemo`、`useState`,或使用第三方状态管理库(如 Redux 或 React Query 😉)来提供“稳定”引用。 + +```js +//✅ 正确:在组件外部定义列 +const columns = [ + // ... +]; + +//✅ 正确:在组件外部定义数据 +const data = [ + // ... +]; + +// 通常更实际的做法是在组件内部定义列和数据,因此使用 `useMemo` 或 `useState` 来提供稳定引用 +export default function MyComponent() { + //✅ 正确:这不会导致无限重新渲染循环,因为 `columns` 是一个稳定引用 + const columns = useMemo(() => [ + // ... + ], []); + + //✅ 正确:这不会导致无限重新渲染循环,因为 `data` 是一个稳定引用 + const [data, setData] = useState(() => [ + // ... + ]); + + // 列和数据具有稳定引用,不会导致无限循环! + const table = useReactTable({ + columns, + data, + }); + + return ...
; +} +``` + +### 陷阱 2:原地修改列或数据 + +即使你为初始的 `columns` 和 `data` 提供了稳定引用,如果你原地修改它们,仍然可能陷入无限循环。这是一个常见的陷阱,一开始可能不会注意到。像简单的内联 `data.filter()` 这样的操作如果不小心处理,也可能导致无限循环。 + +```js +export default function MyComponent() { + //✅ 正确 + const columns = useMemo(() => [ + // ... + ], []); + + //✅ 正确(React Query 会自动为数据提供稳定引用) + const { data, isLoading } = useQuery({ + //... + }); + + const table = useReactTable({ + columns, + //❌ 错误:这将导致无限重新渲染循环,因为 `data` 被原地修改(破坏了稳定引用) + data: data?.filter(d => d.isActive) ?? [], + }); + + return ...
; +} +``` + +### 解决方案 2:缓存数据转换 + +为了避免无限循环,你应该始终缓存数据转换操作。可以使用 `useMemo` 或类似方法实现。 + +```js +export default function MyComponent() { + //✅ 正确 + const columns = useMemo(() => [ + // ... + ], []); + + //✅ 正确 + const { data, isLoading } = useQuery({ + //... + }); + + //✅ 正确:这不会导致无限重新渲染循环,因为 `filteredData` 被缓存了 + const filteredData = useMemo(() => data?.filter(d => d.isActive) ?? [], [data]); + + const table = useReactTable({ + columns, + data: filteredData, // 稳定引用! + }); + + return ...
; +} +``` + +### React Forget + +当 React Forget 发布后,这些问题可能会成为过去。或者直接使用 Solid.js... 🤓 + +## 如何在数据变化时阻止表格状态自动重置? + +大多数插件使用的状态在数据源变化时*通常*应该重置,但有时如果你在外部过滤数据、不可变地编辑数据时查看数据,或只是对数据做任何不希望触发表格状态自动重置的外部操作时,你需要阻止这种自动重置行为。 + +对于这些情况,每个插件都提供了禁用状态自动重置的方法。通过将它们中的任何一个设置为 `false`,你可以阻止自动重置被触发。 + +以下是一个基于 React 的示例,展示了在编辑表格的 `data` 源时阻止所有状态自动重置的方法: + +```js +const [data, setData] = React.useState([]) +const skipPageResetRef = React.useRef() + +const updateData = newData => { + // 当通过此函数更新数据时,设置一个标志 + // 以禁用所有自动重置 + skipPageResetRef.current = true + + setData(newData) +} + +React.useEffect(() => { + // 表格更新后,始终移除标志 + skipPageResetRef.current = false +}) + +useReactTable({ + ... + autoResetPageIndex: !skipPageResetRef.current, + autoResetExpanded: !skipPageResetRef.current, +}) +``` + +现在,当我们更新数据时,上述表格状态将不会自动重置! diff --git a/docs/zh-hans/framework/angular/angular-table.md b/docs/zh-hans/framework/angular/angular-table.md new file mode 100644 index 0000000000..3ebac6dddc --- /dev/null +++ b/docs/zh-hans/framework/angular/angular-table.md @@ -0,0 +1,292 @@ +--- +source-updated-at: '2025-01-20T06:07:15.000Z' +translation-updated-at: '2025-05-02T16:55:56.276Z' +title: Angular 表格适配器 +--- +`@tanstack/angular-table` 适配器是对核心表格逻辑的封装层,其主要职责是以 "Angular 信号 (angular signals)" 的方式管理状态,并提供类型定义以及单元格/表头/页脚模板的渲染实现。 + +## 导出内容 + +`@tanstack/angular-table` 重新导出了 `@tanstack/table-core` 的所有 API 及以下内容: + +### `createAngularTable` + +接收一个返回表格配置项的函数或计算值,并返回表格实例。 + +```ts +import {createAngularTable} from '@tanstack/angular-table' + +export class AppComponent { + data = signal([]) + + table = createAngularTable(() => ({ + data: this.data(), + columns: defaultColumns, + getCoreRowModel: getCoreRowModel(), + })) +} + +// ...在模板中渲染表格 +``` + +### `FlexRender` + +一个 Angular 结构型指令,用于渲染包含动态值的单元格/表头/页脚模板。 + +FlexRender 支持 Angular 支持的所有内容类型: +- 字符串或通过 `innerHTML` 渲染的 HTML 字符串 +- [TemplateRef](https://angular.dev/api/core/TemplateRef) +- 封装为 `FlexRenderComponent` 的[组件](https://angular.dev/api/core/Component) + +虽然可以直接使用 `cell.renderValue` 或 `cell.getValue` API 渲染单元格内容,但这些 API 仅会输出原始单元格值(来自访问器函数)。如果使用了 `cell: () => any` 列定义选项,则需要使用适配器提供的 `FlexRenderDirective`。 + +单元格列定义是**响应式**的,并运行在**注入上下文**中,因此可以注入服务或使用信号 (signals) 自动修改渲染内容。 + +#### 示例 + +```ts +@Component({ + imports: [FlexRenderDirective], + //... +}) +class YourComponent {} +``` + +```angular-html + +@for (row of table.getRowModel().rows; track row.id) { + + @for (cell of row.getVisibleCells(); track cell.id) { + + + + {{ cell }} + +
+
+ + } + +} + +``` + +#### 渲染组件 + +要将组件渲染到特定列的表头/单元格/页脚,可以传递一个用 `ComponentType` 实例化的 `FlexRenderComponent`,并支持包含 inputs、outputs 和自定义注入器等参数。 + +```ts +import {flexRenderComponent} from "./flex-render-component"; +import {ChangeDetectionStrategy, input, output} from "@angular/core"; + +@Component({ + template: ` + ... + `, + standalone: true, + changeDetectionStrategy: ChangeDetectionStrategy.OnPush, + host: { + '(click)': 'clickEvent.emit($event)' + } +}) +class CustomCell { + readonly content = input.required(); + readonly cellType = input(); + + // 每个单元格点击时触发的输出事件 + readonly clickEvent = output(); +} + +class AppComponent { + columns: ColumnDef[] = [ + { + id: 'custom-cell', + header: () => { + const translateService = inject(TranslateService); + return translateService.translate('...'); + }, + cell: (context) => { + return flexRenderComponent( + MyCustomComponent, + { + injector, // 可选的注入器 + inputs: { + // 必须的 input(因为使用了 input.required()) + content: context.row.original.rowProperty, + // cellType? - 可选的 input + }, + outputs: { + clickEvent: () => { + // 执行某些操作 + } + } + } + ) + }, + }, + ] +} +``` + +底层实现使用了 [ViewContainerRef#createComponent](https://angular.dev/api/core/ViewContainerRef#createComponent) API,因此自定义 inputs 应使用 @Input 装饰器或 input/model 信号声明。 + +仍可通过 `injectFlexRenderContext` 函数访问表格单元格上下文,该函数根据传递给 `FlexRenderDirective` 的 props 返回上下文值。 + +```ts +@Component({ + // ... +}) +class CustomCellComponent { + // 单元格组件的上下文 + readonly context = injectFlexRenderContext>(); + // 表头/页脚组件的上下文 + readonly context = injectFlexRenderContext>(); +} +``` + +或者,也可以通过将组件类型传递给相应的列定义来渲染组件。这些列定义将与 `context` 一起提供给 `flexRender` 指令。 + +```ts +class AppComponent { + columns: ColumnDef[] = [ + { + id: 'select', + header: () => TableHeadSelectionComponent, + cell: () => TableRowSelectionComponent, + }, + ] +} +``` + +```angular-html + + {{ headerCell }} + +``` + +`flexRender` 指令提供的 `context` 属性可在组件中访问。可以显式定义组件所需的上下文属性。此示例中,flexRender 提供的上下文类型为 HeaderContext。输入信号 `table`(HeaderContext 的属性之一,与 `column` 和 `header` 属性一起)随后在组件中被定义使用。如果组件需要任何上下文属性,可自由使用它们。请注意,使用此方法定义上下文属性访问时,仅支持输入信号。 + +```angular-ts +@Component({ + template: ` + + `, + // ... +}) +export class TableHeadSelectionComponent { + //column = input.required>() + //header = input.required>() + table = input.required>() +} +``` + +#### 渲染 TemplateRef + +要将 TemplateRef 渲染到特定列的表头/单元格/页脚,可以将 TemplateRef 传入列定义。 + +可通过 `$implicit` 属性访问 TemplateRef 数据,其值基于 flexRender 的 props 字段传递的内容。 + +大多数情况下,每个 TemplateRef 将根据单元格类型以如下方式渲染: + +- 表头: `HeaderContext` +- 单元格: `CellContext` +- 页脚: `HeaderContext` + +```angular-html + + + {{ cell }} + +
+
+ + + + +``` + +完整示例: + +```angular-ts +import type { + CellContext, + ColumnDef, + HeaderContext, +} from '@tanstack/angular-table' +import {Component, TemplateRef, viewChild} from '@angular/core' + +@Component({ + template: ` + + @for (row of table.getRowModel().rows; track row.id) { + + @for (cell of row.getVisibleCells(); track cell.id) { + + + + {{ cell }} + +
+
+ + } + + } + + + + {{ context.getValue() }} + + + {{ context.getValue() }} + + `, +}) +class AppComponent { + customHeader = + viewChild.required }>>( + 'customHeader' + ) + customCell = + viewChild.required }>>( + 'customCell' + ) + + columns: ColumnDef[] = [ + { + id: 'customCell', + header: () => this.customHeader(), + cell: () => this.customCell(), + }, + ] +} +``` diff --git a/docs/zh-hans/framework/angular/guide/table-state.md b/docs/zh-hans/framework/angular/guide/table-state.md new file mode 100644 index 0000000000..c3c6453c1c --- /dev/null +++ b/docs/zh-hans/framework/angular/guide/table-state.md @@ -0,0 +1,217 @@ +--- +source-updated-at: '2024-07-27T18:15:45.000Z' +translation-updated-at: '2025-05-02T17:05:46.367Z' +title: 表格状态 +--- +## 表格状态 (Angular) 指南 + +TanStack Table 的核心是 **框架无关 (framework agnostic)** 的,这意味着无论您使用何种框架,其 API 都保持一致。根据您使用的框架,提供了适配器 (Adapters) 来简化与表格核心的交互。可用的适配器请参阅 Adapters 菜单。 + +### 访问表格状态 + +您无需进行任何特殊设置即可使用表格状态。如果不向 `state`、`initialState` 或任何 `on[State]Change` 表格选项中传递任何内容,表格将在内部自行管理其状态。您可以通过使用 `table.getState()` 表格实例 API 访问此内部状态的任何部分。 + +```ts +table = createAngularTable(() => ({ + columns: this.columns, + data: this.data(), + //... +})) + +someHandler() { + console.log(this.table.getState()) //访问整个内部状态 + console.log(this.table.getState().rowSelection) //仅访问行选择状态 +} +``` + +### 自定义初始状态 + +如果对于某些状态,您只需要自定义它们的初始默认值,那么您仍然不需要自行管理任何状态。您只需在表格实例的 `initialState` 选项中设置值即可。 + +```jsx +table = createAngularTable(() => ({ + columns: this.columns, + data: this.data(), + initialState: { + columnOrder: ['age', 'firstName', 'lastName'], //自定义初始列顺序 + columnVisibility: { + id: false //默认隐藏 id 列 + }, + expanded: true, //默认展开所有行 + sorting: [ + { + id: 'age', + desc: true //默认按年龄降序排序 + } + ] + }, + //... +})) +``` + +> **注意**:每个特定状态只能在 `initialState` 或 `state` 中指定,而不能同时在两者中指定。如果某个状态值同时传递给 `initialState` 和 `state`,`state` 中的初始化状态将覆盖 `initialState` 中的相应值。 + +### 受控状态 + +如果您需要在应用程序的其他部分轻松访问表格状态,TanStack Table 可以让您轻松地在自己的状态管理系统中控制和管理表格状态的任何部分或全部。您可以通过将自己的状态和状态管理函数传递给 `state` 和 `on[State]Change` 表格选项来实现这一点。 + +#### 单独受控状态 + +您可以仅控制需要轻松访问的状态。如果不需要,您不必控制所有表格状态。建议根据具体情况仅控制所需的状态。 + +为了控制特定状态,您需要将相应的 `state` 值和 `on[State]Change` 函数都传递给表格实例。 + +以“手动”服务器端数据获取场景中的过滤、排序和分页为例。您可以将过滤、排序和分页状态存储在自己的状态管理中,但如果您的 API 不关心列顺序、列可见性等值,则可以忽略这些状态。 + +```ts +import {signal} from '@angular/core'; +import {SortingState, ColumnFiltersState, PaginationState} from '@tanstack/angular-table' +import {toObservable} from "@angular/core/rxjs-interop"; +import {combineLatest, switchMap} from 'rxjs'; + +class TableComponent { + readonly columnFilters = signal([]) //无默认过滤器 + readonly sorting = signal([ + { + id: 'age', + desc: true, //默认按年龄降序排序 + } + ]) + readonly pagination = signal({ + pageIndex: 0, + pageSize: 15 + }) + + //使用受控状态值获取数据 + readonly data$ = combineLatest({ + filters: toObservable(this.columnFilters), + sorting: toObservable(this.sorting), + pagination: toObservable(this.pagination) + }).pipe( + switchMap(({filters, sorting, pagination}) => fetchData(filters, sorting, pagination)) + ) + readonly data = toSignal(this.data$); + + readonly table = createAngularTable(() => ({ + columns: this.columns, + data: this.data(), + //... + state: { + columnFilters: this.columnFilters(), //将受控状态传递回表格(覆盖内部状态) + sorting: this.sorting(), + pagination: this.pagination(), + }, + onColumnFiltersChange: updater => { //将 columnFilters 状态提升到自己的状态管理 + updater instanceof Function + ? this.columnFilters.update(updater) + : this.columnFilters.set(updater) + }, + onSortingChange: updater => { + updater instanceof Function + ? this.sorting.update(updater) + : this.sorting.set(updater) + }, + onPaginationChange: updater => { + updater instanceof Function + ? this.pagination.update(updater) + : this.pagination.set(updater) + }, + })) +} + +//... +``` + +#### 完全受控状态 + +或者,您可以使用 `onStateChange` 表格选项控制整个表格状态。这会将整个表格状态提升到您自己的状态管理系统中。使用此方法时要小心,因为您可能会发现将一些频繁变化的状态值(如 `columnSizingInfo` 状态)提升到组件树中可能会导致性能问题。 + +可能需要一些额外的技巧来实现这一点。如果使用 `onStateChange` 表格选项,`state` 的初始值必须填充所有相关状态值,以便使用所有所需功能。您可以手动输入所有初始状态值,或者如下所示以特殊方式使用构造函数。 + +```ts + + +class TableComponent { + // 创建一个空的表格状态,稍后覆盖它 + readonly state = signal({} as TableState); + + // 使用默认状态值创建表格实例 + readonly table = createAngularTable(() => ({ + columns: this.columns, + data: this.data(), + // 完全受控状态覆盖内部状态 + state: this.state(), + onStateChange: updater => { + // 任何状态更改都将推送到我们自己的状态管理 + this.state.set( + updater instanceof Function ? updater(this.state()) : updater + ) + } + })) + + constructor() { + // 设置初始表格状态 + this.state.set({ + // 使用表格实例中的所有默认状态值填充初始状态 + ...this.table.initialState, + pagination: { + pageIndex: 0, + pageSize: 15, // 可选自定义初始分页状态 + }, + }) + } +} +``` + +### 状态变更回调 + +到目前为止,我们已经看到 `on[State]Change` 和 `onStateChange` 表格选项用于将表格状态更改“提升”到我们自己的状态管理中。然而,使用这些选项时需要注意以下几点。 + +#### 1. **状态变更回调必须在 `state` 选项中有对应的状态值**。 + +指定 `on[State]Change` 回调会告诉表格实例这是一个受控状态。如果未指定相应的 `state` 值,该状态将“冻结”为其初始值。 + +```ts +class TableComponent { + sorting = signal([]) + + table = createAngularTable(() => ({ + columns: this.columns, + data: this.data(), + //... + state: { + sorting: this.sorting(), // 必需,因为我们使用了 `onSortingChange` + }, + onSortingChange: updater => { // 使 `state.sorting` 受控 + updater instanceof Function + ? this.sorting.update(updater) + : this.sorting.set(updater) + } + })) +} +``` + +#### 2. **更新器可以是原始值或回调函数**。 + +`on[State]Change` 和 `onStateChange` 回调的工作方式与 React 中的 `setState` 函数完全相同。更新器值可以是新的状态值,也可以是接收先前状态值并返回新状态值的回调函数。 + +这意味着什么?这意味着如果您想在 `on[State]Change` 回调中添加一些额外逻辑,可以这样做,但需要检查新的更新器值是函数还是值。 + +这就是为什么在上面的示例中会看到 `updater instanceof Function ? this.state.update(updater) : this.state.set(updater)` 模式。此模式检查更新器是否为函数,如果是,则使用先前的状态值调用该函数以获取新状态值,否则信号将要求使用 `signal.update` 而不是 `signal.set` 来调用更新器。 + +### 状态类型 + +TanStack Table 中的所有复杂状态都有自己的 TypeScript 类型,您可以导入并使用。这对于确保您为控制的状态值使用正确的数据结构和属性非常有用。 + +```ts +import {createAngularTable, type SortingState} from '@tanstack/angular-table' + +class TableComponent { + readonly sorting = signal([ + { + id: 'age', // 您应该会获得 `id` 和 `desc` 属性的自动完成 + desc: true, + } + ]) +} +``` diff --git a/docs/zh-hans/framework/lit/guide/table-state.md b/docs/zh-hans/framework/lit/guide/table-state.md new file mode 100644 index 0000000000..56d85df8f1 --- /dev/null +++ b/docs/zh-hans/framework/lit/guide/table-state.md @@ -0,0 +1,194 @@ +--- +source-updated-at: '2024-05-17T05:10:48.000Z' +translation-updated-at: '2025-05-02T17:06:48.028Z' +title: 表格状态 +--- +## Table State (Lit) 指南 + +TanStack Table 的核心是**框架无关 (framework agnostic)** 的,这意味着无论您使用哪种框架,其 API 都是相同的。根据您使用的框架,提供了适配器 (Adapters) 来简化与表格核心的交互。可用的适配器请参阅 Adapters 菜单。 + +### 访问表格状态 + +您无需进行任何特殊设置即可使表格状态正常工作。如果您没有向 `state`、`initialState` 或任何 `on[State]Change` 表格选项中传递任何内容,表格将在内部管理自己的状态。您可以使用 `table.getState()` 表格实例 API 访问此内部状态的任何部分。 + +```ts +private tableController = new TableController(this); + +render() { + const table = this.tableController.table({ + columns, + data, + ... + }) + + console.log(table.getState()) //访问整个内部状态 + console.log(table.getState().rowSelection) //仅访问行选择状态 + // ... +} +``` + +### 自定义初始状态 + +如果您只需要为某些状态自定义其初始默认值,您仍然不需要自己管理任何状态。您只需在表格实例的 `initialState` 选项中设置值即可。 + +```ts +render() { + const table = this.tableController.table({ + columns, + data, + initialState: { + columnOrder: ['age', 'firstName', 'lastName'], //自定义初始列顺序 + columnVisibility: { + id: false //默认隐藏 id 列 + }, + expanded: true, //默认展开所有行 + sorting: [ + { + id: 'age', + desc: true //默认按年龄降序排序 + } + ] + }, + }) + + return html`...`; +} +``` + +> **注意**:每个特定的状态只能在 `initialState` 或 `state` 中指定,但不能同时在两者中指定。如果您将特定状态值同时传递给 `initialState` 和 `state`,`state` 中的初始化状态将覆盖 `initialState` 中的任何对应值。 + +### 受控状态 + +如果您需要在应用程序的其他区域轻松访问表格状态,TanStack Table 使得在您自己的状态管理系统中控制和管理任何或所有表格状态变得容易。您可以通过将自己的状态和状态管理函数传递给 `state` 和 `on[State]Change` 表格选项来实现这一点。 + +#### 单独受控状态 + +您可以仅控制您需要轻松访问的状态。如果不需要,您不必控制所有表格状态。建议根据具体情况仅控制您需要的状态。 + +为了控制特定状态,您需要将相应的 `state` 值和 `on[State]Change` 函数都传递给表格实例。 + +让我们以“手动”服务端数据获取场景中的过滤、排序和分页为例。您可以将过滤、排序和分页状态存储在您自己的状态管理中,但如果您的 API 不关心这些值,可以忽略其他状态,如列顺序、列可见性等。 + +```jsx +import {html} from "lit"; + +@customElement('my-component') +class MyComponent extends LitElement { + @state() + private _sorting: SortingState = [] + + render() { + const table = this.tableController.table({ + columns, + data, + state: { + sorting: this._sorting, + }, + onSortingChange: updaterOrValue => { + if (typeof updaterOrValue === 'function') { + this._sorting = updaterOrValue(this._sorting) + } else { + this._sorting = updaterOrValue + } + }, + getSortedRowModel: getSortedRowModel(), + getCoreRowModel: getCoreRowModel(), + }) + + return html`...` + } +} +//... +``` + +#### 完全受控状态 + +或者,您可以使用 `onStateChange` 表格选项控制整个表格状态。它将整个表格状态提升到您自己的状态管理系统中。使用此方法时要小心,因为您可能会发现将一些频繁变化的状态值(如 `columnSizingInfo` 状态)提升到组件树中可能会导致性能问题。 + +可能需要一些额外的技巧来实现这一点。如果您使用 `onStateChange` 表格选项,`state` 的初始值必须填充您想要使用的所有相关状态值。您可以手动键入所有初始状态值,或者以如下所示的方式使用 `table.setOptions` API。 + +```ts + +private tableController = new TableController(this); + +@state() +private _tableState; + +render() { + const table = this.tableController.table({ + columns, + data, + getCoreRowModel: getCoreRowModel(), + getSortedRowModel: getSortedRowModel() + }) + const state = { ...table.initialState, ...this._tableState }; + table.setOptions(prev => ({ + ...prev, + state, + onStateChange: updater => { + this._tableState = + updater instanceof Function ? updater(state) : updater //任何状态更改都将推送到我们自己的状态管理 + }, + })) + + return html`...`; +} +``` + +### 状态更改回调 + +到目前为止,我们已经看到 `on[State]Change` 和 `onStateChange` 表格选项用于将表格状态更改“提升”到我们自己的状态管理中。然而,使用这些选项时需要注意以下几点。 + +#### 1. **状态更改回调必须在 `state` 选项中有对应的状态值**。 + +指定 `on[State]Change` 回调会告诉表格实例这将是一个受控状态。如果您没有指定相应的 `state` 值,该状态将“冻结”为其初始值。 + +```jsx +@state() +private _sorting = []; +//... +render() { + const table = this.tableController.table({ + columns, + data, + state: { + sorting: this._sorting, + }, + onSortingChange: updaterOrValue => { + if (typeof updaterOrValue === 'function') { + this._sorting = updaterOrValue(this._sorting) + } else { + this._sorting = updaterOrValue + } + }, + getSortedRowModel: getSortedRowModel(), + getCoreRowModel: getCoreRowModel(), + }) + + return html`...`; +} +``` + +#### 2. **更新器可以是原始值或回调函数**。 + +`on[State]Change` 和 `onStateChange` 回调的工作方式与 React 中的 `setState` 函数完全相同。更新器值可以是一个新的状态值,也可以是一个回调函数,该函数接收先前的状态值并返回新的状态值。 + +这有什么影响?这意味着如果您想在任何一个 `on[State]Change` 回调中添加一些额外的逻辑,您可以这样做,但您需要检查新的传入更新器值是函数还是值。 + +这就是为什么您会在上面的示例中看到 `updater instanceof Function ? updater(state.value) : updater` 模式。此模式检查更新器是否是函数,如果是,则使用先前的状态值调用该函数以获取新的状态值。 + +### 状态类型 + +TanStack Table 中的所有复杂状态都有自己的 TypeScript 类型,您可以导入并使用。这对于确保您为控制的状态值使用正确的数据结构和属性非常方便。 + +```tsx +import { TableController, type SortingState } from '@tanstack/lit-table' +//... +@state() +private _sorting: SortingState = [ + { + id: 'age', //您应该会获得 `id` 和 `desc` 属性的自动补全 + desc: true, + } +] +``` diff --git a/docs/zh-hans/framework/lit/lit-table.md b/docs/zh-hans/framework/lit/lit-table.md new file mode 100644 index 0000000000..3812d9c23d --- /dev/null +++ b/docs/zh-hans/framework/lit/lit-table.md @@ -0,0 +1,66 @@ +--- +source-updated-at: '2024-05-17T05:10:48.000Z' +translation-updated-at: '2025-05-02T16:57:43.591Z' +title: Lit 表格适配器 +--- +# Lit Table (不翻译标题) + +`@tanstack/lit-table` 适配器是对核心表格逻辑的封装层,其主要职责是以 "lit" 的方式管理状态,并提供单元格/表头/页脚模板的类型定义与渲染实现。 + +## 导出项 + +`@tanstack/lit-table` 重新导出了 `@tanstack/table-core` 的所有 API 及以下内容: + +### `TableController` + +这是一个响应式控制器,提供接收 `options` 配置对象并返回表格实例的 `table` API。 + +```ts +import { TableController } from '@tanstack/lit-table' + +@customElement('my-table-element') +class MyTableElement extends LitElement { + private tableController = new TableController(this) + + protected render() { + const table = this.tableController.table(options) + // ...渲染你的表格 + } +} +``` + +### `flexRender` + +用于渲染带有动态值的单元格/表头/页脚模板的工具函数。 + +示例: + +```jsx +import { flexRender } from '@tanstack/lit-table' +//... +return html` + + ${table + .getRowModel() + .rows.slice(0, 10) + .map( + row => html` + + ${row + .getVisibleCells() + .map( + cell => html` + + ${flexRender( + cell.column.columnDef.cell, + cell.getContext() + )} + + ` + )} + + ` + )} + +` +``` diff --git a/docs/zh-hans/framework/qwik/guide/table-state.md b/docs/zh-hans/framework/qwik/guide/table-state.md new file mode 100644 index 0000000000..4b0f07b89e --- /dev/null +++ b/docs/zh-hans/framework/qwik/guide/table-state.md @@ -0,0 +1,179 @@ +--- +source-updated-at: '2024-05-17T05:10:48.000Z' +translation-updated-at: '2025-05-02T17:07:50.431Z' +title: 表格状态 +--- +## 表格状态 (Qwik) 指南 + +TanStack Table 拥有一个简单的底层内部状态管理系统,用于存储和管理表格状态。它还允许您有选择性地提取需要在自身状态管理中处理的任何状态。本指南将介绍与表格状态交互和管理的不同方式。 + +### 访问表格状态 + +您无需进行任何特殊设置即可使表格状态正常工作。如果未向 `state`、`initialState` 或任何 `on[State]Change` 表格选项传入任何内容,表格将在内部自行管理状态。您可以使用 `table.getState()` 表格实例 API 访问这部分内部状态的任何内容。 + +```jsx +const table = useQwikTable({ + columns, + data, + //... +}) + +console.log(table.getState()) //访问整个内部状态 +console.log(table.getState().rowSelection) //仅访问行选中状态 +``` + +### 自定义初始状态 + +如果仅需为某些状态自定义其初始默认值,您仍无需自行管理任何状态。只需在表格实例的 `initialState` 选项中设置值即可。 + +```jsx +const table = useQwikTable({ + columns, + data, + initialState: { + columnOrder: ['age', 'firstName', 'lastName'], //自定义初始列排序 + columnVisibility: { + id: false //默认隐藏 id 列 + }, + expanded: true, //默认展开所有行 + sorting: [ + { + id: 'age', + desc: true //默认按年龄降序排序 + } + ] + }, + //... +}) +``` + +> **注意**:每个特定状态只能在 `initialState` 或 `state` 中指定,不能同时存在于两者。如果向 `initialState` 和 `state` 都传入了特定状态值,`state` 中的初始化状态将覆盖 `initialState` 中的对应值。 + +### 受控状态 + +如果需要在应用程序的其他区域轻松访问表格状态,TanStack Table 可让您轻松在自身状态管理系统中控制和管理部分或全部表格状态。通过向 `state` 和 `on[State]Change` 表格选项传入自身状态和状态管理函数即可实现。 + +#### 单独受控状态 + +您可以仅控制需要轻松访问的状态。如果不需要,不必控制所有表格状态。建议根据具体情况仅控制所需状态。 + +为了控制特定状态,您需要向表格实例同时传入对应的 `state` 值和 `on[State]Change` 函数。 + +以“手动”服务端数据获取场景中的筛选、排序和分页为例。您可以将筛选、排序和分页状态存储在自身状态管理中,但如果 API 不关心列顺序、列可见性等值,则可以忽略这些状态。 + +```jsx +const columnFilters = Qwik.useSignal([]) //无默认筛选器 +const sorting = Qwik.useSignal([{ + id: 'age', + desc: true, //默认按年龄降序排序 +}]) +const pagination = Qwik.useSignal({ pageIndex: 0, pageSize: 15 }) + +//使用受控状态值获取数据 +const tableQuery = useQuery({ + queryKey: ['users', columnFilters.value, sorting.value, pagination.value], + queryFn: () => fetchUsers(columnFilters.value, sorting.value, pagination.value), + //... +}) + +const table = useQwikTable({ + columns: columns.value, + data: tableQuery.data, + //... + state: { + columnFilters: columnFilters.value, //将受控状态传回表格(覆盖内部状态) + sorting: sorting.value, + pagination: pagination.value, + }, + onColumnFiltersChange: updater => { + columnFilters.value = updater instanceof Function ? updater(columnFilters.value) : updater //将 columnFilters 状态提升至自身状态管理 + }, + onSortingChange: updater => { + sorting.value = updater instanceof Function ? updater(sorting.value) : updater + }, + onPaginationChange: updater => { + pagination.value = updater instanceof Function ? updater(pagination.value) : updater + }, +}) +//... +``` + +#### 完全受控状态 + +或者,您可以使用 `onStateChange` 表格选项控制整个表格状态。这会将整个表格状态提升至自身状态管理系统。请注意此方法,因为将一些频繁变化的状态值(如 `columnSizingInfo` 状态)提升至组件树可能会导致性能问题。 + +可能需要更多技巧来实现这一点。如果使用 `onStateChange` 表格选项,`state` 的初始值必须填充所有相关状态值以满足您想使用的所有功能。您可以手动输入所有初始状态值,或如下所示以特殊方式使用 `table.setOptions` API。 + +```jsx +//创建带有默认状态值的表格实例 +const table = useQwikTable({ + columns, + data, + //... 注意:此时尚未传入 `state` 值 +}) + + +const sate = Qwik.useSignal({ + ...table.initialState, //用表格实例的所有默认状态值填充初始状态 + pagination: { + pageIndex: 0, + pageSize: 15 //可选自定义初始分页状态 + } +}) + +//使用 table.setOptions API 将完全受控状态合并到表格实例 +table.setOptions(prev => ({ + ...prev, //保留之前设置的任何其他选项 + state: state.value, //完全受控状态覆盖内部状态 + onStateChange: updater => { + state.value = updater instanceof Function ? updater(state.value) : updater //任何状态变更都将提升至自身状态管理 + }, +})) +``` + +### 状态变更回调 + +到目前为止,我们已经看到 `on[State]Change` 和 `onStateChange` 表格选项将表格状态变更“提升”至自身状态管理。但使用这些选项时需要注意以下几点。 + +#### 1. **状态变更回调必须在 `state` 选项中有对应的状态值**。 + +指定 `on[State]Change` 回调会告知表格实例该状态为受控状态。如果未指定对应的 `state` 值,该状态将“冻结”为其初始值。 + +```jsx +const sorting = Qwik.useSignal([]) +//... +const table = useQwikTable({ + columns, + data, + //... + state: { + sorting: sorting.value, //必需,因为我们使用了 `onSortingChange` + }, + onSortingChange: updater => { + sorting.value = updater instanceof Function ? updater(sorting) : updater //使 `state.sorting` 受控 + }, +}) +``` + +#### 2. **更新器可以是原始值或回调函数**。 + +`on[State]Change` 和 `onStateChange` 回调的工作方式与 React 中的 `setState` 函数完全相同。更新器值可以是新状态值,也可以是接收先前状态值并返回新状态值的回调函数。 + +这意味着什么?这意味着如果想在任何 `on[State]Change` 回调中添加额外逻辑,可以这样做,但需要检查新传入的更新器值是函数还是值。 + +这就是为什么在上面的示例中会看到 `updater instanceof Function ? updater(state.value) : updater` 模式。此模式检查更新器是否为函数,如果是,则调用该函数并传入先前状态值以获取新状态值。 + +### 状态类型 + +TanStack Table 中的所有复杂状态都有各自的 TypeScript 类型可供导入和使用。这有助于确保您为控制的状态值使用正确的数据结构和属性。 + +```tsx +import { useQwikTable, type SortingState } from '@tanstack/qwik-table' +//... +const sorting = Qwik.useSignal([ + { + id: 'age', //应获得 `id` 和 `desc` 属性的自动补全 + desc: true, + } +]) +``` diff --git a/docs/zh-hans/framework/qwik/qwik-table.md b/docs/zh-hans/framework/qwik/qwik-table.md new file mode 100644 index 0000000000..9397d3a692 --- /dev/null +++ b/docs/zh-hans/framework/qwik/qwik-table.md @@ -0,0 +1,49 @@ +--- +source-updated-at: '2024-05-17T05:10:48.000Z' +translation-updated-at: '2025-05-02T16:54:14.299Z' +title: Qwik 表格适配器 +--- +# Qwik Table (请勿包含此标题在翻译中) + +`@tanstack/qwik-table` 适配器是对核心表格逻辑的封装层。其主要职责是以 "Qwik" 方式管理状态,提供类型支持以及单元格/表头/表尾模板的渲染实现。 + +## 导出项 + +`@tanstack/qwik-table` 重新导出了 `@tanstack/table-core` 的所有 API 及以下内容: + +### `useQwikTable` + +接收一个 `options` 配置对象,并返回来自 Qwik Store 的带有 `NoSerialize` 特性的表格实例。 + +```ts +import { useQwikTable } from '@tanstack/qwik-table' + +const table = useQwikTable(options) +// ...渲染你的表格 +``` + +### `flexRender` + +用于渲染带有动态值的单元格/表头/表尾模板的工具函数。 + +示例: + +```jsx +import { flexRender } from '@tanstack/qwik-table' +//... +return ( + + {table.getRowModel().rows.map(row => { + return ( + + {row.getVisibleCells().map(cell => ( + + {flexRender(cell.column.columnDef.cell, cell.getContext())} + + ))} + + ) + })} + +); +``` diff --git a/docs/zh-hans/framework/react/guide/table-state.md b/docs/zh-hans/framework/react/guide/table-state.md new file mode 100644 index 0000000000..e650a69d13 --- /dev/null +++ b/docs/zh-hans/framework/react/guide/table-state.md @@ -0,0 +1,203 @@ +--- +source-updated-at: '2025-03-20T21:15:29.000Z' +translation-updated-at: '2025-05-02T17:08:52.338Z' +title: 表格状态 +--- +## 示例 + +想直接查看实现代码?请参考以下示例: + +- [综合示例](../examples/kitchen-sink) +- [完全受控](../examples/fully-controlled) + +## 表格状态 (React) 指南 + +TanStack Table 的核心是 **框架无关 (framework agnostic)** 的,这意味着无论使用哪个框架,其 API 都保持一致。根据所用框架不同,适配器 (Adapters) 可以让表格核心更易使用。可用适配器详见适配器菜单。 + +### 访问表格状态 + +无需特殊设置即可使用表格状态功能。如果不向 `state`、`initialState` 或任何 `on[State]Change` 表格选项传入参数,表格将在内部自行管理状态。可通过 `table.getState()` 表格实例 API 访问内部状态。 + +```jsx +const table = useReactTable({ + columns, + data, + //... +}) + +console.log(table.getState()) //访问完整内部状态 +console.log(table.getState().rowSelection) //仅访问行选中状态 +``` + +### 自定义初始状态 + +若只需自定义某些状态的初始默认值,仍无需自行管理状态。只需在表格实例的 `initialState` 选项中设置值即可。 + +```jsx +const table = useReactTable({ + columns, + data, + initialState: { + columnOrder: ['age', 'firstName', 'lastName'], //自定义初始列排序 + columnVisibility: { + id: false //默认隐藏 id 列 + }, + expanded: true, //默认展开所有行 + sorting: [ + { + id: 'age', + desc: true //默认按年龄降序排序 + } + ] + }, + //... +}) +``` + +> **注意**:每个特定状态只能在 `initialState` 或 `state` 中指定,不能同时存在。若某个状态值同时传入 `initialState` 和 `state`,`state` 中的初始化值将覆盖 `initialState` 中的对应值。 + +### 受控状态 + +如需在应用其他区域轻松访问表格状态,TanStack Table 支持将部分或全部表格状态交由外部状态管理系统控制。通过向 `state` 和 `on[State]Change` 表格选项传入自定义状态及管理函数即可实现。 + +#### 部分受控状态 + +可以仅控制需要访问的状态,不必全盘接管。建议根据实际需求逐个控制特定状态。 + +控制特定状态需同时向表格实例传入对应的 `state` 值和 `on[State]Change` 函数。以下以服务端手动获取数据场景中的筛选、排序和分页为例: + +```jsx +const [columnFilters, setColumnFilters] = React.useState([]) //无默认筛选 +const [sorting, setSorting] = React.useState([{ + id: 'age', + desc: true, //默认按年龄降序排序 +}]) +const [pagination, setPagination] = React.useState({ pageIndex: 0, pageSize: 15 }) + +//使用受控状态值获取数据 +const tableQuery = useQuery({ + queryKey: ['users', columnFilters, sorting, pagination], + queryFn: () => fetchUsers(columnFilters, sorting, pagination), + //... +}) + +const table = useReactTable({ + columns, + data: tableQuery.data, + //... + state: { + columnFilters, //将受控状态传回表格(覆盖内部状态) + sorting, + pagination + }, + onColumnFiltersChange: setColumnFilters, //将 columnFilters 状态提升至自定义状态管理 + onSortingChange: setSorting, + onPaginationChange: setPagination, +}) +//... +``` + +#### 完全受控状态 + +也可通过 `onStateChange` 表格选项完全控制整个表格状态。此时需注意:将高频变更的状态值(如 `columnSizingInfo`)提升至 React 组件树可能导致性能问题。 + +实现完全控制需要一些技巧。使用 `onStateChange` 时,`state` 初始值必须包含所有相关状态值。可以手动编写所有初始状态,或如下特殊使用 `table.setOptions` API: + +```jsx +//创建带默认状态的表格实例 +const table = useReactTable({ + columns, + data, + //... 注意:此时未传入 `state` 值 +}) + + +const [state, setState] = React.useState({ + ...table.initialState, //用表格实例的默认状态填充初始状态 + pagination: { + pageIndex: 0, + pageSize: 15 //可选自定义分页初始状态 + } +}) + +//使用 table.setOptions API 将完全受控状态合并到表格实例 +table.setOptions(prev => ({ + ...prev, //保留之前设置的所有选项 + state, //完全受控状态覆盖内部状态 + onStateChange: setState //状态变更将推送至自定义状态管理 +})) +``` + +### 状态变更回调 + +前文展示了通过 `on[State]Change` 和 `onStateChange` 将表格状态变更"提升"至自定义状态管理。但使用这些选项时需注意以下几点: + +#### 1. **状态变更回调必须对应 `state` 选项中的状态值** + +指定 `on[State]Change` 回调即表示该状态将受控。若未指定对应的 `state` 值,该状态将保持初始值不变。 + +```jsx +const [sorting, setSorting] = React.useState([]) +//... +const table = useReactTable({ + columns, + data, + //... + state: { + sorting, //必须存在,因为我们使用了 `onSortingChange` + }, + onSortingChange: setSorting, //使 `state.sorting` 受控 +}) +``` + +#### 2. **更新器可以是原始值或回调函数** + +`on[State]Change` 和 `onStateChange` 回调的工作方式与 React 的 `setState` 函数完全相同。更新器可以是新状态值,也可以是接收旧状态值并返回新状态值的回调函数。 + +这意味着可以在 `on[State]Change` 回调中添加额外逻辑,但需判断传入的更新器是函数还是值: + +```jsx +const [sorting, setSorting] = React.useState([]) +const [pagination, setPagination] = React.useState({ pageIndex: 0, pageSize: 10 }) + +const table = useReactTable({ + columns, + data, + //... + state: { + pagination, + sorting, + } + //语法 1 + onPaginationChange: (updater) => { + setPagination(old => { + const newPaginationValue = updater instanceof Function ? updater(old) : updater + //对新分页值进行操作 + //... + return newPaginationValue + }) + }, + //语法 2 + onSortingChange: (updater) => { + const newSortingValue = updater instanceof Function ? updater(sorting) : updater + //对新排序值进行操作 + //... + setSorting(updater) //正常状态更新 + } +}) +``` + +### 状态类型 + +TanStack Table 中所有复杂状态都有对应的 TypeScript 类型可供导入使用,这有助于确保受控状态值使用正确的数据结构和属性。 + +```tsx +import { useReactTable, type SortingState } from '@tanstack/react-table' +//... +const [sorting, setSorting] = React.useState([ + { + id: 'age', //可获取 `id` 和 `desc` 属性的自动补全 + desc: true, + } +]) +``` diff --git a/docs/zh-hans/framework/react/react-table.md b/docs/zh-hans/framework/react/react-table.md new file mode 100644 index 0000000000..b4ee7717f5 --- /dev/null +++ b/docs/zh-hans/framework/react/react-table.md @@ -0,0 +1,20 @@ +--- +source-updated-at: '2024-01-24T21:39:34.000Z' +translation-updated-at: '2025-05-02T16:56:03.829Z' +title: React 表格适配器 +--- +`@tanstack/react-table` 适配器是对核心表格逻辑的封装层,其主要职责是以 "React" 的方式管理状态,并提供单元格/表头/表尾模板的类型定义与渲染实现。 + +## `useReactTable` + +接收一个 `options` 配置对象并返回表格实例。 + +```tsx +import { useReactTable } from '@tanstack/react-table' + +function App() { + const table = useReactTable(options) + + // ...在此处渲染你的表格 +} +``` diff --git a/docs/zh-hans/framework/solid/guide/table-state.md b/docs/zh-hans/framework/solid/guide/table-state.md new file mode 100644 index 0000000000..2a809043a8 --- /dev/null +++ b/docs/zh-hans/framework/solid/guide/table-state.md @@ -0,0 +1,219 @@ +--- +source-updated-at: '2024-05-17T05:10:48.000Z' +translation-updated-at: '2025-05-02T17:09:57.406Z' +title: 表格状态 +--- +## 表格状态管理 (Solid) 指南 + +TanStack Table 的核心是**框架无关 (framework agnostic)** 的,这意味着无论您使用何种框架,其 API 都保持一致。通过适配器 (Adapters) 可以更方便地在不同框架中使用表格核心功能。可用适配器请参阅 Adapters 菜单。 + +### 访问表格状态 + +表格状态管理无需特殊设置。如果不向 `state`、`initialState` 或任何 `on[State]Change` 表格选项传递参数,表格将在内部自行管理状态。您可以通过 `table.getState()` 表格实例 API 访问任何内部状态。 + +```jsx +const table = createSolidTable({ + columns, + get data() { + return data() + }, + //... +}) + +console.log(table.getState()) // 访问完整内部状态 +console.log(table.getState().rowSelection) // 仅访问行选中状态 +``` + +### 自定义初始状态 + +若只需自定义某些状态的初始默认值,您仍无需自行管理状态。只需在表格实例的 `initialState` 选项中设置值即可。 + +```jsx +const table = createSolidTable({ + columns, + data, + initialState: { + columnOrder: ['age', 'firstName', 'lastName'], // 自定义初始列排序 + columnVisibility: { + id: false // 默认隐藏 id 列 + }, + expanded: true, // 默认展开所有行 + sorting: [ + { + id: 'age', + desc: true // 默认按年龄降序排序 + } + ] + }, + //... +}) +``` + +> **注意**:每个特定状态只能在 `initialState` 或 `state` 中指定,不能同时存在于两者。若某个状态值同时传递给 `initialState` 和 `state`,`state` 中的初始化值将覆盖 `initialState` 中的对应值。 + +### 受控状态 + +如需在应用其他区域轻松访问表格状态,TanStack Table 支持将部分或全部表格状态交由您自己的状态管理系统控制。通过向 `state` 和 `on[State]Change` 表格选项传递自定义状态和管理函数即可实现。 + +#### 部分受控状态 + +您可以仅控制需要频繁访问的状态,无需全盘接管。建议根据实际需求按需控制特定状态。 + +要控制特定状态,需同时向表格实例传递对应的 `state` 值和 `on[State]Change` 函数。以下以服务端手动获取数据场景中的筛选、排序和分页状态为例: + +```jsx +const [columnFilters, setColumnFilters] = createSignal([]) // 无默认筛选条件 +const [sorting, setSorting] = createSignal([{ + id: 'age', + desc: true, // 默认按年龄降序排序 +}]) +const [pagination, setPagination] = createSignal({ pageIndex: 0, pageSize: 15 }) + +// 使用受控状态值获取数据 +const tableQuery = createQuery({ + queryKey: ['users', columnFilters, sorting, pagination], + queryFn: () => fetchUsers(columnFilters, sorting, pagination), + //... +}) + +const table = createSolidTable({ + columns, + get data() { + return tableQuery.data() + }, + //... + state: { + get columnFilters() { + return columnFilters() // 将受控状态传回表格(覆盖内部状态) + }, + get sorting() { + return sorting() + }, + get pagination() { + return pagination() + }, + }, + onColumnFiltersChange: setColumnFilters, // 将 columnFilters 状态提升至自有状态管理 + onSortingChange: setSorting, + onPaginationChange: setPagination, +}) +//... +``` + +#### 完全受控状态 + +也可通过 `onStateChange` 表格选项控制整个表格状态。这会将所有状态提升至您的状态管理系统。需注意:频繁变化的状态值(如 `columnSizingInfo`)可能导致性能问题。 + +实现完全控制需要一些技巧。使用 `onStateChange` 时,必须为所有要使用的功能预填充 `state` 初始值。可以手动编写所有初始状态,或如下特殊使用 `table.setOptions` API: + +```jsx +// 创建带有默认状态值的表格实例 +const table = createSolidTable({ + columns, + get data() { + return data() + }, + //... 注意:此时尚未传递 `state` 值 +}) + +const [state, setState] = createSignal({ + ...table.initialState, // 用表格实例的所有默认状态值填充初始状态 + pagination: { + pageIndex: 0, + pageSize: 15 // 可选自定义分页初始状态 + } +}) + +// 使用 table.setOptions API 将完全受控状态合并到表格实例 +table.setOptions(prev => ({ + ...prev, // 保留之前设置的所有选项 + get state() { + return state() // 完全受控状态覆盖内部状态 + }, + onStateChange: setState // 所有状态变更将推送至自有状态管理 +})) +``` + +### 状态变更回调 + +前文展示了 `on[State]Change` 和 `onStateChange` 如何将表格状态变更"提升"至自有状态管理。但使用这些选项时需注意以下几点: + +#### 1. **状态变更回调必须对应 `state` 选项中的状态值** + +指定 `on[State]Change` 回调即表示该状态将受控。若未指定对应的 `state` 值,该状态将保持初始值不变。 + +```jsx +const [sorting, setSorting] = createSignal([]) +//... +const table = createSolidTable({ + columns, + data, + //... + state: { + get sorting() { + return sorting() // 必须提供,因为使用了 `onSortingChange` + }, + }, + onSortingChange: setSorting, // 使 `state.sorting` 成为受控状态 +}) +``` + +#### 2. **更新器可以是原始值或回调函数** + +`on[State]Change` 和 `onStateChange` 回调的工作方式与 React (Solid Setters) 中的 `setState` 函数完全相同。更新器可以是新状态值,也可以是接收旧状态值并返回新状态值的回调函数。 + +这意味着您可以在 `on[State]Change` 回调中添加额外逻辑,但需要检查传入的更新器是函数还是值: + +```jsx +const [sorting, setSorting] = createSignal([]) +const [pagination, setPagination] = createSignal({ pageIndex: 0, pageSize: 10 }) + +const table = createSolidTable({ + get columns() { + return columns() + }, + get data() { + return data() + }, + //... + state: { + get pagination() { + return pagination() + }, + get sorting() { + return sorting() + }, + } + // 语法 1 + onPaginationChange: (updater) => { + setPagination(old => { + const newPaginationValue = updater instanceof Function ? updater(old) : updater + // 可对新分页值进行处理 + //... + return newPaginationValue + }) + }, + // 语法 2 + onSortingChange: (updater) => { + const newSortingValue = updater instanceof Function ? updater(sorting) : updater + // 可对新排序值进行处理 + //... + setSorting(updater) // 正常状态更新 + } +}) +``` + +### 状态类型 + +TanStack Table 中所有复杂状态都有对应的 TypeScript 类型可供导入使用。这能确保您为受控状态值使用正确的数据结构和属性。 + +```tsx +import { createSolidTable, type SortingState } from '@tanstack/solid-table' +//... +const [sorting, setSorting] = createSignal([ + { + id: 'age', // 可自动补全 `id` 和 `desc` 属性 + desc: true, + } +]) +``` diff --git a/docs/zh-hans/framework/solid/solid-table.md b/docs/zh-hans/framework/solid/solid-table.md new file mode 100644 index 0000000000..c0dc6930d0 --- /dev/null +++ b/docs/zh-hans/framework/solid/solid-table.md @@ -0,0 +1,20 @@ +--- +source-updated-at: '2024-01-24T21:39:34.000Z' +translation-updated-at: '2025-05-02T16:54:29.218Z' +title: Solid 表格适配器 +--- +Solid Table 是围绕核心表格逻辑的适配器封装,其主要职责是以 "solid" 的方式管理状态,并提供单元格/表头/表尾模板的类型定义与渲染实现。 + +## `createSolidTable` + +接收一个 `options` 配置对象并返回表格实例。 + +```tsx +import { createSolidTable } from '@tanstack/solid-table' + +function App() { + const table = createSolidTable(options) + + // ...渲染表格 +} +``` diff --git a/docs/zh-hans/framework/svelte/guide/table-state.md b/docs/zh-hans/framework/svelte/guide/table-state.md new file mode 100644 index 0000000000..3d45d640f3 --- /dev/null +++ b/docs/zh-hans/framework/svelte/guide/table-state.md @@ -0,0 +1,261 @@ +--- +source-updated-at: '2024-05-17T05:10:48.000Z' +translation-updated-at: '2025-05-02T17:11:08.700Z' +title: 表格状态 +--- +## 表格状态管理 (Svelte) 指南 + +TanStack Table 的核心是**框架无关 (framework agnostic)** 的,这意味着无论您使用哪种框架,其 API 都保持一致。根据您使用的框架,提供了适配器 (Adapters) 来简化与表格核心的交互。可用的适配器请参阅 Adapters 菜单。 + +### 访问表格状态 + +无需特殊设置即可使用表格状态功能。如果不向 `state`、`initialState` 或任何 `on[State]Change` 表格选项中传递任何内容,表格将在内部自行管理状态。您可以通过 `table.getState()` 表格实例 API 访问内部状态的任何部分。 + +```jsx +const options = writable({ + columns, + data, + //... +}) + +const table = createSvelteTable(options) + +console.log(table.getState()) //访问整个内部状态 +console.log(table.getState().rowSelection) //仅访问行选中状态 +``` + +### 自定义初始状态 + +如果仅需为某些状态定制其初始默认值,您仍然无需自行管理任何状态。只需在表格实例的 `initialState` 选项中设置值即可。 + +```jsx +const options = writable({ + columns, + data, + initialState: { + columnOrder: ['age', 'firstName', 'lastName'], //自定义初始列顺序 + columnVisibility: { + id: false //默认隐藏 id 列 + }, + expanded: true, //默认展开所有行 + sorting: [ + { + id: 'age', + desc: true //默认按年龄降序排序 + } + ] + }, + //... +}) + +const table = createSvelteTable(options) +``` + +> **注意**:每个特定状态只能在 `initialState` 或 `state` 中指定,不能同时存在于两者。如果某个状态值同时传递给 `initialState` 和 `state`,`state` 中的初始化状态将覆盖 `initialState` 中的对应值。 + +### 受控状态 + +如果需要在应用程序的其他区域轻松访问表格状态,TanStack Table 允许您在自己的状态管理系统中轻松控制和管理表格的全部或部分状态。通过将自己的状态和状态管理函数传递给 `state` 和 `on[State]Change` 表格选项即可实现。 + +#### 部分受控状态 + +您可以仅控制需要轻松访问的状态。如果不需要,不必控制所有表格状态。建议根据具体情况仅控制所需状态。 + +为了控制特定状态,您需要将对应的 `state` 值和 `on[State]Change` 函数传递给表格实例。 + +以“手动”服务端数据获取场景中的筛选、排序和分页为例。您可以将筛选、排序和分页状态存储在自己的状态管理中,但如果您的 API 不关心列顺序、列可见性等其他状态,则可以忽略它们。 + +```ts +let sorting = [ + { + id: 'age', + desc: true, //默认按年龄降序排序 + }, +] +const setSorting = updater => { + if (updater instanceof Function) { + sorting = updater(sorting) + } else { + sorting = updater + } + options.update(old => ({ + ...old, + state: { + ...old.state, + sorting, + }, + })) +} + +let columnFilters = [] //无默认筛选条件 +const setColumnFilters = updater => { + if (updater instanceof Function) { + columnFilters = updater(columnFilters) + } else { + columnFilters = updater + } + options.update(old => ({ + ...old, + state: { + ...old.state, + columnFilters, + }, + })) +} + +let pagination = { pageIndex: 0, pageSize: 15 } //默认分页 +const setPagination = updater => { + if (updater instanceof Function) { + pagination = updater(pagination) + } else { + pagination = updater + } + options.update(old => ({ + ...old, + state: { + ...old.state, + pagination, + }, + })) +} + +//使用受控状态值获取数据 +const tableQuery = createQuery({ + queryKey: ['users', columnFilters, sorting, pagination], + queryFn: () => fetchUsers(columnFilters, sorting, pagination), + //... +}) + +const options = writable({ + columns, + data: tableQuery.data, + //... + state: { + columnFilters, //将受控状态传回表格(覆盖内部状态) + sorting, + pagination + }, + onColumnFiltersChange: setColumnFilters, //将 columnFilters 状态提升至自己的状态管理 + onSortingChange: setSorting, + onPaginationChange: setPagination, +}) + +const table = createSvelteTable(options) +//... +``` + +#### 完全受控状态 + +或者,您可以使用 `onStateChange` 表格选项控制整个表格状态。这将把整个表格状态提升至您自己的状态管理系统。使用此方法需谨慎,因为将一些频繁变化的状态值(如 `columnSizingInfo` 状态)提升至 Svelte 树中可能会导致性能问题。 + +可能需要一些额外技巧来实现这一点。如果使用 `onStateChange` 表格选项,`state` 的初始值必须填充您想使用的所有相关状态值。您可以手动输入所有初始状态值,或如下所示特殊方式使用 `table.setOptions` API。 + +```jsx +//创建带有默认状态值的表格实例 +const options = writable({ + columns, + data, + //... 注意:尚未传递 `state` 值 +}) +const table = createSvelteTable(options) + +let state = { + ...table.initialState, //用表格实例的所有默认状态值填充初始状态 + pagination: { + pageIndex: 0, + pageSize: 15 //可选自定义初始分页状态 + } +} +const setState = updater => { + if (updater instanceof Function) { + state = updater(state) + } else { + state = updater + } + options.update(old => ({ + ...old, + state, + })) +} + +//使用 table.setOptions API 将完全受控状态合并到表格实例 +table.setOptions(prev => ({ + ...prev, //保留上面设置的任何其他选项 + state, //完全受控状态覆盖内部状态 + onStateChange: setState //任何状态变更将推送至自己的状态管理 +})) +``` + +### 状态变更回调 + +到目前为止,我们已经看到 `on[State]Change` 和 `onStateChange` 表格选项如何将表格状态变更“提升”至我们自己的状态管理。但使用这些选项时需要注意以下几点。 + +#### 1. **状态变更回调必须在其对应的 `state` 选项中有相应的状态值**。 + +指定 `on[State]Change` 回调会告知表格实例这是一个受控状态。如果未指定对应的 `state` 值,该状态将“冻结”为其初始值。 + +```ts +let sorting = [] +const setSorting = updater => { + if (updater instanceof Function) { + sorting = updater(sorting) + } else { + sorting = updater + } + options.update(old => ({ + ...old, + state: { + ...old.state, + sorting, + }, + })) +} +//... +const options = writable({ + columns, + data, + //... + state: { + sorting, //必须因为我们正在使用 `onSortingChange` + }, + onSortingChange: setSorting, //使 `state.sorting` 受控 +}) +const table = createSvelteTable(options) +``` + +#### 2. **更新器可以是原始值或回调函数**。 + +`on[State]Change` 和 `onStateChange` 回调的工作方式与 React 中的 `setState` 函数完全相同。更新器值可以是新状态值,也可以是接收先前状态值并返回新状态值的回调函数。 + +这意味着什么?如果想在任何 `on[State]Change` 回调中添加额外逻辑,可以这样做,但需要检查新传入的更新器值是函数还是值。 + +这就是为什么在上面的示例中 `setState` 函数会有 `if (updater instanceof Function)` 检查。 + +### 状态类型 + +TanStack Table 中的所有复杂状态都有自己的 TypeScript 类型,您可以导入并使用。这有助于确保您为控制的状态值使用正确的数据结构和属性。 + +```ts +import { createSvelteTable, type SortingState, type Updater } from '@tanstack/svelte-table' +//... +let sorting: SortingState[] = [ + { + id: 'age', //您应该能获得 `id` 和 `desc` 属性的自动补全 + desc: true, + } +] +const setSorting = (updater: Updater) => { + if (updater instanceof Function) { + sorting = updater(sorting) + } else { + sorting = updater + } + options.update(old => ({ + ...old, + state: { + ...old.state, + sorting, + }, + })) +} +``` diff --git a/docs/zh-hans/framework/svelte/svelte-table.md b/docs/zh-hans/framework/svelte/svelte-table.md new file mode 100644 index 0000000000..0a3fdae242 --- /dev/null +++ b/docs/zh-hans/framework/svelte/svelte-table.md @@ -0,0 +1,20 @@ +--- +source-updated-at: '2024-01-24T21:39:34.000Z' +translation-updated-at: '2025-05-02T16:54:37.121Z' +title: Svelte 表格适配器 +--- +`@tanstack/svelte-table` 适配器是对核心表格逻辑的封装层,其主要职责是以 "svelte" 的方式管理状态,并提供单元格/表头/页脚模板的类型定义与渲染实现。 + +## `createSvelteTable` + +接收一个 `options` 配置对象并返回表格实例。 + +```svelte + +``` diff --git a/docs/zh-hans/framework/vanilla/guide/table-state.md b/docs/zh-hans/framework/vanilla/guide/table-state.md new file mode 100644 index 0000000000..735e81b38d --- /dev/null +++ b/docs/zh-hans/framework/vanilla/guide/table-state.md @@ -0,0 +1,6 @@ +--- +source-updated-at: '2024-03-22T06:50:43.000Z' +translation-updated-at: '2025-05-02T17:12:31.170Z' +title: 表格状态 +--- +## 表格状态 (Vanilla JS) 指南 diff --git a/docs/zh-hans/framework/vanilla/table-core.md b/docs/zh-hans/framework/vanilla/table-core.md new file mode 100644 index 0000000000..63ecd299f3 --- /dev/null +++ b/docs/zh-hans/framework/vanilla/table-core.md @@ -0,0 +1,5 @@ +--- +source-updated-at: '2024-03-22T06:50:43.000Z' +translation-updated-at: '2025-05-06T01:25:06.255Z' +--- + diff --git a/docs/zh-hans/framework/vue/guide/table-state.md b/docs/zh-hans/framework/vue/guide/table-state.md new file mode 100644 index 0000000000..7580342be2 --- /dev/null +++ b/docs/zh-hans/framework/vue/guide/table-state.md @@ -0,0 +1,249 @@ +--- +source-updated-at: '2024-08-10T14:15:46.000Z' +translation-updated-at: '2025-05-02T17:12:25.078Z' +title: 表格状态 +--- +## 表格状态 (Vue) 指南 + +TanStack Table 拥有一个简单的基础内部状态管理系统,用于存储和管理表格的状态。它还允许您有选择性地提取需要在自身状态管理中处理的任何状态。本指南将带您了解与表格状态交互和管理的不同方式。 + +### 访问表格状态 + +您无需进行任何特殊设置即可使表格状态正常工作。如果未向 `state`、`initialState` 或任何 `on[State]Change` 表格选项传递任何内容,表格将在内部自行管理其状态。您可以通过使用 `table.getState()` 表格实例 API 访问此内部状态的任何部分。 + +```ts +const table = useVueTable({ + columns, + data: dataRef, // 响应式数据支持 + //... +}) + +console.log(table.getState()) // 访问整个内部状态 +console.log(table.getState().rowSelection) // 仅访问行选择状态 +``` + +### 使用响应式数据 + +> **v8.20.0 新增功能** + +`useVueTable` 钩子现在支持响应式数据。这意味着您可以向 `data` 选项传递包含数据的 Vue `ref` 或 `computed`。表格将自动响应数据的变化。 + +```ts +const columns = [ + { accessor: 'id', Header: 'ID' }, + { accessor: 'name', Header: 'Name' } +] + +const dataRef = ref([ + { id: 1, name: 'John' }, + { id: 2, name: 'Jane' } +]) + +const table = useVueTable({ + columns, + data: dataRef, // 传递响应式数据 ref +}) + +// 之后,更新 dataRef 将自动更新表格 +dataRef.value = [ + { id: 1, name: 'John' }, + { id: 2, name: 'Jane' }, + { id: 3, name: 'Doe' } +] +``` + +> ⚠️ 出于性能考虑,底层使用了 `shallowRef`,这意味着数据不是深度响应式的,只有 `.value` 是。要更新数据,您必须直接修改数据。 + +```ts +const dataRef = ref([ + { id: 1, name: 'John' }, + { id: 2, name: 'Jane' } +]) + +// 这不会更新表格 ❌ +dataRef.value.push({ id: 4, name: 'John' }) + +// 这会更新表格 ✅ +dataRef.value = [ + ...dataRef.value, + { id: 4, name: 'John' } +] +``` + +### 自定义初始状态 + +如果对于某些状态,您只需要自定义其初始默认值,那么您仍然不需要自行管理任何状态。您只需在表格实例的 `initialState` 选项中设置值即可。 + +```jsx +const table = useVueTable({ + columns, + data, + initialState: { + columnOrder: ['age', 'firstName', 'lastName'], // 自定义初始列顺序 + columnVisibility: { + id: false // 默认隐藏 id 列 + }, + expanded: true, // 默认展开所有行 + sorting: [ + { + id: 'age', + desc: true // 默认按年龄降序排序 + } + ] + }, + //... +}) +``` + +> **注意**:每个特定的状态只能在 `initialState` 或 `state` 中指定,但不能同时在两者中指定。如果您将特定状态值同时传递给 `initialState` 和 `state`,`state` 中的初始化状态将覆盖 `initialState` 中的任何对应值。 + +### 受控状态 + +如果您需要在应用程序的其他区域轻松访问表格状态,TanStack Table 使得在您自己的状态管理系统中控制和管理表格的任何或所有状态变得容易。您可以通过向 `state` 和 `on[State]Change` 表格选项传递自己的状态和状态管理函数来实现这一点。 + +#### 单独受控状态 + +您可以仅控制您需要轻松访问的状态。如果不需要,您不必控制所有表格状态。建议根据具体情况仅控制您需要的状态。 + +为了控制特定状态,您需要同时将相应的 `state` 值和 `on[State]Change` 函数传递给表格实例。 + +让我们以“手动”服务器端数据获取场景中的过滤、排序和分页为例。您可以将过滤、排序和分页状态存储在您自己的状态管理中,但如果您的 API 不关心列顺序、列可见性等值,则可以忽略这些状态。 + +```ts +const columnFilters = ref([]) // 无默认过滤器 +const sorting = ref([{ + id: 'age', + desc: true, // 默认按年龄降序排序 +}]) +const pagination = ref({ pageIndex: 0, pageSize: 15 } + +// 使用我们的受控状态值获取数据 +const tableQuery = useQuery({ + queryKey: ['users', columnFilters, sorting, pagination], + queryFn: () => fetchUsers(columnFilters, sorting, pagination), + //... +}) + +const table = useVueTable({ + columns, + data: tableQuery.data, + //... + state: { + get columnFilters() { + return columnFilters.value + }, + get sorting() { + return sorting.value + }, + get pagination() { + return pagination.value + } + }, + onColumnFiltersChange: updater => { + columnFilters.value = + updater instanceof Function + ? updater(columnFilters.value) + : updater + }, + onSortingChange: updater => { + sorting.value = + updater instanceof Function + ? updater(sorting.value) + : updater + }, + onPaginationChange: updater => { + pagination.value = + updater instanceof Function + ? updater(pagination.value) + : updater + }, +}) +//... +``` + +#### 完全受控状态 + +或者,您可以使用 `onStateChange` 表格选项控制整个表格状态。这将把整个表格状态提升到您自己的状态管理系统中。使用此方法时要小心,因为您可能会发现将一些频繁变化的状态值(如 `columnSizingInfo` 状态)提升到 react 树中可能会导致性能问题。 + +可能需要一些额外的技巧来实现这一点。如果您使用 `onStateChange` 表格选项,`state` 的初始值必须填充您想要使用的所有相关状态值。您可以手动输入所有初始状态值,或者以如下所示的方式使用 `table.setOptions` API。 + +```jsx +// 使用默认状态值创建表格实例 +const table = useVueTable({ + get columns() { + return columns.value + }, + data, + //... 注意:尚未传递 `state` 值 +}) + +const state = ref({ + ...table.initialState, + pagination: { + pageIndex: 0, + pageSize: 15 + } +}) +const setState = updater => { + state.value = updater instanceof Function ? updater(state.value) : updater +} + +// 使用 table.setOptions API 将我们的完全受控状态合并到表格实例中 +table.setOptions(prev => ({ + ...prev, // 保留我们上面设置的任何其他选项 + get state() { + return state.value + }, + onStateChange: setState // 任何状态更改都将推送到我们自己的状态管理 +})) +``` + +### 状态变更回调 + +到目前为止,我们已经看到 `on[State]Change` 和 `onStateChange` 表格选项将表格状态更改“提升”到我们自己的状态管理中。然而,使用这些选项时有一些需要注意的事项。 + +#### 1. **状态变更回调必须在 `state` 选项中有相应的状态值**。 + +指定 `on[State]Change` 回调会告诉表格实例这将是一个受控状态。如果未指定相应的 `state` 值,该状态将“冻结”为其初始值。 + +```jsx +const sorting = ref([]) +const setSorting = updater => { + sorting.value = updater instanceof Function ? updater(sorting.value) : updater +} +//... +const table = useVueTable({ + columns, + data, + //... + state: { + get sorting() { + return sorting // 必需,因为我们正在使用 `onSortingChange` + }, + }, + onSortingChange: setSorting, // 使 `state.sorting` 受控 +}) +``` + +#### 2. **更新器可以是原始值或回调函数**。 + +`on[State]Change` 和 `onStateChange` 回调的工作方式与 React 中的 `setState` 函数完全相同。更新器值可以是新的状态值,也可以是接收先前状态值并返回新状态值的回调函数。 + +这意味着什么?这意味着如果您想在任何一个 `on[State]Change` 回调中添加一些额外的逻辑,您可以这样做,但需要检查新的传入更新器值是函数还是值。 + +这就是为什么我们在上面的 `setState` 函数中有 `updater instanceof Function` 检查。此检查允许我们在同一个函数中处理原始值和回调函数。 + +### 状态类型 + +TanStack Table 中的所有复杂状态都有自己的 TypeScript 类型,您可以导入并使用。这对于确保您为控制的状态值使用正确的数据结构和属性非常有用。 + +```tsx +import { useVueTable, type SortingState } from '@tanstack/vue-table' +//... +const sorting = ref([ + { + id: 'age', // 您应该会获得 `id` 和 `desc` 属性的自动完成 + desc: true, + } +]) +``` diff --git a/docs/zh-hans/framework/vue/vue-table.md b/docs/zh-hans/framework/vue/vue-table.md new file mode 100644 index 0000000000..3d1a1f8fde --- /dev/null +++ b/docs/zh-hans/framework/vue/vue-table.md @@ -0,0 +1,46 @@ +--- +source-updated-at: '2024-05-17T05:10:48.000Z' +translation-updated-at: '2025-05-02T16:57:56.577Z' +title: Vue 表格适配器 +--- +Vue Table + +`@tanstack/vue-table` 适配器是对核心表格逻辑的封装层,其主要职责是以 "Vue" 的方式管理状态,并提供类型支持以及单元格/表头/表尾模板的渲染实现。 + +## 导出项 + +`@tanstack/vue-table` 重新导出了 `@tanstack/table-core` 的所有 API 及以下内容: + +### `useVueTable` + +接收一个 `options` 配置对象并返回表格实例。 + +```ts +import { useVueTable } from '@tanstack/vue-table' + +const table = useVueTable(options) +// ...渲染你的表格 +``` + +### `FlexRender` + +用于渲染带有动态值的单元格/表头/表尾模板的 Vue 组件。 + +示例: + +```vue +import { FlexRender } from '@tanstack/vue-table' + + +``` diff --git a/docs/zh-hans/guide/cells.md b/docs/zh-hans/guide/cells.md new file mode 100644 index 0000000000..b9e44c62fb --- /dev/null +++ b/docs/zh-hans/guide/cells.md @@ -0,0 +1,87 @@ +--- +source-updated-at: '2025-03-20T21:15:29.000Z' +translation-updated-at: '2025-05-02T17:03:10.945Z' +title: 单元格 +--- +## API + +[Cell API](../api/core/cell) + +## Cells 指南 + +本快速指南将讨论在 TanStack Table 中获取和交互 `cell` 对象的不同方式。 + +### 从哪里获取 Cells + +Cells 来源于 [Rows](../guide/rows)。简单明了,对吧? + +根据你使用的功能,可以通过多种 `row` 实例 API 从行中获取对应的 cells。最常见的是使用 `row.getAllCells` 或 `row.getVisibleCells` API(如果你使用了列可见性功能),但还有其他类似的 API 可供使用。 + +### Cell 对象 + +每个 cell 对象可以与 UI 中的 `` 或类似单元格元素关联。`cell` 对象上有一些属性和方法,可用于与表格状态交互,并根据表格状态提取单元格值。 + +#### Cell ID + +每个 cell 对象都有一个 `id` 属性,使其在表格实例中唯一。每个 `cell.id` 的构造方式是其父行和列 ID 以下划线连接。 + +```js +{ id: `${row.id}_${column.id}` } +``` + +在分组或聚合功能中,`cell.id` 会附加额外的字符串。 + +#### Cell 父对象 + +每个 cell 存储了对其父 [row](../guide/rows) 和 [column](../guide/columns) 对象的引用。 + +#### 访问 Cell 值 + +推荐使用 `cell.getValue` 或 `cell.renderValue` API 访问 cell 的数据值。这两个 API 都会缓存访问器函数的结果,保持渲染高效。唯一的区别是,`cell.renderValue` 会返回值或 `renderFallbackValue`(如果值为 undefined),而 `cell.getValue` 会返回值或 `undefined`(如果值为 undefined)。 + +> 注意:`cell.getValue` 和 `cell.renderValue` API 分别是 `row.getValue` 和 `row.renderValue` API 的快捷方式。 + +```js +// 从任意列访问数据 +const firstName = cell.getValue('firstName') // 从 firstName 列读取 cell 值 +const renderedLastName = cell.renderValue('lastName') // 渲染 lastName 列的值 +``` + +#### 从任意 Cell 访问其他行数据 + +由于每个 cell 对象都关联其父行,因此可以通过 `cell.row.original` 访问表格中使用的原始行数据。 + +```js +// 即使在不同 cell 的作用域中,仍可访问原始行数据 +const firstName = cell.row.original.firstName // { firstName: 'John', lastName: 'Doe' } +``` + +### 更多 Cell API + +根据表格使用的功能,还有数十个其他有用的 API 可用于与 cells 交互。更多信息请参阅各功能的 API 文档或指南。 + +### Cell 渲染 + +你可以直接使用 `cell.renderValue` 或 `cell.getValue` API 渲染表格的 cells。但这些 API 仅输出原始 cell 值(来自访问器函数)。如果使用了 `cell: () => JSX` 列定义选项,则需要使用适配器中的 `flexRender` API 工具。 + +使用 `flexRender` API 可以正确渲染 cell 及其额外的标记或 JSX,并以正确的参数调用回调函数。 + +```jsx +import { flexRender } from '@tanstack/react-table' + +const columns = [ + { + accessorKey: 'fullName', + cell: ({ cell, row }) => { + return
{row.original.firstName} {row.original.lastName}
+ } + //... + } +] +//... + + {row.getVisibleCells().map(cell => { + return {flexRender(cell.column.columnDef.cell, cell.getContext())} + })} + +``` diff --git a/docs/zh-hans/guide/column-defs.md b/docs/zh-hans/guide/column-defs.md new file mode 100644 index 0000000000..4dcf7eec11 --- /dev/null +++ b/docs/zh-hans/guide/column-defs.md @@ -0,0 +1,283 @@ +--- +source-updated-at: '2025-03-20T21:15:29.000Z' +translation-updated-at: '2025-05-02T17:00:26.469Z' +title: 列定义 +--- +## API + +[列定义 (Column Def)](../api/core/column-def) + +## 列定义指南 + +> 注意:本指南介绍的是为表格设置列定义,而非表格实例中实际生成的 [`column`](../guide/columns) 对象。 + +列定义是构建表格最重要的部分,它们负责: + +- 构建底层数据模型,该模型将用于排序、筛选、分组等所有功能 +- 将数据模型格式化为表格中显示的内容 +- 创建 [表头组 (header groups)](../api/core/header-group)、[表头 (headers)](../api/core/header) 和 [表尾 (footers)](../api/core/column-def#footer) +- 创建仅用于展示的列,例如操作按钮、复选框、展开器、迷你图等 + +## 列定义类型 + +以下列定义"类型"并非实际的 TypeScript 类型,而是用于描述列定义的整体分类方式: + +- `访问器列 (Accessor Columns)` + - 访问器列具有底层数据模型,因此可以进行排序、筛选、分组等操作 +- `展示列 (Display Columns)` + - 展示列**没有**数据模型,因此无法排序、筛选等,但可用于在表格中显示任意内容,例如行操作按钮、复选框、展开器等 +- `分组列 (Grouping Columns)` + - 分组列**没有**数据模型,因此同样无法排序、筛选等,用于将其他列组合在一起。通常为列分组定义表头或表尾 + +## 列辅助工具 + +虽然列定义本质上只是普通对象,但表格核心提供了 `createColumnHelper` 函数,当传入行类型调用时,会返回一个工具函数,用于以最高类型安全性创建不同类型的列定义。 + +以下是创建和使用列辅助工具的示例: + +```tsx +// 定义行数据结构 +type Person = { + firstName: string + lastName: string + age: number + visits: number + status: string + progress: number +} + +const columnHelper = createColumnHelper() + +// 创建列! +const defaultColumns = [ + // 展示列 + columnHelper.display({ + id: 'actions', + cell: props => , + }), + // 分组列 + columnHelper.group({ + header: '姓名', + footer: props => props.column.id, + columns: [ + // 访问器列 + columnHelper.accessor('firstName', { + cell: info => info.getValue(), + footer: props => props.column.id, + }), + // 访问器列 + columnHelper.accessor(row => row.lastName, { + id: 'lastName', + cell: info => info.getValue(), + header: () => 姓氏, + footer: props => props.column.id, + }), + ], + }), + // 分组列 + columnHelper.group({ + header: '信息', + footer: props => props.column.id, + columns: [ + // 访问器列 + columnHelper.accessor('age', { + header: () => '年龄', + footer: props => props.column.id, + }), + // 分组列 + columnHelper.group({ + header: '更多信息', + columns: [ + // 访问器列 + columnHelper.accessor('visits', { + header: () => 访问次数, + footer: props => props.column.id, + }), + // 访问器列 + columnHelper.accessor('status', { + header: '状态', + footer: props => props.column.id, + }), + // 访问器列 + columnHelper.accessor('progress', { + header: '资料进度', + footer: props => props.column.id, + }), + ], + }), + ], + }), +] +``` + +## 创建访问器列 + +数据列的特殊之处在于必须配置为从 `data` 数组中的每个项提取原始值。 + +有三种实现方式: + +- 如果项是 `对象`,使用与要提取值对应的对象键 +- 如果项是嵌套 `数组`,使用与要提取值对应的数组索引 +- 使用返回要提取值的访问器函数 + +## 对象键 + +如果每个项是具有以下结构的对象: + +```tsx +type Person = { + firstName: string + lastName: string + age: number + visits: number + status: string + progress: number +} +``` + +可以这样提取 `firstName` 值: + +```tsx +columnHelper.accessor('firstName') + +// 或 + +{ + accessorKey: 'firstName', +} +``` + +## 深层键 + +如果每个项是具有以下结构的对象: + +```tsx +type Person = { + name: { + first: string + last: string + } + info: { + age: number + visits: number + } +} +``` + +可以这样提取 `first` 值: + +```tsx +columnHelper.accessor('name.first', { + id: 'firstName', +}) + +// 或 + +{ + accessorKey: 'name.first', + id: 'firstName', +} +``` + +## 数组索引 + +如果每个项是具有以下结构的数组: + +```tsx +type Sales = [Date, number] +``` + +可以这样提取 `number` 值: + +```tsx +columnHelper.accessor(1) + +// 或 + +{ + accessorKey: 1, +} +``` + +## 访问器函数 + +如果每个项是具有以下结构的对象: + +```tsx +type Person = { + firstName: string + lastName: string + age: number + visits: number + status: string + progress: number +} +``` + +可以这样提取计算得到的全名值: + +```tsx +columnHelper.accessor(row => `${row.firstName} ${row.lastName}`, { + id: 'fullName', +}) + +// 或 + +{ + id: 'fullName', + accessorFn: row => `${row.firstName} ${row.lastName}`, +} +``` + +> 🧠 记住,访问的值将用于排序、筛选等操作,因此需要确保访问器函数返回的原始值能以有意义的方式操作。如果返回非原始值(如对象或数组),则需要提供相应的筛选/排序/分组函数来操作它们,甚至可能需要自定义这些函数!😬 + +## 唯一列 ID + +列通过以下三种策略进行唯一标识: + +- 如果使用对象键或数组索引定义访问器列,则相同的键或索引将用于唯一标识列 + - 对象键中的任何句点 (`.`) 都将替换为下划线 (`_`) +- 如果使用访问器函数定义访问器列 + - 将使用列的 `id` 属性唯一标识列,或 + - 如果提供了原始 `string` 类型的表头,则该表头字符串将用于唯一标识列 + +> 🧠 简单记忆方法:如果使用访问器函数定义列,请提供字符串表头或唯一的 `id` 属性。 + +## 列格式化与渲染 + +默认情况下,列单元格会将其数据模型值显示为字符串。可以通过提供自定义渲染实现来覆盖此行为。每个实现都会获得有关单元格、表头或表尾的相关信息,并返回框架适配器可以渲染的内容,例如 JSX/组件/字符串等。具体取决于使用的适配器。 + +有几种格式化器可供使用: + +- `cell`:用于格式化单元格 +- `aggregatedCell`:用于格式化聚合时的单元格 +- `header`:用于格式化表头 +- `footer`:用于格式化表尾 + +## 单元格格式化 + +可以通过向 `cell` 属性传递函数并使用 `props.getValue()` 函数访问单元格值来提供自定义单元格格式化器: + +```tsx +columnHelper.accessor('firstName', { + cell: props => {props.getValue().toUpperCase()}, +}) +``` + +单元格格式化器还可以获取 `row` 和 `table` 对象,允许超越单元格值进行更灵活的格式化。以下示例虽然使用 `firstName` 作为访问器,但同时显示位于原始行对象上的带前缀用户 ID: + +```tsx +columnHelper.accessor('firstName', { + cell: props => ( + {`${props.row.original.id} - ${props.getValue()}`} + ), +}) +``` + +## 聚合单元格格式化 + +有关聚合单元格的更多信息,请参阅 [分组 (grouping)](../guide/grouping)。 + +## 表头与表尾格式化 + +表头和表尾无法访问行数据,但仍使用相同的概念来显示自定义内容。 diff --git a/docs/zh-hans/guide/column-faceting.md b/docs/zh-hans/guide/column-faceting.md new file mode 100644 index 0000000000..0604922032 --- /dev/null +++ b/docs/zh-hans/guide/column-faceting.md @@ -0,0 +1,90 @@ +--- +source-updated-at: '2025-03-20T21:15:29.000Z' +translation-updated-at: '2025-05-02T17:19:41.820Z' +title: 列分面 +--- +## 示例 + +想要直接查看实现?请参考以下示例: + +- [filters-faceted](../framework/react/examples/filters-faceted) + +## API + +[列分面 API](../api/features/column-faceting) + +## 列分面指南 + +列分面 (Column Faceting) 是一项功能,允许您从列数据中为该列生成值列表。例如,可以从列的所有行中生成唯一值列表,用作自动完成筛选组件中的搜索建议;或者从数字列中生成最小值和最大值的元组,用作范围滑块筛选组件的范围。 + +### 列分面行模型 + +要使用任何列分面功能,必须在表格选项中包含相应的行模型。 + +```ts +//仅导入需要的行模型 +import { + getCoreRowModel, + getFacetedRowModel, + getFacetedMinMaxValues, //依赖 getFacetedRowModel + getFacetedUniqueValues, //依赖 getFacetedRowModel +} +//... +const table = useReactTable({ + columns, + data, + getCoreRowModel: getCoreRowModel(), + getFacetedRowModel: getFacetedRowModel(), //如果需要为列生成值列表(其他分面行模型依赖此模型) + getFacetedMinMaxValues: getFacetedMinMaxValues(), //如果需要最小/最大值 + getFacetedUniqueValues: getFacetedUniqueValues(), //如果需要唯一值列表 + //... +}) +``` + +首先必须包含 `getFacetedRowModel` 行模型。该模型会为给定列生成值列表。如果需要唯一值列表,则包含 `getFacetedUniqueValues` 行模型;如果需要最小值和最大值的元组,则包含 `getFacetedMinMaxValues` 行模型。 + +### 使用分面行模型 + +在表格选项中包含相应的行模型后,即可使用分面列实例 API 访问由分面行模型生成的值列表。 + +```ts +// 用于自动完成筛选的唯一值列表 +const autoCompleteSuggestions = + Array.from(column.getFacetedUniqueValues().keys()) + .sort() + .slice(0, 5000); +``` + +```ts +// 用于范围筛选的最小最大值元组 +const [min, max] = column.getFacetedMinMaxValues() ?? [0, 1]; +``` + +### 自定义(服务端)分面 + +如果不使用内置的客户端分面功能,可以在服务端实现自己的分面逻辑,并将分面值传递到客户端。可以使用 `getFacetedUniqueValues` 和 `getFacetedMinMaxValues` 表格选项从服务端解析分面值。 + +```ts +const facetingQuery = useQuery( + //... +) + +const table = useReactTable({ + columns, + data, + getCoreRowModel: getCoreRowModel(), + getFacetedRowModel: getFacetedRowModel(), + getFacetedUniqueValues: (table, columnId) => { + const uniqueValueMap = new Map(); + //... + return uniqueValueMap; + }, + getFacetedMinMaxValues: (table, columnId) => { + //... + return [min, max]; + }, + //... +}) +``` + +或者,您也可以完全不通过 TanStack Table API 实现任何分面逻辑,只需直接获取列表并传递给筛选组件即可。 diff --git a/docs/zh-hans/guide/column-filtering.md b/docs/zh-hans/guide/column-filtering.md new file mode 100644 index 0000000000..b9194ba74c --- /dev/null +++ b/docs/zh-hans/guide/column-filtering.md @@ -0,0 +1,338 @@ +--- +source-updated-at: '2025-03-20T21:15:29.000Z' +translation-updated-at: '2025-05-02T17:17:31.983Z' +title: 列过滤 +--- +## 示例 + +想要直接查看实现方式?请参考以下示例: + +- [列过滤](../framework/react/examples/filters) +- [多面过滤](../framework/react/examples/filters-faceted)(自动补全和范围过滤) +- [模糊搜索](../framework/react/examples/filters-fuzzy)(匹配排序器) +- [可编辑数据](../framework/react/examples/editable-data) +- [展开](../framework/react/examples/expanding)(从子行过滤) +- [分组](../framework/react/examples/grouping) +- [分页](../framework/react/examples/pagination) +- [行选择](../framework/react/examples/row-selection) + +## API + +[列过滤 API](../api/features/column-filtering) + +## 列过滤指南 + +过滤功能分为两种:列过滤和全局过滤。 + +本指南将重点介绍列过滤,即应用于单列访问器值的过滤。 + +TanStack Table 支持客户端过滤和手动服务端过滤。本指南将介绍如何实现和自定义这两种方式,并帮助您决定哪种方式最适合您的使用场景。 + +### 客户端过滤 vs 服务端过滤 + +如果您有一个大型数据集,可能不希望将所有数据加载到客户端浏览器中进行过滤。在这种情况下,您很可能需要实现服务端过滤、排序、分页等功能。 + +然而,正如[分页指南](../guide/pagination#should-you-use-client-side-pagination)中所讨论的,许多开发者低估了可以在客户端加载的行数而不会影响性能。TanStack Table 的示例通常测试可以处理多达 100,000 行或更多数据,并在客户端过滤、排序、分页和分组方面表现良好。这并不一定意味着您的应用程序能够处理这么多行,但如果您的表格最多只有几千行,您或许可以利用 TanStack Table 提供的客户端过滤、排序、分页和分组功能。 + +> TanStack Table 可以以良好的性能处理数千行的客户端数据。在未经思考前,不要排除客户端过滤、分页、排序等功能。 + +每个使用场景都不同,取决于表格的复杂性、列的数量、每条数据的大小等。需要注意的主要瓶颈是: + +1. 您的服务器能否在合理的时间(和成本)内查询所有数据? +2. 获取的总大小是多少?(如果列不多,可能不会像您想象的那么糟糕。) +3. 如果一次性加载所有数据,客户端的浏览器是否会占用过多内存? + +如果不确定,可以先从客户端过滤和分页开始,随着数据增长再切换到服务端策略。 + +### 手动服务端过滤 + +如果您决定需要实现服务端过滤而不是使用内置的客户端过滤,以下是操作方法。 + +手动服务端过滤不需要 `getFilteredRowModel` 表格选项。相反,传递给表格的 `data` 应该已经过滤好了。但是,如果您已经传递了 `getFilteredRowModel` 表格选项,可以通过将 `manualFiltering` 选项设置为 `true` 来告诉表格跳过它。 + +```jsx +const table = useReactTable({ + data, + columns, + getCoreRowModel: getCoreRowModel(), + // getFilteredRowModel: getFilteredRowModel(), // 手动服务端过滤不需要 + manualFiltering: true, +}) +``` + +> **注意:** 使用手动过滤时,本指南中讨论的许多选项将无效。当 `manualFiltering` 设置为 `true` 时,表格实例不会对传递给它的行应用任何过滤逻辑。相反,它会假设行已经过滤,并按原样使用您传递的 `data`。 + +### 客户端过滤 + +如果您使用内置的客户端过滤功能,首先需要将 `getFilteredRowModel` 函数传递给表格选项。每当表格需要过滤数据时,都会调用此函数。您可以从 TanStack Table 导入默认的 `getFilteredRowModel` 函数,或创建自己的函数。 + +```jsx +import { useReactTable, getFilteredRowModel } from '@tanstack/react-table' +//... +const table = useReactTable({ + data, + columns, + getCoreRowModel: getCoreRowModel(), + getFilteredRowModel: getFilteredRowModel(), // 客户端过滤需要 +}) +``` + +### 列过滤状态 + +无论您使用客户端还是服务端过滤,都可以利用 TanStack Table 提供的内置列过滤状态管理。有许多表格和列 API 可以用于修改和交互过滤状态以及检索列过滤状态。 + +列过滤状态定义为以下形状的对象数组: + +```ts +interface ColumnFilter { + id: string + value: unknown +} +type ColumnFiltersState = ColumnFilter[] +``` + +由于列过滤状态是一个对象数组,您可以同时应用多个列过滤。 + +#### 访问列过滤状态 + +您可以使用 `table.getState()` API 从表格实例中访问列过滤状态,就像访问其他表格状态一样。 + +```jsx +const table = useReactTable({ + columns, + data, + //... +}) + +console.log(table.getState().columnFilters) // 从表格实例访问列过滤状态 +``` + +但是,如果需要在表格初始化之前访问列过滤状态,可以像下面这样“控制”列过滤状态。 + +### 受控列过滤状态 + +如果需要轻松访问列过滤状态,可以使用 `state.columnFilters` 和 `onColumnFiltersChange` 表格选项在自己的状态管理中控制/管理列过滤状态。 + +```tsx +const [columnFilters, setColumnFilters] = useState([]) // 可以在此设置初始列过滤状态 +//... +const table = useReactTable({ + columns, + data, + //... + state: { + columnFilters, + }, + onColumnFiltersChange: setColumnFilters, +}) +``` + +#### 初始列过滤状态 + +如果不需要在自己的状态管理或作用域中控制列过滤状态,但仍希望设置初始列过滤状态,可以使用 `initialState` 表格选项而不是 `state`。 + +```jsx +const table = useReactTable({ + columns, + data, + //... + initialState: { + columnFilters: [ + { + id: 'name', + value: 'John', // 默认按 'John' 过滤名称列 + }, + ], + }, +}) +``` + +> **注意**:不要同时使用 `initialState.columnFilters` 和 `state.columnFilters`,因为 `state.columnFilters` 中的初始化状态会覆盖 `initialState.columnFilters`。 + +### 过滤函数 (FilterFns) + +每列可以有自己的独特过滤逻辑。您可以选择 TanStack Table 提供的任何过滤函数,或创建自己的函数。 + +默认情况下,有 10 种内置过滤函数可供选择: + +- `includesString` - 不区分大小写的字符串包含 +- `includesStringSensitive` - 区分大小写的字符串包含 +- `equalsString` - 不区分大小写的字符串相等 +- `equalsStringSensitive` - 区分大小写的字符串相等 +- `arrIncludes` - 数组中包含项 +- `arrIncludesAll` - 数组中包含所有项 +- `arrIncludesSome` - 数组中包含某些项 +- `equals` - 对象/引用相等 `Object.is`/`===` +- `weakEquals` - 弱对象/引用相等 `==` +- `inNumberRange` - 数字范围包含 + +您还可以通过 `filterFn` 列选项或 `filterFns` 表格选项定义自己的自定义过滤函数。 + +#### 自定义过滤函数 + +> **注意**:这些过滤函数仅在客户端过滤期间运行。 + +在 `filterFn` 列选项或 `filterFns` 表格选项中定义自定义过滤函数时,应具有以下签名: + +```ts +const myCustomFilterFn: FilterFn = (row: Row, columnId: string, filterValue: any, addMeta: (meta: any) => void) => boolean +``` + +每个过滤函数接收: + +- 要过滤的行 +- 用于检索行值的列 ID +- 过滤值 + +并应返回 `true` 如果行应包含在过滤后的行中,返回 `false` 如果应移除。 + +```jsx +const columns = [ + { + header: () => 'Name', + accessorKey: 'name', + filterFn: 'includesString', // 使用内置过滤函数 + }, + { + header: () => 'Age', + accessorKey: 'age', + filterFn: 'inNumberRange', + }, + { + header: () => 'Birthday', + accessorKey: 'birthday', + filterFn: 'myCustomFilterFn', // 使用自定义全局过滤函数 + }, + { + header: () => 'Profile', + accessorKey: 'profile', + // 直接使用自定义过滤函数 + filterFn: (row, columnId, filterValue) => { + return // 根据自定义逻辑返回 true 或 false + }, + } +] +//... +const table = useReactTable({ + columns, + data, + getCoreRowModel: getCoreRowModel(), + getFilteredRowModel: getFilteredRowModel(), + filterFns: { // 添加自定义全局过滤函数 + myCustomFilterFn: (row, columnId, filterValue) => { // 在此内联定义 + return // 根据自定义逻辑返回 true 或 false + }, + startsWith: startsWithFilterFn, // 在其他地方定义 + }, +}) +``` + +##### 自定义过滤函数行为 + +您可以为过滤函数附加一些其他属性以自定义其行为: + +- `filterFn.resolveFilterValue` - 此可选“挂载”方法允许过滤函数在传递过滤值之前对其进行转换/清理/格式化。 + +- `filterFn.autoRemove` - 此可选“挂载”方法传递一个过滤值,并期望返回 `true` 如果应从过滤状态中移除该过滤值。例如,某些布尔风格的过滤可能希望在过滤值设置为 `false` 时将其从表格状态中移除。 + +```tsx +const startsWithFilterFn = ( + row: Row, + columnId: string, + filterValue: number | string, //resolveFilterValue 会将其转换为字符串 +) => + row + .getValue(columnId) + .toString() + .toLowerCase() + .trim() + .startsWith(filterValue); // 在 `resolveFilterValue` 中对过滤值进行 toString、toLowerCase 和 trim 操作 + +// 如果过滤值为假值(在此例中为空字符串),则从过滤状态中移除 +startsWithFilterFn.autoRemove = (val: any) => !val; + +// 在传递过滤值之前对其进行转换/清理/格式化 +startsWithFilterFn.resolveFilterValue = (val: any) => val.toString().toLowerCase().trim(); +``` + +### 自定义列过滤 + +有许多表格和列选项可用于进一步自定义列过滤行为。 + +#### 禁用列过滤 + +默认情况下,所有列都启用了列过滤。您可以使用 `enableColumnFilters` 表格选项或 `enableColumnFilter` 列选项禁用所有列或特定列的列过滤。您还可以通过将 `enableFilters` 表格选项设置为 `false` 来关闭列过滤和全局过滤。 + +禁用列的列过滤将导致 `column.getCanFilter` API 对该列返回 `false`。 + +```jsx +const columns = [ + { + header: () => 'Id', + accessorKey: 'id', + enableColumnFilter: false, // 禁用此列的列过滤 + }, + //... +] +//... +const table = useReactTable({ + columns, + data, + enableColumnFilters: false, // 禁用所有列的列过滤 +}) +``` + +#### 过滤子行(展开) + +在使用展开、分组和聚合等功能时,还有一些额外的表格选项可以自定义列过滤行为。 + +##### 从叶子行过滤 + +默认情况下,过滤是从父行向下进行的,因此如果父行被过滤掉,其所有子行也会被过滤掉。根据您的使用场景,如果您只希望用户搜索顶级行而不搜索子行,这可能是期望的行为。这也是性能最高的选项。 + +但是,如果您希望允许子行被过滤和搜索,无论父行是否被过滤掉,可以将 `filterFromLeafRows` 表格选项设置为 `true`。将此选项设置为 `true` 将导致过滤从叶子行向上进行,这意味着只要子行或孙行中的一个被包含,父行也会被包含。 + +```jsx +const table = useReactTable({ + columns, + data, + getCoreRowModel: getCoreRowModel(), + getFilteredRowModel: getFilteredRowModel(), + getExpandedRowModel: getExpandedRowModel(), + filterFromLeafRows: true, // 过滤和搜索子行 +}) +``` + +##### 最大叶子行过滤深度 + +默认情况下,过滤应用于树中的所有行,无论它们是根级父行还是父行的子叶子行。将 `maxLeafRowFilterDepth` 表格选项设置为 `0` 将导致过滤仅应用于根级父行,所有子行保持未过滤状态。类似地,将此选项设置为 `1` 将导致过滤仅应用于深度为 1 的子叶子行,依此类推。 + +如果希望在父行通过过滤时保留父行的子行不被过滤掉,请使用 `maxLeafRowFilterDepth: 0`。 + +```jsx +const table = useReactTable({ + columns, + data, + getCoreRowModel: getCoreRowModel(), + getFilteredRowModel: getFilteredRowModel(), + getExpandedRowModel: getExpandedRowModel(), + maxLeafRowFilterDepth: 0, // 仅过滤根级父行 +}) +``` + +### 列过滤 API + +有许多列和表格 API 可用于与列过滤状态交互并连接到您的 UI 组件。以下是可用 API 及其最常见用例的列表: + +- `table.setColumnFilters` - 用新状态覆盖整个列过滤状态。 +- `table.resetColumnFilters` - 用于“清除/重置所有过滤”按钮。 + +- **`column.getFilterValue`** - 用于获取输入的默认初始过滤值,甚至直接为过滤输入提供过滤值。 +- **`column.setFilterValue`** - 用于将过滤输入连接到其 `onChange` 或 `onBlur` 处理程序。 + +- `column.getCanFilter` - 用于禁用/启用过滤输入。 +- `column.getIsFiltered` - 用于显示当前正在过滤的列的视觉指示器。 +- `column.getFilterIndex` - 用于显示当前过滤应用的顺序。 + +- `column.getAutoFilterFn` - 内部用于查找列的默认过滤函数(如果未指定)。 +- `column.getFilterFn` - 用于显示当前使用的过滤模式或函数。 diff --git a/docs/zh-hans/guide/column-ordering.md b/docs/zh-hans/guide/column-ordering.md new file mode 100644 index 0000000000..989bc403f0 --- /dev/null +++ b/docs/zh-hans/guide/column-ordering.md @@ -0,0 +1,112 @@ +--- +source-updated-at: '2025-03-20T21:15:29.000Z' +translation-updated-at: '2025-05-02T17:13:21.812Z' +title: 列排序 +--- +## 示例 + +想直接查看实现方式?请参考以下示例: + +- [列排序](../framework/react/examples/column-ordering) +- [列拖拽排序](../framework/react/examples/column-dnd) + +## API + +[列排序 API](../api/features/column-ordering) + +## 列排序指南 + +默认情况下,列的顺序与它们在 `columns` 数组中定义的顺序一致。但你可以通过 `columnOrder` 状态手动指定列顺序。其他功能如列固定 (column pinning) 和分组 (grouping) 也会影响列顺序。 + +### 影响列顺序的因素 + +有 3 种表格功能会改变列顺序,优先级如下: + +1. [列固定 (Column Pinning)](../guide/column-pinning) - 如果启用了固定功能,列会被分为左侧固定、中间非固定和右侧固定三部分。 +2. **手动列排序 (Column Ordering)** - 应用手动指定的列顺序。 +3. [分组 (Grouping)](../guide/grouping) - 如果启用了分组功能且存在分组状态,且 `tableOptions.groupedColumnMode` 设置为 `'reorder' | 'remove'`,则分组列会被重新排序到列流的最前面。 + +> **注意:** 当与列固定功能同时使用时,`columnOrder` 状态只会影响未固定的列。 + +### 列排序状态 + +如果不提供 `columnOrder` 状态,TanStack Table 会直接使用 `columns` 数组中的列顺序。但你可以通过向 `columnOrder` 状态提供一个列 ID 字符串数组来指定列顺序。 + +#### 默认列顺序 + +如果只需要指定初始列顺序,可以在 `initialState` 表格选项中设置 `columnOrder` 状态。 + +```jsx +const table = useReactTable({ + //... + initialState: { + columnOrder: ['columnId1', 'columnId2', 'columnId3'], + } + //... +}); +``` + +> **注意:** 如果同时使用 `state` 表格选项来指定 `columnOrder` 状态,则 `initialState` 不会生效。请仅在 `initialState` 或 `state` 中指定特定状态,不要同时使用两者。 + +#### 管理列排序状态 + +如果需要动态更改列顺序,或在表格初始化后设置列顺序,可以像管理其他表格状态一样管理 `columnOrder` 状态。 + +```jsx +const [columnOrder, setColumnOrder] = useState(['columnId1', 'columnId2', 'columnId3']); //可选地初始化列顺序 +//... +const table = useReactTable({ + //... + state: { + columnOrder, + //... + } + onColumnOrderChange: setColumnOrder, + //... +}); +``` + +### 重新排序列 + +如果表格提供了允许用户重新排列表列的 UI,可以按如下方式设置逻辑: + +```tsx +const [columnOrder, setColumnOrder] = useState(columns.map(c => c.id)); + +//根据所选拖拽方案,可能需要或不需此类状态 +const [movingColumnId, setMovingColumnId] = useState(null); +const [targetColumnId, setTargetColumnId] = useState(null); + +//用于拼接和重新排列 columnOrder 数组的工具函数 +const reorderColumn = ( + movingColumnId: Column, + targetColumnId: Column, +): string[] => { + const newColumnOrder = [...columnOrder]; + newColumnOrder.splice( + newColumnOrder.indexOf(targetColumnId), + 0, + newColumnOrder.splice(newColumnOrder.indexOf(movingColumnId), 1)[0], + ); + setColumnOrder(newColumnOrder); +}; + +const handleDragEnd = (e: DragEvent) => { + if(!movingColumnId || !targetColumnId) return; + setColumnOrder(reorderColumn(movingColumnId, targetColumnId)); +}; + +//使用你选择的拖拽方案 +``` + +#### 拖拽排列表列建议 (React) + +实现 TanStack Table 的拖拽功能有多种方式。以下建议可帮助你避免踩坑: + +1. **不要** 在 React 18 或更新版本中使用 [`"react-dnd"`](https://react-dnd.github.io/react-dnd/docs/overview)。React DnD 在其时代是重要的库,但现在更新频率低,且与 React 18(尤其是严格模式)存在兼容性问题。虽然仍可使其工作,但有更现代、兼容性更好且维护更积极的替代方案。React DnD 的 Provider 也可能与你应用中其他 DnD 方案冲突。 + +2. 使用 [`"@dnd-kit/core"`](https://dndkit.com/)。DnD Kit 是一个现代化、模块化且轻量级的拖拽库,与现代 React 生态高度兼容,并能良好支持语义化的 `` 标记。TanStack 官方提供的两个拖拽示例 [列拖拽](../framework/react/examples/column-dnd) 和 [行拖拽](../framework/react/examples/row-dnd) 现在均使用 DnD Kit。 + +3. 也可考虑其他 DnD 库如 [`"react-beautiful-dnd"`](https://github.com/atlassian/react-beautiful-dnd),但需注意其可能较大的包体积、维护状态及对 `
` 标记的兼容性。 + +4. 考虑使用原生浏览器事件和状态管理实现轻量级拖拽功能。但需注意,如果不额外实现触摸事件支持,此方案可能对移动端用户不友好。[Material React Table V2](https://www.material-react-table.com/docs/examples/column-ordering) 是一个仅使用浏览器拖拽事件(如 `onDragStart`、`onDragEnd`、`onDragEnter`)且无其他依赖的实现示例,可参考其源码。 diff --git a/docs/zh-hans/guide/column-pinning.md b/docs/zh-hans/guide/column-pinning.md new file mode 100644 index 0000000000..c82b0d3a7e --- /dev/null +++ b/docs/zh-hans/guide/column-pinning.md @@ -0,0 +1,93 @@ +--- +source-updated-at: '2025-03-20T21:15:29.000Z' +translation-updated-at: '2025-05-02T17:13:59.207Z' +title: 列固定 +--- +## 示例 + +想要直接查看实现方式?请参考以下示例: + +- [列固定](../framework/react/examples/column-pinning) +- [粘性列固定](../framework/react/examples/column-pinning-sticky) + +### 其他示例 + +- [Svelte 列固定](../framework/svelte/examples/column-pinning) +- [Vue 列固定](../framework/vue/examples/column-pinning) + +## API + +[列固定 API](../api/features/column-pinning) + +## 列固定指南 + +TanStack Table 提供了有助于在表格 UI 中实现列固定功能的状态和 API。您可以通过多种方式实现列固定:既可以将固定列拆分为独立的表格,也可以将所有列保留在同一表格中,但通过固定状态正确排序列,并使用粘性 CSS 将列固定在左侧或右侧。 + +### 列固定如何影响列顺序 + +有 3 种表格功能会重新排序列,其执行顺序如下: + +1. **列固定** - 如果启用固定,列会被拆分为左侧、中间(未固定)和右侧固定列。 +2. 手动[列排序](../guide/column-ordering) - 应用手动指定的列顺序。 +3. [分组](../guide/grouping) - 如果启用了分组、存在分组状态且 `tableOptions.groupedColumnMode` 设置为 `'reorder' | 'remove'`,则分组列会被重新排序到列流的最前面。 + +改变固定列顺序的唯一方式是直接修改 `columnPinning.left` 和 `columnPinning.right` 状态本身。`columnOrder` 状态仅影响未固定("中间")列的排序。 + +### 列固定状态 + +管理 `columnPinning` 状态是可选的,通常在添加持久状态功能时才需要。TanStack Table 会为您自动跟踪列固定状态。如需管理,可像处理其他表格状态一样操作: + +```jsx +const [columnPinning, setColumnPinning] = useState({ + left: [], + right: [], +}); +//... +const table = useReactTable({ + //... + state: { + columnPinning, + //... + } + onColumnPinningChange: setColumnPinning, + //... +}); +``` + +### 默认固定列 + +一个常见需求是默认固定某些列。可以通过初始化 `columnPinning` 状态或使用 `initialState` 表格选项实现: + +```jsx +const table = useReactTable({ + //... + initialState: { + columnPinning: { + left: ['expand-column'], + right: ['actions-column'], + }, + //... + } + //... +}); +``` + +### 实用列固定 API + +> 注意:部分 API 在 v8.12.0 版本新增 + +以下列 API 方法可帮助实现列固定功能: + +- [`column.getCanPin`](../api/features/column-pinning#getcanpin):判断列是否可固定 +- [`column.pin`](../api/features/column-pinning#pin):将列固定到左侧/右侧,或取消固定 +- [`column.getIsPinned`](../api/features/column-pinning#getispinned):获取列的固定位置 +- [`column.getStart`](../api/features/column-pinning#getstart):获取固定列的正确 `left` CSS 值 +- [`column.getAfter`](../api/features/column-pinning#getafter):获取固定列的正确 `right` CSS 值 +- [`column.getIsLastColumn`](../api/features/column-pinning#getislastcolumn):判断列是否是其固定组中的最后一列(适用于添加盒阴影) +- [`column.getIsFirstColumn`](../api/features/column-pinning#getisfirstcolumn):判断列是否是其固定组中的第一列(适用于添加盒阴影) + +### 拆分表格列固定 + +如果仅使用粘性 CSS 固定列,通常只需正常渲染表格,使用 `table.getHeaderGroups` 和 `row.getVisibleCells` 方法即可。 + +但若要将固定列拆分为独立表格,可以使用 `table.getLeftHeaderGroups`、`table.getCenterHeaderGroups`、`table.getRightHeaderGroups`、`row.getLeftVisibleCells`、`row.getCenterVisibleCells` 和 `row.getRightVisibleCells` 方法,仅渲染当前表格相关的列。 diff --git a/docs/zh-hans/guide/column-sizing.md b/docs/zh-hans/guide/column-sizing.md new file mode 100644 index 0000000000..b4c431e021 --- /dev/null +++ b/docs/zh-hans/guide/column-sizing.md @@ -0,0 +1,178 @@ +--- +source-updated-at: '2025-03-20T21:15:29.000Z' +translation-updated-at: '2025-05-02T17:14:58.706Z' +title: 列尺寸调整 +--- +## 示例 + +想直接查看实现方式?请参考以下示例: + +- [列宽调整](../framework/react/examples/column-sizing) +- [高性能列宽调整](../framework/react/examples/column-resizing-performant) + +## API + +[列宽调整 API](../api/features/column-sizing) + +## 列宽调整指南 + +列宽调整功能允许你为每列指定宽度(包括最小和最大宽度),同时也支持用户动态调整所有列的宽度,例如通过拖拽列标题实现。 + +### 列宽设置 + +默认情况下,列具有以下尺寸参数: + +```tsx +export const defaultColumnSizing = { + size: 150, + minSize: 20, + maxSize: Number.MAX_SAFE_INTEGER, +} +``` + +这些默认值可以通过 `tableOptions.defaultColumn` 和单独的列定义按顺序覆盖。 + +```tsx +const columns = [ + { + accessorKey: 'col1', + size: 270, //为本列设置宽度 + }, + //... +] + +const table = useReactTable({ + //覆盖默认列尺寸 + defaultColumn: { + size: 200, //初始列宽 + minSize: 50, //调整列宽时的最小值 + maxSize: 500, //调整列宽时的最大值 + }, +}) +``` + +列的 "尺寸" 以数字形式存储在表格状态中,通常被解释为像素单位值,但你可以根据需要将这些列宽值关联到 CSS 样式中。 + +作为一个无头工具 (headless utility),表格的列宽逻辑实际上只是一组状态集合,你可以按需应用到自己的布局中(我们的示例实现了两种样式逻辑)。这些宽度测量可以通过多种方式应用: + +- 语义化的 `table` 元素或任何以表格 CSS 模式显示的元素 +- `div/span` 元素或任何以非表格 CSS 模式显示的元素 + - 具有固定宽度的块级元素 + - 具有固定宽度的绝对定位元素 + - 具有弹性宽度的 Flexbox 布局元素 + - 具有弹性宽度的 Grid 布局元素 +- 实际上任何能将单元格宽度插入表格结构的布局机制 + +每种方法都有其权衡和限制,这些通常是 UI/组件库或设计系统的设计考量,幸运的是这不关你的事 😉。 + +### 列宽调整功能 + +TanStack Table 提供内置的列宽调整状态和 API,让你能够轻松在表格 UI 中实现列宽调整,并提供多种用户体验和性能选项。 + +#### 启用列宽调整 + +默认情况下,`column.getCanResize()` API 对所有列返回 `true`,但你可以通过 `enableColumnResizing` 表格选项全局禁用列宽调整,或通过 `enableResizing` 列选项单独禁用。 + +```tsx +const columns = [ + { + accessorKey: 'id', + enableResizing: false, //仅禁用本列调整 + size: 200, //初始列宽 + }, + //... +] +``` + +#### 列宽调整模式 + +默认列宽调整模式为 `"onEnd"`。这意味着 `column.getSize()` API 只在用户完成调整(拖拽)列宽后返回新尺寸。通常在调整过程中会显示一个小型 UI 指示器。 + +在 React TanStack Table 适配器中,根据表格或网页的复杂程度,实现 60 fps 的列宽调整渲染可能较为困难。`"onEnd"` 列宽调整模式可以作为一个良好的默认选项,避免用户在调整列宽时出现卡顿或延迟。这并不是说使用 TanStack React Table 无法实现 60 fps 的列宽调整渲染,但你可能需要进行额外的记忆化 (memoization) 或其他性能优化才能实现。 + +> 高级列宽调整性能技巧将在[下方讨论](#高级列宽调整性能优化)。 + +如需将列宽调整模式改为 `"onChange"` 以实现即时渲染,可通过 `columnResizeMode` 表格选项设置。 + +```tsx +const table = useReactTable({ + //... + columnResizeMode: 'onChange', //将列宽调整模式改为 "onChange" +}) +``` + +#### 列宽调整方向 + +默认情况下,TanStack Table 假设表格标记是按从左到右方向布局的。对于从右到左的布局,可能需要将列宽调整方向改为 `"rtl"`。 + +```tsx +const table = useReactTable({ + //... + columnResizeDirection: 'rtl', //为特定语言环境改为从右到左调整 +}) +``` + +#### 将列宽调整 API 连接到 UI + +有几个非常方便的 API 可用于将列宽调整的拖拽交互连接到你的 UI。 + +##### 列尺寸 API + +要将列尺寸应用到列标题单元格、数据单元格或页脚单元格,可以使用以下 API: + +```ts +header.getSize() +column.getSize() +cell.column.getSize() +``` + +如何将这些尺寸样式应用到标记由你决定,但通常使用 CSS 变量或内联样式来设置列宽。 + +```tsx + +) +``` + +#### 必须这样做吗? + +这只是将自定义代码与 TanStack Table 内置功能集成的新方法。在上面的示例中,我们也可以将 `density` 状态存储在 `React.useState` 中,在任何地方定义自己的 `toggleDensity` 处理程序,并在代码中独立于表实例使用它。在 TanStack Table 旁边构建表格功能,而不是深度集成到表实例中,仍然是构建自定义功能的完全有效方式。根据你的用例,这可能不是扩展 TanStack Table 自定义功能的最简洁方式。 diff --git a/docs/zh-hans/guide/data.md b/docs/zh-hans/guide/data.md new file mode 100644 index 0000000000..d40ce32da3 --- /dev/null +++ b/docs/zh-hans/guide/data.md @@ -0,0 +1,251 @@ +--- +source-updated-at: '2025-03-20T21:15:29.000Z' +translation-updated-at: '2025-05-02T16:59:13.372Z' +title: 数据 +--- +## 数据指南 + +表格始于您的数据。列定义和行数据将取决于数据的结构。TanStack Table 提供了一些 TypeScript 功能,可帮助您以类型安全的方式构建表格代码。如果正确设置数据和类型,TanStack Table 将能够推断数据的结构,并确保列定义的正确性。 + +### TypeScript + +使用 TanStack Table 并不强制要求 TypeScript... ***但*** TanStack Table 的编写和组织方式使其出色的 TypeScript 体验成为该库的主要卖点之一。如果不使用 TypeScript,您将错过许多优秀的自动补全和类型检查功能,这些功能既能加快开发速度,又能减少代码中的错误。 + +#### TypeScript 泛型 + +对 TypeScript 泛型及其工作原理有基本了解将有助于更好地理解本指南,但即使不熟悉也能轻松上手。官方 [TypeScript 泛型文档](https://www.typescriptlang.org/docs/handbook/2/generics.html) 可能对尚未熟悉 TypeScript 的开发者有所帮助。 + +### 定义数据类型 + +`data` 是一个对象数组,将被转换为表格的行。数组中的每个对象通常代表一行数据。如果使用 TypeScript,我们通常会为数据的结构定义一个类型。此类型用作表格、列、行和单元格实例的泛型类型。在 TanStack Table 的类型和 API 中,此泛型通常称为 `TData`。 + +例如,如果有一个显示用户列表的表格,数据如下: + +```json +[ + { + "firstName": "Tanner", + "lastName": "Linsley", + "age": 33, + "visits": 100, + "progress": 50, + "status": "Married" + }, + { + "firstName": "Kevin", + "lastName": "Vandy", + "age": 27, + "visits": 200, + "progress": 100, + "status": "Single" + } +] +``` + +我们可以定义一个 `User` (`TData`) 类型: + +```ts +//TData +type User = { + firstName: string + lastName: string + age: number + visits: number + progress: number + status: string +} +``` + +然后可以用此类型定义 `data` 数组,TanStack Table 将能够智能推断后续列、行、单元格等的类型。这是因为 `data` 类型实际上是 `TData` 泛型类型。传递给 `data` 表格选项的内容将成为表格实例其余部分的 `TData` 类型。只需确保后续定义列时使用与 `data` 相同的 `TData` 类型。 + +```ts +//注意:data 需要一个“稳定”的引用以防止无限重新渲染 +const data: User[] = [] +//或 +const [data, setData] = React.useState([]) +//或 +const data = ref([]) //vue +//等等... +``` + +#### 深层键控数据 + +如果数据不是简单的扁平对象数组,也没关系!定义列时,可以通过访问器策略访问深层嵌套数据。 + +如果 `data` 如下所示: + +```json +[ + { + "name": { + "first": "Tanner", + "last": "Linsley" + }, + "info": { + "age": 33, + "visits": 100, + } + }, + { + "name": { + "first": "Kevin", + "last": "Vandy" + }, + "info": { + "age": 27, + "visits": 200, + } + } +] +``` + +可以定义如下类型: + +```ts +type User = { + name: { + first: string + last: string + } + info: { + age: number + visits: number + } +} +``` + +然后可以在列定义中通过 `accessorKey` 的点符号或 `accessorFn` 访问数据。 + +```ts +const columns = [ + { + header: 'First Name', + accessorKey: 'name.first', + }, + { + header: 'Last Name', + accessorKey: 'name.last', + }, + { + header: 'Age', + accessorFn: row => row.info.age, + }, + //... +] +``` + +更多细节请参阅 [列定义指南](../guide/column-defs)。 + +> 注意:JSON 数据中的“键”通常可以是任何内容,但键中的句点将被解释为深层键并可能导致错误。 + +#### 嵌套子行数据 + +如果使用展开功能,数据中可能会有嵌套的子行。这会形成一个略有不同的递归类型。 + +如果数据如下: + +```json +[ + { + "firstName": "Tanner", + "lastName": "Linsley", + "subRows": [ + { + "firstName": "Kevin", + "lastName": "Vandy", + }, + { + "firstName": "John", + "lastName": "Doe", + "subRows": [ + //... + ] + } + ] + }, + { + "firstName": "Jane", + "lastName": "Doe", + } +] +``` + +可以定义如下类型: + +```ts +type User = { + firstName: string + lastName: string + subRows?: User[] //不必命名为 "subRows",可以是任意名称 +} +``` + +其中 `subRows` 是 `User` 对象的可选数组。更多细节请参阅 [展开指南](../guide/expanding)。 + +### 为数据提供“稳定”引用 + +传递给表格实例的 `data` 数组 ***必须*** 具有“稳定”的引用,以防止导致无限重新渲染的 bug(尤其是在 React 中)。 + +这取决于您使用的框架适配器,但在 React 中,通常应使用 `React.useState`、`React.useMemo` 或类似方法确保 `data` 和 `columns` 表格选项具有稳定的引用。 + +```tsx +const fallbackData = [] + +export default function MyComponent() { + //✅ 良好:`columns` 是稳定引用,不会导致无限重新渲染 + const columns = useMemo(() => [ + // ... + ], []); + + //✅ 良好:`data` 是稳定引用,不会导致无限重新渲染 + const [data, setData] = useState(() => [ + // ... + ]); + + // 列和数据定义在稳定引用中,不会导致无限循环! + const table = useReactTable({ + columns, + data ?? fallbackData, //也可以使用组件外部定义的备用数组(稳定引用) + }); + + return
+``` + +不过,如[高级列宽调整性能章节](#高级列宽调整性能优化)所述,建议考虑使用 CSS 变量来设置列宽。 + +##### 列宽调整 API + +TanStack Table 提供预构建的事件处理器来简化拖拽交互的实现。这些事件处理器是调用其他内部 API 来更新列宽状态并重新渲染表格的便捷函数。使用 `header.getResizeHandler()` 来连接列宽调整的拖拽交互,同时支持鼠标和触摸事件。 + +```tsx + +``` + +##### 使用 ColumnSizingInfoState 显示调整指示器 + +TanStack Table 会跟踪一个名为 `columnSizingInfo` 的状态对象,可用于渲染列宽调整指示器 UI。 + +```jsx + +``` + +#### 高级列宽调整性能优化 + +如果你正在创建大型或复杂的表格(并且使用 React 😉),可能会发现如果没有为渲染逻辑添加适当的记忆化,用户在调整列宽时可能会遇到性能下降的问题。 + +我们创建了一个[高性能列宽调整示例](../framework/react/examples/column-resizing-performant),展示了如何通过复杂表格实现 60 fps 的列宽调整渲染(否则可能会出现渲染缓慢的情况)。建议直接查看该示例了解实现方式,但以下是需要记住的基本要点: + +1. 不要在每个表头和每个数据单元格上使用 `column.getSize()`。相反,**预先计算并记忆化**所有列宽! +2. 在调整过程中记忆化表格主体 (Table Body)。 +3. 使用 CSS 变量将列宽传递给表格单元格。 + +如果遵循这些步骤,应该能在列宽调整时看到显著的性能提升。 + +如果你不使用 React,而是使用 Svelte、Vue 或 Solid 适配器,可能不需要太担心这个问题,但类似的原则同样适用。 diff --git a/docs/zh-hans/guide/column-visibility.md b/docs/zh-hans/guide/column-visibility.md new file mode 100644 index 0000000000..2cffbb04b7 --- /dev/null +++ b/docs/zh-hans/guide/column-visibility.md @@ -0,0 +1,132 @@ +--- +source-updated-at: '2025-03-20T21:15:29.000Z' +translation-updated-at: '2025-05-02T17:15:38.808Z' +title: 列可见性 +--- +## 示例 + +想直接查看实现代码?请参考以下示例: + +- [column-visibility](../framework/react/examples/column-visibility) +- [column-ordering](../framework/react/examples/column-ordering) +- [sticky-column-pinning](../framework/react/examples/column-pinning-sticky) + +### 其他示例 + +- [SolidJS column-visibility](../framework/solid/examples/column-visibility) +- [Svelte column-visibility](../framework/svelte/examples/column-visibility) + +## API + +[列可见性 API](../api/features/column-visibility) + +## 列可见性指南 + +列可见性功能允许动态隐藏或显示表格列。在 react-table 的早期版本中,此功能是列的静态属性,但在 v8 版本中,提供了专门的 `columnVisibility` 状态和 API 来动态管理列可见性。 + +### 列可见性状态 + +`columnVisibility` 状态是一个列 ID 到布尔值的映射。如果列 ID 存在于映射中且值为 `false`,则该列将被隐藏。如果列 ID 不存在于映射中,或值为 `true`,则该列将显示。 + +```jsx +const [columnVisibility, setColumnVisibility] = useState({ + columnId1: true, + columnId2: false, //默认隐藏此列 + columnId3: true, +}); + +const table = useReactTable({ + //... + state: { + columnVisibility, + //... + }, + onColumnVisibilityChange: setColumnVisibility, +}); +``` + +或者,如果不需要在表格外部管理列可见性状态,仍可以使用 `initialState` 选项设置初始默认列可见性状态。 + +> **注意**:如果 `columnVisibility` 同时提供给 `initialState` 和 `state`,则 `state` 的初始化将优先,`initialState` 将被忽略。不要同时向 `initialState` 和 `state` 提供 `columnVisibility`,只需选择其中之一。 + +```jsx +const table = useReactTable({ + //... + initialState: { + columnVisibility: { + columnId1: true, + columnId2: false, //默认隐藏此列 + columnId3: true, + }, + //... + }, +}); +``` + +### 禁用列隐藏 + +默认情况下,所有列都可以隐藏或显示。如果想防止某些列被隐藏,可以将这些列的 `enableHiding` 选项设置为 `false`。 + +```jsx +const columns = [ + { + header: 'ID', + accessorKey: 'id', + enableHiding: false, // 禁用此列的隐藏功能 + }, + { + header: 'Name', + accessor: 'name', // 可以隐藏 + }, +]; +``` + +### 列可见性切换 API + +有多个列 API 方法可用于在 UI 中渲染列可见性切换控件。 + +- `column.getCanHide` - 对于设置了 `enableHiding` 为 `false` 的列,可用于禁用其可见性切换。 +- `column.getIsVisible` - 可用于设置可见性切换的初始状态。 +- `column.toggleVisibility` - 可用于切换列的可见性。 +- `column.getToggleVisibilityHandler` - 将 `column.toggleVisibility` 方法连接到 UI 事件处理程序的快捷方式。 + +```jsx +{table.getAllColumns().map((column) => ( + +))} +``` + +### 列可见性感知的表 API + +在渲染表头、表体和表尾单元格时,有许多 API 选项可用。你可能会看到 `table.getAllLeafColumns` 和 `row.getAllCells` 等 API,但如果使用这些 API,它们不会考虑列可见性。相反,需要使用这些 API 的“可见”变体,例如 `table.getVisibleLeafColumns` 和 `row.getVisibleCells`。 + +```jsx + + + + {table.getVisibleLeafColumns().map((column) => ( // 考虑列可见性 + // + ))} + + + + {table.getRowModel().rows.map((row) => ( + + {row.getVisibleCells().map((cell) => ( // 考虑列可见性 + // + ))} + + ))} + +
+``` + +如果使用表头组 API,它们已经考虑了列可见性。 diff --git a/docs/zh-hans/guide/columns.md b/docs/zh-hans/guide/columns.md new file mode 100644 index 0000000000..3795034e85 --- /dev/null +++ b/docs/zh-hans/guide/columns.md @@ -0,0 +1,73 @@ +--- +source-updated-at: '2025-03-20T21:15:29.000Z' +translation-updated-at: '2025-05-02T17:04:35.823Z' +title: 列 +--- +## API + +[列 API](../api/core/column) + +## 列指南 + +> 注意:本指南讨论的是表格实例内部生成的实际 `column` 对象,而非如何为表格设置 [列定义](../guide/column-defs)。 + +本快速指南将介绍在 TanStack Table 中获取和操作 `column` 对象的不同方式。 + +### 获取列的途径 + +您可以在多处找到 `column` 对象,它们通常附加于: + +#### 表头 (Header) 和单元格 (Cell) 对象 + +在使用 `table` 实例 API 之前,请考虑是否真的需要获取 `columns`,而不是 [表头](../guide/headers) 或 [单元格](../guide/cells)。如果您正在渲染表格的标记,很可能会需要使用返回表头或单元格的 API,而非列对象本身。列对象并不直接用于渲染表头或单元格,但 `header` 和 `cell` 对象会包含对这些 `column` 对象的引用,从而可以从中派生渲染 UI 所需的信息。 + +```js +const column = cell.column; // 从单元格获取列 +const column = header.column; // 从表头获取列 +``` + +#### 列表格实例 API + +有数十种 `table` 实例 API 可用于从表格实例中检索列。具体使用哪些 API 完全取决于表格中使用的功能及您的用例。 + +##### 获取单个列 + +如果只需通过 ID 获取单个列,可以使用 `table.getColumn` API。 + +```js +const column = table.getColumn('firstName'); +``` + +##### 获取多列 + +最简单的列 API 是 `table.getAllColumns`,它会返回表格中所有列的列表。但还有许多其他列 API 会受到其他功能和表格状态的影响,例如 `table.getAllFlatColumns`、`table.getAllLeafColumns`、`getCenterLeafColumns`、`table.getLeftVisibleLeafColumns` 等,这些 API 可能与列可见性或列固定功能配合使用。 + +### 列对象 + +列对象实际上并不直接用于渲染表格 UI,因此它们与表格中的 `
` 或 `` 元素并非一一对应。但它们包含许多有用的属性和方法,可用于与表格状态交互。 + +#### 列 ID + +每个列在其关联的 [列定义](../guide/column-defs) 中必须具有唯一的 `id`。通常,您可以自行定义此 `id`,或者它会从列定义中的 `accessorKey` 或 `header` 属性派生。 + +#### ColumnDef + +列对象上始终保留着用于创建该列的原始 `columnDef` 对象的引用。 + +#### 嵌套分组列属性 + +如果列是嵌套或分组列结构的一部分,则以下属性会特别有用: + +- `columns`:属于分组列的子列数组。 +- `depth`:列所属的表头分组“行索引”。 +- `parent`:列的父列。如果列是顶级列,则此值为 `undefined`。 + +### 更多列 API + +有数十种列 API 可用于与表格状态交互,并根据表格状态提取单元格值。详细信息请参阅各功能的列 API 文档。 + +### 列渲染 + +不要直接使用 `column` 对象来渲染 `headers` 或 `cells`。相反,应使用上述的 [`header`](../guide/headers) 和 [`cell`](../guide/cells) 对象。 + +但如果您只是在 UI 的其他位置(例如列可见性菜单等)渲染列列表,可以直接遍历列数组并按常规方式渲染 UI。 diff --git a/docs/zh-hans/guide/custom-features.md b/docs/zh-hans/guide/custom-features.md new file mode 100644 index 0000000000..de6c900c10 --- /dev/null +++ b/docs/zh-hans/guide/custom-features.md @@ -0,0 +1,286 @@ +--- +source-updated-at: '2025-03-20T21:15:29.000Z' +translation-updated-at: '2025-05-02T17:29:08.150Z' +title: 自定义功能 +--- +## 示例 + +想直接查看实现代码?请参考以下示例: + +- [custom-features](../framework/react/examples/custom-features) + +## 自定义功能指南 + +本指南将介绍如何扩展 TanStack Table 以添加自定义功能,同时我们也会深入了解 TanStack Table v8 代码库的结构和工作原理。 + +### TanStack Table 追求精简 + +TanStack Table 内置了一套核心功能,如排序、过滤、分页等。我们收到了许多请求,有时甚至是经过深思熟虑的 PR,希望在库中添加更多功能。虽然我们始终欢迎对库进行改进,但也希望确保 TanStack Table 保持精简,不会包含太多在大多数用例中不太可能使用的冗余代码。并非每个 PR 都能或应该被合并到核心库中,即使它确实解决了实际问题。对于 TanStack Table 能满足 90% 需求但需要更多控制的开发者来说,这可能会令人沮丧。 + +TanStack Table 从 v7 开始就设计为高度可扩展。无论你使用哪个框架适配器(`useReactTable`、`useVueTable` 等),返回的 `table` 实例都是一个普通的 JavaScript 对象,可以添加额外的属性或 API。一直以来,都可以通过组合的方式向表实例添加自定义逻辑、状态和 API。像 [Material React Table](https://github.com/KevinVandy/material-react-table/blob/v2/packages/material-react-table/src/hooks/useMRT_TableInstance.ts) 这样的库,就是通过在 `useReactTable` 钩子上创建自定义包装钩子来扩展表实例的功能。 + +然而,从 v8.14.0 开始,TanStack Table 提供了一个新的 `_features` 表选项,允许你以与内置表功能完全相同的方式,更紧密、更清晰地集成自定义代码到表实例中。 + +> TanStack Table v8.14.0 引入了新的 `_features` 选项,允许你向表实例添加自定义功能。 + +通过这种更紧密的集成,你可以轻松地为表格添加更复杂的自定义功能,甚至可以将它们打包并与社区分享。我们将观察这一功能如何随时间发展。在未来的 v9 版本中,我们可能会通过让所有功能变为可选来进一步减小 TanStack Table 的包体积,但这仍在探索中。 + +### TanStack Table 功能的工作原理 + +TanStack Table 的源代码可以说相对简单(至少我们这样认为)。每个功能的代码都拆分到自己的对象/文件中,包含创建初始状态的方法、默认表和列选项,以及可以添加到 `table`、`header`、`column`、`row` 和 `cell` 实例的 API 方法。 + +所有功能对象的功能都可以通过 TanStack Table 导出的 `TableFeature` 类型来描述。这个类型是一个 TypeScript 接口,描述了创建功能所需的对象结构。 + +```ts +export interface TableFeature { + createCell?: ( + cell: Cell, + column: Column, + row: Row, + table: Table + ) => void + createColumn?: (column: Column, table: Table) => void + createHeader?: (header: Header, table: Table) => void + createRow?: (row: Row, table: Table) => void + createTable?: (table: Table) => void + getDefaultColumnDef?: () => Partial> + getDefaultOptions?: ( + table: Table + ) => Partial> + getInitialState?: (initialState?: InitialTableState) => Partial +} +``` + +这可能有点令人困惑,让我们分解一下这些方法的作用: + +#### 默认选项和初始状态 + +
+ +##### getDefaultOptions + +表功能中的 `getDefaultOptions` 方法负责为该功能设置默认表选项。例如,在 [列调整大小](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/ColumnSizing.ts) 功能中,`getDefaultOptions` 方法设置了默认的 `columnResizeMode` 选项,其默认值为 `"onEnd"`。 + +
+ +##### getDefaultColumnDef + +表功能中的 `getDefaultColumnDef` 方法负责为该功能设置默认列选项。例如,在 [排序](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/RowSorting.ts) 功能中,`getDefaultColumnDef` 方法设置了默认的 `sortUndefined` 列选项,其默认值为 `1`。 + +
+ +##### getInitialState + +表功能中的 `getInitialState` 方法负责为该功能设置默认状态。例如,在 [分页](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/RowPagination.ts) 功能中,`getInitialState` 方法设置了默认的 `pageSize` 状态值为 `10`,默认的 `pageIndex` 状态值为 `0`。 + +#### API 创建器 + +
+ +##### createTable + +表功能中的 `createTable` 方法负责向 `table` 实例添加方法。例如,在 [行选择](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/RowSelection.ts) 功能中,`createTable` 方法添加了许多表实例 API 方法,如 `toggleAllRowsSelected`、`getIsAllRowsSelected`、`getIsSomeRowsSelected` 等。因此,当你调用 `table.toggleAllRowsSelected()` 时,你调用的就是由 `RowSelection` 功能添加到表实例的方法。 + +
+ +##### createHeader + +表功能中的 `createHeader` 方法负责向 `header` 实例添加方法。例如,在 [列调整大小](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/ColumnSizing.ts) 功能中,`createHeader` 方法添加了许多表头实例 API 方法,如 `getStart` 等。因此,当你调用 `header.getStart()` 时,你调用的就是由 `ColumnSizing` 功能添加到表头实例的方法。 + +
+ +##### createColumn + +表功能中的 `createColumn` 方法负责向 `column` 实例添加方法。例如,在 [排序](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/RowSorting.ts) 功能中,`createColumn` 方法添加了许多列实例 API 方法,如 `getNextSortingOrder`、`toggleSorting` 等。因此,当你调用 `column.toggleSorting()` 时,你调用的就是由 `RowSorting` 功能添加到列实例的方法。 + +
+ +##### createRow + +表功能中的 `createRow` 方法负责向 `row` 实例添加方法。例如,在 [行选择](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/RowSelection.ts) 功能中,`createRow` 方法添加了许多行实例 API 方法,如 `toggleSelected`、`getIsSelected` 等。因此,当你调用 `row.toggleSelected()` 时,你调用的就是由 `RowSelection` 功能添加到行实例的方法。 + +
+ +##### createCell + +表功能中的 `createCell` 方法负责向 `cell` 实例添加方法。例如,在 [列分组](https://github.com/TanStack/table/blob/main/packages/table-core/src/features/ColumnGrouping.ts) 功能中,`createCell` 方法添加了许多单元格实例 API 方法,如 `getIsGrouped`、`getIsAggregated` 等。因此,当你调用 `cell.getIsGrouped()` 时,你调用的就是由 `ColumnGrouping` 功能添加到单元格实例的方法。 + +### 添加自定义功能 + +让我们通过一个假设的用例来逐步实现一个自定义表功能。假设我们想向表实例添加一个功能,允许用户更改表格的“密度”(单元格的内边距)。 + +查看完整的 [custom-features](../framework/react/examples/custom-features) 示例以了解完整实现,以下是创建自定义功能的详细步骤。 + +#### 步骤 1:设置 TypeScript 类型 + +假设你希望像 TanStack Table 内置功能一样拥有完整的类型安全,让我们为新功能设置所有 TypeScript 类型。我们将为新的表选项、状态和表实例 API 方法创建类型。 + +这些类型遵循 TanStack Table 内部使用的命名约定,但你可以随意命名。我们暂时不会将这些类型添加到 TanStack Table 中,下一步会进行。 + +```ts +// 为新功能的自定义状态定义类型 +export type DensityState = 'sm' | 'md' | 'lg' +export interface DensityTableState { + density: DensityState +} + +// 为新功能的表选项定义类型 +export interface DensityOptions { + enableDensity?: boolean + onDensityChange?: OnChangeFn +} + +// 为新功能的表 API 定义类型 +export interface DensityInstance { + setDensity: (updater: Updater) => void + toggleDensity: (value?: DensityState) => void +} +``` + +#### 步骤 2:使用声明合并将新类型添加到 TanStack Table + +我们可以告诉 TypeScript 修改从 TanStack Table 导出的类型,以包含新功能的类型。这称为“声明合并”,是 TypeScript 的一个强大功能。这样,我们在新功能的代码或应用代码中就不需要使用 `as unknown as CustomTable` 或 `// @ts-ignore` 等 TypeScript 技巧。 + +```ts +// 使用声明合并将新功能的 API 和状态类型添加到 TanStack Table 的现有类型中。 +declare module '@tanstack/react-table' { // 或你正在使用的任何框架适配器 + // 将新功能的状态与现有表状态合并 + interface TableState extends DensityTableState {} + // 将新功能的选项与现有表选项合并 + interface TableOptionsResolved + extends DensityOptions {} + // 将新功能的实例 API 与现有表实例 API 合并 + interface Table extends DensityInstance {} + // 如果需要添加单元格实例 API... + // interface Cell extends DensityCell + // 如果需要添加行实例 API... + // interface Row extends DensityRow + // 如果需要添加列实例 API... + // interface Column extends DensityColumn + // 如果需要添加表头实例 API... + // interface Header extends DensityHeader + + // 注意:无法对 `ColumnDef` 进行声明合并,因为它是一个复杂类型,而不是接口。 + // 但你仍然可以对 `ColumnDef.meta` 进行声明合并。 +} +``` + +正确完成后,我们在创建新功能代码和在应用中使用它时应该不会有 TypeScript 错误。 + +##### 使用声明合并的注意事项 + +使用声明合并的一个注意事项是,它会影响代码库中所有表的 TanStack Table 类型。如果你计划为应用中的每个表加载相同的功能集,这不是问题,但如果某些表加载额外功能而某些不加载,可能会出现问题。或者,你可以创建一组自定义类型,从 TanStack Table 类型扩展并添加新功能。[Material React Table](https://github.com/KevinVandy/material-react-table/blob/v2/packages/material-react-table/src/types.ts) 就是这样做的,以避免影响普通 TanStack Table 表的类型,但这更繁琐,并且在某些地方需要进行大量类型转换。 + +#### 步骤 3:创建功能对象 + +完成所有 TypeScript 设置后,我们现在可以为新功能创建功能对象。在这里,我们定义将添加到表实例的所有方法。 + +使用 `TableFeature` 类型确保你正确创建功能对象。如果 TypeScript 类型设置正确,创建包含新状态、选项和实例 API 的功能对象时应该不会有 TypeScript 错误。 + +```ts +export const DensityFeature: TableFeature = { // 使用 TableFeature 类型!! + // 定义新功能的初始状态 + getInitialState: (state): DensityTableState => { + return { + density: 'md', + ...state, + } + }, + + // 定义新功能的默认选项 + getDefaultOptions: ( + table: Table + ): DensityOptions => { + return { + enableDensity: true, + onDensityChange: makeStateUpdater('density', table), + } as DensityOptions + }, + // 如果需要添加默认列定义... + // getDefaultColumnDef: (): Partial> => { + // return { meta: {} } // 使用 meta 而不是直接添加到 columnDef,以避免难以解决的 TypeScript 问题 + // }, + + // 定义新功能的表实例方法 + createTable: (table: Table): void => { + table.setDensity = updater => { + const safeUpdater: Updater = old => { + let newState = functionalUpdate(updater, old) + return newState + } + return table.options.onDensityChange?.(safeUpdater) + } + table.toggleDensity = value => { + table.setDensity(old => { + if (value) return value + return old === 'lg' ? 'md' : old === 'md' ? 'sm' : 'lg' // 在 3 个选项间循环 + }) + } + }, + + // 如果需要添加行实例 API... + // createRow: (row, table): void => {}, + // 如果需要添加单元格实例 API... + // createCell: (cell, column, row, table): void => {}, + // 如果需要添加列实例 API... + // createColumn: (column, table): void => {}, + // 如果需要添加表头实例 API... + // createHeader: (header, table): void => {}, +} +``` + +#### 步骤 4:将功能添加到表 + +现在我们有了功能对象,可以在创建表实例时通过 `_features` 选项将其添加到表实例中。 + +```ts +const table = useReactTable({ + _features: [DensityFeature], // 将新功能传递给表,与所有内置功能在底层合并 + columns, + data, + //.. +}) +``` + +#### 步骤 5:在应用中使用功能 + +现在功能已添加到表实例中,你可以在应用中使用新的实例 API、选项和状态。 + +```tsx +const table = useReactTable({ + _features: [DensityFeature], // 将自定义功能传递给表,在创建时实例化 + columns, + data, + //... + state: { + density, // 将密度状态传递给表,TS 仍然正常 :) + }, + onDensityChange: setDensity, // 使用新的 onDensityChange 选项,TS 仍然正常 :) +}) +//... +const { density } = table.getState() +return( +
+ {flexRender( + cell.column.columnDef.cell, + cell.getContext() + )} +
...
; +} +``` + +`React.useState` 和 `React.useMemo` 并非唯一提供稳定引用的方式。也可以在组件外部定义数据,或使用 Redux、Zustand 或 TanStack Query 等第三方状态管理库。 + +主要避免的是在 `useReactTable` 调用的同一作用域内定义 `data` 数组。这会导致 `data` 数组在每次渲染时重新定义,从而引发无限重新渲染循环。 + +```tsx +export default function MyComponent() { + //😵 错误:`columns` 在每次渲染时重新定义为新数组,会导致无限重新渲染! + const columns = [ + // ... + ]; + + //😵 错误:`data` 在每次渲染时重新定义为新数组,会导致无限重新渲染! + const data = [ + // ... + ]; + + //❌ 列和数据在 `useReactTable` 的同一作用域内定义且无稳定引用,会导致无限循环! + const table = useReactTable({ + columns, + data ?? [], //❌ 备用数组在每次渲染时重新创建,同样不好 + }); + + return ...
; +} +``` + +### TanStack Table 如何转换数据 + +在文档的其他部分,您将看到 TanStack Table 如何处理传递给表格的 `data`,并生成用于创建表格的行和单元格对象。TanStack Table 不会修改传递给表格的 `data`,但行和单元格中的实际值可能会通过列定义中的访问器或其他功能(如分组或聚合)进行转换,这些功能由 [行模型](../guide/row-models) 执行。 + +### TanStack Table 能处理多少数据? + +信不信由您,TanStack Table 实际上是为处理客户端可能数十万行数据而构建的。这显然并不总是可行,具体取决于每列数据的大小和列数。但排序、筛选、分页和分组功能在设计时都考虑了大型数据集的性能。 + +开发者构建数据网格的默认思维是为大型数据集实现服务端分页、排序和筛选。这通常仍是个好主意,但许多开发者低估了现代浏览器和适当优化后客户端实际能处理的数据量。如果表格的行数永远不会超过几千行,您可能可以利用 TanStack Table 的客户端功能,而不是自己在服务端实现。当然,在决定让 TanStack Table 的客户端功能处理大型数据集之前,应使用实际数据进行测试,以确保性能满足需求。 + +更多细节请参阅 [分页指南](../guide/pagination#should-you-use-client-side-pagination)。 diff --git a/docs/zh-hans/guide/expanding.md b/docs/zh-hans/guide/expanding.md new file mode 100644 index 0000000000..567f288a21 --- /dev/null +++ b/docs/zh-hans/guide/expanding.md @@ -0,0 +1,230 @@ +--- +source-updated-at: '2025-03-20T21:15:29.000Z' +translation-updated-at: '2025-05-02T17:22:08.105Z' +title: 展开 +--- +## 示例 + +想直接查看实现方式?请参考以下示例: + +- [展开功能](../framework/react/examples/expanding) +- [分组功能](../framework/react/examples/grouping) +- [子组件](../framework/react/examples/sub-components) + +## API + +[展开功能 API](../api/features/expanding) + +## 展开功能指南 + +展开功能允许显示或隐藏与特定行相关的额外数据行。这在处理层级数据时非常有用,可以让用户从高层级向下钻取数据,或者用于展示与某行相关的附加信息。 + +### 展开功能的不同应用场景 + +TanStack Table 的展开功能有以下几种常见应用场景: + +1. 展开子行(子数据行、聚合行等) +2. 展开自定义 UI(详情面板、子表格等) + +### 启用客户端展开功能 + +要使用客户端展开功能,需要在表格选项中定义 `getExpandedRowModel` 函数,该函数负责返回展开的行模型。 + +```ts +const table = useReactTable({ + // 其他选项... + getExpandedRowModel: getExpandedRowModel(), +}) +``` + +展开的数据可以包含表格行或任何你想显示的其他数据。本指南将讨论如何处理这两种情况。 + +### 使用表格行作为展开数据 + +展开行本质上是继承父行相同列结构的子行。如果数据对象已包含这些展开行数据,可以使用 `getSubRows` 函数指定这些子行。如果数据对象不包含展开行数据,则可以将它们视为自定义展开数据(下一节讨论)。 + +例如,如果有如下数据对象: + +```ts +type Person = { + id: number + name: string + age: number + children?: Person[] | undefined +} + +const data: Person[] = [ + { id: 1, + name: 'John', + age: 30, + children: [ + { id: 2, name: 'Jane', age: 5 }, + { id: 5, name: 'Jim', age: 10 } + ] + }, + { id: 3, + name: 'Doe', + age: 40, + children: [ + { id: 4, name: 'Alice', age: 10 } + ] + }, +] +``` + +然后可以使用 `getSubRows` 函数将每行的 `children` 数组作为展开行返回。表格实例现在会知道在哪里查找每行的子行。 + +```ts +const table = useReactTable({ + // 其他选项... + getSubRows: (row) => row.children, // 将 children 数组作为子行返回 + getCoreRowModel: getCoreRowModel(), + getExpandedRowModel: getExpandedRowModel(), +}) +``` + +> **注意:** 你可以编写复杂的 `getSubRows` 函数,但请注意该函数会对每行及其子行运行。如果函数未优化可能会影响性能。不支持异步函数。 + +### 自定义展开 UI + +有时你可能希望显示额外的细节或信息,这些内容可能不属于表格数据对象,比如行的展开数据。这类展开行 UI 有过多种名称,如"可展开行"、"详情面板"、"子组件"等。 + +默认情况下,`row.getCanExpand()` 行实例 API 会返回 false,除非在行上找到 `subRows`。可以通过在表格实例选项中实现自己的 `getRowCanExpand` 函数来覆盖此行为。 + +```ts +//... +const table = useReactTable({ + // 其他选项... + getRowCanExpand: (row) => true, // 添加逻辑判断行是否可展开。true 表示所有行都包含展开数据 + getCoreRowModel: getCoreRowModel(), + getExpandedRowModel: getExpandedRowModel(), +}) +//... + + {table.getRowModel().rows.map((row) => ( + + {/* 正常行 UI */} + + {row.getVisibleCells().map((cell) => ( + + + + ))} + + {/* 如果行已展开,将展开的 UI 渲染为单独的行,其单元格跨整个表格宽度 */} + {row.getIsExpanded() && ( + + // 如果展开数据不是与父行共享相同列的行,则指定要跨越的列数 + // 在此放置自定义 UI + + + )} + + ))} + +//... +``` + +### 展开行状态 + +如果需要控制表格中行的展开状态,可以使用 `expanded` 状态和 `onExpandedChange` 选项。这允许你根据需要管理展开状态。 + +```ts +const [expanded, setExpanded] = useState({}) + +const table = useReactTable({ + // 其他选项... + state: { + expanded: expanded, // 必须将展开状态传回表格 + }, + onExpandedChange: setExpanded +}) +``` + +`ExpandedState` 类型定义如下: + +```ts +type ExpandedState = true | Record +``` + +如果 `ExpandedState` 为 true,表示所有行都已展开。如果是记录类型,则只有 ID 作为记录键且值为 true 的行才会展开。例如,如果展开状态为 { row1: true, row2: false },表示 ID 为 row1 的行已展开,而 ID 为 row2 的行未展开。表格使用此状态确定哪些行已展开并应显示其子行(如果有)。 + +### 展开行的 UI 切换处理程序 + +TanStack Table 不会为展开数据添加切换处理程序 UI 到你的表格中。你应手动在每个行的 UI 中添加它,以允许用户展开和折叠行。例如,可以在列定义中添加按钮 UI。 + +```ts +const columns = [ + { + accessorKey: 'name', + header: 'Name', + }, + { + accessorKey: 'age', + header: 'Age', + }, + { + header: 'Children', + cell: ({ row }) => { + return row.getCanExpand() ? + + : ''; + }, + }, +] +``` + +### 过滤展开行 + +默认情况下,过滤过程从父行开始向下移动。这意味着如果父行被过滤器排除,其所有子行也将被排除。但可以通过使用 `filterFromLeafRows` 选项改变此行为。启用此选项后,过滤过程从叶子(子)行开始向上移动。这确保只要至少一个子行或孙行满足过滤条件,父行就会包含在过滤结果中。此外,可以使用 `maxLeafRowFilterDepth` 选项控制过滤器在子层级中的深度。此选项允许指定过滤器应考虑的子行最大深度。 + +```ts +//... +const table = useReactTable({ + // 其他选项... + getSubRows: row => row.subRows, + getCoreRowModel: getCoreRowModel(), + getFilteredRowModel: getFilteredRowModel(), + getExpandedRowModel: getExpandedRowModel(), + filterFromLeafRows: true, // 搜索展开的行 + maxLeafRowFilterDepth: 1, // 限制被搜索的展开行深度 +}) +``` + +### 分页展开行 + +默认情况下,展开行与表格其余部分一起分页(这意味着展开行可能跨越多个页面)。如果想禁用此行为(这意味着展开行将始终在其父页面上渲染,也意味着会渲染比设置页面大小更多的行),可以使用 `paginateExpandedRows` 选项。 + +```ts +const table = useReactTable({ + // 其他选项... + paginateExpandedRows: false, +}) +``` + +### 固定展开行 + +固定展开行与固定常规行的方式相同。可以将展开行固定到表格顶部或底部。有关行固定的更多信息,请参考[固定指南](./pinning.md)。 + +### 排序展开行 + +默认情况下,展开行与表格其余部分一起排序。 + +### 手动展开(服务端) + +如果进行服务端展开,可以通过将 `manualExpanding` 选项设置为 true 来启用手动行展开。这意味着 `getExpandedRowModel` 不会用于展开行,你需要在数据模型中自行执行展开操作。 + +```ts +const table = useReactTable({ + // 其他选项... + manualExpanding: true, +}) +``` diff --git a/docs/zh-hans/guide/features.md b/docs/zh-hans/guide/features.md new file mode 100644 index 0000000000..0f9b82db80 --- /dev/null +++ b/docs/zh-hans/guide/features.md @@ -0,0 +1,22 @@ +--- +source-updated-at: '2025-03-20T21:15:29.000Z' +translation-updated-at: '2025-05-06T01:25:18.564Z' +title: Features Guide +--- +TanStack Table 提供了众多功能,每个功能都有其对应的选项和 API: + +- [列排序 (Column Ordering)](../guide/column-ordering) +- [列固定 (Column Pinning)](../guide/column-pinning) +- [列尺寸调整 (Column Sizing)](../guide/column-sizing) +- [列可见性 (Column Visibility)](../guide/column-visibility) +- [展开 (Expanding)](../guide/expanding) +- [列切面 (Column Faceting)](../guide/column-faceting) +- [列过滤 (Column Filtering)](../guide/column-filtering) +- [全局切面 (Global Faceting)](../guide/global-faceting) +- [全局过滤 (Global Filtering)](../guide/global-filtering) +- [分组 (Grouping)](../guide/grouping) +- [分页 (Pagination)](../guide/pagination) +- [行固定 (Row Pinning)](../guide/row-pinning) +- [行选择 (Row Selection)](../guide/row-selection) +- [排序 (Sorting)](../guide/sorting) +- [虚拟化 (Virtualization)](../guide/virtualization) diff --git a/docs/zh-hans/guide/filters.md b/docs/zh-hans/guide/filters.md new file mode 100644 index 0000000000..9037892e01 --- /dev/null +++ b/docs/zh-hans/guide/filters.md @@ -0,0 +1,14 @@ +--- +source-updated-at: '2025-03-20T21:15:29.000Z' +translation-updated-at: '2025-05-06T01:25:13.581Z' +title: Filters Guide +--- + + +筛选指南现已拆分为多个独立文档: + +- [列筛选 (Column Filtering)](../guide/column-filtering) +- [全局筛选 (Global Filtering)](../guide/global-filtering) +- [模糊筛选 (Fuzzy Filtering)](../guide/fuzzy-filtering) +- [列分面 (Column Faceting)](../guide/column-faceting) +- [全局分面 (Global Faceting)](../guide/global-faceting) diff --git a/docs/zh-hans/guide/fuzzy-filtering.md b/docs/zh-hans/guide/fuzzy-filtering.md new file mode 100644 index 0000000000..e6b9d79c2a --- /dev/null +++ b/docs/zh-hans/guide/fuzzy-filtering.md @@ -0,0 +1,125 @@ +--- +source-updated-at: '2025-03-20T21:15:29.000Z' +translation-updated-at: '2025-05-02T17:19:13.276Z' +title: 模糊过滤 +--- +## 示例 + +想直接查看实现代码?请参考以下示例: + +- [模糊过滤器](../framework/react/examples/filters-fuzzy) + +## API + +[过滤器 API](../api/features/filters) + +## 模糊过滤指南 + +模糊过滤是一种基于近似匹配筛选数据的技术。当您需要搜索与给定值相似而非完全匹配的数据时,这项技术尤为实用。 + +您可以通过定义自定义过滤器函数来实现客户端模糊过滤。该函数接收行数据、列ID和过滤值作为参数,并返回布尔值以指示该行是否应包含在筛选结果中。 + +模糊过滤通常用于全局过滤,但也可应用于单个列。我们将讨论如何在这两种场景下实现模糊过滤。 + +> **注意:** 使用模糊过滤功能需要安装 `@tanstack/match-sorter-utils` 库。 +> TanStack Match Sorter Utils 是 Kent C. Dodds 开发的 [match-sorter](https://github.com/kentcdodds/match-sorter) 的分支版本。该分支旨在更好地适配 TanStack Table 的逐行过滤机制。 + +虽然 match-sorter 系列库是可选的,但 TanStack Match Sorter Utils 库提供了出色的模糊过滤功能,并能根据返回的排名信息进行排序,从而实现按搜索匹配度排序行的功能。 + +### 定义自定义模糊过滤函数 + +以下是一个自定义模糊过滤函数示例: + +```typescript +import { rankItem } from '@tanstack/match-sorter-utils'; +import { FilterFn } from '@tanstack/table'; + +const fuzzyFilter: FilterFn = (row, columnId, value, addMeta) => { + // 对项目进行排名 + const itemRank = rankItem(row.getValue(columnId), value) + + // 存储排名信息 + addMeta({ itemRank }) + + // 返回该项目是否应被保留 + return itemRank.passed +} +``` + +在此函数中,我们使用 @tanstack/match-sorter-utils 库的 rankItem 函数对项目进行排名。随后将排名信息存入行的元数据,并返回该项目是否通过排名标准。 + +### 全局模糊过滤实现 + +要在全局过滤中使用模糊过滤,可在表格实例的 globalFilterFn 选项中指定模糊过滤函数: + +```typescript +const table = useReactTable({ // 或您所用框架的等效函数 + columns, + data, + filterFns: { + fuzzy: fuzzyFilter, //定义为可在列定义中使用的过滤函数 + }, + globalFilterFn: 'fuzzy', //将模糊过滤器应用于全局过滤(最常见的模糊过滤使用场景) + getCoreRowModel: getCoreRowModel(), + getFilteredRowModel: getFilteredRowModel(), //客户端过滤 + getSortedRowModel: getSortedRowModel(), //如需同时使用排序功能则需要客户端排序 +}) +``` + +### 列级模糊过滤实现 + +要在列过滤中使用模糊过滤,首先需要在表格实例的 filterFns 选项中定义模糊过滤函数,然后在列定义的 filterFn 选项中指定该函数: + +```typescript +const column = [ + { + accessorFn: row => `${row.firstName} ${row.lastName}`, + id: 'fullName', + header: '全名', + cell: info => info.getValue(), + filterFn: 'fuzzy', //使用我们自定义的模糊过滤函数 + }, + // 其他列... +]; +``` + +本示例将模糊过滤应用于组合了 firstName 和 lastName 字段的数据列。 + +#### 模糊过滤排序 + +使用列级模糊过滤时,您可能还需要根据排名信息对数据进行排序。可通过定义自定义排序函数实现: + +```typescript +import { compareItems } from '@tanstack/match-sorter-utils' +import { sortingFns } from '@tanstack/table' + +const fuzzySort: SortingFn = (rowA, rowB, columnId) => { + let dir = 0 + + // 仅当列包含排名信息时才进行排序 + if (rowA.columnFiltersMeta[columnId]) { + dir = compareItems( + rowA.columnFiltersMeta[columnId]?.itemRank!, + rowB.columnFiltersMeta[columnId]?.itemRank! + ) + } + + // 当项目排名相同时提供字母数字回退方案 + return dir === 0 ? sortingFns.alphanumeric(rowA, rowB, columnId) : dir +} +``` + +此函数会比较两行的排名信息。若排名相同,则回退至字母数字排序。 + +随后可在列定义的 sortFn 选项中指定此排序函数: + +```typescript +{ + accessorFn: row => `${row.firstName} ${row.lastName}`, + id: 'fullName', + header: '全名', + cell: info => info.getValue(), + filterFn: 'fuzzy', //使用自定义模糊过滤函数 + sortFn: 'fuzzySort', //使用自定义模糊排序函数 +} +``` diff --git a/docs/zh-hans/guide/global-faceting.md b/docs/zh-hans/guide/global-faceting.md new file mode 100644 index 0000000000..c3dc8c4c87 --- /dev/null +++ b/docs/zh-hans/guide/global-faceting.md @@ -0,0 +1,80 @@ +--- +source-updated-at: '2025-03-20T21:15:29.000Z' +translation-updated-at: '2025-05-02T17:20:09.805Z' +title: 全局分面 +--- +## 示例 + +想要直接查看实现方式?请参考以下示例: + +- [filters-faceted](../framework/react/examples/filters) + +## API + +[全局分面 API](../api/features/global-faceting) + +## 全局分面指南 + +全局分面 (Global Faceting) 功能允许您从表格数据中为所有列生成值列表。例如,可以从所有列的所有行中生成唯一值列表,用作自动完成筛选组件中的搜索建议;或者从数字表格中生成最小值和最大值的元组,用作范围滑块筛选组件的区间。 + +### 全局分面行模型 + +要使用任何全局分面功能,您必须在表格选项中包含相应的行模型。 + +```ts +// 仅导入需要的行模型 +import { + getCoreRowModel, + getFacetedRowModel, + getFacetedMinMaxValues, // 依赖于 getFacetedRowModel + getFacetedUniqueValues, // 依赖于 getFacetedRowModel +} from '@tanstack/react-table' +//... +const table = useReactTable({ + // 其他选项... + getCoreRowModel: getCoreRowModel(), + getFacetedRowModel: getFacetedRowModel(), // 客户端分面模型(其他分面方法依赖此模型) + getFacetedMinMaxValues: getFacetedMinMaxValues(), // 如需最小/最大值 + getFacetedUniqueValues: getFacetedUniqueValues(), // 如需唯一值列表 + //... +}) +``` + +### 使用全局分面行模型 + +在表格选项中包含相应的行模型后,您就可以使用分面表格实例 API 来访问由分面行模型生成的值列表。 + +```ts +// 用于自动完成筛选的唯一值列表 +const autoCompleteSuggestions = + Array.from(table.getGlobalFacetedUniqueValues().keys()) + .sort() + .slice(0, 5000); +``` + +```ts +// 用于范围筛选的最小最大值元组 +const [min, max] = table.getGlobalFacetedMinMaxValues() ?? [0, 1]; +``` + +### 自定义全局(服务端)分面 + +如果不使用内置的客户端分面功能,您可以在服务端实现自己的分面逻辑,并将分面值传递到客户端。可以使用 getGlobalFacetedUniqueValues 和 getGlobalFacetedMinMaxValues 表格选项从服务端解析分面值。 + +```ts +const facetingQuery = useQuery( + 'faceting', + async () => { + const response = await fetch('/api/faceting'); + return response.json(); + }, + { + onSuccess: (data) => { + table.getGlobalFacetedUniqueValues = () => data.uniqueValues; + table.getGlobalFacetedMinMaxValues = () => data.minMaxValues; + }, + } +); +``` + +在此示例中,我们使用 `react-query` 的 `useQuery` 钩子从服务端获取分面数据。获取数据后,我们将 `getGlobalFacetedUniqueValues` 和 `getGlobalFacetedMinMaxValues` 表格选项设置为返回服务端响应中的分面值。这将允许表格使用服务端分面数据来生成自动完成建议和范围筛选器。 diff --git a/docs/zh-hans/guide/global-filtering.md b/docs/zh-hans/guide/global-filtering.md new file mode 100644 index 0000000000..b80ea02e6b --- /dev/null +++ b/docs/zh-hans/guide/global-filtering.md @@ -0,0 +1,196 @@ +--- +source-updated-at: '2025-03-20T21:15:29.000Z' +translation-updated-at: '2025-05-02T17:18:32.792Z' +title: 全局过滤 +--- +## 示例 + +想直接查看实现方式?请参考以下示例: + +- [全局过滤](../framework/react/examples/filters-global) + +## API + +[全局过滤 API](../api/features/global-filtering) + +## 全局过滤指南 + +过滤功能分为两种:列过滤 (Column Filtering) 和全局过滤 (Global Filtering)。 + +本指南将重点介绍全局过滤,即应用于所有列的过滤方式。 + +### 客户端过滤与服务端过滤 (Client-Side vs Server-Side Filtering) + +如果您的数据集较大,可能不希望将所有数据加载到客户端浏览器中进行过滤。这种情况下,您很可能需要实现服务端过滤 (Server-Side Filtering)、排序、分页等功能。 + +然而,正如[分页指南](../guide/pagination#should-you-use-client-side-pagination)中所述,许多开发者低估了客户端能处理的数据量。TanStack Table 的示例经常测试处理多达 100,000 行甚至更多数据,在客户端过滤、排序、分页和分组方面仍能保持良好的性能。这并不意味着您的应用一定能处理这么多数据,但如果表格最多只有几千行数据,您可以充分利用 TanStack Table 提供的客户端过滤、排序、分页和分组功能。 + +> TanStack Table 可以高效处理数千行的客户端数据。不要未经思考就排除客户端过滤、分页、排序等方案。 + +每个用例都不同,具体取决于表格的复杂度、列数、数据大小等因素。需要关注的主要瓶颈包括: + +1. 您的服务器能否在合理的时间(和成本)内查询所有数据? +2. 获取的数据总量是多少?(如果列数不多,实际影响可能比您想象的要小。) +3. 如果一次性加载所有数据,客户端浏览器的内存占用会过高吗? + +如果不确定,可以先从客户端过滤和分页开始,随着数据增长再切换到服务端策略。 + +### 手动实现服务端全局过滤 (Manual Server-Side Global Filtering) + +如果您决定需要手动实现服务端全局过滤,而非使用内置的客户端全局过滤,方法如下: + +手动服务端全局过滤不需要 `getFilteredRowModel` 表格选项。相反,传递给表格的 `data` 应已预先过滤。但如果已设置 `getFilteredRowModel` 选项,可以通过将 `manualFiltering` 设为 `true` 来跳过该逻辑。 + +```jsx +const table = useReactTable({ + data, + columns, + // getFilteredRowModel: getFilteredRowModel(), // 手动服务端全局过滤不需要此选项 + manualFiltering: true, +}) +``` + +注意:使用手动全局过滤时,本指南后续讨论的许多选项将无效。当 `manualFiltering` 设为 `true` 时,表格实例不会对传入的行应用任何全局过滤逻辑,而是直接使用您提供的数据。 + +### 客户端全局过滤 (Client-Side Global Filtering) + +如果使用内置的客户端全局过滤,首先需要在表格选项中传入 `getFilteredRowModel` 函数。 + +```jsx +import { useReactTable, getFilteredRowModel } from '@tanstack/react-table' +//... +const table = useReactTable({ + // 其他选项... + getCoreRowModel: getCoreRowModel(), + getFilteredRowModel: getFilteredRowModel(), // 客户端全局过滤需要此选项 +}) +``` + +### 全局过滤函数 (Global Filter Function) + +`globalFilterFn` 选项允许您指定用于全局过滤的函数。过滤函数可以是内置过滤函数的名称、通过 `tableOptions.filterFns` 提供的自定义过滤函数名称,或直接传入的自定义函数。 + +```jsx +const table = useReactTable({ + data, + columns, + getCoreRowModel: getCoreRowModel(), + getFilteredRowModel: getFilteredRowModel(), + globalFilterFn: 'text' // 内置过滤函数 +}) +``` + +默认提供 10 种内置过滤函数: + +- includesString - 不区分大小写的字符串包含 +- includesStringSensitive - 区分大小写的字符串包含 +- equalsString - 不区分大小写的字符串相等 +- equalsStringSensitive - 区分大小写的字符串相等 +- arrIncludes - 数组元素包含 +- arrIncludesAll - 包含所有指定数组元素 +- arrIncludesSome - 包含部分指定数组元素 +- equals - 对象/引用相等 Object.is/=== +- weakEquals - 弱对象/引用相等 == +- inNumberRange - 数值范围包含 + +您也可以自定义全局过滤函数并通过 `globalFilterFn` 选项传入。 + +### 全局过滤状态 (Global Filter State) + +全局过滤状态存储在表格内部状态中,可通过 `table.getState().globalFilter` 访问。如果需要持久化全局过滤状态,可以使用 `onGlobalFilterChange` 选项提供回调函数。 + +```jsx +const [globalFilter, setGlobalFilter] = useState([]) + +const table = useReactTable({ + // 其他选项... + state: { + globalFilter, + }, + onGlobalFilterChange: setGlobalFilter +}) +``` + +全局过滤状态的类型定义如下: + +```jsx +interface GlobalFilter { + globalFilter: any +} +``` + +### 添加全局过滤输入 UI + +TanStack Table 不会自动添加全局过滤输入 UI。您需要手动添加以允许用户过滤表格。例如,可以在表格上方添加输入框: + +```jsx +return ( +
+ table.setGlobalFilter(String(e.target.value))} + placeholder="搜索..." + /> +
+) +``` + +### 自定义全局过滤函数 (Custom Global Filter Function) + +如需使用自定义全局过滤函数,可以定义函数并通过 `globalFilterFn` 选项传入。 + +> **注意:** 全局过滤常使用模糊过滤函数 (Fuzzy Filtering),相关讨论见[模糊过滤指南](./fuzzy-filtering.md)。 + +```jsx +const customFilterFn = (rows, columnId, filterValue) => { + // 自定义过滤逻辑 +} + +const table = useReactTable({ + // 其他选项... + globalFilterFn: customFilterFn +}) +``` + +### 初始全局过滤状态 (Initial Global Filter State) + +如需在表格初始化时设置初始全局过滤状态,可以通过 `initialState` 选项传入。但更推荐直接在 `state.globalFilter` 中管理初始状态。 + +```jsx +const [globalFilter, setGlobalFilter] = useState("搜索词") // 推荐在此初始化全局过滤状态 + +const table = useReactTable({ + // 其他选项... + initialState: { + globalFilter: '搜索词', // 如果不管理 globalFilter 状态,在此设置初始状态 + } + state: { + globalFilter, // 将受控的 globalFilter 状态传递给表格 + } +}) +``` + +> 注意:不要同时使用 `initialState.globalFilter` 和 `state.globalFilter`,因为 `state.globalFilter` 会覆盖 `initialState.globalFilter`。 + +### 禁用全局过滤 (Disable Global Filtering) + +默认情况下,所有列都启用全局过滤。可以通过 `enableGlobalFilter` 表格选项禁用所有列的全局过滤,或通过将 `enableFilters` 设为 `false` 同时禁用列过滤和全局过滤。 + +禁用全局过滤后,`column.getCanGlobalFilter` API 将返回 `false`。 + +```jsx +const columns = [ + { + header: () => 'ID', + accessorKey: 'id', + enableGlobalFilter: false, // 禁用此列的全局过滤 + }, + //... +] +//... +const table = useReactTable({ + // 其他选项... + columns, + enableGlobalFilter: false, // 禁用所有列的全局过滤 +}) +``` diff --git a/docs/zh-hans/guide/grouping.md b/docs/zh-hans/guide/grouping.md new file mode 100644 index 0000000000..9680306a8e --- /dev/null +++ b/docs/zh-hans/guide/grouping.md @@ -0,0 +1,148 @@ +--- +source-updated-at: '2025-03-20T21:15:29.000Z' +translation-updated-at: '2025-05-02T17:20:58.976Z' +title: 分组 +--- +## 示例 + +想直接查看实现代码?请参考以下示例: + +- [分组](../framework/react/examples/grouping) + +## API + +[分组 API](../api/features/grouping) + +## 分组指南 + +表格中有 3 种可以重新排序列的功能,它们的执行顺序如下: + +1. [列固定 (Column Pinning)](../guide/column-pinning) - 如果启用了固定列,列会被分为左侧、中间(未固定)和右侧固定列。 +2. 手动[列排序 (Column Ordering)](../guide/column-ordering) - 应用手动指定的列顺序。 +3. **分组 (Grouping)** - 如果启用了分组功能、存在分组状态且 `tableOptions.groupedColumnMode` 设置为 `'reorder' | 'remove'`,则分组列会被重新排序到列流的最前面。 + +TanStack Table 中的分组功能应用于列,允许你根据特定列对表格行进行分类和组织。这在处理大量数据并希望根据特定条件进行分组时非常有用。 + +要使用分组功能,你需要使用分组行模型 (grouped row model)。该模型负责根据分组状态对行进行分组。 + +```tsx +import { getGroupedRowModel } from '@tanstack/react-table' + +const table = useReactTable({ + // 其他选项... + getGroupedRowModel: getGroupedRowModel(), +}) +``` + +当分组状态激活时,表格会将匹配的行作为子行 (subRows) 添加到分组行中。分组行会被添加到表格行中,其索引与第一个匹配行相同。匹配的行会从表格行中移除。 +要允许用户展开和折叠分组行,可以使用展开功能 (expanding feature)。 + +```tsx +import { getGroupedRowModel, getExpandedRowModel} from '@tanstack/react-table' + +const table = useReactTable({ + // 其他选项... + getGroupedRowModel: getGroupedRowModel(), + getExpandedRowModel: getExpandedRowModel(), +}) +``` + +### 分组状态 + +分组状态是一个字符串数组,每个字符串是要分组的列的 ID。数组中的字符串顺序决定了分组的顺序。例如,如果分组状态是 ['column1', 'column2'],表格会先按 column1 分组,然后在每个组内再按 column2 分组。你可以使用 setGrouping 函数控制分组状态: + +```tsx +table.setGrouping(['column1', 'column2']); +``` + +你也可以使用 resetGrouping 函数将分组状态重置为初始状态: + +```tsx +table.resetGrouping(); +``` + +默认情况下,当列被分组时,它会被移动到表格的最前面。你可以使用 groupedColumnMode 选项控制这一行为。如果设置为 'reorder',分组列会被移动到表格的最前面。如果设置为 'remove',分组列会从表格中移除。如果设置为 false,分组列不会被移动或移除。 + +```tsx +const table = useReactTable({ + // 其他选项... + groupedColumnMode: 'reorder', +}) +``` + +### 聚合 + +当行被分组时,你可以使用 aggregationFn 选项按列聚合分组行中的数据。这是一个字符串,表示聚合函数的 ID。你可以使用 aggregationFns 选项定义聚合函数。 + +```tsx +const column = columnHelper.accessor('key', { + aggregationFn: 'sum', +}) +``` + +在上面的例子中,sum 聚合函数会被用于聚合分组行中的数据。 +默认情况下,数值列会使用 sum 聚合函数,非数值列会使用 count 聚合函数。你可以通过在列定义中指定 aggregationFn 选项来覆盖这一行为。 + +以下是几种内置的聚合函数: + +- sum - 对分组行中的值求和。 +- count - 计算分组行中的行数。 +- min - 找出分组行中的最小值。 +- max - 找出分组行中的最大值。 +- extent - 找出分组行中值的范围(最小值和最大值)。 +- mean - 计算分组行中值的平均值。 +- median - 找出分组行中值的中位数。 +- unique - 返回分组行中唯一值的数组。 +- uniqueCount - 计算分组行中唯一值的数量。 + +#### 自定义聚合 + +当行被分组时,你可以使用 aggregationFns 选项聚合分组行中的数据。这是一个记录,其中键是聚合函数的 ID,值是聚合函数本身。然后你可以在列的 aggregationFn 选项中引用这些聚合函数。 + +```tsx +const table = useReactTable({ + // 其他选项... + aggregationFns: { + myCustomAggregation: (columnId, leafRows, childRows) => { + // 返回聚合后的值 + }, + }, +}) +``` + +在上面的例子中,myCustomAggregation 是一个自定义聚合函数,它接收列 ID、叶子行 (leafRows) 和子行 (childRows),并返回聚合后的值。然后你可以在列的 aggregationFn 选项中使用这个聚合函数: + +```tsx +const column = columnHelper.accessor('key', { + aggregationFn: 'myCustomAggregation', +}) +``` + +### 手动分组 + +如果你正在进行服务端分组 (server-side grouping) 和聚合,可以使用 manualGrouping 选项启用手动分组。当此选项设置为 true 时,表格不会自动使用 getGroupedRowModel() 分组行,而是期望你在将行传递给表格之前手动分组。 + +```tsx +const table = useReactTable({ + // 其他选项... + manualGrouping: true, +}) +``` + +> **注意:** 目前 TanStack Table 没有很多已知的简单方法来实现服务端分组。你需要进行大量自定义单元格渲染才能实现这一功能。 + +### 分组变更处理程序 + +如果你想自己管理分组状态,可以使用 onGroupingChange 选项。此选项是一个函数,当分组状态发生变化时会被调用。你可以通过 tableOptions.state.grouping 选项将托管状态传递回表格。 + +```tsx +const [grouping, setGrouping] = useState([]) + +const table = useReactTable({ + // 其他选项... + state: { + grouping: grouping, + }, + onGroupingChange: setGrouping +}) +``` diff --git a/docs/zh-hans/guide/header-groups.md b/docs/zh-hans/guide/header-groups.md new file mode 100644 index 0000000000..421ce0e530 --- /dev/null +++ b/docs/zh-hans/guide/header-groups.md @@ -0,0 +1,50 @@ +--- +source-updated-at: '2025-03-20T21:15:29.000Z' +translation-updated-at: '2025-05-02T17:03:29.963Z' +title: 表头分组 +--- +## API + +[Header Group API](../api/core/header-group) + +## 表头分组指南 + +本快速指南将讨论在 TanStack Table 中获取和操作表头分组对象的不同方法。 + +### 什么是表头分组? + +表头分组就是表头的"行"。不要被名称迷惑,它就是这么简单。绝大多数表格只有一行表头(单个表头分组),但如果像[列分组示例](../framework/react/examples/column-groups)那样定义嵌套列结构,就可以有多行表头(多个表头分组)。 + +### 如何获取表头分组 + +可以通过多个 `table` 实例 API 从表格实例中获取表头分组。`table.getHeaderGroups` 是最常用的 API,但根据使用的功能特性,可能需要使用其他 API,例如在使用列固定功能时,可能需要使用 `table.get[Left/Center/Right]HeaderGroups`。 + +### 表头分组对象 + +表头分组对象与[行对象](../guide/rows)类似,但更简单,因为表头行没有数据行那么复杂的逻辑。 + +默认情况下,表头分组只有三个属性: + +- `id`:根据深度(索引)生成的唯一标识符。这对 React 组件的 key 属性很有用。 +- `depth`:表头分组的深度,从零开始索引。可以理解为所有表头行中的行索引。 +- `headers`:属于该表头分组(行)的[表头单元格](../guide/headers)对象数组。 + +### 访问表头单元格 + +要渲染表头分组中的单元格,只需遍历表头分组对象的 `headers` 数组。 + +```jsx + + {table.getHeaderGroups().map(headerGroup => { + return ( + + {headerGroup.headers.map(header => ( // 遍历 headerGroup 的 headers 数组 + + {/* */} + + ))} + + ) + })} + +``` diff --git a/docs/zh-hans/guide/headers.md b/docs/zh-hans/guide/headers.md new file mode 100644 index 0000000000..4c2ba3b81b --- /dev/null +++ b/docs/zh-hans/guide/headers.md @@ -0,0 +1,86 @@ +--- +source-updated-at: '2025-03-20T21:15:29.000Z' +translation-updated-at: '2025-05-02T17:04:06.657Z' +title: 表头 +--- +## API + +[Header API](../api/core/header) + +## 表头指南 + +本快速指南将讨论在 TanStack Table 中获取和操作 `header` 对象的不同方式。 + +表头相当于单元格,但专用于表格的 `` 区域而非 `` 区域。 + +### 获取表头的途径 + +表头来源于 [Header Groups(表头组)](../guide/header-groups),其相当于行,但专用于表格的 `` 区域而非 `` 区域。 + +#### 表头组中的表头 + +若在表头组中,表头会以数组形式存储在 `headerGroup.headers` 属性中。通常只需遍历该数组即可渲染表头。 + +```jsx + + {table.getHeaderGroups().map(headerGroup => { + return ( + + {headerGroup.headers.map(header => ( // 遍历 headerGroup.headers 数组 + + {/* */} + + ))} + + ) + })} + +``` + +#### 表头表实例 API + +根据使用的功能,可通过多种 `table` 实例 API 获取表头列表。最常用的可能是 `table.getFlatHeaders`,它会返回表格中所有表头的扁平列表,但还有十余种其他 API 与列可见性和列固定功能配合使用。例如 `table.getLeftLeafHeaders` 或 `table.getRightFlatHeaders` 可能适用于特定场景。 + +### 表头对象 + +表头对象类似于 [Cell(单元格)](../guide/cells) 对象,但专用于表格的 `` 区域。每个表头对象可与 UI 中的 `` 或类似单元格元素关联。`header` 对象上有若干属性和方法,可用于与表格状态交互,并根据表格状态提取单元格值。 + +#### 表头 ID + +每个表头对象都有唯一的 `id` 属性。通常仅需将其用作 React key 的唯一标识符,或参考 [高性能列调整示例](../framework/react/examples/column-resizing-performant) 时使用。 + +对于没有嵌套或分组逻辑的简单表头,`header.id` 与其父级 `column.id` 相同。但若表头属于分组列或占位单元格,则会生成更复杂的 ID,由表头族系、深度/表头行索引、列 ID 和表头组 ID 构成。 + +#### 嵌套分组表头属性 + +若表头属于嵌套或分组结构,则以下属性特别有用: + +- `colspan`:表头应跨越的列数,适用于设置 `` 元素的 `colSpan` 属性。 +- `rowSpan`:表头应跨越的行数,适用于设置 `` 元素的 `rowSpan` 属性。(当前 TanStack Table 默认未实现) +- `depth`:表头组所属的“行索引”。 +- `isPlaceholder`:布尔标志,若表头为占位表头则为 true。占位表头用于填充列隐藏或列分组时的空缺。 +- `placeholderId`:占位表头的唯一标识符。 +- `subHeaders`:属于该表头的子表头数组。若为叶子表头则为空。 + +> 注意:`header.index` 表示其在表头组(表头行)中的索引(从左到右的位置),与表示表头组“行索引”的 `header.depth` 不同。 + +#### 表头父对象 + +每个表头存储对其父级 [column(列)](../guide/columns) 对象和父级 [header group(表头组)](../guide/header-groups) 对象的引用。 + +### 更多表头 API + +表头上还附加了一些用于与表格状态交互的实用 API,多数与列尺寸调整功能相关。详见 [列尺寸调整指南](../guide/column-sizing)。 + +### 表头渲染 + +由于定义的 `header` 列选项可以是字符串、JSX 或返回二者的函数,最佳渲染方式是使用适配器中的 `flexRender` 工具,它能处理所有情况。 + +```jsx +{headerGroup.headers.map(header => ( + + {/* 处理 `header` 列定义的所有可能场景 */} + {flexRender(header.column.columnDef.header, header.getContext())} + +))} +``` diff --git a/docs/zh-hans/guide/migrating.md b/docs/zh-hans/guide/migrating.md new file mode 100644 index 0000000000..de5042213e --- /dev/null +++ b/docs/zh-hans/guide/migrating.md @@ -0,0 +1,194 @@ +--- +source-updated-at: '2024-12-30T21:50:15.000Z' +translation-updated-at: '2025-05-02T16:57:27.257Z' +title: 迁移至 V8 +--- +## 迁移至 V8 版本指南 + +TanStack Table V8 是基于 TypeScript 对 React Table v7 进行的全面重写。您的标记和 CSS 的整体结构/组织方式基本保持不变,但许多 API 已被重命名或替换。 + +### 重要变更 + +- 全面重写为 TypeScript,基础包已内置类型声明 +- 移除插件系统,改为更倾向于控制反转的设计 +- API 规模大幅扩展且功能增强(新增如固定列等特性) +- 改进的受控状态管理 +- 更完善的服务器端操作支持 +- 完整(但可选)的数据管道控制 +- 框架无关的核心设计,提供 React、Solid、Svelte、Vue 等适配器,未来可能支持更多框架 +- 全新的开发者工具 + +### 安装新版本 + +新版 TanStack Table 发布在 `@tanstack` 作用域下。使用您喜欢的包管理器安装新包: + +```bash +npm uninstall react-table @types/react-table +npm install @tanstack/react-table +``` + +```tsx +- import { useTable } from 'react-table' // [!code --] ++ import { useReactTable } from '@tanstack/react-table' // [!code ++] +``` + +类型声明现已包含在基础包中,因此可以移除 `@types/react-table` 包。 + +> 如需逐步迁移代码,可保留旧版 `react-table` 包。两个版本的包可以并存,分别用于不同的表格而不会产生冲突。 + +### 更新表格配置选项 + +- 将 `useTable` 重命名为 `useReactTable` +- 旧版钩子和插件系统已被移除,改为按功能分模块导入的树摇优化行模型 + +```tsx +- import { useTable, usePagination, useSortBy } from 'react-table'; // [!code --] ++ import { // [!code ++] ++ useReactTable, // [!code ++] ++ getCoreRowModel, // [!code ++] ++ getPaginationRowModel, // [!code ++] ++ getSortedRowModel // [!code ++] ++ } from '@tanstack/react-table'; // [!code ++] + +// ... + +- const tableInstance = useTable( // [!code --] +- { columns, data }, // [!code --] +- useSortBy, // [!code --] +- usePagination, //order of hooks used to matter // [!code --] +- // etc. // [!code --] +- ); // [!code --] ++ const tableInstance = useReactTable({ // [!code ++] ++ columns, // [!code ++] ++ data, // [!code ++] ++ getCoreRowModel: getCoreRowModel(), // [!code ++] ++ getPaginationRowModel: getPaginationRowModel(), // [!code ++] ++ getSortedRowModel: getSortedRowModel(), //order doesn't matter anymore! // [!code ++] ++ // etc. // [!code ++] ++ }); // [!code ++] +``` + +- 所有 `disable*` 表格选项更名为 `enable*`(如 `disableSortBy` 改为 `enableSorting`,`disableGroupBy` 改为 `enableGrouping` 等) +- ... + +### 更新列定义 + +- `accessor` 更名为 `accessorKey` 或 `accessorFn`(根据使用字符串还是函数决定) +- `width`、`minWidth`、`maxWidth` 更名为 `size`、`minSize`、`maxSize` +- 可选使用新的 `createColumnHelper` 函数包裹列定义,获得更好的 TypeScript 提示(仍可直接使用列定义数组) + - 第一个参数是访问器函数或访问器字符串 + - 第二个参数是列选项对象 + +```tsx +const columns = [ +- { // [!code --] +- accessor: 'firstName', // [!code --] +- Header: 'First Name', // [!code --] +- }, // [!code --] +- { // [!code --] +- accessor: row => row.lastName, // [!code --] +- Header: () => Last Name, // [!code --] +- }, // [!code --] + +// 最佳 TypeScript 体验,特别在使用 `cell.getValue()` 时 ++ columnHelper.accessor('firstName', { //accessorKey // [!code ++] ++ header: 'First Name', // [!code ++] ++ }), // [!code ++] ++ columnHelper.accessor(row => row.lastName, { //accessorFn // [!code ++] ++ header: () => Last Name, // [!code ++] ++ }), // [!code ++] + +// 或(如果偏好) ++ { // [!code ++] ++ accessorKey: 'firstName', // [!code ++] ++ header: 'First Name', // [!code ++] ++ }, // [!code ++] ++ { // [!code ++] ++ accessorFn: row => row.lastName, // [!code ++] ++ header: () => Last Name, // [!code ++] ++ }, // [!code ++] +] +``` + +> 注意:在组件内定义列时,仍应为列定义保持稳定标识。这有助于性能优化并避免不必要的重新渲染。将列定义存储在 `useMemo` 或 `useState` 钩子中。 + +- 列选项名称变更 + - `Header` 更名为 `header` + - `Cell` 更名为 `cell`(单元格渲染函数也有变更,见下文) + - `Footer` 更名为 `footer` + - 所有 `disable*` 列选项更名为 `enable*` 列选项(如 `disableSortBy` 改为 `enableSorting`,`disableGroupBy` 改为 `enableGrouping` 等) + - `sortType` 改为 `sortingFn` + - ... + +- 自定义单元格渲染器变更 + - `value` 更名为 `getValue`(为提高性能,改为暴露 `getValue` 函数来按需取值并缓存结果) + - `cell: { isGrouped, isPlaceholder, isAggregated }` 改为 `cell: { getIsGrouped, getIsPlaceholder, getIsAggregated }` + - `column`:基础属性现在专属于表格库,自定义属性现在位于 `columnDef` 层级下 + - `table`:传入 `useTable` 钩子的属性现在位于 `options` 下 + +### 迁移表格标记 + +- 使用 `flexRender()` 替代 `cell.render('Cell')` 或 `column.render('Header')` 等 +- `getHeaderProps`、`getFooterProps`、`getCellProps`、`getRowProps` 等均已弃用 + - TanStack Table 不再提供默认的 `style` 或无障碍属性如 `role`(这些仍很重要,但为支持框架无关性已被移除) + - 需手动定义 `onClick` 事件处理器,但有新的 `get*Handler` 辅助函数简化操作 + - 需手动定义 `key` 属性 + - 使用分组表头、聚合等功能时需手动定义 `colSpan` 属性 + +```tsx +- {cell.render('Header')} // [!code --] ++ // [!code ++] ++ {flexRender( // [!code ++] ++ header.column.columnDef.header, // [!code ++] ++ header.getContext() // [!code ++] ++ )} // [!code ++] ++ // [!code ++] +``` + +```tsx +- {cell.render('Cell')} // [!code --] ++ // [!code ++] ++ {flexRender( // [!code ++] ++ cell.column.columnDef.cell, // [!code ++] ++ cell.getContext() // [!code ++] ++ )} // [!code ++] ++ // [!code ++] +``` + +```tsx +// 此场景下的列定义示例 +- Header: ({ getToggleAllRowsSelectedProps }) => ( // [!code --] +- // [!code --] +- ), // [!code --] +- Cell: ({ row }) => ( // [!code --] +- // [!code --] +- ), // [!code --] ++ header: ({ table }) => ( // [!code ++] ++ // [!code ++] ++ ), // [!code ++] ++ cell: ({ row }) => ( // [!code ++] ++ // [!code ++] ++ ), // [!code ++] +``` + +### 其他变更 + +- 自定义 `filterTypes`(现称 `filterFns`)函数签名变更,现在只需返回布尔值表示是否包含该行 + +```tsx +- (rows: Row[], id: string, filterValue: any) => Row[] // [!code --] ++ (row: Row, id: string, filterValue: any) => boolean // [!code ++] +``` + +- ... + +> 本指南仍在完善中。如有时间,欢迎贡献您的经验! diff --git a/docs/zh-hans/guide/pagination.md b/docs/zh-hans/guide/pagination.md new file mode 100644 index 0000000000..5f5871795c --- /dev/null +++ b/docs/zh-hans/guide/pagination.md @@ -0,0 +1,223 @@ +--- +source-updated-at: '2025-03-20T21:15:29.000Z' +translation-updated-at: '2025-05-02T17:23:27.954Z' +title: 分页 +--- +## 示例 + +想直接查看实现代码?请参考以下示例: + +- [分页](../framework/react/examples/pagination) +- [受控分页 (React Query)](../framework/react/examples/pagination-controlled) +- [可编辑数据](../framework/react/examples/editable-data) +- [展开行](../framework/react/examples/expanding) +- [筛选](../framework/react/examples/filters) +- [完全受控](../framework/react/examples/fully-controlled) +- [行选择](../framework/react/examples/row-selection) + +## API + +[分页 API](../api/features/pagination) + +## 分页指南 + +TanStack Table 对客户端分页和服务端分页都提供了完善的支持。本指南将引导您了解在表格中实现分页的不同方式。 + +### 客户端分页 + +使用客户端分页意味着您获取的 `data` 将包含表格的***所有***行数据,表格实例会在前端处理分页逻辑。 + +#### 是否应该使用客户端分页? + +客户端分页通常是使用 TanStack Table 实现分页的最简单方式,但对于非常大的数据集可能不太实用。 + +不过,很多人低估了客户端能处理的数据量。如果您的表格最多只有几千行数据,客户端分页仍然是一个可行的选择。TanStack Table 设计用于处理数万行数据,在分页、筛选、排序和分组方面都能保持良好的性能。[官方分页示例](../framework/react/examples/pagination)加载了 10 万行数据,仍然表现良好(尽管只有少数几列)。 + +每个用例都不同,取决于表格的复杂度、列数、每条数据的大小等因素。需要关注的主要瓶颈是: + +1. 您的服务器能否在合理的时间(和成本)内查询所有数据? +2. 获取的数据总量是多少?(如果列数不多,实际影响可能没有想象中严重。) +3. 如果一次性加载所有数据,客户端的浏览器是否会占用过多内存? + +如果不确定,可以先从客户端分页开始,随着数据增长再切换到服务端分页。 + +#### 是否应该改用虚拟化? + +另一种处理大数据集的方式是不分页,而是在同一页面上渲染所有行,但仅使用浏览器资源渲染视口中可见的行。这种策略通常称为“虚拟化”或“窗口化”。TanStack 提供了一个虚拟化库 [TanStack Virtual](https://tanstack.com/virtual/latest),可以与 TanStack Table 配合使用。虚拟化和分页在 UI/UX 上各有优缺点,请根据您的用例选择最适合的方式。 + +#### 分页行模型 + +如果想利用 TanStack Table 内置的客户端分页功能,首先需要传入分页行模型。 + +```jsx +import { useReactTable, getCoreRowModel, getPaginationRowModel } from '@tanstack/react-table'; +//... +const table = useReactTable({ + columns, + data, + getCoreRowModel: getCoreRowModel(), + getPaginationRowModel: getPaginationRowModel(), //加载客户端分页代码 +}); +``` + +### 手动服务端分页 + +如果确定需要使用服务端分页,以下是实现方式。 + +服务端分页不需要分页行模型,但如果为其他需要分页的共享组件提供了该模型,仍可以通过将 `manualPagination` 选项设为 `true` 来关闭客户端分页。设置 `manualPagination: true` 会让表格实例在底层使用 `table.getPrePaginationRowModel` 行模型,并假设传入的 `data` 已经是分页后的数据。 + +#### 总页数和总行数 + +除非明确告知,否则表格实例无法知道后端总共有多少行/页数据。通过提供 `rowCount` 或 `pageCount` 表格选项,可以让表格实例知道总页数。如果提供 `rowCount`,表格实例会根据 `rowCount` 和 `pageSize` 内部计算 `pageCount`。也可以直接提供 `pageCount`(如果已知)。如果不知道总页数,可以传入 `-1`,但此时 `getCanNextPage` 和 `getCanPreviousPage` 行模型函数将始终返回 `true`。 + +```jsx +import { useReactTable, getCoreRowModel, getPaginationRowModel } from '@tanstack/react-table'; +//... +const table = useReactTable({ + columns, + data, + getCoreRowModel: getCoreRowModel(), + // getPaginationRowModel: getPaginationRowModel(), //服务端分页不需要 + manualPagination: true, //关闭客户端分页 + rowCount: dataQuery.data?.rowCount, //传入总行数,表格会计算总页数(如果不提供 pageCount) + // pageCount: dataQuery.data?.pageCount, //或者直接传入 pageCount +}); +``` + +> **注意**:设置 `manualPagination: true` 会让表格实例假设传入的 `data` 已经是分页后的数据。 + +### 分页状态 + +无论使用客户端分页还是手动服务端分页,都可以使用内置的 `pagination` 状态和 API。 + +`pagination` 状态是一个包含以下属性的对象: + +- `pageIndex`:当前页码(从 0 开始)。 +- `pageSize`:当前每页大小。 + +可以像管理表格实例中的其他状态一样管理 `pagination` 状态。 + +```jsx +import { useReactTable, getCoreRowModel, getPaginationRowModel } from '@tanstack/react-table'; +//... +const [pagination, setPagination] = useState({ + pageIndex: 0, //初始页码 + pageSize: 10, //默认每页大小 +}); + +const table = useReactTable({ + columns, + data, + getCoreRowModel: getCoreRowModel(), + getPaginationRowModel: getPaginationRowModel(), + onPaginationChange: setPagination, //当内部 API 修改分页状态时更新 + state: { + //... + pagination, + }, +}); +``` + +如果不需要在自身作用域中管理 `pagination` 状态,但需要设置不同的 `pageIndex` 和 `pageSize` 初始值,可以使用 `initialState` 选项。 + +```jsx +const table = useReactTable({ + columns, + data, + getCoreRowModel: getCoreRowModel(), + getPaginationRowModel: getPaginationRowModel(), + initialState: { + pagination: { + pageIndex: 2, //自定义初始页码 + pageSize: 25, //自定义默认每页大小 + }, + }, +}); +``` + +> **注意**:不要同时将 `pagination` 状态传递给 `state` 和 `initialState` 选项。`state` 会覆盖 `initialState`,只需使用其中之一。 + +### 分页选项 + +除了对手动服务端分页有用的 `manualPagination`、`pageCount` 和 `rowCount` 选项(已在[上文](#手动服务端分页)讨论),还有一个表格选项值得了解。 + +#### 自动重置页码 + +默认情况下,当发生影响分页的状态变化(如 `data` 更新、筛选条件变化、分组变化等)时,`pageIndex` 会自动重置为 `0`。当 `manualPagination` 为 `true` 时,此行为会自动禁用,但可以通过显式为 `autoResetPageIndex` 表格选项分配布尔值来覆盖。 + +```jsx +const table = useReactTable({ + columns, + data, + getCoreRowModel: getCoreRowModel(), + getPaginationRowModel: getPaginationRowModel(), + autoResetPageIndex: false, //关闭自动重置页码 +}); +``` + +但请注意,如果关闭 `autoResetPageIndex`,可能需要自行添加逻辑来处理 `pageIndex` 的重置,以避免显示空页面。 + +### 分页 API + +有几个分页表格实例 API 可用于连接分页 UI 组件。 + +#### 分页按钮 API + +- `getCanPreviousPage`:用于在第一页时禁用“上一页”按钮。 +- `getCanNextPage`:用于在没有更多页面时禁用“下一页”按钮。 +- `previousPage`:用于跳转到上一页(按钮点击处理函数)。 +- `nextPage`:用于跳转到下一页(按钮点击处理函数)。 +- `firstPage`:用于跳转到第一页(按钮点击处理函数)。 +- `lastPage`:用于跳转到最后一页(按钮点击处理函数)。 +- `setPageIndex`:用于“跳转到页”输入框。 +- `resetPageIndex`:用于将表格状态重置为初始页码。 +- `setPageSize`:用于“每页大小”输入框/下拉框。 +- `resetPageSize`:用于将表格状态重置为初始每页大小。 +- `setPagination`:用于一次性设置所有分页状态。 +- `resetPagination`:用于将表格状态重置为初始分页状态。 + +> **注意**:部分 API 是 `v8.13.0` 新增的。 + +```jsx + + + + + +``` + +#### 分页信息 API + +- `getPageCount`:用于显示总页数。 +- `getRowCount`:用于显示总行数。 diff --git a/docs/zh-hans/guide/pinning.md b/docs/zh-hans/guide/pinning.md new file mode 100644 index 0000000000..41275e9f73 --- /dev/null +++ b/docs/zh-hans/guide/pinning.md @@ -0,0 +1,11 @@ +--- +source-updated-at: '2025-03-20T21:15:29.000Z' +translation-updated-at: '2025-05-06T01:25:12.357Z' +title: Pinning Guide +--- + + +固定 (Pinning) 功能分为两个不同的特性指南: + +- [列固定 (Column Pinning)](../guide/column-pinning) +- [行固定 (Row Pinning)](../guide/row-pinning) diff --git a/docs/zh-hans/guide/row-models.md b/docs/zh-hans/guide/row-models.md new file mode 100644 index 0000000000..27d1867f2c --- /dev/null +++ b/docs/zh-hans/guide/row-models.md @@ -0,0 +1,123 @@ +--- +source-updated-at: '2024-04-24T03:41:47.000Z' +translation-updated-at: '2025-05-02T17:02:04.700Z' +title: 行模型 +--- +## 行模型指南 + +如果查看 TanStack Table 最基础的示例,你会看到类似这样的代码片段: + +```ts +import { getCoreRowModel, useReactTable } from '@tanstack/react-table' + +function Component() { + const table = useReactTable({ + data, + columns, + getCoreRowModel: getCoreRowModel(), //行模型 + }) +} +``` + +这个 `getCoreRowModel` 函数是什么?为什么必须从 TanStack Table 导入它,然后又直接传回给它本身? + +答案是:TanStack Table 是一个模块化的库。并非所有功能的代码都默认包含在 createTable 函数/钩子中。你只需要导入并包含那些基于所需功能来正确生成行的代码。 + +### 什么是行模型? + +行模型在 TanStack Table 内部运行,以有用的方式转换原始数据,这些转换是数据网格功能(如筛选、排序、分组、展开和分页)所必需的。最终生成并渲染在屏幕上的行,并不一定与你传给表格的原始数据是 1:1 对应的关系。它们可能经过排序、筛选、分页等处理。 + +### 导入行模型 + +你只需导入需要的行模型。以下是所有可用的行模型: + +```ts +//仅导入需要的行模型 +import { + getCoreRowModel, + getExpandedRowModel, + getFacetedMinMaxValues, + getFacetedRowModel, + getFacetedUniqueValues, + getFilteredRowModel, + getGroupedRowModel, + getPaginationRowModel, + getSortedRowModel, +} +//... +const table = useReactTable({ + columns, + data, + getCoreRowModel: getCoreRowModel(), + getExpandedRowModel: getExpandedRowModel(), + getFacetedMinMaxValues: getFacetedMinMaxValues(), + getFacetedRowModel: getFacetedRowModel(), + getFacetedUniqueValues: getFacetedUniqueValues(), + getFilteredRowModel: getFilteredRowModel(), + getGroupedRowModel: getGroupedRowModel(), + getPaginationRowModel: getPaginationRowModel(), + getSortedRowModel: getSortedRowModel(), +}) +``` + +### 自定义/派生行模型 + +你不必使用 TanStack Table 提供的标准行模型。如果需要对某些行模型进行高级定制,可以复制想要定制的行模型的[源代码](https://github.com/TanStack/table/tree/main/packages/table-core/src/utils),然后根据需求修改它。 + +### 使用行模型 + +创建表格实例后,你可以直接从该实例访问所有可能需要行模型。除了已导入的行模型外,还有更多派生行模型可用。 + +对于常规的渲染用例,你可能只需要使用 `table.getRowModel()` 方法,因为这个行模型会根据启用或禁用的功能来使用所有/任何其他行模型。所有其他行模型都可供你“深入”查看表格中发生的一些底层数据转换。 + +### 表格实例上可用的行模型 + +- **`getRowModel`** - 这是渲染表格行标记时应使用的主要行模型。它将使用所有其他行模型来生成最终的行模型,用于渲染表格行。 + +- `getCoreRowModel` - 返回一个基本的行模型,仅与传入表格的原始数据保持 1:1 映射关系。 + +- `getFilteredRowModel` - 返回一个考虑了列筛选和全局筛选的行模型。 +- `getPreFilteredRowModel` - 返回在应用列筛选和全局筛选之前的行模型。 + +- `getGroupedRowModel` - 返回一个应用了分组和聚合数据并创建子行的行模型。 +- `getPreGroupedRowModel` - 返回在应用分组和聚合之前的行模型。 + +- `getSortedRowModel` - 返回一个已应用排序的行模型。 +- `getPreSortedRowModel` - 返回在应用排序之前的行模型(行保持原始顺序)。 + +- `getExpandedRowModel` - 返回一个考虑了展开/隐藏子行的行模型。 +- `getPreExpandedRowModel` - 返回一个仅包含根级别行且不包含展开子行的行模型。但仍然包含排序。 + +- `getPaginationRowModel` - 返回一个仅包含基于分页状态应在当前页显示的行模型。 +- `getPrePaginationRowModel` - 返回一个未应用分页的行模型(包含所有行)。 + +- `getSelectedRowModel` - 返回所有选中行的行模型(但仅基于传入表格的数据)。在 getCoreRowModel 之后运行。 +- `getPreSelectedRowModel` - 返回在应用行选择之前的行模型(仅返回 getCoreRowModel)。 +- `getGroupedSelectedRowModel` - 返回分组后选中行的行模型。在 getSortedRowModel 之后运行,而 getSortedRowModel 在 getGroupedRowModel 之后运行,getGroupedRowModel 又在 getFilteredRowModel 之后运行。 +- `getFilteredSelectedRowModel` - 返回在应用列筛选和全局筛选后选中行的行模型。在 getFilteredRowModel 之后运行。 + +### 行模型的执行顺序 + +了解 TanStack Table 内部如何处理行,可以帮助你更好地理解底层机制,并有助于调试可能遇到的问题。 + +在内部,如果相应功能已启用,行模型将按以下顺序应用到数据: + +`getCoreRowModel` -> `getFilteredRowModel` -> `getGroupedRowModel` -> `getSortedRowModel` -> `getExpandedRowModel` -> `getPaginationRowModel` -> `getRowModel` + +如果任何情况下相应功能被禁用或通过 `"manual*"` 表格选项关闭,则该步骤将改用 `getPre*RowModel`。 + +如上所示,数据首先被筛选,然后分组,接着排序,再展开,最后作为最终步骤进行分页。 + +### 行模型的数据结构 + +每个行模型将以 3 种不同的有用格式提供行数据: + +1. `rows` - 行的数组。 +2. `flatRows` - 行的数组,但所有子行都被展平到顶层。 +3. `rowsById` - 行的对象,其中每行按其 `id` 作为键。这对于通过 `id` 快速查找行非常有用,性能更好。 + +```ts +console.log(table.getRowModel().rows) // 行的数组 +console.log(table.getRowModel().flatRows) // 行的数组,但所有子行被展平到顶层 +console.log(table.getRowModel().rowsById['row-id']) // 行的对象,其中每行按其 `id` 作为键 +``` diff --git a/docs/zh-hans/guide/row-pinning.md b/docs/zh-hans/guide/row-pinning.md new file mode 100644 index 0000000000..53a1b04808 --- /dev/null +++ b/docs/zh-hans/guide/row-pinning.md @@ -0,0 +1,21 @@ +--- +source-updated-at: '2025-03-20T21:15:29.000Z' +translation-updated-at: '2025-05-02T17:23:35.732Z' +title: 行固定 +--- +## 示例 + +想直接查看实现方式?请参考以下示例: + +- [行固定 (row-pinning)](../framework/react/examples/row-pinning) + +## API + +[行固定 API (Row Pinning API)](../api/features/row-pinning) + +## 行固定指南 + +有两种表格功能可以对行进行重新排序,执行顺序如下: + +1. **行固定 (Row Pinning)** - 如果启用了固定功能,行会被分为顶部固定行、中部(未固定)行和底部固定行。 +2. [排序 (Sorting)](../guide/sorting) diff --git a/docs/zh-hans/guide/row-selection.md b/docs/zh-hans/guide/row-selection.md new file mode 100644 index 0000000000..e41c17c577 --- /dev/null +++ b/docs/zh-hans/guide/row-selection.md @@ -0,0 +1,185 @@ +--- +source-updated-at: '2025-03-20T21:15:29.000Z' +translation-updated-at: '2025-05-02T17:24:34.809Z' +title: 行选择 +--- +## 示例 + +想直接查看实现代码?请参考以下示例: + +- [React 行选择](../framework/react/examples/row-selection) +- [Vue 行选择](../framework/vue/examples/row-selection) +- [React 展开行](../framework/react/examples/expanding) + +## API + +[行选择 API](../api/features/row-selection) + +## 行选择指南 + +行选择功能用于跟踪哪些行被选中,并允许通过多种方式切换行的选中状态。下面我们来看一些常见用例。 + +### 访问行选择状态 + +表格实例已自动管理行选择状态(但如下文所示,在自有作用域中管理行选择状态可能更方便)。您可以通过以下 API 访问内部行选择状态或已选中的行: + +- `getState().rowSelection` - 返回内部行选择状态 +- `getSelectedRowModel()` - 返回已选中的行 +- `getFilteredSelectedRowModel()` - 返回筛选后的已选中行 +- `getGroupedSelectedRowModel()` - 返回分组排序后的已选中行 + +```ts +console.log(table.getState().rowSelection) //获取行选择状态 - { 1: true, 2: false, 等等... } +console.log(table.getSelectedRowModel().rows) //获取完整的客户端已选中行 +console.log(table.getFilteredSelectedRowModel().rows) //获取筛选后的客户端已选中行 +console.log(table.getGroupedSelectedRowModel().rows) //获取分组后的客户端已选中行 +``` + +> 注意:如果使用 `manualPagination`,请注意 `getSelectedRowModel` API 仅返回当前页的选中行,因为表格行模型只能基于传入的 `data` 生成行。但行选择状态可以包含不存在于 `data` 数组中的行 ID。 + +### 管理行选择状态 + +虽然表格实例会自动管理行选择状态,但通常更方便的做法是在自有作用域中管理状态,以便轻松访问选中行 ID 用于 API 调用或其他操作。 + +使用 `onRowSelectionChange` 表格选项将行选择状态提升到自有作用域,然后通过 `state` 表格选项将行选择状态传回表格实例。 + +```ts +const [rowSelection, setRowSelection] = useState({}) //在自有作用域管理行选择状态 + +const table = useReactTable({ + //... + onRowSelectionChange: setRowSelection, //将行选择状态提升到自有作用域 + state: { + rowSelection, //将行选择状态传回表格实例 + }, +}) +``` + +### 实用的行 ID + +默认情况下,每行的 ID 就是 `row.index`。如果使用行选择功能,建议使用更有意义的行标识符,因为行选择状态是按行 ID 存储的。可以通过 `getRowId` 表格选项指定返回唯一行 ID 的函数。 + +```ts +const table = useReactTable({ + //... + getRowId: row => row.uuid, //使用数据库中的行 uuid 作为行 ID +}) +``` + +此时选中行的状态会显示为: + +```json +{ + "13e79140-62a8-4f9c-b087-5da737903b76": true, + "f3e2a5c0-5b7a-4d8a-9a5c-9c9b8a8e5f7e": false + //... +} +``` + +而不是: + +```json +{ + "0": true, + "1": false + //... +} +``` + +### 条件启用行选择 + +默认所有行都启用行选择。要通过条件启用某些行的选择或禁用所有行的选择,可以使用 `enableRowSelection` 表格选项,该选项接受布尔值或函数以实现更精细的控制。 + +```ts +const table = useReactTable({ + //... + enableRowSelection: row => row.original.age > 18, //仅对成年人启用行选择 +}) +``` + +要在 UI 中强制控制行是否可选,可以使用 `row.getCanSelect()` API 来设置复选框或其他选择 UI。 + +### 单选行 + +默认情况下,表格允许多选行。如果只需要单选行,可以将 `enableMultiRowSelection` 表格选项设为 `false` 禁用多选,或传入函数条件式禁用行的子行多选。 + +这在需要单选按钮替代复选框的场景中非常有用。 + +```ts +const table = useReactTable({ + //... + enableMultiRowSelection: false, //仅允许单选行 + // enableMultiRowSelection: row => row.original.age > 18, //仅对成年人允许单选行 +}) +``` + +### 子行选择 + +默认选中父行会同时选中其所有子行。如需禁用自动子行选择,可将 `enableSubRowSelection` 表格选项设为 `false`,或传入函数条件式禁用行的子行选择。 + +```ts +const table = useReactTable({ + //... + enableSubRowSelection: false, //禁用子行选择 + // enableSubRowSelection: row => row.original.age > 18, //对成年人禁用子行选择 +}) +``` + +### 渲染行选择 UI + +TanStack Table 不限制行选择 UI 的渲染方式。您可以使用复选框、单选按钮,或直接绑定点击事件到行本身。表格实例提供了一些 API 来帮助渲染行选择 UI。 + +#### 将行选择 API 连接到复选框输入 + +TanStack Table 提供了一些可直接绑定到复选框输入的处理函数,便于切换行选择状态。这些函数会自动调用其他内部 API 来更新行选择状态并重新渲染表格。 + +使用 `row.getToggleSelectedHandler()` API 连接复选框输入来切换行的选中状态。 + +使用 `table.getToggleAllRowsSelectedHandler()` 或 `table.getToggleAllPageRowsSelectedHandler` API 连接"全选"复选框来切换所有行的选中状态。 + +如需更精细控制这些处理函数,可以直接使用 `row.toggleSelected()` 或 `table.toggleAllRowsSelected()` API,甚至直接调用 `table.setRowSelection()` API 来设置行选择状态。这些处理函数仅为便捷方法。 + +```tsx +const columns = [ + { + id: 'select-col', + header: ({ table }) => ( + + ), + cell: ({ row }) => ( + + ), + }, + //... 更多列定义... +] +``` + +#### 将行选择 API 连接到 UI + +如需更简洁的行选择 UI,可以直接绑定点击事件到行本身。`row.getToggleSelectedHandler()` API 也适用于此场景。 + +```tsx + + {table.getRowModel().rows.map(row => { + return ( + + {row.getVisibleCells().map(cell => { + return {/* */} + })} + + ) + })} + +``` diff --git a/docs/zh-hans/guide/rows.md b/docs/zh-hans/guide/rows.md new file mode 100644 index 0000000000..6e24eca354 --- /dev/null +++ b/docs/zh-hans/guide/rows.md @@ -0,0 +1,98 @@ +--- +source-updated-at: '2025-03-20T21:15:29.000Z' +translation-updated-at: '2025-05-02T17:02:36.442Z' +title: 行 +--- +## API + +[行对象 API](../api/core/row) + +## 行对象指南 + +本快速指南将讨论在 TanStack Table 中获取和操作行对象的不同方式。 + +### 获取行对象的途径 + +表格实例提供了多种 API 用于从表实例中检索行对象。 + +#### table.getRow + +如需通过 `id` 访问特定行,可使用 `table.getRow` 表实例 API。 + +```js +const row = table.getRow(rowId) +``` + +#### 行模型 + +表格实例会生成 `row` 对象并将其存储在称为["行模型"](../guide/row-models)的实用数组中。[行模型指南](../guide/row-models)对此有更详细的讨论,以下是访问行模型的常见方式。 + +##### 渲染行对象 + +```jsx + + {table.getRowModel().rows.map(row => ( + + {/* ... */} + + ))} + +``` + +##### 获取选中行 + +```js +const selectedRows = table.getSelectedRowModel().rows +``` + +### 行对象结构 + +每个行对象包含行数据及众多 API,可用于与表格状态交互,或基于表格状态从行中提取单元格数据。 + +#### 行 ID + +每个行对象都有唯一的 `id` 属性。默认情况下 `row.id` 与行模型中创建的 `row.index` 相同。但可以通过原始行数据的唯一标识符覆盖此值,使用 `getRowId` 表格选项实现。 + +```js +const table = useReactTable({ + columns, + data, + getRowId: originalRow => originalRow.uuid, // 用原始行数据的 uuid 覆盖 row.id +}) +``` + +> 注意:在分组或展开等特性中,`row.id` 会被附加额外字符串。 + +#### 访问行数据值 + +推荐使用 `row.getValue` 或 `row.renderValue` API 访问行数据。这两个 API 都会缓存访问器函数结果以保持渲染效率。区别在于:当值为 undefined 时,`row.renderValue` 会返回 `renderFallbackValue`,而 `row.getValue` 会直接返回 undefined。 + +```js +// 从任意列访问数据 +const firstName = row.getValue('firstName') // 读取 firstName 列的行值 +const renderedLastName = row.renderValue('lastName') // 渲染 lastName 列的值 +``` + +> 注意:`cell.getValue` 和 `cell.renderValue` 分别是 `row.getValue` 和 `row.renderValue` 的快捷方式。 + +#### 访问原始行数据 + +通过 `row.original` 属性可访问传入表实例的原始数据。这些数据不会受列定义中访问器的修改影响,因此如果在访问器中进行了数据转换,这些转换不会反映在 `row.original` 对象中。 + +```js +// 访问原始行的任意数据 +const firstName = row.original.firstName // { firstName: 'John', lastName: 'Doe' } +``` + +### 子行对象 + +如果使用分组或展开功能,行对象可能包含子行或父行引用。[展开指南](../guide/expanding)对此有详细说明,以下是处理子行的常用属性和方法: + +- `row.subRows`:该行的子行数组 +- `row.depth`:行相对于根行数组的嵌套深度(0 表示根行,1 表示子行,2 表示孙行等) +- `row.parentId`:该行父行的唯一 ID(即 subRows 数组包含该行的父行) +- `row.getParentRow`:返回该行的父行(如果存在) + +### 更多行对象 API + +根据表格使用的功能特性,还有数十个用于与行交互的实用 API。详见各功能对应的 API 文档或指南。 diff --git a/docs/zh-hans/guide/sorting.md b/docs/zh-hans/guide/sorting.md new file mode 100644 index 0000000000..c277a74a19 --- /dev/null +++ b/docs/zh-hans/guide/sorting.md @@ -0,0 +1,416 @@ +--- +source-updated-at: '2025-03-20T21:15:29.000Z' +translation-updated-at: '2025-05-02T17:26:48.850Z' +title: 排序 +--- +## 示例 + +想直接查看实现代码?请参考以下示例: + +- [排序](../framework/react/examples/sorting) +- [过滤](../framework/react/examples/filters) + +## API + +[排序 API](../api/features/sorting) + +## 排序指南 + +TanStack Table 为几乎所有排序场景提供了解决方案。本指南将介绍如何通过多种选项来自定义内置的客户端排序功能,以及如何选择手动服务端排序而非客户端排序。 + +### 排序状态 + +排序状态定义为包含以下结构的对象数组: + +```tsx +type ColumnSort = { + id: string + desc: boolean +} +type SortingState = ColumnSort[] +``` + +由于排序状态是数组,因此可以同时对多列进行排序。更多关于多列排序的定制选项请参阅[下文](#multi-sorting)。 + +#### 访问排序状态 + +可以通过 `table.getState()` API 直接从表格实例中访问排序状态,就像访问其他状态一样。 + +```tsx +const table = useReactTable({ + columns, + data, + //... +}) + +console.log(table.getState().sorting) // 从表格实例中访问排序状态 +``` + +但如果需要在表格初始化前访问排序状态,可以像下面这样“控制”排序状态。 + +#### 受控排序状态 + +如果需要轻松访问排序状态,可以通过 `state.sorting` 和 `onSortingChange` 表格选项在自有状态管理中控制/管理排序状态。 + +```tsx +const [sorting, setSorting] = useState([]) // 可在此设置初始排序状态 +//... +// 使用排序状态从服务器获取数据或其他操作... +//... +const table = useReactTable({ + columns, + data, + //... + state: { + sorting, + }, + onSortingChange: setSorting, +}) +``` + +#### 初始排序状态 + +如果不需要在自有状态管理或作用域中控制排序状态,但仍希望设置初始排序状态,可以使用 `initialState` 表格选项而非 `state`。 + +```jsx +const table = useReactTable({ + columns, + data, + //... + initialState: { + sorting: [ + { + id: 'name', + desc: true, // 默认按名称降序排序 + }, + ], + }, +}) +``` + +> **注意**:不要同时使用 `initialState.sorting` 和 `state.sorting`,因为 `state.sorting` 中的初始化状态会覆盖 `initialState.sorting`。 + +### 客户端排序与服务端排序 + +是否使用客户端排序或服务端排序完全取决于是否同时使用客户端或服务端分页或过滤。保持一致很重要,因为使用客户端排序与服务端分页或过滤只会对当前加载的数据进行排序,而非整个数据集。 + +### 手动服务端排序 + +如果计划仅在后端逻辑中使用自己的服务端排序,则无需提供排序行模型。但如果已提供排序行模型却希望禁用它,可以使用 `manualSorting` 表格选项。 + +```jsx +const [sorting, setSorting] = useState([]) +//... +const table = useReactTable({ + columns, + data, + getCoreRowModel: getCoreRowModel(), + //getSortedRowModel: getSortedRowModel(), // 手动排序不需要此行 + manualSorting: true, // 使用预排序行模型而非排序行模型 + state: { + sorting, + }, + onSortingChange: setSorting, +}) +``` + +> **注意**:当 `manualSorting` 设为 `true` 时,表格会假设提供的数据已排序,不会对其应用任何排序。 + +### 客户端排序 + +要实现客户端排序,首先需要为表格提供排序行模型。可以从 TanStack Table 导入 `getSortedRowModel` 函数,它将用于将行转换为已排序的行。 + +```jsx +import { useReactTable } from '@tanstack/react-table' +//... +const table = useReactTable({ + columns, + data, + getCoreRowModel: getCoreRowModel(), + getSortedRowModel: getSortedRowModel(), // 提供排序行模型 +}) +``` + +### 排序函数 + +所有列的默认排序函数会根据列的数据类型推断得出。但为特定列定义确切的排序函数非常有用,尤其是当数据可为空或非标准数据类型时。 + +可以通过 `sortingFn` 列选项为每列确定自定义排序函数。 + +默认情况下,有 6 种内置排序函数可选: + +- `alphanumeric` - 不区分大小写地按混合字母数字值排序。速度较慢,但如果字符串包含需要自然排序的数字则更准确。 +- `alphanumericCaseSensitive` - 区分大小写地按混合字母数字值排序。速度较慢,但如果字符串包含需要自然排序的数字则更准确。 +- `text` - 不区分大小写地按文本/字符串值排序。速度较快,但如果字符串包含需要自然排序的数字则准确性较低。 +- `textCaseSensitive` - 区分大小写地按文本/字符串值排序。速度较快,但如果字符串包含需要自然排序的数字则准确性较低。 +- `datetime` - 按时间排序,如果值为 `Date` 对象则使用此函数。 +- `basic` - 使用基本的 `a > b ? 1 : a < b ? -1 : 0` 比较排序。这是最快的排序函数,但准确性可能不高。 + +也可以通过 `sortingFn` 列选项或 `sortingFns` 表格选项定义自定义排序函数。 + +#### 自定义排序函数 + +在 `sortingFns` 表格选项或 `sortingFn` 列选项中定义自定义排序函数时,应具有以下签名: + +```tsx +// 可选使用 SortingFn 推断参数类型 +const myCustomSortingFn: SortingFn = (rowA: Row, rowB: Row, columnId: string) => { + return // -1、0 或 1 - 使用 rowA.original 和 rowB.original 访问任意行数据 +} +``` + +> 注意:比较函数无需考虑列是降序还是升序。行模型会处理该逻辑。`sortingFn` 函数只需提供一致的比较。 + +每个排序函数接收 2 行和列 ID,并应使用列 ID 比较两行,以升序返回 `-1`、`0` 或 `1`。以下是速查表: + +| 返回值 | 升序顺序 | +| ------ | --------------- | +| `-1` | `a < b` | +| `0` | `a === b` | +| `1` | `a > b` | + +```jsx +const columns = [ + { + header: () => '名称', + accessorKey: 'name', + sortingFn: 'alphanumeric', // 按名称使用内置排序函数 + }, + { + header: () => '年龄', + accessorKey: 'age', + sortingFn: 'myCustomSortingFn', // 使用自定义全局排序函数 + }, + { + header: () => '生日', + accessorKey: 'birthday', + sortingFn: 'datetime', // 推荐用于日期列 + }, + { + header: () => '个人资料', + accessorKey: 'profile', + // 直接使用自定义排序函数 + sortingFn: (rowA, rowB, columnId) => { + return rowA.original.someProperty - rowB.original.someProperty + }, + } +] +//... +const table = useReactTable({ + columns, + data, + getCoreRowModel: getCoreRowModel(), + getSortedRowModel: getSortedRowModel(), + sortingFns: { // 添加自定义排序函数 + myCustomSortingFn: (rowA, rowB, columnId) => { + return rowA.original[columnId] > rowB.original[columnId] ? 1 : rowA.original[columnId] < rowB.original[columnId] ? -1 : 0 + }, + }, +}) +``` + +### 自定义排序 + +有许多表格和列选项可用于进一步自定义排序用户体验和行为。 + +#### 禁用排序 + +可以通过 `enableSorting` 列选项或表格选项禁用特定列或整个表格的排序。 + +```jsx +const columns = [ + { + header: () => 'ID', + accessorKey: 'id', + enableSorting: false, // 禁用此列的排序 + }, + { + header: () => '名称', + accessorKey: 'name', + }, + //... +] +//... +const table = useReactTable({ + columns, + data, + enableSorting: false, // 禁用整个表格的排序 +}) +``` + +#### 排序方向 + +默认情况下,使用 `toggleSorting` API 循环切换列的排序方向时,字符串列的第一个排序方向为升序,数字列则为降序。可以通过 `sortDescFirst` 列选项或表格选项更改此行为。 + +```jsx +const columns = [ + { + header: () => '名称', + accessorKey: 'name', + sortDescFirst: true, // 名称列默认先按降序排序(字符串列默认为升序) + }, + { + header: () => '年龄', + accessorKey: 'age', + sortDescFirst: false, // 年龄列默认先按升序排序(数字列默认为降序) + }, + //... +] +//... +const table = useReactTable({ + columns, + data, + sortDescFirst: true, // 所有列默认先按降序排序(字符串列默认为升序,数字列默认为降序) +}) +``` + +> **注意**:对于包含可空值的列,可能需要显式设置 `sortDescFirst` 列选项。如果列包含可空值,表格可能无法正确判断列是数字还是字符串。 + +#### 反转排序 + +反转排序与更改默认排序方向不同。如果列的 `invertSorting` 选项为 `true`,则“降序/升序”排序状态仍会正常循环,但行的实际排序会反转。这对于具有反向优劣比例的值非常有用,例如排名(第一名、第二名、第三名)或类似高尔夫得分的低分最佳情况。 + +```jsx +const columns = [ + { + header: () => '排名', + accessorKey: 'rank', + invertSorting: true, // 反转此列的排序。即使应用“降序”排序,1st -> 2nd -> 3rd -> ... + }, + //... +] +``` + +#### 排序未定义值 + +任何未定义的值会根据 `sortUndefined` 列选项或表格选项排序到列表的开头或末尾。可以根据具体用例自定义此行为。 + +如果未指定,`sortUndefined` 的默认值为 `1`,未定义的值会以较低优先级排序(降序),如果为升序,未定义的值会出现在列表末尾。 + +- `'first'` - 未定义的值会被推到列表开头 +- `'last'` - 未定义的值会被推到列表末尾 +- `false` - 未定义的值会被视为并列,需要由下一个列过滤器或原始索引排序(视情况而定) +- `-1` - 未定义的值会以较高优先级排序(升序)(如果为升序,未定义的值会出现在列表开头) +- `1` - 未定义的值会以较低优先级排序(降序)(如果为升序,未定义的值会出现在列表末尾) + +> 注意:`'first'` 和 `'last'` 选项在 v8.16.0 中新增 + +```jsx +const columns = [ + { + header: () => '排名', + accessorKey: 'rank', + sortUndefined: -1, // 'first' | 'last' | 1 | -1 | false + }, +] +``` + +#### 排序移除 + +默认情况下,在循环切换列的排序状态时允许移除排序。可以通过 `enableSortingRemoval` 表格选项禁用此行为。此行为在希望确保至少有一列始终排序时非常有用。 + +使用 `getToggleSortingHandler` 或 `toggleSorting` API 时的默认行为如下: + +`'none' -> 'desc' -> 'asc' -> 'none' -> 'desc' -> 'asc' -> ...` + +如果禁用排序移除,行为将如下: + +`'none' -> 'desc' -> 'asc' -> 'desc' -> 'asc' -> ...` + +一旦列被排序且 `enableSortingRemoval` 为 `false`,切换该列的排序将永远不会移除排序。但如果用户对另一列排序且非多列排序事件,则前一列的排序会被移除,仅应用于新列。 + +> 将 `enableSortingRemoval` 设为 `false` 可确保至少有一列始终排序。 + +```jsx +const table = useReactTable({ + columns, + data, + enableSortingRemoval: false, // 禁用移除列排序的功能(始终为 none -> asc -> desc -> asc) +}) +``` + +#### 多列排序 + +如果使用 `column.getToggleSortingHandler` API,默认启用同时对多列排序。如果用户在点击列标题时按住 `Shift` 键,表格将对该列以及已排序的其他列进行排序。如果使用 `column.toggleSorting` API,则需要手动传递是否使用多列排序。(`column.toggleSorting(desc, multi)`)。 + +##### 禁用多列排序 + +可以通过 `enableMultiSort` 列选项或表格选项禁用特定列或整个表格的多列排序。禁用特定列的多列排序将用该列的新排序替换所有现有排序。 + +```jsx +const columns = [ + { + header: () => '创建时间', + accessorKey: 'createdAt', + enableMultiSort: false, // 如果对该列排序,则始终仅按该列排序 + }, + //... +] +//... +const table = useReactTable({ + columns, + data, + enableMultiSort: false, // 禁用整个表格的多列排序 +}) +``` + +##### 自定义多列排序触发 + +默认情况下,使用 `Shift` 键触发多列排序。可以通过 `isMultiSortEvent` 表格选项更改此行为。甚至可以通过从自定义函数返回 `true` 来指定所有排序事件都应触发多列排序。 + +```jsx +const table = useReactTable({ + columns, + data, + isMultiSortEvent: (e) => true, // 普通点击触发多列排序 + // 或 + isMultiSortEvent: (e) => e.ctrlKey || e.shiftKey, // 同时使用 `Ctrl` 键触发多列排序 +}) +``` + +##### 多列排序限制 + +默认情况下,可同时排序的列数没有限制。可以通过 `maxMultiSortColCount` 表格选项设置限制。 + +```jsx +const table = useReactTable({ + columns, + data, + maxMultiSortColCount: 3, // 仅允许同时排序 3 列 +}) +``` + +##### 多列排序移除 + +默认情况下,允许移除多列排序。可以通过 `enableMultiRemove` 表格选项禁用此行为。 + +```jsx +const table = useReactTable({ + columns, + data, + enableMultiRemove: false, // 禁用移除多列排序的功能 +}) +``` + +### 排序 API + +有许多与排序相关的 API 可用于连接到用户界面或其他逻辑。以下是所有排序 API 及其部分用例的列表。 + +- `table.setSorting` - 直接设置排序状态。 +- `table.resetSorting` - 将排序状态重置为初始状态或清除。 + +- `column.getCanSort` - 用于启用/禁用列的排序用户界面。 +- `column.getIsSorted` - 用于显示列的视觉排序指示器。 + +- `column.getToggleSortingHandler` - 用于连接列的排序用户界面。可添加到排序箭头(图标按钮)、菜单项或整个列标题单元格。此处理程序会使用正确的参数调用 `column.toggleSorting`。 +- `column.toggleSorting` - 用于连接列的排序用户界面。如果使用此函数而非 `column.getToggleSortingHandler`,则需要手动传递是否使用多列排序。(`column.toggleSorting(desc, multi)`) +- `column.clearSorting` - 用于特定列的“清除排序”按钮或菜单项。 + +- `column.getNextSortingOrder` - 用于显示列下一次排序的方向。(在工具提示/菜单项/aria-label 等中显示 asc/desc/clear) +- `column.getFirstSortDir` - 用于显示列第一次排序的方向。(在工具提示/菜单项/aria-label 等中显示 asc/desc) +- `column.getAutoSortDir` - 确定列的第一次排序方向是升序还是降序。 +- `column.getAutoSortingFn` - 内部用于查找列的默认排序函数(如果未指定)。 +- `column.getSortingFn` - 返回列使用的确切排序函数。 + +- `column.getCanMultiSort` - 用于启用/禁用列的多列排序用户界面。 +- `column.getSortIndex` - 用于在多列排序场景中显示列的排序顺序标记或指示器。例如,它是第一个、第二个、第三个等被排序的列。 diff --git a/docs/zh-hans/guide/tables.md b/docs/zh-hans/guide/tables.md new file mode 100644 index 0000000000..6d665ae18f --- /dev/null +++ b/docs/zh-hans/guide/tables.md @@ -0,0 +1,102 @@ +--- +source-updated-at: '2025-03-20T21:15:29.000Z' +translation-updated-at: '2025-05-02T17:01:10.937Z' +title: 表格实例 +--- +## API + +[表格 API](../api/core/table) + +## 表格实例指南 + +TanStack Table 是一个无头 UI 库。当我们谈论 `table` 或 "表格实例" 时,并不是指字面上的 `` 元素,而是指包含表格状态和 API 的核心表格对象。`table` 实例是通过调用适配器的 `createTable` 函数创建的(例如 `useReactTable`、`useVueTable`、`createSolidTable`、`createSvelteTable`、`createAngularTable`、`useQwikTable`)。 + +从 `createTable` 函数(来自框架适配器)返回的 `table` 实例是您与之交互以读取和变更表格状态的主要对象。它是 TanStack Table 中一切发生的核心。当您开始渲染 UI 时,将使用此 `table` 实例提供的 API。 + +### 创建表格实例 + +创建表格实例需要 3 个必填 `options`:`columns`、`data` 和 `getCoreRowModel` 实现。虽然还有数十种其他表格选项可用于配置功能和行为,但这 3 项是必需的。 + +#### 定义数据 + +将数据定义为具有稳定引用的对象数组。`data` 可以来自 API 响应或静态定义的代码,但必须保持引用稳定以避免无限重新渲染。如果使用 TypeScript,您为数据指定的类型将作为 `TData` 泛型使用。更多信息请参阅[数据指南](../guide/data)。 + +#### 定义列 + +列定义在前文的[列定义指南](../guide/column-defs)中有详细说明。这里需要特别注意的是,定义列类型时应使用与数据相同的 `TData` 类型。 + +```ts +const columns: ColumnDef[] = [] //将 User 类型作为泛型 TData 类型传入 +//或 +const columnHelper = createColumnHelper() //将 User 类型作为泛型 TData 类型传入 +``` + +列定义中通过 `accessorKey` 或 `accessorFn` 指定每列如何访问和/或转换行数据。详情参见[列定义指南](../guide/column-defs#creating-accessor-columns)。 + +#### 传入行模型 + +[行模型指南](../guide/row-models)对此有更详细的解释。目前只需从 TanStack Table 导入 `getCoreRowModel` 函数并将其作为表格选项传入即可。根据您计划使用的功能,后续可能需要传入其他行模型。 + +```ts +import { getCoreRowModel } from '@tanstack/[framework]-table' + +const table = createTable({ columns, data, getCoreRowModel: getCoreRowModel() }) +``` + +#### 初始化表格实例 + +定义好 `columns`、`data` 和 `getCoreRowModel` 后,现在可以创建基础表格实例,同时传入其他所需的表格选项。 + +```ts +//原生 JS +const table = createTable({ columns, data, getCoreRowModel: getCoreRowModel() }) + +//Angular +this.table = createAngularTable({ columns: this.columns, data: this.data(), getCoreRowModel: getCoreRowModel() }) + +//Lit +const table = this.tableController.table({ columns, data, getCoreRowModel: getCoreRowModel() }) + +//Qwik +const table = useQwikTable({ columns, data, getCoreRowModel: getCoreRowModel() }) + +//React +const table = useReactTable({ columns, data, getCoreRowModel: getCoreRowModel() }) + +//Solid +const table = createSolidTable({ columns, get data() { return data() }, getCoreRowModel: getCoreRowModel() }) + +//Svelte +const table = createSvelteTable({ columns, data, getCoreRowModel: getCoreRowModel() }) + +//Vue +const table = useVueTable({ columns, data, getCoreRowModel: getCoreRowModel() }) +``` + +`table` 实例包含哪些内容?让我们看看可以与表格实例进行哪些交互。 + +### 表格状态 + +表格实例包含所有表格状态,可通过 `table.getState()` API 访问。每个表格功能会在表格状态中注册各种状态。例如,行选择功能注册 `rowSelection` 状态,分页功能注册 `pagination` 状态等。 + +每个功能还会在表格实例上提供对应的状态设置 API 和状态重置 API。例如,行选择功能会有 `setRowSelection` API 和 `resetRowSelection`。 + +```ts +table.getState().rowSelection //读取行选择状态 +table.setRowSelection((old) => ({...old})) //设置行选择状态 +table.resetRowSelection() //重置行选择状态 +``` + +更多细节请参阅[表格状态指南](../framework/react/guide/table-state) + +### 表格 API + +每个功能都会创建数十个表格 API,帮助您以不同方式读取或变更表格状态。 + +核心表格实例及所有其他功能 API 的参考文档可在 API 文档各处找到。 + +例如,核心表格实例 API 文档在此:[表格 API](../api/core/table#table-api) + +### 表格行模型 + +表格实例有一组特殊的 API 用于读取行数据,称为行模型。TanStack Table 的高级功能可能导致生成的行与最初传入的 `data` 数组有很大差异。要了解可以作为表格选项传入的不同行模型,请参阅[行模型指南](../guide/row-models)。 diff --git a/docs/zh-hans/guide/virtualization.md b/docs/zh-hans/guide/virtualization.md new file mode 100644 index 0000000000..642ba92508 --- /dev/null +++ b/docs/zh-hans/guide/virtualization.md @@ -0,0 +1,21 @@ +--- +source-updated-at: '2025-03-20T21:15:29.000Z' +translation-updated-at: '2025-05-02T17:27:01.269Z' +title: 虚拟化 +--- +## 示例 + +想直接查看实现代码?请参考以下示例: + +- [虚拟化列 (virtualized-columns)](../framework/react/examples/virtualized-columns) +- [虚拟化行 (动态行高) (virtualized-rows (dynamic row height))](../framework/react/examples/virtualized-rows) +- [虚拟化行 (固定行高) (virtualized-rows (fixed row height))](../../../../virtual/v3/docs/framework/react/examples/table) +- [虚拟化无限滚动 (virtualized-infinite-scrolling)](../framework/react/examples/virtualized-infinite-scrolling) + +## API + +[TanStack Virtual 虚拟化器 API (TanStack Virtual Virtualizer API)](../../../../virtual/v3/docs/api/virtualizer) + +## 虚拟化指南 + +TanStack Table 的核心包并未内置任何虚拟化 API 或功能,但可以轻松与其他虚拟化库如 [react-window](https://www.npmjs.com/package/react-window) 或 TanStack 自家的 [TanStack Virtual](https://tanstack.com/virtual/v3) 协同工作。本指南将展示 TanStack Table 与 TanStack Virtual 配合使用的几种策略。 diff --git a/docs/zh-hans/installation.md b/docs/zh-hans/installation.md new file mode 100644 index 0000000000..bcd1f1e764 --- /dev/null +++ b/docs/zh-hans/installation.md @@ -0,0 +1,82 @@ +--- +source-updated-at: '2024-05-19T21:37:34.000Z' +translation-updated-at: '2025-05-02T16:54:22.010Z' +title: 安装 +--- +在深入探索 API 之前,让我们先完成环境配置! + +使用你喜欢的 npm 包管理器安装表格适配器作为依赖项。 + +_只需安装以下其中一个包:_ + +## React Table + +```bash +npm install @tanstack/react-table +``` + +`@tanstack/react-table` 包兼容 React 16.8、React 17、React 18 和 React 19。 + +> 注意:尽管 React 适配器支持 React 19,但它可能无法与即将随 React 19 发布的新 React 编译器 (React Compiler) 兼容。此问题可能会在未来的 TanStack Table 更新中修复。 + +## Vue Table + +```bash +npm install @tanstack/vue-table +``` + +`@tanstack/vue-table` 包兼容 Vue 3。 + +## Solid Table + +```bash +npm install @tanstack/solid-table +``` + +`@tanstack/solid-table` 包兼容 Solid-JS 1。 + +## Svelte Table + +```bash +npm install @tanstack/svelte-table +``` + +`@tanstack/svelte-table` 包兼容 Svelte 3 和 Svelte 4。 + +> 注意:目前尚未内置 Svelte 5 适配器,但你仍可通过安装 `@tanstack/table-core` 包并使用社区提供的自定义适配器,在 Svelte 5 中使用 TanStack Table。可参考此 [PR](https://github.com/TanStack/table/pull/5403) 获取灵感。 + +## Qwik Table + +```bash +npm install @tanstack/qwik-table +``` + +`@tanstack/qwik-table` 包兼容 Qwik 1。 + +> 注意:未来将发布一个支持 Qwik 2 的“破坏性变更”版本。该版本将以次版本号升级的形式发布,但会提供详细文档。Qwik 2 本身不会有破坏性变更,但其在 npm 注册表中的名称将更改,并需要不同的 peer 依赖项。 + +> 注意:当前的 Qwik 适配器仅支持客户端渲染 (CSR)。更多改进可能需要等待未来版本的表格库。 + +## Angular Table + +```bash +npm install @tanstack/angular-table +``` + +`@tanstack/angular-table` 包兼容 Angular 17。Angular 适配器采用了新的 Angular 信号 (Signal) 实现。 + +## Lit Table + +```bash +npm install @tanstack/lit-table +``` + +`@tanstack/lit-table` 包兼容 Lit 3。 + +## Table Core (无框架版本) + +```bash +npm install @tanstack/table-core +``` + +没有找到你喜欢的框架(或框架版本)?你始终可以直接使用 `@tanstack/table-core` 包,并在自己的代码库中构建适配器。通常只需一个轻量封装来管理特定框架的状态和渲染逻辑。浏览其他所有适配器的 [源代码](https://github.com/TanStack/table/tree/main/packages) 了解其实现方式。 diff --git a/docs/zh-hans/introduction.md b/docs/zh-hans/introduction.md new file mode 100644 index 0000000000..5715294f44 --- /dev/null +++ b/docs/zh-hans/introduction.md @@ -0,0 +1,70 @@ +--- +source-updated-at: '2024-03-22T01:02:38.000Z' +translation-updated-at: '2025-05-02T15:29:27.873Z' +title: 简介 +--- +TanStack Table 是一个 **无头 UI (Headless UI)** 库,用于为 TS/JS、React、Vue、Solid、Qwik 和 Svelte 构建强大的表格和数据网格。 + +## 什么是“无头”UI? + +**无头 UI (Headless UI)** 是指那些提供 UI 元素和交互逻辑、状态、处理及 API,但**不提供标记、样式或预构建实现**的库和工具。感到困惑了吗?😉 无头 UI 有几个主要目标: + +构建复杂 UI 最困难的部分通常围绕状态、事件、副作用、数据计算/管理展开。通过将这些关注点与标记、样式和实现细节分离,我们的逻辑和组件可以更加模块化和可复用。 + +UI 构建是一种高度品牌化和定制化的体验,即使这意味着选择设计系统或遵循设计规范。为了支持这种定制化体验,基于组件的 UI 库需要围绕标记和样式定制提供庞大(且看似无止境)的 API 表面。无头 UI 库将逻辑与 UI 解耦。 + +当你使用无头 UI 库时,**数据处理、状态管理和业务逻辑**等复杂任务会被自动处理,让你可以专注于不同实现和用例中更高维度的决策。 + +> 想深入了解?[阅读更多关于无头 UI 的内容](https://www.merrickchristensen.com/articles/headless-user-interface-components/)。 + +## 基于组件的库 vs 无头库 + +在表格/数据网格库的生态系统中,主要有两类: + +- 基于组件的表格库 +- 无头表格库 + +### 我应该使用哪种表格库? + +每种方法都有微妙的权衡。理解这些细微差别将帮助你为应用和团队做出正确决策。 + +### 基于组件的表格库 + +基于组件的表格库通常会提供一个功能丰富的即插即用解决方案,以及带有样式/主题的现成组件和标记。[AG Grid](https://ag-grid.com/react-data-grid/?utm_source=reacttable&utm_campaign=githubreacttable) 是这类表格库的绝佳示例。 + +**优点:** + +- 提供现成的标记/样式 +- 设置简单 +- 开箱即用的体验 + +**缺点:** + +- 对标记的控制较少 +- 自定义样式通常基于主题 +- 较大的包体积 +- 高度依赖框架适配器和平台 + +**如果你需要一个现成的表格,并且设计/包体积不是硬性要求**,那么你应该考虑使用基于组件的表格库。 + +市面上有许多基于组件的表格库,但我们认为 [AG Grid](https://ag-grid.com/react-data-grid/?utm_source=reacttable&utm_campaign=githubreacttable) 是黄金标准,也是我们最喜欢的网格兄弟(别告诉其他人 🤫)。 + +### 无头表格库 + +无头表格库通常会提供函数、状态、工具和事件监听器,用于构建自己的表格标记或附加到现有表格标记上。 + +**优点:** + +- 完全控制标记和样式 +- 支持所有样式模式(CSS、CSS-in-JS、UI 库等) +- 更小的包体积 +- 可移植。能在任何运行 JS 的地方使用! + +**缺点:** + +- 需要更多设置 +- 不提供标记、样式或主题 + +**如果你想要一个更轻量级的表格或对设计有完全控制权**,那么你应该考虑使用无头表格库。 + +市面上无头表格库非常少,显然,**TanStack Table** 是我们的最爱! diff --git a/docs/zh-hans/overview.md b/docs/zh-hans/overview.md new file mode 100644 index 0000000000..5990c1e2c5 --- /dev/null +++ b/docs/zh-hans/overview.md @@ -0,0 +1,64 @@ +--- +source-updated-at: '2024-05-12T19:19:51.000Z' +translation-updated-at: '2025-05-02T15:31:44.246Z' +title: 概述 +--- +TanStack Table 的核心是 **框架无关 (framework agnostic)** 的,这意味着无论您使用何种框架,其 API 都保持一致。根据您使用的框架,我们提供了适配器 (Adapters) 来简化与表格核心的交互。请参阅 Adapters 菜单了解可用的适配器。 + +## TypeScript + +虽然 TanStack Table 使用 [TypeScript](https://www.typescriptlang.org/) 编写,但在您的应用程序中使用 TypeScript 是可选的(但强烈推荐,因为它能为您和代码库带来显著优势)。 + +如果您使用 TypeScript,您将获得顶级的类型安全性和编辑器自动补全功能,适用于所有表格 API 和状态。 + +## 无头设计 (Headless) + +正如在[介绍](../introduction)部分中广泛提到的,TanStack Table 是 **无头 (headless)** 的。这意味着它不会渲染任何 DOM 元素,而是依赖于您——UI/UX 开发者——来提供表格的标记和样式。这是一种构建可在任何 UI 框架中使用的表格的绝佳方式,包括 React、Vue、Solid、Svelte、Qwik、Angular,甚至像 React Native 这样的 JS 到原生平台! + +## 无关性 (Agnostic) + +由于 TanStack Table 是无头的,并且运行在原生 JavaScript 核心上,它在几个方面具有无关性: + +1. TanStack Table 是 **框架无关 (Framework Agnostic)** 的,这意味着您可以将其与任何您想要的 JavaScript 框架(或库)一起使用。TanStack Table 提供了开箱即用的适配器,支持 React、Vue、Solid、Svelte 和 Qwik,但您也可以根据需要创建自己的适配器。 +2. TanStack Table 是 **CSS / 组件库无关 (CSS / Component Library Agnostic)** 的,这意味着您可以将其与任何 CSS 策略或组件库一起使用。TanStack Table 本身不会渲染任何表格标记或样式。您需要自己提供!想使用 Tailwind 或 ShadCN?没问题!想使用 Material UI 或 Bootstrap?也没问题!有自己的自定义设计系统?TanStack Table 就是为您而设计的! + +## 核心对象与类型 + +表格核心使用以下抽象概念,通常由适配器暴露: + +- [数据 (Data)](../guide/data) - 您提供给表格的核心数据数组 +- [列定义 (Column Defs)](../guide/column-defs):用于配置列及其数据模型、显示模板等的对象 +- [表格实例 (Table Instance)](../guide/tables):包含状态和 API 的核心表格对象 +- [行模型 (Row Models)](../guide/row-models):根据您使用的功能,将 `data` 数组转换为有用的行的方式 +- [行 (Rows)](../guide/rows):每行镜像其对应的行数据,并提供行特定的 API +- [单元格 (Cells)](../guide/cells):每个单元格镜像其对应的行-列交集,并提供单元格特定的 API +- [表头组 (Header Groups)](../guide/header-groups):表头组是嵌套表头级别的计算切片,每组包含一组表头 +- [表头 (Headers)](../guide/headers):每个表头直接关联或派生自其列定义,并提供表头特定的 API +- [列 (Columns)](../guide/columns):每列镜像其对应的列定义,并提供列特定的 API + +## 功能 + +TanStack Table 可以帮助您构建几乎任何类型的表格。它为以下功能提供了内置的状态和 API: + +- [列分面 (Column Faceting)](../guide/column-faceting) - 列出列的唯一值列表或列的最小/最大值 +- [列过滤 (Column Filtering)](../guide/column-filtering) - 根据列的搜索值过滤行 +- [列分组 (Column Grouping)](../guide/grouping) - 将列分组、运行聚合等 +- [列排序 (Column Ordering)](../guide/column-ordering) - 动态更改列的顺序 +- [列固定 (Column Pinning)](../guide/column-pinning) - 将列固定在表格的左侧或右侧 +- [列尺寸调整 (Column Sizing)](../guide/column-sizing) - 动态调整列的尺寸(列调整手柄) +- [列可见性 (Column Visibility)](../guide/column-visibility) - 显示/隐藏列 +- [全局分面 (Global Faceting)](../guide/global-faceting) - 列出整个表格的唯一值列表或最小/最大值 +- [全局过滤 (Global Filtering)](../guide/global-filtering) - 根据整个表格的搜索值过滤行 +- [行展开 (Row Expanding)](../guide/expanding) - 展开/折叠行(子行) +- [行分页 (Row Pagination)](../guide/pagination) - 对行进行分页 +- [行固定 (Row Pinning)](../guide/row-pinning) - 将行固定在表格的顶部或底部 +- [行选择 (Row Selection)](../guide/row-selection) - 选择/取消选择行(复选框) +- [行排序 (Row Sorting)](../guide/sorting) - 按列值对行排序 + +这些只是您可以使用 TanStack Table 构建的部分功能。还有许多其他功能可以通过内置功能之外的扩展实现。 + +[虚拟化 (Virtualization)](../guide/virtualization) 是一个未内置到 TanStack Table 中的功能示例,但可以通过使用其他库(如 [TanStack Virtual](https://tanstack.com/virtual/v3))并结合其他表格渲染逻辑来实现。 + +TanStack Table 还支持[自定义功能 (Custom Features)](../guide/custom-features)(插件),您可以使用这些功能修改表格实例,以更集成的方式向表格添加自定义逻辑。 + +当然,您也可以编写自己的状态和钩子来为表格添加任何其他功能。TanStack Table 核心的功能只是一个坚实的基础,重点关注性能和开发者体验 (DX)。 diff --git a/docs/zh-hans/vanilla.md b/docs/zh-hans/vanilla.md new file mode 100644 index 0000000000..25256b6ff7 --- /dev/null +++ b/docs/zh-hans/vanilla.md @@ -0,0 +1,16 @@ +--- +source-updated-at: '2024-01-24T21:39:34.000Z' +translation-updated-at: '2025-05-02T16:53:59.912Z' +title: 原生 JS (无框架) +--- +`@tanstack/table-core` 库包含了 TanStack Table 的核心逻辑。如果您使用的是非标准框架或无法使用框架,可以直接通过 TypeScript 或 JavaScript 使用核心库。 + +## `createTable` + +接收一个 `options` 对象并返回一个表格实例。 + +```tsx +import { createTable } from '@tanstack/table-core' + +const table = createTable(options) +``` diff --git a/docs/zh-hant/config.json b/docs/zh-hant/config.json new file mode 100644 index 0000000000..b2b860eed1 --- /dev/null +++ b/docs/zh-hant/config.json @@ -0,0 +1,790 @@ +{ + "$schema": "https://raw.githubusercontent.com/TanStack/tanstack.com/main/tanstack-docs-config.schema.json", + "docSearch": { + "appId": "74SF5EKVW9", + "apiKey": "9fc015a3310be6669ed66c6c459f319f", + "indexName": "tanstack-table" + }, + "sections": [ + { + "label": "入門指南", + "children": [ + { + "label": "簡介", + "to": "introduction" + }, + { + "label": "概述", + "to": "overview" + }, + { + "label": "安裝", + "to": "installation" + }, + { + "label": "遷移至 V8", + "to": "guide/migrating" + }, + { + "label": "常見問題", + "to": "faq" + } + ], + "frameworks": [ + { + "label": "angular", + "children": [ + { + "label": "Angular 表格適配器", + "to": "framework/angular/angular-table" + } + ] + }, + { + "label": "lit", + "children": [ + { + "label": "Lit 表格適配器", + "to": "framework/lit/lit-table" + } + ] + }, + { + "label": "qwik", + "children": [ + { + "label": "Qwik 表格適配器", + "to": "framework/qwik/qwik-table" + } + ] + }, + { + "label": "react", + "children": [ + { + "label": "React 表格適配器", + "to": "framework/react/react-table" + } + ] + }, + { + "label": "solid", + "children": [ + { + "label": "Solid 表格適配器", + "to": "framework/solid/solid-table" + } + ] + }, + { + "label": "svelte", + "children": [ + { + "label": "Svelte 表格適配器", + "to": "framework/svelte/svelte-table" + } + ] + }, + { + "label": "vue", + "children": [ + { + "label": "Vue 表格適配器", + "to": "framework/vue/vue-table" + } + ] + }, + { + "label": "vanilla", + "children": [ + { + "label": "Vanilla JS (無框架)", + "to": "vanilla" + } + ] + } + ] + }, + { + "label": "核心指南", + "children": [ + { + "label": "資料", + "to": "guide/data" + }, + { + "label": "欄位定義", + "to": "guide/column-defs" + }, + { + "label": "表格實例", + "to": "guide/tables" + }, + { + "label": "行模型", + "to": "guide/row-models" + }, + { + "label": "行", + "to": "guide/rows" + }, + { + "label": "儲存格", + "to": "guide/cells" + }, + { + "label": "標題群組", + "to": "guide/header-groups" + }, + { + "label": "標題", + "to": "guide/headers" + }, + { + "label": "欄位", + "to": "guide/columns" + } + ], + "frameworks": [ + { + "label": "angular", + "children": [ + { + "label": "表格狀態", + "to": "framework/angular/guide/table-state" + } + ] + }, + { + "label": "lit", + "children": [ + { + "label": "表格狀態", + "to": "framework/lit/guide/table-state" + } + ] + }, + { + "label": "qwik", + "children": [ + { + "label": "表格狀態", + "to": "framework/qwik/guide/table-state" + } + ] + }, + { + "label": "react", + "children": [ + { + "label": "表格狀態", + "to": "framework/react/guide/table-state" + } + ] + }, + { + "label": "solid", + "children": [ + { + "label": "表格狀態", + "to": "framework/solid/guide/table-state" + } + ] + }, + { + "label": "svelte", + "children": [ + { + "label": "表格狀態", + "to": "framework/svelte/guide/table-state" + } + ] + }, + { + "label": "vue", + "children": [ + { + "label": "表格狀態", + "to": "framework/vue/guide/table-state" + } + ] + }, + { + "label": "vanilla", + "children": [ + { + "label": "表格狀態", + "to": "framework/vanilla/guide/table-state" + } + ] + } + ] + }, + { + "label": "功能指南", + "children": [ + { + "label": "欄位排序", + "to": "guide/column-ordering" + }, + { + "label": "欄位固定", + "to": "guide/column-pinning" + }, + { + "label": "欄位調整大小", + "to": "guide/column-sizing" + }, + { + "label": "欄位可見性", + "to": "guide/column-visibility" + }, + { + "label": "欄位過濾", + "to": "guide/column-filtering" + }, + { + "label": "全域過濾", + "to": "guide/global-filtering" + }, + { + "label": "模糊過濾", + "to": "guide/fuzzy-filtering" + }, + { + "label": "欄位面向", + "to": "guide/column-faceting" + }, + { + "label": "全域面向", + "to": "guide/global-faceting" + }, + { + "label": "分組", + "to": "guide/grouping" + }, + { + "label": "展開", + "to": "guide/expanding" + }, + { + "label": "分頁", + "to": "guide/pagination" + }, + { + "label": "行固定", + "to": "guide/row-pinning" + }, + { + "label": "行選擇", + "to": "guide/row-selection" + }, + { + "label": "排序", + "to": "guide/sorting" + }, + { + "label": "虛擬化", + "to": "guide/virtualization" + }, + { + "label": "自訂功能", + "to": "guide/custom-features" + } + ] + }, + { + "label": "核心 API", + "children": [ + { + "label": "欄位定義", + "to": "api/core/column-def" + }, + { + "label": "表格", + "to": "api/core/table" + }, + { + "label": "欄位", + "to": "api/core/column" + }, + { + "label": "標題群組", + "to": "api/core/header-group" + }, + { + "label": "標題", + "to": "api/core/header" + }, + { + "label": "行", + "to": "api/core/row" + }, + { + "label": "儲存格", + "to": "api/core/cell" + } + ] + }, + { + "label": "功能 API", + "children": [ + { + "label": "欄位過濾", + "to": "api/features/column-filtering" + }, + { + "label": "欄位面向", + "to": "api/features/column-faceting" + }, + { + "label": "欄位排序", + "to": "api/features/column-ordering" + }, + { + "label": "欄位固定", + "to": "api/features/column-pinning" + }, + { + "label": "欄位調整大小", + "to": "api/features/column-sizing" + }, + { + "label": "欄位可見性", + "to": "api/features/column-visibility" + }, + { + "label": "全域面向", + "to": "api/features/global-faceting" + }, + { + "label": "全域過濾", + "to": "api/features/global-filtering" + }, + { + "label": "排序", + "to": "api/features/sorting" + }, + { + "label": "分組", + "to": "api/features/grouping" + }, + { + "label": "展開", + "to": "api/features/expanding" + }, + { + "label": "分頁", + "to": "api/features/pagination" + }, + { + "label": "行固定", + "to": "api/features/row-pinning" + }, + { + "label": "行選擇", + "to": "api/features/row-selection" + } + ] + }, + { + "label": "企業版", + "children": [ + { + "label": "AG Grid", + "to": "enterprise/ag-grid" + } + ] + }, + { + "label": "範例", + "children": [], + "frameworks": [ + { + "label": "angular", + "children": [ + { + "to": "framework/angular/examples/basic", + "label": "基礎" + }, + { + "to": "framework/angular/examples/grouping", + "label": "欄位分組" + }, + { + "to": "framework/angular/examples/column-ordering", + "label": "欄位排序" + }, + { + "to": "framework/angular/examples/column-pinning", + "label": "欄位固定" + }, + { + "to": "framework/angular/examples/column-pinning-sticky", + "label": "黏性欄位固定" + }, + { + "to": "framework/angular/examples/column-visibility", + "label": "欄位可見性" + }, + { + "to": "framework/angular/examples/filters", + "label": "欄位過濾器" + }, + { + "to": "framework/angular/examples/row-selection", + "label": "行選擇" + }, + { + "to": "framework/angular/examples/expanding", + "label": "展開" + }, + { + "to": "framework/angular/examples/sub-components", + "label": "子元件" + }, + { + "to": "framework/angular/examples/signal-input", + "label": "訊號輸入" + }, + { + "to": "framework/angular/examples/editable", + "label": "可編輯資料" + }, + { + "to": "framework/angular/examples/row-dnd", + "label": "行拖放" + }, + { + "to": "framework/angular/examples/column-resizing-performant", + "label": "高效欄位調整大小" + } + ] + }, + { + "label": "lit", + "children": [ + { + "to": "framework/lit/examples/basic", + "label": "基礎" + }, + { + "to": "framework/lit/examples/column-sizing", + "label": "欄位調整大小" + }, + { + "to": "framework/lit/examples/filters", + "label": "過濾器" + }, + { + "to": "framework/lit/examples/row-selection", + "label": "行選擇" + }, + { + "to": "framework/lit/examples/sorting", + "label": "排序" + }, + { + "to": "framework/lit/examples/virtualized-rows", + "label": "虛擬化行" + } + ] + }, + { + "label": "qwik", + "children": [ + { + "to": "framework/qwik/examples/basic", + "label": "基礎" + }, + { + "to": "framework/qwik/examples/filters", + "label": "過濾器" + }, + { + "to": "framework/qwik/examples/row-selection", + "label": "行選擇" + }, + { + "to": "framework/qwik/examples/sorting", + "label": "排序" + } + ] + }, + { + "label": "react", + "children": [ + { + "to": "framework/react/examples/basic", + "label": "基礎" + }, + { + "to": "framework/react/examples/column-groups", + "label": "標題群組" + }, + { + "to": "framework/react/examples/filters", + "label": "欄位過濾器" + }, + { + "to": "framework/react/examples/filters-faceted", + "label": "欄位過濾器 (面向)" + }, + { + "to": "framework/react/examples/filters-fuzzy", + "label": "模糊搜尋過濾器" + }, + { + "to": "framework/react/examples/column-ordering", + "label": "欄位排序" + }, + { + "to": "framework/react/examples/column-dnd", + "label": "欄位排序 (拖放)" + }, + { + "to": "framework/react/examples/column-pinning", + "label": "欄位固定" + }, + { + "to": "framework/react/examples/column-pinning-sticky", + "label": "黏性欄位固定" + }, + { + "to": "framework/react/examples/column-sizing", + "label": "欄位調整大小" + }, + { + "to": "framework/react/examples/column-resizing-performant", + "label": "高效欄位調整大小" + }, + { + "to": "framework/react/examples/column-visibility", + "label": "欄位可見性" + }, + { + "to": "framework/react/examples/editable-data", + "label": "可編輯資料" + }, + { + "to": "framework/react/examples/expanding", + "label": "展開" + }, + { + "to": "framework/react/examples/sub-components", + "label": "子元件" + }, + { + "to": "framework/react/examples/fully-controlled", + "label": "完全控制" + }, + { + "to": "framework/react/examples/grouping", + "label": "分組" + }, + { + "to": "framework/react/examples/pagination", + "label": "分頁" + }, + { + "to": "framework/react/examples/pagination-controlled", + "label": "分頁控制" + }, + { + "to": "framework/react/examples/row-dnd", + "label": "行拖放" + }, + { + "to": "framework/react/examples/row-pinning", + "label": "行固定" + }, + { + "to": "framework/react/examples/row-selection", + "label": "行選擇" + }, + { + "to": "framework/react/examples/sorting", + "label": "排序" + }, + { + "to": "framework/react/examples/virtualized-columns", + "label": "虛擬化欄位" + }, + { + "to": "framework/react/examples/virtualized-columns-experimental", + "label": "虛擬化欄位 (實驗性)" + }, + { + "to": "framework/react/examples/virtualized-rows", + "label": "虛擬化行" + }, + { + "to": "framework/react/examples/virtualized-rows-experimental", + "label": "虛擬化行 (實驗性)" + }, + { + "to": "framework/react/examples/virtualized-infinite-scrolling", + "label": "虛擬化無限滾動" + }, + { + "to": "framework/react/examples/kitchen-sink", + "label": "綜合範例" + }, + { + "to": "framework/react/examples/bootstrap", + "label": "React Bootstrap" + }, + { + "to": "framework/react/examples/material-ui-pagination", + "label": "Material UI 分頁" + }, + { + "to": "framework/react/examples/full-width-table", + "label": "React 全寬度" + }, + { + "to": "framework/react/examples/full-width-resizable-table", + "label": "React 全寬度可調整大小" + }, + { + "to": "framework/react/examples/custom-features", + "label": "自訂功能" + }, + { + "to": "framework/react/examples/query-router-search-params", + "label": "查詢路由搜尋參數" + } + ] + }, + { + "label": "solid", + "children": [ + { + "to": "framework/solid/examples/basic", + "label": "基礎" + }, + { + "to": "framework/solid/examples/column-groups", + "label": "欄位群組" + }, + { + "to": "framework/solid/examples/column-ordering", + "label": "欄位排序" + }, + { + "to": "framework/solid/examples/column-visibility", + "label": "欄位可見性" + }, + { + "to": "framework/solid/examples/filters", + "label": "過濾器" + }, + { + "to": "framework/solid/examples/sorting", + "label": "排序" + }, + { + "to": "framework/solid/examples/bootstrap", + "label": "Solid Bootstrap" + } + ] + }, + { + "label": "svelte", + "children": [ + { + "to": "framework/svelte/examples/basic", + "label": "基礎" + }, + { + "to": "framework/svelte/examples/column-groups", + "label": "欄位群組" + }, + { + "to": "framework/svelte/examples/column-ordering", + "label": "欄位排序" + }, + { + "to": "framework/svelte/examples/column-pinning", + "label": "欄位固定" + }, + { + "to": "framework/svelte/examples/column-visibility", + "label": "欄位可見性" + }, + { + "to": "framework/svelte/examples/filtering", + "label": "過濾" + }, + { + "to": "framework/svelte/examples/sorting", + "label": "排序" + } + ] + }, + { + "label": "vue", + "children": [ + { + "to": "framework/vue/examples/basic", + "label": "基礎" + }, + { + "to": "framework/vue/examples/column-ordering", + "label": "欄位排序" + }, + { + "to": "framework/vue/examples/column-pinning", + "label": "欄位固定" + }, + { + "to": "framework/vue/examples/pagination", + "label": "分頁" + }, + { + "to": "framework/vue/examples/row-selection", + "label": "行選擇" + }, + { + "to": "framework/vue/examples/sorting", + "label": "排序" + }, + { + "to": "framework/vue/examples/sub-components", + "label": "子元件" + }, + { + "to": "framework/vue/examples/filters", + "label": "欄位過濾器" + }, + { + "to": "framework/vue/examples/virtualized-rows", + "label": "虛擬化行" + }, + { + "to": "framework/vue/examples/grouping", + "label": "分組" + } + ] + }, + { + "label": "vanilla", + "children": [ + { + "to": "framework/vanilla/examples/basic", + "label": "基礎" + }, + { + "to": "framework/vanilla/examples/pagination", + "label": "分頁" + }, + { + "to": "framework/vanilla/examples/sorting", + "label": "排序" + } + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/translation.config.mjs b/translation.config.mjs new file mode 100644 index 0000000000..7046d03288 --- /dev/null +++ b/translation.config.mjs @@ -0,0 +1,102 @@ +export default { + langs: { + 'zh-Hans': { + code: 'zh-Hans', + name: 'Simplified Chinese', + // 翻译规则和指南 + guide: ` + - For technical terms that should not be fully translated, use the format: "中文翻译 (English term)" + Example: "服务端渲染 (SSR)" instead of just "SSR" or just "服务端渲染" + - Add a space between Chinese characters and English words/symbols to improve readability + - Maintain consistent translations for common terms across the entire document +`, + // 常见技术术语翻译词典 + // 格式: 'English term': '中文翻译' + terms: {}, + }, + 'zh-Hant': { + code: 'zh-Hant', + name: 'Traditional Chinese', + // 翻譯規則和指南 + guide: ` + - For technical terms that should not be fully translated, use the format: "繁體中文翻譯 (English term)" + Example: "伺服器渲染 (SSR)" instead of just "SSR" or just "伺服器渲染" + - Add a space between Chinese characters and English words/symbols to improve readability + - Maintain consistent translations for common terms across the entire document +`, + // 常見技術術語翻譯詞典 + // 格式: 'English term': '繁體中文翻譯' + terms: {}, + }, + ja: { + code: 'ja', + name: 'Japanese', + guide: ` + - For technical terms that should not be fully translated, use the format: "日本語訳 (English term)" + Example: "サーバーサイドレンダリング (SSR)" instead of just "SSR" or just "サーバーサイドレンダリング" + - Maintain consistent translations for common terms across the entire document + - Use katakana for foreign technical terms where appropriate +`, + terms: {}, + }, + es: { + code: 'es', + name: 'Spanish', + guide: ` + - For technical terms that should not be fully translated, use the format: "Traducción en español (English term)" + Example: "Renderizado del lado del servidor (SSR)" instead of just "SSR" or just "Renderizado del lado del servidor" + - Maintain consistent translations for common terms across the entire document + - Use formal "usted" form instead of informal "tú" for instructions +`, + terms: {}, + }, + de: { + code: 'de', + name: 'German', + guide: ` + - For technical terms that should not be fully translated, use the format: "Deutsche Übersetzung (English term)" + Example: "Server-seitiges Rendering (SSR)" instead of just "SSR" or just "Server-seitiges Rendering" + - Maintain consistent translations for common terms across the entire document + - Follow German capitalization rules for nouns +`, + terms: {}, + }, + fr: { + code: 'fr', + name: 'French', + guide: ` + - For technical terms that should not be fully translated, use the format: "Traduction française (English term)" + Example: "Rendu côté serveur (SSR)" instead of just "SSR" or just "Rendu côté serveur" + - Maintain consistent translations for common terms across the entire document + - Use proper French punctuation with spaces before certain punctuation marks +`, + terms: {}, + }, + ru: { + code: 'ru', + name: 'Russian', + guide: ` + - For technical terms that should not be fully translated, use the format: "Русский перевод (English term)" + Example: "Рендеринг на стороне сервера (SSR)" instead of just "SSR" or just "Рендеринг на стороне сервера" + - Maintain consistent translations for common terms across the entire document + - Use proper Russian cases for technical terms where appropriate +`, + terms: {}, + }, + ar: { + code: 'ar', + name: 'Arabic', + guide: ` + - For technical terms that should not be fully translated, use the format: "الترجمة العربية (English term)" + Example: "العرض من جانب الخادم (SSR)" instead of just "SSR" or just "العرض من جانب الخادم" + - Maintain consistent translations for common terms across the entire document + - Arabic text should flow right-to-left, but keep code examples and technical terms left-to-right +`, + terms: {}, + }, + }, + docsRoot: 'docs', + docsContext: ` +TanStack Table's core is **framework agnostic**, which means its API is the same regardless of the framework you're using. Adapters are provided to make working with the table core easier depending on your framework. See the Adapters menu for available adapters.`, + copyPath: 'reference/**,framework/*/reference/**', +}