diff --git a/.github/workflows/autofix.yml b/.github/workflows/autofix.yml index b348b2b9c..d7a4f2478 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.2.2 diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index d8e41189f..07cbb6c44 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -17,6 +17,7 @@ jobs: test: name: Test runs-on: ubuntu-latest + if: github.repository_owner == 'TanStack' steps: - name: Checkout uses: actions/checkout@v4.2.2 @@ -33,6 +34,7 @@ jobs: preview: name: Preview runs-on: ubuntu-latest + if: github.repository_owner == 'TanStack' steps: - name: Checkout uses: actions/checkout@v4.2.2 diff --git a/.github/workflows/translate.yml b/.github/workflows/translate.yml new file mode 100644 index 000000000..33d69ce16 --- /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/api/virtual-item.md b/docs/ar/api/virtual-item.md new file mode 100644 index 000000000..e73f45a3c --- /dev/null +++ b/docs/ar/api/virtual-item.md @@ -0,0 +1,68 @@ +--- +source-updated-at: '2024-08-29T09:26:23.000Z' +translation-updated-at: '2025-05-02T20:48:22.483Z' +title: العنصر الظاهري +--- +# VirtualItem + +يمثل كائن `VirtualItem` عنصرًا مفردًا يتم إرجاعه بواسطة أداة التنسيق الافتراضي (virtualizer). يحتوي على المعلومات التي تحتاجها لتنسيق العنصر في مساحة الإحداثيات ضمن عنصر التمرير (scrollElement) لأداة التنسيق الافتراضي، بالإضافة إلى خصائص ووظائف أخرى مفيدة. + +```tsx +export interface VirtualItem { + key: string | number | bigint + index: number + start: number + end: number + size: number +} +``` + +الخصائص والوظائف التالية متاحة لكل كائن VirtualItem: + +### `key` + +```tsx +key: string | number | bigint +``` + +المفتاح الفريد للعنصر. افتراضيًا يكون هذا هو فهرس العنصر، ولكن يجب تكوينه عبر خيار `getItemKey` في أداة التنسيق الافتراضي (Virtualizer). + +### `index` + +```tsx +index: number +``` + +فهرس العنصر. + +### `start` + +```tsx +start: number +``` + +إزاحة البكسل البادئة للعنصر. عادةً ما يتم تعيين هذه القيمة إلى خاصية CSS أو تحويل مثل `top/left` أو `translateX/translateY`. + +### `end` + +```tsx +end: number +``` + +إزاحة البكسل المنتهية للعنصر. هذه القيمة ليست ضرورية لمعظم التنسيقات، ولكن يمكن أن تكون مفيدة لذا قمنا بتوفيرها على أي حال. + +### `size` + +```tsx +size: number +``` + +حجم العنصر. عادةً ما يتم تعيين هذه القيمة إلى خاصية CSS مثل `width/height`. قبل قياس العنصر باستخدام طريقة `VirtualItem.measureElement`، ستكون هذه القيمة هي الحجم المقدر الذي يتم إرجاعه من خيار `estimateSize` في أداة التنسيق الافتراضي. بعد قياس العنصر (إذا اخترت قياسه)، ستكون هذه القيمة هي الرقم الذي يتم إرجاعه من خيار `measureElement` في أداة التنسيق الافتراضي (والذي يكون مضبوطًا افتراضيًا لقياس العناصر باستخدام `getBoundingClientRect()`). + +### `lane` + +```tsx +lane: number +``` + +فهرس الممر (lane) للعنصر. في القوائم العادية سيكون دائمًا مضبوطًا على `0`، ولكنه يصبح مفيدًا لتنسيقات البناء (masonry layouts) (راجع الأمثلة المتغيرة لمزيد من التفاصيل). diff --git a/docs/ar/api/virtualizer.md b/docs/ar/api/virtualizer.md new file mode 100644 index 000000000..bbb652fc7 --- /dev/null +++ b/docs/ar/api/virtualizer.md @@ -0,0 +1,398 @@ +--- +source-updated-at: '2025-05-05T15:05:35.000Z' +translation-updated-at: '2025-05-06T23:15:36.227Z' +title: الظاهري +--- +# الفِرْتوالايزر (Virtualizer) + +فئة `Virtualizer` هي جوهر مكتبة TanStack Virtual. عادةً ما يتم إنشاء مثيلات الفِرْتوالايزر لك بواسطة أداة التكامل مع إطار العمل الخاص بك، لكنك تحصل على الفِرْتوالايزر مباشرة. + +```tsx +export class Virtualizer { + constructor(options: VirtualizerOptions) +} +``` + +## الخيارات المطلوبة + +### `count` + +```tsx +count: number +``` + +العدد الإجمالي للعناصر المراد تحويلها إلى افتراضية. + +### `getScrollElement` + +```tsx +getScrollElement: () => TScrollElement +``` + +دالة تُرجع العنصر القابل للتمرير للفِرْتوالايزر. قد تُرجع قيمة null إذا كان العنصر غير متاح بعد. + +### `estimateSize` + +```tsx +estimateSize: (index: number) => number +``` + +> � إذا كنت تقيس عناصرك ديناميكيًا، يُنصح بتقدير أكبر حجم ممكن (عرض/ارتفاع، ضمن حدود معقولة) لعناصرك. هذا يضمن أن ميزات مثل التمرير السلس لديها فرصة أفضل للعمل بشكل صحيح. + +هذه الدالة تستقبل فهرس كل عنصر ويجب أن تُرجع الحجم الفعلي (أو الحجم المقدر إذا كنت ستقيس العناصر ديناميكيًا باستخدام `virtualItem.measureElement`) لكل عنصر. يجب أن يُرجع هذا القياس إما العرض أو الارتفاع اعتمادًا على اتجاه الفِرْتوالايزر الخاص بك. + +## الخيارات الاختيارية + +### `enabled` + +```tsx +enabled?: boolean +``` + +اضبط على `false` لتعطيل مراقبي scrollElement وإعادة تعيين حالة الفِرْتوالايزر. + +### `debug` + +```tsx +debug?: boolean +``` + +اضبط على `true` لتمكين سجلات التصحيح. + +### `initialRect` + +```tsx +initialRect?: Rect +``` + +المستطيل الابتدائي لـ scrollElement. يكون هذا مفيدًا بشكل أساسي إذا كنت بحاجة إلى تشغيل الفِرْتوالايزر في بيئة SSR، وإلا سيتم حساب initialRect عند التحميل بواسطة تنفيذ `observeElementRect`. + +### `onChange` + +```tsx +onChange?: (instance: Virtualizer, sync: boolean) => void +``` + +دالة رد اتصال تُنفّذ عند تغيير الحالة الداخلية للفِرْتوالايزر. يتم تمرير مثيل الفِرْتوالايزر ومعلمة sync إليها. + +تشير معلمة sync إلى ما إذا كان التمرير جاريًا حاليًا. تكون `true` عندما يكون التمرير مستمرًا، و`false` عندما يتوقف التمرير أو يتم تنفيذ إجراءات أخرى (مثل تغيير الحجم). + +### `overscan` + +```tsx +overscan?: number +``` + +عدد العناصر التي يجب عرضها أعلى وأسفل المنطقة المرئية. زيادة هذا الرقم ستزيد من الوقت المطلوب لعرض الفِرْتوالايزر، ولكن قد تقلل من احتمالية رؤية عناصر فارغة بطيئة العرض في أعلى وأسفل الفِرْتوالايزر عند التمرير. القيمة الافتراضية هي `1`. + +### `horizontal` + +```tsx +horizontal?: boolean +``` + +اضبط هذا على `true` إذا كان الفِرْتوالايزر الخاص بك موجهًا أفقيًا. + +### `paddingStart` + +```tsx +paddingStart?: number +``` + +الحشو المطبق على بداية الفِرْتوالايزر بالبكسل. + +### `paddingEnd` + +```tsx +paddingEnd?: number +``` + +الحشو المطبق على نهاية الفِرْتوالايزر بالبكسل. + +### `scrollPaddingStart` + +```tsx +scrollPaddingStart?: number +``` + +الحشو المطبق على بداية الفِرْتوالايزر بالبكسل عند التمرير إلى عنصر. + +### `scrollPaddingEnd` + +```tsx +scrollPaddingEnd?: number +``` + +الحشو المطبق على نهاية الفِرْتوالايزر بالبكسل عند التمرير إلى عنصر. + +### `initialOffset` + +```tsx +initialOffset?: number | (() => number) +``` + +الإزاحة الابتدائية المطبقة على الفِرْتوالايزر. يكون هذا مفيدًا عادةً فقط إذا كنت تعرض الفِرْتوالايزر في بيئة SSR. + +### `getItemKey` + +```tsx +getItemKey?: (index: number) => Key +``` + +هذه الدالة تستقبل فهرس كل عنصر ويجب أن تُرجع مفتاحًا فريدًا لهذا العنصر. الوظيفة الافتراضية لهذه الدالة هي إرجاع فهرس العنصر، ولكن يجب عليك تجاوز هذا عندما يكون ذلك ممكنًا لإرجاع معرف فريد لكل عنصر عبر المجموعة بأكملها. يجب حفظ نتائج هذه الدالة (memoized) لمنع إعادة التصيير غير الضرورية. + +### `rangeExtractor` + +```tsx +rangeExtractor?: (range: Range) => number[] +``` + +هذه الدالة تستقبل فهارس النطاق المرئي ويجب أن تُرجع مصفوفة من الفهارس للعرض. يكون هذا مفيدًا إذا كنت بحاجة إلى إضافة أو إزالة عناصر من الفِرْتوالايزر يدويًا بغض النظر عن النطاق المرئي، مثل عرض العناصر الثابتة أو العناوين أو التذييلات، إلخ. تنفيذ extractor النطاق الافتراضي سيرجع فهارس النطاق المرئي ويتم تصديره كـ `defaultRangeExtractor`. + +### `scrollToFn` + +```tsx +scrollToFn?: ( + offset: number, + options: { adjustments?: number; behavior?: 'auto' | 'smooth' }, + instance: Virtualizer, +) => void +``` + +دالة اختيارية (إذا تم توفيرها) يجب أن تنفذ سلوك التمرير لـ scrollElement الخاص بك. سيتم استدعاؤها بالوسائط التالية: + +- `offset` (بالبكسل) للتمرير نحوه. +- كائن يشير إلى ما إذا كان هناك فرق بين الحجم المقدر والحجم الفعلي (`adjustments`) و/أو ما إذا تم استدعاء التمرير بتحريك سلس (`behaviour`). +- مثيل الفِرْتوالايزر نفسه. + +لاحظ أن تنفيذات التمرير المضمنة يتم تصديرها كـ `elementScroll` و `windowScroll`، والتي يتم تكوينها تلقائيًا بواسطة دوال تكامل إطار العمل مثل `useVirtualizer` أو `useWindowVirtualizer`. + +> ⚠️ محاولة استخدام smoothScroll مع العناصر المقاسة ديناميكيًا لن تعمل. + +### `observeElementRect` + +```tsx +observeElementRect: ( + instance: Virtualizer, + cb: (rect: Rect) => void, +) => void | (() => void) +``` + +دالة اختيارية إذا تم توفيرها يتم استدعاؤها عند تغيير scrollElement ويجب أن تنفذ القياس الأولي والمراقبة المستمرة لـ `Rect` لـ scrollElement (كائن به `width` و `height`). يتم استدعاؤها بالمثيل (الذي يمنحك أيضًا الوصول إلى scrollElement عبر `instance.scrollElement`. يتم تصدير التنفيذات المضمنة كـ `observeElementRect` و `observeWindowRect` والتي يتم تكوينها تلقائيًا لك بواسطة دوال تكامل إطار العمل المصدرة مثل `useVirtualizer` أو `useWindowVirtualizer`. + +### `observeElementOffset` + +```tsx +observeElementOffset: ( + instance: Virtualizer, + cb: (offset: number) => void, + ) => void | (() => void) +``` + +دالة اختيارية إذا تم توفيرها يتم استدعاؤها عند تغيير scrollElement ويجب أن تنفذ القياس الأولي والمراقبة المستمرة لإزاحة التمرير لـ scrollElement (رقم). يتم استدعاؤها بالمثيل (الذي يمنحك أيضًا الوصول إلى scrollElement عبر `instance.scrollElement`. يتم تصدير التنفيذات المضمنة كـ `observeElementOffset` و `observeWindowOffset` والتي يتم تكوينها تلقائيًا لك بواسطة دوال تكامل إطار العمل المصدرة مثل `useVirtualizer` أو `useWindowVirtualizer`. + +### `measureElement` + +```tsx +measureElement?: ( + element: TItemElement, + entry: ResizeObserverEntry | undefined, + instance: Virtualizer, +) => number +``` + +هذه الدالة الاختيارية تُستدعى عندما يحتاج الفِرْتوالايزر إلى قياس حجم (عرض أو ارتفاع) عنصر ما ديناميكيًا. + +> 🧠 يمكنك استخدام `instance.options.horizontal` لتحديد ما إذا كان يجب قياس عرض أو ارتفاع العنصر. + +### `scrollMargin` + +```tsx +scrollMargin?: number +``` + +باستخدام هذا الخيار، يمكنك تحديد المكان الذي يجب أن تنشأ منه إزاحة التمرير. عادةً، تمثل هذه القيمة المسافة بين بداية عنصر التمرير وبداية القائمة. يكون هذا مفيدًا بشكل خاص في السيناريوهات الشائعة مثل عندما يكون لديك ترويسة تسبق window virtualizer أو عند استخدام عدة virtualizers داخل عنصر تمرير واحد. إذا كنت تستخدم تحديد الموضع المطلق للعناصر، يجب أن تأخذ في الاعتبار `scrollMargin` في تحويل CSS الخاص بك: +```tsx +transform: `translateY(${ + virtualRow.start - rowVirtualizer.options.scrollMargin +}px)` +``` +لقياس قيمة `scrollMargin` ديناميكيًا، يمكنك استخدام `getBoundingClientRect()` أو ResizeObserver. يكون هذا مفيدًا في السيناريوهات عندما قد تتغير ارتفاع العناصر فوق القائمة الافتراضية الخاصة بك. + +### `gap` + +```tsx +gap?: number +``` + +يسمح لك هذا الخيار بتعيين التباعد بين العناصر في القائمة الافتراضية. يكون مفيدًا بشكل خاص للحفاظ على فصل مرئي متسق بين العناصر دون الحاجة إلى ضبط هامش أو حشو كل عنصر يدويًا. يتم تحديد القيمة بالبكسل. + +### `lanes` + +```tsx +lanes: number +``` + +عدد الممرات التي تنقسم إليها القائمة (المعروفة أيضًا بالأعمدة للقوائم الرأسية والصفوف للقوائم الأفقية). + +### `isScrollingResetDelay` + +```tsx +isScrollingResetDelay: number +``` + +يسمح لك هذا الخيار بتحديد المدة التي يجب الانتظارها بعد آخر حدث تمرير قبل إعادة تعيين خاصية المثيل isScrolling. القيمة الافتراضية هي 150 مللي ثانية. + +يتم تنفيذ هذا الخيار بسبب الحاجة إلى آلية موثوقة للتعامل مع سلوك التمرير عبر المتصفحات المختلفة. حتى تدعم جميع المتصفحات حدث scrollEnd بشكل موحد. + +### `useScrollendEvent` + +```tsx +useScrollendEvent: boolean +``` + +يحدد ما إذا كان سيتم استخدام حدث scrollend الأصلي للكشف عن توقف التمرير. إذا تم تعيينه على false، يتم استخدام fallback debounced لإعادة تعيين خاصية المثيل isScrolling بعد isScrollingResetDelay مللي ثانية. القيمة الافتراضية هي `false`. + +يتم تنفيذ هذا الخيار بسبب الحاجة إلى آلية موثوقة للتعامل مع سلوك التمرير عبر المتصفحات المختلفة. حتى تدعم جميع المتصفحات حدث scrollEnd بشكل موحد. + +### `isRtl` + +```tsx +isRtl: boolean +``` + +ما إذا كان سيتم عكس التمرير الأفقي لدعم اللغات من اليمين إلى اليسار. + +### `useAnimationFrameWithResizeObserver` + +```tsx +useAnimationFrameWithResizeObserver: boolean +``` + +يمكّن هذا الخيار من تغليف قياسات ResizeObserver في requestAnimationFrame للتحديثات الأكثر سلاسة وتقليل التكرار في التخطيط. القيمة الافتراضية هي `false`. + +يساعد في منع خطأ "ResizeObserver loop completed with undelivered notifications" عن طريق التأكد من أن القياسات تتماشى مع دورة التصيير. يمكن أن يحسن الأداء ويقلل من ارتعاش واجهة المستخدم، خاصة عند تغيير حجم العناصر ديناميكيًا. ومع ذلك، نظرًا لأن ResizeObserver يعمل بالفعل بشكل غير متزامن، فإن إضافة requestAnimationFrame قد تقدم تأخيرًا طفيفًا في القياسات، والذي قد يكون ملحوظًا في بعض الحالات. إذا كانت عمليات تغيير الحجم خفيفة ولا تسبب إعادة تدفقات، فقد لا يوفر تمكين هذا الخيار فوائد كبيرة. + +## مثيل الفِرْتوالايزر + +الخصائص والطرق التالية متاحة على مثيل الفِرْتوالايزر: + +### `options` + +```tsx +options: readonly Required> +``` + +الخيارات الحالية للفِرْتوالايزر. يتم تحديث هذه الخاصية عبر أداة تكامل إطار العمل الخاص بك وهي للقراءة فقط. + +### `scrollElement` + +```tsx +scrollElement: readonly TScrollElement | null +``` + +عنصر التمرير الحالي للفِرْتوالايزر. يتم تحديث هذه الخاصية عبر أداة تكامل إطار العمل الخاص بك وهي للقراءة فقط. + +### `getVirtualItems` + +```tsx +type getVirtualItems = () => VirtualItem[] +``` + +تُرجع العناصر الافتراضية للحالة الحالية للفِرْتوالايزر. + +### `getVirtualIndexes` + +```tsx +type getVirtualIndexes = () => number[] +``` + +تُرجع فهارس الصفوف الافتراضية للحالة الحالية للفِرْتوالايزر. + +### `scrollToOffset` + +```tsx +scrollToOffset: ( + toOffset: number, + options?: { + align?: 'start' | 'center' | 'end' | 'auto', + behavior?: 'auto' | 'smooth' + } +) => void +``` + +يُمرر الفِرْتوالايزر إلى إزاحة البكسل المقدمة. يمكنك اختياريًا تمرير وضع محاذاة لربط التمرير بجزء معين من scrollElement. + +### `scrollToIndex` + +```tsx +scrollToIndex: ( + index: number, + options?: { + align?: 'start' | 'center' | 'end' | 'auto', + behavior?: 'auto' | 'smooth' + } +) => void +``` + +يُمرر الفِرْتوالايزر إلى عناصر الفهرس المقدم. يمكنك اختياريًا تمرير وضع محاذاة لربط التمرير بجزء معين من scrollElement. + +### `getTotalSize` + +```tsx +getTotalSize: () => number +``` + +تُرجع الحجم الإجمالي بالبكسل للعناصر الافتراضية. سيتغير هذا القياس تدريجيًا إذا اخترت قياس عناصرك ديناميكيًا أثناء عرضها. + +### `measure` + +```tsx +measure: () => void +``` + +يعيد تعيين أي قياسات سابقة للعناصر. + +### `measureElement` + +```tsx +measureElement: (el: TItemElement | null) => void +``` + +يقيس العنصر باستخدام خيار `measureElement` المكون للفِرْتوالايزر. أنت مسؤول عن استدعاء هذا في ترميز الفِرْتوالايزر الخاص بك عندما يتم عرض المكون (على سبيل المثال، باستخدام شيء مثل خاصية رد الاتصال ref في React) مع إضافة `data-index` + +```tsx +
...
+``` + +بشكل افتراضي، يتم تكوين خيار `measureElement` للفِرْتوالايزر لقياس العناصر باستخدام `getBoundingClientRect()`. + +### `resizeItem` + +```tsx +resizeItem: (index: number, size: number) => void +``` + +قم بتغيير حجم العنصر الافتراضي يدويًا. استخدم هذه الدالة لتعيين الحجم المحسوب لهذا الفهرس يدويًا. يكون مفيدًا في الحالات عند استخدام بعض تحولات التشكيل المخصصة وأنت تعرف حجم العنصر المشكل مسبقًا. + +يمكنك أيضًا استخدام هذه الطريقة مع ResizeObserver محدود بدلاً من `Virtualizer.measureElement` لتقليل إعادة التصيير. + +> ⚠️ يرجى العلم أن تغيير حجم العنصر يدويًا عند استخدام `Virtualizer.measureElement` لمراقبة هذا العنصر، سيؤدي إلى سلوك غير متوقع لأن `Virtualizer.measureElement` يغير الحجم أيضًا. ومع ذلك، يمكنك استخدام إما resizeItem أو measureElement في نفس مثيل الفِرْتوالايزر ولكن على فهارس عناصر مختلفة. + +### `scrollRect` + +```tsx +scrollRect: Rect +``` + +المستطيل الحالي لعنصر التمرير. + +### `shouldAdjustScrollPositionOnItemSizeChange` + +```tsx +shouldAdjustScrollPositionOnItemSizeChange: undefined | ((item: VirtualItem, delta: number, instance: Virtualizer) => boolean) diff --git a/docs/ar/config.json b/docs/ar/config.json new file mode 100644 index 000000000..7b903e89e --- /dev/null +++ b/docs/ar/config.json @@ -0,0 +1,258 @@ +{ + "$schema": "https://raw.githubusercontent.com/TanStack/tanstack.com/main/tanstack-docs-config.schema.json", + "docSearch": { + "appId": "", + "indexName": "", + "apiKey": "" + }, + "sections": [ + { + "label": "البدء", + "children": [ + { + "label": "المقدمة", + "to": "introduction" + }, + { + "label": "التثبيت", + "to": "installation" + } + ], + "frameworks": [ + { + "label": "react", + "children": [ + { + "label": "React Virtual", + "to": "framework/react/react-virtual" + } + ] + }, + { + "label": "angular", + "children": [ + { + "label": "Angular Virtual", + "to": "framework/angular/angular-virtual" + } + ] + }, + { + "label": "solid", + "children": [ + { + "label": "Solid Virtual", + "to": "framework/solid/solid-virtual" + } + ] + }, + { + "label": "svelte", + "children": [ + { + "label": "Svelte Virtual", + "to": "framework/svelte/svelte-virtual" + } + ] + }, + { + "label": "vue", + "children": [ + { + "label": "Vue Virtual", + "to": "framework/vue/vue-virtual" + } + ] + } + ] + }, + { + "label": "واجهات برمجة التطبيقات الأساسية", + "children": [ + { + "label": "الظاهري", + "to": "api/virtualizer" + }, + { + "label": "العنصر الظاهري", + "to": "api/virtual-item" + } + ] + }, + { + "label": "أمثلة", + "children": [], + "frameworks": [ + { + "label": "angular", + "children": [ + { + "to": "framework/angular/examples/fixed", + "label": "ثابت" + }, + { + "to": "framework/angular/examples/variable", + "label": "متغير" + }, + { + "to": "framework/angular/examples/dynamic", + "label": "ديناميكي" + }, + { + "to": "framework/angular/examples/padding", + "label": "الحشو" + }, + { + "to": "framework/angular/examples/sticky", + "label": "لاصق" + }, + { + "to": "framework/angular/examples/infinite-scroll", + "label": "التمرير اللانهائي" + }, + { + "to": "framework/angular/examples/smooth-scroll", + "label": "التمرير السلس" + }, + { + "to": "framework/angular/examples/table", + "label": "جدول" + }, + { + "to": "framework/angular/examples/window", + "label": "نافذة" + } + ] + }, + { + "label": "react", + "children": [ + { + "to": "framework/react/examples/fixed", + "label": "ثابت" + }, + { + "to": "framework/react/examples/variable", + "label": "متغير" + }, + { + "to": "framework/react/examples/dynamic", + "label": "ديناميكي" + }, + { + "to": "framework/react/examples/padding", + "label": "الحشو" + }, + { + "to": "framework/react/examples/sticky", + "label": "لاصق" + }, + { + "to": "framework/react/examples/infinite-scroll", + "label": "التمرير اللانهائي" + }, + { + "to": "framework/react/examples/smooth-scroll", + "label": "التمرير السلس" + }, + { + "to": "framework/react/examples/table", + "label": "جدول" + }, + { + "to": "framework/react/examples/window", + "label": "نافذة" + } + ] + }, + { + "label": "svelte", + "children": [ + { + "to": "framework/svelte/examples/fixed", + "label": "ثابت" + }, + { + "to": "framework/svelte/examples/variable", + "label": "متغير" + }, + { + "to": "framework/svelte/examples/dynamic", + "label": "ديناميكي" + }, + { + "to": "framework/svelte/examples/sticky", + "label": "لاصق" + }, + { + "to": "framework/svelte/examples/infinite-scroll", + "label": "التمرير اللانهائي" + }, + { + "to": "framework/svelte/examples/smooth-scroll", + "label": "التمرير السلس" + }, + { + "to": "framework/svelte/examples/table", + "label": "جدول" + } + ] + }, + { + "label": "vue", + "children": [ + { + "to": "framework/vue/examples/fixed", + "label": "ثابت" + }, + { + "to": "framework/vue/examples/variable", + "label": "متغير" + }, + { + "to": "framework/vue/examples/dynamic", + "label": "ديناميكي" + }, + { + "to": "framework/vue/examples/sticky", + "label": "لاصق" + }, + { + "to": "framework/vue/examples/infinite-scroll", + "label": "التمرير اللانهائي" + }, + { + "to": "framework/vue/examples/smooth-scroll", + "label": "التمرير السلس" + }, + { + "to": "framework/vue/examples/table", + "label": "جدول" + }, + { + "to": "framework/vue/examples/padding", + "label": "الحشو" + }, + { + "to": "framework/vue/examples/scroll-padding", + "label": "حشو التمرير" + } + ] + }, + { + "label": "lit", + "children": [ + { + "to": "framework/lit/examples/fixed", + "label": "ثابت" + }, + { + "to": "framework/lit/examples/dynamic", + "label": "ديناميكي" + } + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/docs/ar/framework/angular/angular-virtual.md b/docs/ar/framework/angular/angular-virtual.md new file mode 100644 index 000000000..4a99bc359 --- /dev/null +++ b/docs/ar/framework/angular/angular-virtual.md @@ -0,0 +1,35 @@ +--- +source-updated-at: '2024-08-19T19:18:26.000Z' +translation-updated-at: '2025-05-02T20:48:11.378Z' +title: Angular Virtual +--- +محول `@tanstack/angular-virtual` هو غلاف حول المنطق الأساسي للتمرير الافتراضي. + +## `injectVirtualizer` + +```ts +function injectVirtualizer( + options: PartialKeys< + Omit, 'getScrollElement'>, + 'observeElementRect' | 'observeElementOffset' | 'scrollToFn' + > & { scrollElement: ElementRef | TScrollElement | undefined }, +): AngularVirtualizer +``` + +تُرجع هذه الدالة نسخة من `AngularVirtualizer` مُهيأة للعمل مع عنصر HTML كـ scrollElement. + +## `injectWindowVirtualizer` + +```ts +function injectWindowVirtualizer( + options: PartialKeys< + VirtualizerOptions, + | 'getScrollElement' + | 'observeElementRect' + | 'observeElementOffset' + | 'scrollToFn' + >, +): AngularVirtualizer +``` + +تُرجع هذه الدالة نسخة من `AngularVirtualizer` تعتمد على النافذة ومُهيأة للعمل مع النافذة كـ scrollElement. diff --git a/docs/ar/framework/lit/lit-virtual.md b/docs/ar/framework/lit/lit-virtual.md new file mode 100644 index 000000000..16eeae6fe --- /dev/null +++ b/docs/ar/framework/lit/lit-virtual.md @@ -0,0 +1,38 @@ +--- +source-updated-at: '2024-06-24T18:08:48.000Z' +translation-updated-at: '2025-05-06T23:13:15.681Z' +title: Lit Virtual +--- +```markdown +`@tanstack/lit-virtual` هو مُحَوِّل (adapter) يغلف المنطق الأساسي للعناصر الافتراضية (virtual logic). + +## `createVirtualizer` + +```tsx +private virtualizerController = new VirtualizerController( + options: PartialKeys< VirtualizerOptions, + 'observeElementRect' | 'observeElementOffset' | 'scrollToFn' +) +``` + +تمثل هذه الفئة نسخة قياسية من `Virtualizer` مُهيأة للعمل مع عنصر HTML كعنصر التمرير (scrollElement). +سيؤدي هذا إلى إنشاء وحدة تحكم (Controller) من Lit يمكن الوصول إليها في طريقة عرض العنصر (render method). + +```tsx +render() { + const virtualizer = this.virtualizerController.getVirtualizer(); + const virtualItems = virtualizer.getVirtualItems(); +} +) +``` + +## `createWindowVirtualizer` + +```tsx +private windowVirtualizerController = new WindowVirtualizerController( + options: PartialKeys< VirtualizerOptions, + 'getScrollElement' | 'observeElementRect' | 'observeElementOffset' | 'scrollToFn' +``` + +تمثل هذه الفئة نسخة من `Virtualizer` تعتمد على النافذة (window-based) ومُهيأة للعمل مع عنصر HTML كعنصر التمرير (scrollElement). +``` diff --git a/docs/ar/framework/react/react-virtual.md b/docs/ar/framework/react/react-virtual.md new file mode 100644 index 000000000..684fae5d5 --- /dev/null +++ b/docs/ar/framework/react/react-virtual.md @@ -0,0 +1,37 @@ +--- +source-updated-at: '2024-01-25T21:23:10.000Z' +translation-updated-at: '2025-05-02T20:48:10.408Z' +title: React Virtual +--- +# React Virtual + +مُحَوِّل `@tanstack/react-virtual` هو غلاف حول المنطق الأساسي للتخيل (virtual logic). + +## `useVirtualizer` + +```tsx +function useVirtualizer( + options: PartialKeys< + VirtualizerOptions, + 'observeElementRect' | 'observeElementOffset' | 'scrollToFn' + >, +): Virtualizer +``` + +تُعيد هذه الدالة نسخة قياسية من `Virtualizer` مُهيأة للعمل مع عنصر HTML كـ `scrollElement`. + +## `useWindowVirtualizer` + +```tsx +function useWindowVirtualizer( + options: PartialKeys< + VirtualizerOptions, + | 'getScrollElement' + | 'observeElementRect' + | 'observeElementOffset' + | 'scrollToFn' + >, +): Virtualizer +``` + +تُعيد هذه الدالة نسخة من `Virtualizer` تعتمد على النافذة (window-based) مُهيأة للعمل مع النافذة كـ `scrollElement`. diff --git a/docs/ar/framework/solid/solid-virtual.md b/docs/ar/framework/solid/solid-virtual.md new file mode 100644 index 000000000..71c8f9219 --- /dev/null +++ b/docs/ar/framework/solid/solid-virtual.md @@ -0,0 +1,35 @@ +--- +source-updated-at: '2024-01-25T21:23:10.000Z' +translation-updated-at: '2025-05-02T20:48:10.870Z' +title: Solid Virtual +--- +```solid-virtual@tanstack/` هو عبارة عن غلاف (wrapper) حول المنطق الأساسي للتخيل الافتراضي. + +## `createVirtualizer` + +```tsx +function createVirtualizer( + options: PartialKeys< + VirtualizerOptions, + 'observeElementRect' | 'observeElementOffset' | 'scrollToFn' + >, +): Virtualizer +``` + +تُرجع هذه الدالة نسخة قياسية من `Virtualizer` مهيأة للعمل مع عنصر HTML كـ `scrollElement`. + +## `createWindowVirtualizer` + +```tsx +function createWindowVirtualizer( + options: PartialKeys< + VirtualizerOptions, + | 'getScrollElement' + | 'observeElementRect' + | 'observeElementOffset' + | 'scrollToFn' + >, +): Virtualizer +``` + +تُرجع هذه الدالة نسخة من `Virtualizer` تعتمد على النافذة (window) ومهيأة للعمل مع النافذة كـ `scrollElement`. diff --git a/docs/ar/framework/svelte/svelte-virtual.md b/docs/ar/framework/svelte/svelte-virtual.md new file mode 100644 index 000000000..92efe03f1 --- /dev/null +++ b/docs/ar/framework/svelte/svelte-virtual.md @@ -0,0 +1,37 @@ +--- +source-updated-at: '2024-01-25T21:23:10.000Z' +translation-updated-at: '2025-05-02T20:48:10.945Z' +title: Svelte Virtual +--- +# Svelte Virtual + +المُكيف `@tanstack/svelte-virtual` هو غلاف حول المنطق الأساسي للعناصر الافتراضية. + +## `createVirtualizer` + +```tsx +function createVirtualizer( + options: PartialKeys< + VirtualizerOptions, + 'observeElementRect' | 'observeElementOffset' | 'scrollToFn' + >, +): Virtualizer +``` + +تُرجع هذه الدالة نسخة قياسية من `Virtualizer` مُهيأة للعمل مع عنصر HTML كعنصر التمرير (scrollElement). + +## `createWindowVirtualizer` + +```tsx +function createWindowVirtualizer( + options: PartialKeys< + VirtualizerOptions, + | 'getScrollElement' + | 'observeElementRect' + | 'observeElementOffset' + | 'scrollToFn' + >, +): Virtualizer +``` + +تُرجع هذه الدالة نسخة من `Virtualizer` تعتمد على النافذة (window-based) ومُهيأة للعمل مع النافذة كعنصر التمرير (scrollElement). diff --git a/docs/ar/framework/vue/vue-virtual.md b/docs/ar/framework/vue/vue-virtual.md new file mode 100644 index 000000000..8f4e94c17 --- /dev/null +++ b/docs/ar/framework/vue/vue-virtual.md @@ -0,0 +1,37 @@ +--- +source-updated-at: '2024-06-01T09:52:04.000Z' +translation-updated-at: '2025-05-02T20:48:10.741Z' +title: Vue Virtual +--- +# Vue Virtual + +مُحَوِّل `@tanstack/vue-virtual` هو غلاف حول المنطق الأساسي للعناصر الافتراضية. + +## `useVirtualizer` + +```tsx +function useVirtualizer( + options: PartialKeys< + VirtualizerOptions, + 'observeElementRect' | 'observeElementOffset' | 'scrollToFn' + >, +): Virtualizer +``` + +تُعيد هذه الدالة نسخة قياسية من `Virtualizer` مُهيأة للعمل مع عنصر HTML كـ `scrollElement`. + +## `useWindowVirtualizer` + +```tsx +function useWindowVirtualizer( + options: PartialKeys< + VirtualizerOptions, + | 'getScrollElement' + | 'observeElementRect' + | 'observeElementOffset' + | 'scrollToFn' + >, +): Virtualizer +``` + +تُعيد هذه الدالة نسخة من `Virtualizer` تعتمد على النافذة ومُهيأة للعمل مع النافذة كـ `scrollElement`. diff --git a/docs/ar/installation.md b/docs/ar/installation.md new file mode 100644 index 000000000..74f5eb1a1 --- /dev/null +++ b/docs/ar/installation.md @@ -0,0 +1,50 @@ +--- +source-updated-at: '2025-03-07T09:19:44.000Z' +translation-updated-at: '2025-05-02T20:48:07.500Z' +title: التثبيت +--- +قبل أن نتعمق في واجهة برمجة التطبيقات (API)، فلنبدأ بإعداد البيئة! + +قم بتثبيت أداة TanStack Virtual الخاصة بك كتبعية (dependency) باستخدام مدير الحزم npm المفضل لديك + +## React Virtual + +```bash +npm install @tanstack/react-virtual +``` + +## Solid Virtual + +```bash +npm install @tanstack/solid-virtual +``` + +## Svelte Virtual + +```bash +npm install @tanstack/svelte-virtual +``` + +## Vue Virtual + +```bash +npm install @tanstack/vue-virtual +``` + +## Lit Virtual + +```bash +$ npm install @tanstack/lit-virtual +``` + +## Angular Virtual + +```bash +$ npm install @tanstack/angular-virtual +``` + +## Virtual Core (بدون إطار عمل) + +```bash +npm install @tanstack/virtual-core +``` diff --git a/docs/ar/introduction.md b/docs/ar/introduction.md new file mode 100644 index 000000000..1cdf55b00 --- /dev/null +++ b/docs/ar/introduction.md @@ -0,0 +1,71 @@ +--- +source-updated-at: '2024-11-25T13:01:52.000Z' +translation-updated-at: '2025-05-02T20:48:25.464Z' +title: المقدمة +--- +# مقدمة + +TanStack Virtual هو أداة واجهة مستخدم "بدون رأس" (headless UI) لتخيل (virtualizing) قوائم طويلة من العناصر في JS/TS، React، Vue، Svelte، Solid، Lit، و Angular. إنها ليست مكونًا (component) وبالتالي لا توفر أو تعرض أي ترميز (markup) أو أنماط (styles) نيابة عنك. بينما يتطلب ذلك منك بعض الترميز والأنماط، ستحتفظ بتحكم بنسبة 100٪ في أنماطك وتصميمك وتنفيذك. + +## المُخَيِّل (Virtualizer) + +في صميم TanStack Virtual يوجد المُخَيِّل (Virtualizer). يمكن توجيه المُخَيِّل على المحور الرأسي (الإفتراضي) أو المحور الأفقي، مما يجعل من الممكن تحقيق التخيل (virtualization) الرأسي والأفقي وحتى الشبيه بالشبكة (grid-like) من خلال الجمع بين تكوينات المحورين معًا. + +إليك مثالًا سريعًا لكيفية تخيل قائمة طويلة داخل عنصر div باستخدام TanStack Virtual في React: + +```tsx +import { useVirtualizer } from '@tanstack/react-virtual'; + +function App() { + // العنصر القابل للتمرير للقائمة + const parentRef = React.useRef(null) + + // المُخَيِّل + const rowVirtualizer = useVirtualizer({ + count: 10000, + getScrollElement: () => parentRef.current, + estimateSize: () => 35, + }) + + return ( + <> + {/* العنصر القابل للتمرير للقائمة */} +
+ {/* العنصر الداخلي الكبير لحفظ جميع العناصر */} +
+ {/* فقط العناصر المرئية في المُخَيِّل، موضوعة يدويًا لتكون في العرض */} + {rowVirtualizer.getVirtualItems().map((virtualItem) => ( +
+ Row {virtualItem.index} +
+ ))} +
+
+ + ) +} +``` + +لنستكشف المزيد من الأمثلة! diff --git a/docs/de/api/virtual-item.md b/docs/de/api/virtual-item.md new file mode 100644 index 000000000..07d2bf403 --- /dev/null +++ b/docs/de/api/virtual-item.md @@ -0,0 +1,66 @@ +--- +source-updated-at: '2024-08-29T09:26:23.000Z' +translation-updated-at: '2025-05-02T20:38:59.662Z' +title: VirtualItem +--- +Das `VirtualItem`-Objekt repräsentiert ein einzelnes Element, das vom Virtualisierer zurückgegeben wird. Es enthält die Informationen, die Sie benötigen, um das Element im Koordinatenraum innerhalb des `scrollElement` Ihres Virtualisierers zu rendern, sowie weitere hilfreiche Eigenschaften und Funktionen. + +```tsx +export interface VirtualItem { + key: string | number | bigint + index: number + start: number + end: number + size: number +} +``` + +Die folgenden Eigenschaften und Methoden sind für jedes `VirtualItem`-Objekt verfügbar: + +### `key` + +```tsx +key: string | number | bigint +``` + +Der eindeutige Schlüssel für das Element. Standardmäßig ist dies der Index des Elements, sollte jedoch über die `getItemKey`-Option des Virtualisierers konfiguriert werden. + +### `index` + +```tsx +index: number +``` + +Der Index des Elements. + +### `start` + +```tsx +start: number +``` + +Der Start-Pixel-Offset des Elements. Dies wird normalerweise auf eine CSS-Eigenschaft oder Transformation wie `top/left` oder `translateX/translateY` abgebildet. + +### `end` + +```tsx +end: number +``` + +Der End-Pixel-Offset des Elements. Dieser Wert ist für die meisten Layouts nicht notwendig, kann aber hilfreich sein, daher wird er trotzdem bereitgestellt. + +### `size` + +```tsx +size: number +``` + +Die Größe des Elements. Dies wird normalerweise auf eine CSS-Eigenschaft wie `width/height` abgebildet. Bevor ein Element mit der `VirtualItem.measureElement`-Methode vermessen wird, ist dies die geschätzte Größe, die von der `estimateSize`-Option des Virtualisierers zurückgegeben wird. Nachdem ein Element vermessen wurde (falls Sie es überhaupt vermessen), entspricht dieser Wert der von der `measureElement`-Option des Virtualisierers zurückgegebenen Zahl (die standardmäßig so konfiguriert ist, dass Elemente mit `getBoundingClientRect()` vermessen werden). + +### `lane` + +```tsx +lane: number +``` + +Der Lane-Index des Elements. In regulären Listen ist dieser immer auf `0` gesetzt, wird jedoch für Masonry-Layouts nützlich (siehe variable Beispiele für weitere Details). diff --git a/docs/de/api/virtualizer.md b/docs/de/api/virtualizer.md new file mode 100644 index 000000000..b4c25d48f --- /dev/null +++ b/docs/de/api/virtualizer.md @@ -0,0 +1,420 @@ +--- +source-updated-at: '2025-05-05T15:05:35.000Z' +translation-updated-at: '2025-05-06T23:07:36.854Z' +title: Virtualizer +--- +Die `Virtualizer`-Klasse ist der Kern von TanStack Virtual. Virtualizer-Instanzen werden normalerweise für Sie durch Ihren Framework-Adapter erstellt, aber Sie erhalten den Virtualizer direkt. + +```tsx +export class Virtualizer { + constructor(options: VirtualizerOptions) +} +``` + +## Erforderliche Optionen + +### `count` + +```tsx +count: number +``` + +Die Gesamtanzahl der zu virtualisierenden Elemente. + +### `getScrollElement` + +```tsx +getScrollElement: () => TScrollElement +``` + +Eine Funktion, die das scrollbare Element für den Virtualizer zurückgibt. Sie kann null zurückgeben, wenn das Element noch nicht verfügbar ist. + +### `estimateSize` + +```tsx +estimateSize: (index: number) => number +``` + +> 🧠 Wenn Sie Ihre Elemente dynamisch messen, wird empfohlen, die größtmögliche Größe (Breite/Höhe, im Rahmen des Zumutbaren) Ihrer Elemente zu schätzen. Dies stellt sicher, dass Funktionen wie sanftes Scrollen besser funktionieren. + +Diese Funktion erhält den Index jedes Elements und sollte die tatsächliche Größe (oder geschätzte Größe, wenn Sie Elemente dynamisch mit `virtualItem.measureElement` messen) für jedes Element zurückgeben. Diese Messung sollte je nach Ausrichtung Ihres Virtualizers entweder die Breite oder Höhe zurückgeben. + +## Optionale Optionen + +### `enabled` + +```tsx +enabled?: boolean +``` + +Auf `false` setzen, um ScrollElement-Observer zu deaktivieren und den Zustand des Virtualizers zurückzusetzen. + +### `debug` + +```tsx +debug?: boolean +``` + +Auf `true` setzen, um Debug-Logs zu aktivieren. + +### `initialRect` + +```tsx +initialRect?: Rect +``` + +Das initiale `Rect` des ScrollElements. Dies ist hauptsächlich nützlich, wenn Sie den Virtualizer in einer SSR-Umgebung ausführen müssen, ansonsten wird das initialRect beim Mount durch die `observeElementRect`-Implementierung berechnet. + +### `onChange` + +```tsx +onChange?: (instance: Virtualizer, sync: boolean) => void +``` + +Eine Callback-Funktion, die ausgelöst wird, wenn sich der interne Zustand des Virtualizers ändert. Sie erhält die Virtualizer-Instanz und den sync-Parameter. + +Der sync-Parameter gibt an, ob gerade gescrollt wird. Er ist `true`, wenn das Scrollen läuft, und `false`, wenn das Scrollen gestoppt wurde oder andere Aktionen (wie z.B. Größenänderungen) durchgeführt werden. + +### `overscan` + +```tsx +overscan?: number +``` + +Die Anzahl der Elemente, die oberhalb und unterhalb des sichtbaren Bereichs gerendert werden sollen. Eine Erhöhung dieser Zahl verlängert die Renderzeit des Virtualizers, verringert aber die Wahrscheinlichkeit, langsam renderende leere Elemente oben und unten im Virtualizer beim Scrollen zu sehen. Der Standardwert ist `1`. + +### `horizontal` + +```tsx +horizontal?: boolean +``` + +Auf `true` setzen, wenn Ihr Virtualizer horizontal ausgerichtet ist. + +### `paddingStart` + +```tsx +paddingStart?: number +``` + +Der Abstand, der am Anfang des Virtualizers in Pixeln angewendet werden soll. + +### `paddingEnd` + +```tsx +paddingEnd?: number +``` + +Der Abstand, der am Ende des Virtualizers in Pixeln angewendet werden soll. + +### `scrollPaddingStart` + +```tsx +scrollPaddingStart?: number +``` + +Der Abstand, der am Anfang des Virtualizers in Pixeln angewendet werden soll, wenn zu einem Element gescrollt wird. + +### `scrollPaddingEnd` + +```tsx +scrollPaddingEnd?: number +``` + +Der Abstand, der am Ende des Virtualizers in Pixeln angewendet werden soll, wenn zu einem Element gescrollt wird. + +### `initialOffset` + +```tsx +initialOffset?: number | (() => number) +``` + +Der initiale Offset, der auf den Virtualizer angewendet werden soll. Dies ist normalerweise nur nützlich, wenn Sie den Virtualizer in einer SSR-Umgebung rendern. + +### `getItemKey` + +```tsx +getItemKey?: (index: number) => Key +``` + +Diese Funktion erhält den Index jedes Elements und sollte einen eindeutigen Schlüssel für dieses Element zurückgeben. Die Standardfunktion gibt den Index des Elements zurück, aber Sie sollten dies nach Möglichkeit überschreiben, um einen eindeutigen Bezeichner für jedes Element über den gesamten Satz zurückzugeben. Diese Funktion sollte memoisiert werden, um unnötige Neu-Renderings zu vermeiden. + +### `rangeExtractor` + +```tsx +rangeExtractor?: (range: Range) => number[] +``` + +Diese Funktion erhält sichtbare Bereichsindizes und sollte ein Array von zu rendernden Indizes zurückgeben. Dies ist nützlich, wenn Sie unabhängig vom sichtbaren Bereich manuell Elemente hinzufügen oder entfernen müssen, z.B. für sticky Elemente, Header, Footer usw. Die Standardimplementierung des Range Extractors gibt die sichtbaren Bereichsindizes zurück und ist als `defaultRangeExtractor` exportiert. + +### `scrollToFn` + +```tsx +scrollToFn?: ( + offset: number, + options: { adjustments?: number; behavior?: 'auto' | 'smooth' }, + instance: Virtualizer, +) => void +``` + +Eine optionale Funktion, die (falls bereitgestellt) das Scrollverhalten für Ihr ScrollElement implementieren sollte. Sie wird mit folgenden Argumenten aufgerufen: + +- Ein `offset` (in Pixeln), zu dem gescrollt werden soll. +- Ein Objekt, das angibt, ob es eine Differenz zwischen der geschätzten Größe und der tatsächlichen Größe gab (`adjustments`) und/oder ob das Scrollen mit einer sanften Animation aufgerufen wurde (`behavior`). +- Die Virtualizer-Instanz selbst. + +Hinweis: Integrierte Scroll-Implementierungen sind als `elementScroll` und `windowScroll` exportiert, die automatisch durch die Framework-Adapter-Funktionen wie `useVirtualizer` oder `useWindowVirtualizer` konfiguriert werden. + +> ⚠️ Der Versuch, smoothScroll mit dynamisch gemessenen Elementen zu verwenden, funktioniert nicht. + +### `observeElementRect` + +```tsx +observeElementRect: ( + instance: Virtualizer, + cb: (rect: Rect) => void, +) => void | (() => void) +``` + +Eine optionale Funktion, die (falls bereitgestellt) aufgerufen wird, wenn sich das ScrollElement ändert, und die initiale Messung und kontinuierliche Überwachung des `Rect` des ScrollElements (ein Objekt mit `width` und `height`) implementieren sollte. Sie wird mit der Instanz aufgerufen (die Ihnen auch Zugriff auf das ScrollElement über `instance.scrollElement` gibt). Integrierte Implementierungen sind als `observeElementRect` und `observeWindowRect` exportiert, die automatisch durch die Framework-Adapter-Funktionen wie `useVirtualizer` oder `useWindowVirtualizer` konfiguriert werden. + +### `observeElementOffset` + +```tsx +observeElementOffset: ( + instance: Virtualizer, + cb: (offset: number) => void, + ) => void | (() => void) +``` + +Eine optionale Funktion, die (falls bereitgestellt) aufgerufen wird, wenn sich das ScrollElement ändert, und die initiale Messung und kontinuierliche Überwachung des Scroll-Offsets des ScrollElements (eine Zahl) implementieren sollte. Sie wird mit der Instanz aufgerufen (die Ihnen auch Zugriff auf das ScrollElement über `instance.scrollElement` gibt). Integrierte Implementierungen sind als `observeElementOffset` und `observeWindowOffset` exportiert, die automatisch durch die Framework-Adapter-Funktionen wie `useVirtualizer` oder `useWindowVirtualizer` konfiguriert werden. + +### `measureElement` + +```tsx +measureElement?: ( + element: TItemElement, + entry: ResizeObserverEntry | undefined, + instance: Virtualizer, +) => number +``` + +Diese optionale Funktion wird aufgerufen, wenn der Virtualizer die Größe (Breite oder Höhe) eines Elements dynamisch messen muss. + +> 🧠 Sie können `instance.options.horizontal` verwenden, um zu bestimmen, ob die Breite oder Höhe des Elements gemessen werden soll. + +### `scrollMargin` + +```tsx +scrollMargin?: number +``` + +Mit dieser Option können Sie festlegen, wo der Scroll-Offset beginnen soll. Typischerweise repräsentiert dieser Wert den Abstand zwischen dem Anfang des Scroll-Elements und dem Beginn der Liste. Dies ist besonders nützlich in gängigen Szenarien, wie z.B. wenn Sie einen Header vor einem Window-Virtualizer haben oder wenn mehrere Virtualizer innerhalb eines einzigen Scroll-Elements verwendet werden. Wenn Sie absolute Positionierung von Elementen verwenden, sollten Sie den `scrollMargin` in Ihrer CSS-Transform berücksichtigen: +```tsx +transform: `translateY(${ + virtualRow.start - rowVirtualizer.options.scrollMargin +}px)` +``` +Um den Wert für `scrollMargin` dynamisch zu messen, können Sie `getBoundingClientRect()` oder ResizeObserver verwenden. Dies ist hilfreich in Szenarien, in denen Elemente über Ihrer virtuellen Liste ihre Höhe ändern können. + +### `gap` + +```tsx +gap?: number +``` + +Diese Option ermöglicht es Ihnen, den Abstand zwischen Elementen in der virtualisierten Liste festzulegen. Sie ist besonders nützlich, um eine konsistente visuelle Trennung zwischen Elementen beizubehalten, ohne die Ränder oder Abstände jedes Elements manuell anpassen zu müssen. Der Wert wird in Pixeln angegeben. + +### `lanes` + +```tsx +lanes: number +``` + +Die Anzahl der Spuren, in die die Liste unterteilt ist (auch Spalten für vertikale Listen und Zeilen für horizontale Listen). + +### `isScrollingResetDelay` + +```tsx +isScrollingResetDelay: number +``` + +Diese Option ermöglicht es Ihnen, die Dauer festzulegen, die nach dem letzten Scroll-Ereignis gewartet werden soll, bevor die isScrolling-Instanzeigenschaft zurückgesetzt wird. Der Standardwert beträgt 150 Millisekunden. + +Die Implementierung dieser Option wird durch die Notwendigkeit eines zuverlässigen Mechanismus zur Handhabung des Scrollverhaltens über verschiedene Browser hinweg angetrieben. Bis alle Browser den scrollEnd-Event einheitlich unterstützen. + +### `useScrollendEvent` + +```tsx +useScrollendEvent: boolean +``` + +Bestimmt, ob das native scrollend-Event verwendet werden soll, um zu erkennen, wann das Scrollen gestoppt wurde. Wenn auf false gesetzt, wird ein debounced-Fallback verwendet, um die isScrolling-Instanzeigenschaft nach isScrollingResetDelay Millisekunden zurückzusetzen. Der Standardwert ist `false`. + +Die Implementierung dieser Option wird durch die Notwendigkeit eines zuverlässigen Mechanismus zur Handhabung des Scrollverhaltens über verschiedene Browser hinweg angetrieben. Bis alle Browser den scrollEnd-Event einheitlich unterstützen. + +### `isRtl` + +```tsx +isRtl: boolean +``` + +Ob das horizontale Scrollen invertiert werden soll, um rechts-nach-links-Sprachumgebungen zu unterstützen. + +### `useAnimationFrameWithResizeObserver` + +```tsx +useAnimationFrameWithResizeObserver: boolean +``` + +Diese Option aktiviert das Einwickeln von ResizeObserver-Messungen in requestAnimationFrame für flüssigere Updates und weniger Layout-Thrashing. Der Standardwert ist `false`. + +Es hilft, den Fehler "ResizeObserver loop completed with undelivered notifications" zu vermeiden, indem sichergestellt wird, dass Messungen mit dem Rendering-Zyklus übereinstimmen. Dies kann die Leistung verbessern und UI-Ruckeln reduzieren, insbesondere wenn Elemente dynamisch in der Größe geändert werden. Da ResizeObserver jedoch bereits asynchron läuft, kann das Hinzufügen von requestAnimationFrame eine leichte Verzögerung bei Messungen verursachen, die in einigen Fällen bemerkbar sein kann. Wenn Größenänderungsoperationen leichtgewichtig sind und keine Reflows verursachen, bietet diese Option möglicherweise keine signifikanten Vorteile. + +## Virtualizer-Instanz + +Die folgenden Eigenschaften und Methoden sind auf der Virtualizer-Instanz verfügbar: + +### `options` + +```tsx +options: readonly Required> +``` + +Die aktuellen Optionen für den Virtualizer. Diese Eigenschaft wird über Ihren Framework-Adapter aktualisiert und ist schreibgeschützt. + +### `scrollElement` + +```tsx +scrollElement: readonly TScrollElement | null +``` + +Das aktuelle ScrollElement für den Virtualizer. Diese Eigenschaft wird über Ihren Framework-Adapter aktualisiert und ist schreibgeschützt. + +### `getVirtualItems` + +```tsx +type getVirtualItems = () => VirtualItem[] +``` + +Gibt die virtuellen Elemente für den aktuellen Zustand des Virtualizers zurück. + +### `getVirtualIndexes` + +```tsx +type getVirtualIndexes = () => number[] +``` + +Gibt die virtuellen Zeilenindizes für den aktuellen Zustand des Virtualizers zurück. + +### `scrollToOffset` + +```tsx +scrollToOffset: ( + toOffset: number, + options?: { + align?: 'start' | 'center' | 'end' | 'auto', + behavior?: 'auto' | 'smooth' + } +) => void +``` + +Scrollt den Virtualizer zum angegebenen Pixel-Offset. Optional können Sie einen Ausrichtungsmodus übergeben, um den Scroll an einem bestimmten Teil des ScrollElements zu verankern. + +### `scrollToIndex` + +```tsx +scrollToIndex: ( + index: number, + options?: { + align?: 'start' | 'center' | 'end' | 'auto', + behavior?: 'auto' | 'smooth' + } +) => void +``` + +Scrollt den Virtualizer zu dem Element des angegebenen Index. Optional können Sie einen Ausrichtungsmodus übergeben, um den Scroll an einem bestimmten Teil des ScrollElements zu verankern. + +### `getTotalSize` + +```tsx +getTotalSize: () => number +``` + +Gibt die Gesamtgröße in Pixeln für die virtualisierten Elemente zurück. Diese Messung ändert sich inkrementell, wenn Sie sich entscheiden, Ihre Elemente dynamisch zu messen, während sie gerendert werden. + +### `measure` + +```tsx +measure: () => void +``` + +Setzt alle vorherigen Elementmessungen zurück. + +### `measureElement` + +```tsx +measureElement: (el: TItemElement | null) => void +``` + +Misst das Element mit Ihrer konfigurierten `measureElement`-Virtualizer-Option. Sie sind dafür verantwortlich, dies in Ihrem Virtualizer-Markup aufzurufen, wenn die Komponente gerendert wird (z.B. mit etwas wie Reacts ref-Callback-Prop) und auch `data-index` hinzuzufügen. + +```tsx +
...
+``` + +Standardmäßig ist die `measureElement`-Virtualizer-Option so konfiguriert, dass Elemente mit `getBoundingClientRect()` gemessen werden. + +### `resizeItem` + +```tsx +resizeItem: (index: number, size: number) => void +``` + +Ändert die Größe des virtualisierten Elements manuell. Verwenden Sie diese Funktion, um die für diesen Index berechnete Größe manuell festzulegen. Nützlich in Fällen, in denen Sie eine benutzerdefinierte Morphing-Transition verwenden und die Größe des gemorphten Elements im Voraus kennen. + +Sie können diese Methode auch mit einem gedrosselten ResizeObserver anstelle von `Virtualizer.measureElement` verwenden, um Neu-Renderings zu reduzieren. + +> ⚠️ Bitte beachten Sie, dass das manuelle Ändern der Größe eines Elements, wenn `Virtualizer.measureElement` zur Überwachung dieses Elements verwendet wird, zu unvorhersehbarem Verhalten führt, da `Virtualizer.measureElement` ebenfalls die Größe ändert. Sie können jedoch entweder resizeItem oder measureElement in derselben Virtualizer-Instanz, aber auf verschiedenen Elementindizes verwenden. + +### `scrollRect` + +```tsx +scrollRect: Rect +``` + +Aktuelles `Rect` des Scroll-Elements. + +### `shouldAdjustScrollPositionOnItemSizeChange` + +```tsx +shouldAdjustScrollPositionOnItemSizeChange: undefined | ((item: VirtualItem, delta: number, instance: Virtualizer) => boolean) +``` + +Die shouldAdjustScrollPositionOnItemSizeChange-Methode ermöglicht eine fein abgestimmte Kontrolle über die Anpassung der Scroll-Position, wenn die Größe dynamisch gerenderter Elemente von der geschätzten Größe abweicht. Wenn Sie in die Mitte der Liste springen und rückwärts scrollen, können neue Elemente eine andere Größe als die ursprünglich geschätzte Größe haben. Diese Diskrepanz kann dazu führen, dass nachfolgende Elemente verschoben werden, was insbesondere beim Rückwärts-Scrollen durch die Liste das Nutzererlebnis stören kann. + +### `isScrolling` + +```tsx +isScrolling: boolean +``` + +Boolean-Flag, das angibt, ob die Liste gerade gescrollt wird. + +### `scrollDirection` + +```tsx +scrollDirection: 'forward' | 'backward' | null +``` + +Diese Option gibt die Scrollrichtung an, mit möglichen Werten 'forward' für das Abwärts-Scrollen und 'backward' für das Aufwärts-Scrollen. Der Wert ist null, wenn kein aktives Scrollen stattfindet. + +### `scrollOffset` + +```tsx +scrollOffset diff --git a/docs/de/config.json b/docs/de/config.json new file mode 100644 index 000000000..69e8391f2 --- /dev/null +++ b/docs/de/config.json @@ -0,0 +1,258 @@ +{ + "$schema": "https://raw.githubusercontent.com/TanStack/tanstack.com/main/tanstack-docs-config.schema.json", + "docSearch": { + "appId": "", + "indexName": "", + "apiKey": "" + }, + "sections": [ + { + "label": "Erste Schritte", + "children": [ + { + "label": "Einführung", + "to": "introduction" + }, + { + "label": "Installation", + "to": "installation" + } + ], + "frameworks": [ + { + "label": "react", + "children": [ + { + "label": "React Virtual", + "to": "framework/react/react-virtual" + } + ] + }, + { + "label": "angular", + "children": [ + { + "label": "Angular Virtual", + "to": "framework/angular/angular-virtual" + } + ] + }, + { + "label": "solid", + "children": [ + { + "label": "Solid Virtual", + "to": "framework/solid/solid-virtual" + } + ] + }, + { + "label": "svelte", + "children": [ + { + "label": "Svelte Virtual", + "to": "framework/svelte/svelte-virtual" + } + ] + }, + { + "label": "vue", + "children": [ + { + "label": "Vue Virtual", + "to": "framework/vue/vue-virtual" + } + ] + } + ] + }, + { + "label": "Kern-APIs", + "children": [ + { + "label": "Virtualizer", + "to": "api/virtualizer" + }, + { + "label": "VirtualItem", + "to": "api/virtual-item" + } + ] + }, + { + "label": "Beispiele", + "children": [], + "frameworks": [ + { + "label": "angular", + "children": [ + { + "to": "framework/angular/examples/fixed", + "label": "Fest" + }, + { + "to": "framework/angular/examples/variable", + "label": "Variabel" + }, + { + "to": "framework/angular/examples/dynamic", + "label": "Dynamisch" + }, + { + "to": "framework/angular/examples/padding", + "label": "Polsterung" + }, + { + "to": "framework/angular/examples/sticky", + "label": "Fixiert" + }, + { + "to": "framework/angular/examples/infinite-scroll", + "label": "Unendliches Scrollen" + }, + { + "to": "framework/angular/examples/smooth-scroll", + "label": "Sanftes Scrollen" + }, + { + "to": "framework/angular/examples/table", + "label": "Tabelle" + }, + { + "to": "framework/angular/examples/window", + "label": "Fenster" + } + ] + }, + { + "label": "react", + "children": [ + { + "to": "framework/react/examples/fixed", + "label": "Fest" + }, + { + "to": "framework/react/examples/variable", + "label": "Variabel" + }, + { + "to": "framework/react/examples/dynamic", + "label": "Dynamisch" + }, + { + "to": "framework/react/examples/padding", + "label": "Polsterung" + }, + { + "to": "framework/react/examples/sticky", + "label": "Fixiert" + }, + { + "to": "framework/react/examples/infinite-scroll", + "label": "Unendliches Scrollen" + }, + { + "to": "framework/react/examples/smooth-scroll", + "label": "Sanftes Scrollen" + }, + { + "to": "framework/react/examples/table", + "label": "Tabelle" + }, + { + "to": "framework/react/examples/window", + "label": "Fenster" + } + ] + }, + { + "label": "svelte", + "children": [ + { + "to": "framework/svelte/examples/fixed", + "label": "Fest" + }, + { + "to": "framework/svelte/examples/variable", + "label": "Variabel" + }, + { + "to": "framework/svelte/examples/dynamic", + "label": "Dynamisch" + }, + { + "to": "framework/svelte/examples/sticky", + "label": "Fixiert" + }, + { + "to": "framework/svelte/examples/infinite-scroll", + "label": "Unendliches Scrollen" + }, + { + "to": "framework/svelte/examples/smooth-scroll", + "label": "Sanftes Scrollen" + }, + { + "to": "framework/svelte/examples/table", + "label": "Tabelle" + } + ] + }, + { + "label": "vue", + "children": [ + { + "to": "framework/vue/examples/fixed", + "label": "Fest" + }, + { + "to": "framework/vue/examples/variable", + "label": "Variabel" + }, + { + "to": "framework/vue/examples/dynamic", + "label": "Dynamisch" + }, + { + "to": "framework/vue/examples/sticky", + "label": "Fixiert" + }, + { + "to": "framework/vue/examples/infinite-scroll", + "label": "Unendliches Scrollen" + }, + { + "to": "framework/vue/examples/smooth-scroll", + "label": "Sanftes Scrollen" + }, + { + "to": "framework/vue/examples/table", + "label": "Tabelle" + }, + { + "to": "framework/vue/examples/padding", + "label": "Polsterung" + }, + { + "to": "framework/vue/examples/scroll-padding", + "label": "Scroll-Polsterung" + } + ] + }, + { + "label": "lit", + "children": [ + { + "to": "framework/lit/examples/fixed", + "label": "Fest" + }, + { + "to": "framework/lit/examples/dynamic", + "label": "Dynamisch" + } + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/docs/de/framework/angular/angular-virtual.md b/docs/de/framework/angular/angular-virtual.md new file mode 100644 index 000000000..02f4f1a9d --- /dev/null +++ b/docs/de/framework/angular/angular-virtual.md @@ -0,0 +1,35 @@ +--- +source-updated-at: '2024-08-19T19:18:26.000Z' +translation-updated-at: '2025-05-02T20:38:50.397Z' +title: Angular Virtual +--- +Der `@tanstack/angular-virtual`-Adapter ist ein Wrapper um die zentrale Virtualisierungslogik. + +## `injectVirtualizer` + +```ts +function injectVirtualizer( + options: PartialKeys< + Omit, 'getScrollElement'>, + 'observeElementRect' | 'observeElementOffset' | 'scrollToFn' + > & { scrollElement: ElementRef | TScrollElement | undefined }, +): AngularVirtualizer +``` + +Diese Funktion gibt eine `AngularVirtualizer`-Instanz zurück, die für die Arbeit mit einem HTML-Element als `scrollElement` konfiguriert ist. + +## `injectWindowVirtualizer` + +```ts +function injectWindowVirtualizer( + options: PartialKeys< + VirtualizerOptions, + | 'getScrollElement' + | 'observeElementRect' + | 'observeElementOffset' + | 'scrollToFn' + >, +): AngularVirtualizer +``` + +Diese Funktion gibt eine fensterbasierte `AngularVirtualizer`-Instanz zurück, die für die Arbeit mit dem Fenster als `scrollElement` konfiguriert ist. diff --git a/docs/de/framework/lit/lit-virtual.md b/docs/de/framework/lit/lit-virtual.md new file mode 100644 index 000000000..2b54c2e22 --- /dev/null +++ b/docs/de/framework/lit/lit-virtual.md @@ -0,0 +1,36 @@ +--- +source-updated-at: '2024-06-24T18:08:48.000Z' +translation-updated-at: '2025-05-06T23:05:13.366Z' +title: Lit Virtual +--- +Der `@tanstack/lit-virtual`-Adapter ist ein Wrapper um die zentrale Virtualisierungslogik. + +## `createVirtualizer` + +```tsx +private virtualizerController = new VirtualizerController( + options: PartialKeys< VirtualizerOptions, + 'observeElementRect' | 'observeElementOffset' | 'scrollToFn' +) +``` + +Diese Klasse repräsentiert eine standardmäßige `Virtualizer`-Instanz, die für die Arbeit mit einem HTML-Element als `scrollElement` konfiguriert ist. +Dies erstellt einen Lit-Controller, auf den in der `render`-Methode des Elements zugegriffen werden kann. + +```tsx +render() { + const virtualizer = this.virtualizerController.getVirtualizer(); + const virtualItems = virtualizer.getVirtualItems(); +} +) +``` + +## `createWindowVirtualizer` + +```tsx +private windowVirtualizerController = new WindowVirtualizerController( + options: PartialKeys< VirtualizerOptions, + 'getScrollElement' | 'observeElementRect' | 'observeElementOffset' | 'scrollToFn' +``` + +Diese Klasse repräsentiert eine fensterbasierte `Virtualizer`-Instanz, die für die Arbeit mit einem HTML-Element als `scrollElement` konfiguriert ist. diff --git a/docs/de/framework/react/react-virtual.md b/docs/de/framework/react/react-virtual.md new file mode 100644 index 000000000..16d2063e4 --- /dev/null +++ b/docs/de/framework/react/react-virtual.md @@ -0,0 +1,35 @@ +--- +source-updated-at: '2024-01-25T21:23:10.000Z' +translation-updated-at: '2025-05-02T20:38:49.522Z' +title: React Virtual +--- +Der `@tanstack/react-virtual`-Adapter ist ein Wrapper um die zentrale Virtualisierungslogik. + +## `useVirtualizer` + +```tsx +function useVirtualizer( + options: PartialKeys< + VirtualizerOptions, + 'observeElementRect' | 'observeElementOffset' | 'scrollToFn' + >, +): Virtualizer +``` + +Diese Funktion gibt eine standardmäßige `Virtualizer`-Instanz zurück, die für die Verwendung mit einem HTML-Element als `scrollElement` konfiguriert ist. + +## `useWindowVirtualizer` + +```tsx +function useWindowVirtualizer( + options: PartialKeys< + VirtualizerOptions, + | 'getScrollElement' + | 'observeElementRect' + | 'observeElementOffset' + | 'scrollToFn' + >, +): Virtualizer +``` + +Diese Funktion gibt eine fensterbasierte `Virtualizer`-Instanz zurück, die für die Verwendung mit dem Fenster als `scrollElement` konfiguriert ist. diff --git a/docs/de/framework/solid/solid-virtual.md b/docs/de/framework/solid/solid-virtual.md new file mode 100644 index 000000000..67177d00f --- /dev/null +++ b/docs/de/framework/solid/solid-virtual.md @@ -0,0 +1,37 @@ +--- +source-updated-at: '2024-01-25T21:23:10.000Z' +translation-updated-at: '2025-05-02T20:38:39.768Z' +title: Solid Virtual +--- +# Solid Virtual + +Der `@tanstack/solid-virtual`-Adapter ist ein Wrapper um die zentrale Virtualisierungslogik. + +## `createVirtualizer` + +```tsx +function createVirtualizer( + options: PartialKeys< + VirtualizerOptions, + 'observeElementRect' | 'observeElementOffset' | 'scrollToFn' + >, +): Virtualizer +``` + +Diese Funktion gibt eine standardmäßige `Virtualizer`-Instanz zurück, die für die Arbeit mit einem HTML-Element als `scrollElement` konfiguriert ist. + +## `createWindowVirtualizer` + +```tsx +function createWindowVirtualizer( + options: PartialKeys< + VirtualizerOptions, + | 'getScrollElement' + | 'observeElementRect' + | 'observeElementOffset' + | 'scrollToFn' + >, +): Virtualizer +``` + +Diese Funktion gibt eine fensterbasierte `Virtualizer`-Instanz zurück, die für die Arbeit mit dem Fenster als `scrollElement` konfiguriert ist. diff --git a/docs/de/framework/svelte/svelte-virtual.md b/docs/de/framework/svelte/svelte-virtual.md new file mode 100644 index 000000000..fdb22d0a0 --- /dev/null +++ b/docs/de/framework/svelte/svelte-virtual.md @@ -0,0 +1,35 @@ +--- +source-updated-at: '2024-01-25T21:23:10.000Z' +translation-updated-at: '2025-05-02T20:38:50.823Z' +title: Svelte Virtual +--- +Der `@tanstack/svelte-virtual`-Adapter ist ein Wrapper um die zentrale Virtualisierungslogik. + +## `createVirtualizer` + +```tsx +function createVirtualizer( + options: PartialKeys< + VirtualizerOptions, + 'observeElementRect' | 'observeElementOffset' | 'scrollToFn' + >, +): Virtualizer +``` + +Diese Funktion gibt eine standardmäßige `Virtualizer`-Instanz zurück, die für die Verwendung mit einem HTML-Element als `scrollElement` konfiguriert ist. + +## `createWindowVirtualizer` + +```tsx +function createWindowVirtualizer( + options: PartialKeys< + VirtualizerOptions, + | 'getScrollElement' + | 'observeElementRect' + | 'observeElementOffset' + | 'scrollToFn' + >, +): Virtualizer +``` + +Diese Funktion gibt eine fensterbasierte `Virtualizer`-Instanz zurück, die für die Verwendung mit dem Fenster als `scrollElement` konfiguriert ist. diff --git a/docs/de/framework/vue/vue-virtual.md b/docs/de/framework/vue/vue-virtual.md new file mode 100644 index 000000000..e442500a5 --- /dev/null +++ b/docs/de/framework/vue/vue-virtual.md @@ -0,0 +1,37 @@ +--- +source-updated-at: '2024-06-01T09:52:04.000Z' +translation-updated-at: '2025-05-02T20:38:50.686Z' +title: Vue Virtual +--- +# Vue Virtual + +Der `@tanstack/vue-virtual`-Adapter ist ein Wrapper um die zentrale Virtualisierungslogik. + +## `useVirtualizer` + +```tsx +function useVirtualizer( + options: PartialKeys< + VirtualizerOptions, + 'observeElementRect' | 'observeElementOffset' | 'scrollToFn' + >, +): Virtualizer +``` + +Diese Funktion gibt eine standardmäßige `Virtualizer`-Instanz zurück, die für die Arbeit mit einem HTML-Element als `scrollElement` konfiguriert ist. + +## `useWindowVirtualizer` + +```tsx +function useWindowVirtualizer( + options: PartialKeys< + VirtualizerOptions, + | 'getScrollElement' + | 'observeElementRect' + | 'observeElementOffset' + | 'scrollToFn' + >, +): Virtualizer +``` + +Diese Funktion gibt eine fensterbasierte `Virtualizer`-Instanz zurück, die für die Arbeit mit dem Fenster als `scrollElement` konfiguriert ist. diff --git a/docs/de/installation.md b/docs/de/installation.md new file mode 100644 index 000000000..6a01c68d4 --- /dev/null +++ b/docs/de/installation.md @@ -0,0 +1,50 @@ +--- +source-updated-at: '2025-03-07T09:19:44.000Z' +translation-updated-at: '2025-05-02T20:38:47.039Z' +title: Installation +--- +Bevor wir uns mit der API befassen, lassen Sie uns zunächst alles einrichten! + +Installieren Sie Ihren TanStack Virtual-Adapter als Abhängigkeit mit Ihrem bevorzugten npm-Paketmanager. + +## React Virtual + +```bash +npm install @tanstack/react-virtual +``` + +## Solid Virtual + +```bash +npm install @tanstack/solid-virtual +``` + +## Svelte Virtual + +```bash +npm install @tanstack/svelte-virtual +``` + +## Vue Virtual + +```bash +npm install @tanstack/vue-virtual +``` + +## Lit Virtual + +```bash +$ npm install @tanstack/lit-virtual +``` + +## Angular Virtual + +```bash +$ npm install @tanstack/angular-virtual +``` + +## Virtual Core (ohne Framework) + +```bash +npm install @tanstack/virtual-core +``` diff --git a/docs/de/introduction.md b/docs/de/introduction.md new file mode 100644 index 000000000..e1f623849 --- /dev/null +++ b/docs/de/introduction.md @@ -0,0 +1,69 @@ +--- +source-updated-at: '2024-11-25T13:01:52.000Z' +translation-updated-at: '2025-05-02T20:38:24.549Z' +title: Einführung +--- +TanStack Virtual ist eine Headless-UI-Hilfsfunktion (Headless UI Utility) zur Virtualisierung langer Elementlisten in JS/TS, React, Vue, Svelte, Solid, Lit und Angular. Es handelt sich nicht um eine Komponente, daher liefert es keine Markup-Elemente oder Styles für Sie aus. Obwohl dies etwas Markup und Styles von Ihnen erfordert, behalten Sie zu 100% die Kontrolle über Ihre Styles, Ihr Design und Ihre Implementierung. + +## Der Virtualizer + +Das Herzstück von TanStack Virtual ist der `Virtualizer`. Virtualizer können entweder vertikal (Standard) oder horizontal ausgerichtet werden, wodurch es möglich ist, vertikale, horizontale und sogar rasterartige Virtualisierung zu erreichen, indem die beiden Achsenkonfigurationen kombiniert werden. + +Hier ist ein kurzes Beispiel, wie es aussieht, eine lange Liste innerhalb eines div-Elements mit TanStack Virtual in React zu virtualisieren: + +```tsx +import { useVirtualizer } from '@tanstack/react-virtual'; + +function App() { + // Das scrollbare Element für Ihre Liste + const parentRef = React.useRef(null) + + // Der Virtualizer + const rowVirtualizer = useVirtualizer({ + count: 10000, + getScrollElement: () => parentRef.current, + estimateSize: () => 35, + }) + + return ( + <> + {/* Das scrollbare Element für Ihre Liste */} +
+ {/* Das große innere Element, das alle Items enthält */} +
+ {/* Nur die sichtbaren Items im Virtualizer, manuell positioniert, um sichtbar zu sein */} + {rowVirtualizer.getVirtualItems().map((virtualItem) => ( +
+ Row {virtualItem.index} +
+ ))} +
+
+ + ) +} +``` + +Lassen Sie uns einige weitere Beispiele genauer betrachten! diff --git a/docs/es/api/virtual-item.md b/docs/es/api/virtual-item.md new file mode 100644 index 000000000..84521bc0b --- /dev/null +++ b/docs/es/api/virtual-item.md @@ -0,0 +1,66 @@ +--- +source-updated-at: '2024-08-29T09:26:23.000Z' +translation-updated-at: '2025-05-02T20:34:11.257Z' +title: Elemento virtual +--- +El objeto `VirtualItem` representa un único elemento devuelto por el virtualizador. Contiene la información necesaria para renderizar el elemento en el espacio de coordenadas dentro del `scrollElement` de su virtualizador, junto con otras propiedades/funciones útiles. + +```tsx +export interface VirtualItem { + key: string | number | bigint + index: number + start: number + end: number + size: number +} +``` + +Las siguientes propiedades y métodos están disponibles en cada objeto `VirtualItem`: + +### `key` + +```tsx +key: string | number | bigint +``` + +La clave única del elemento. Por defecto, corresponde al índice del elemento, pero debe configurarse mediante la opción `getItemKey` del Virtualizador. + +### `index` + +```tsx +index: number +``` + +El índice del elemento. + +### `start` + +```tsx +start: number +``` + +El desplazamiento en píxeles donde comienza el elemento. Generalmente se asigna a una propiedad CSS o transformación como `top/left` o `translateX/translateY`. + +### `end` + +```tsx +end: number +``` + +El desplazamiento en píxeles donde termina el elemento. Este valor no es necesario para la mayoría de los diseños, pero puede ser útil, por lo que se incluye de todas formas. + +### `size` + +```tsx +size: number +``` + +El tamaño del elemento. Normalmente se asigna a una propiedad CSS como `width/height`. Antes de que un elemento sea medido con el método `VirtualItem.measureElement`, este valor será el tamaño estimado devuelto por la opción `estimateSize` del virtualizador. Después de medir el elemento (si se elige medirlo), este valor será el número devuelto por la opción `measureElement` del virtualizador (que, por defecto, está configurada para medir elementos con `getBoundingClientRect()`). + +### `lane` + +```tsx +lane: number +``` + +El índice del "carril" (lane) del elemento. En listas regulares siempre será `0`, pero resulta útil para diseños de tipo mampostería (consulte los ejemplos variables para más detalles). diff --git a/docs/es/api/virtualizer.md b/docs/es/api/virtualizer.md new file mode 100644 index 000000000..9d451f833 --- /dev/null +++ b/docs/es/api/virtualizer.md @@ -0,0 +1,425 @@ +--- +source-updated-at: '2025-05-05T15:05:35.000Z' +translation-updated-at: '2025-05-06T23:04:57.546Z' +title: Virtualizador +--- +# Virtualizer (no incluir esto en la traducción) + +La clase `Virtualizer` es el núcleo de TanStack Virtual. Normalmente, las instancias de Virtualizer son creadas para usted por su adaptador de framework, pero usted recibe directamente el virtualizador. + +```tsx +export class Virtualizer { + constructor(options: VirtualizerOptions) +} +``` + +## Opciones Requeridas + +### `count` + +```tsx +count: number +``` + +El número total de elementos a virtualizar. + +### `getScrollElement` + +```tsx +getScrollElement: () => TScrollElement +``` + +Una función que devuelve el elemento desplazable para el virtualizador. Puede devolver null si el elemento aún no está disponible. + +### `estimateSize` + +```tsx +estimateSize: (index: number) => number +``` + +> 🧠 Si está midiendo dinámicamente sus elementos, se recomienda estimar el tamaño máximo posible (ancho/alto, dentro de lo razonable) de sus elementos. Esto asegurará que características como el desplazamiento suave tengan más probabilidades de funcionar correctamente. + +Esta función recibe el índice de cada elemento y debe devolver el tamaño real (o tamaño estimado si medirá dinámicamente los elementos con `virtualItem.measureElement`) para cada elemento. Esta medida debe devolver el ancho o el alto dependiendo de la orientación de su virtualizador. + +## Opciones Opcionales + +### `enabled` + +```tsx +enabled?: boolean +``` + +Establézcalo en `false` para desactivar los observadores del scrollElement y reiniciar el estado del virtualizador. + +### `debug` + +```tsx +debug?: boolean +``` + +Establézcalo en `true` para habilitar registros de depuración. + +### `initialRect` + +```tsx +initialRect?: Rect +``` + +El `Rect` inicial del scrollElement. Esto es principalmente útil si necesita ejecutar el virtualizador en un entorno de Renderizado del lado del servidor (SSR), de lo contrario, el initialRect se calculará al montar mediante la implementación de `observeElementRect`. + +### `onChange` + +```tsx +onChange?: (instance: Virtualizer, sync: boolean) => void +``` + +Una función de callback que se ejecuta cuando cambia el estado interno del virtualizador. Recibe la instancia del virtualizador y el parámetro sync. + +El parámetro sync indica si el desplazamiento está en curso. Es `true` cuando el desplazamiento está en progreso y `false` cuando el desplazamiento se ha detenido o se están realizando otras acciones (como redimensionar). + +### `overscan` + +```tsx +overscan?: number +``` + +El número de elementos a renderizar por encima y por debajo del área visible. Aumentar este número incrementará el tiempo que toma renderizar el virtualizador, pero podría disminuir la probabilidad de ver elementos en blanco de renderización lenta en la parte superior e inferior del virtualizador al desplazarse. El valor predeterminado es `1`. + +### `horizontal` + +```tsx +horizontal?: boolean +``` + +Establézcalo en `true` si su virtualizador está orientado horizontalmente. + +### `paddingStart` + +```tsx +paddingStart?: number +``` + +El relleno a aplicar al inicio del virtualizador en píxeles. + +### `paddingEnd` + +```tsx +paddingEnd?: number +``` + +El relleno a aplicar al final del virtualizador en píxeles. + +### `scrollPaddingStart` + +```tsx +scrollPaddingStart?: number +``` + +El relleno a aplicar al inicio del virtualizador en píxeles al desplazarse a un elemento. + +### `scrollPaddingEnd` + +```tsx +scrollPaddingEnd?: number +``` + +El relleno a aplicar al final del virtualizador en píxeles al desplazarse a un elemento. + +### `initialOffset` + +```tsx +initialOffset?: number | (() => number) +``` + +El desplazamiento inicial a aplicar al virtualizador. Esto suele ser útil solo si está renderizando el virtualizador en un entorno de Renderizado del lado del servidor (SSR). + +### `getItemKey` + +```tsx +getItemKey?: (index: number) => Key +``` + +Esta función recibe el índice de cada elemento y debe devolver una clave única para ese elemento. La funcionalidad predeterminada de esta función es devolver el índice del elemento, pero debería sobrescribir esto cuando sea posible para devolver un identificador único para cada elemento en todo el conjunto. Esta función debe estar memorizada para evitar re-renderizados innecesarios. + +### `rangeExtractor` + +```tsx +rangeExtractor?: (range: Range) => number[] +``` + +Esta función recibe los índices del rango visible y debe devolver un arreglo de índices a renderizar. Esto es útil si necesita agregar o eliminar elementos del virtualizador manualmente independientemente del rango visible, por ejemplo, renderizar elementos fijos, encabezados, pies de página, etc. La implementación predeterminada del extractor de rango devolverá los índices del rango visible y se exporta como `defaultRangeExtractor`. + +### `scrollToFn` + +```tsx +scrollToFn?: ( + offset: number, + options: { adjustments?: number; behavior?: 'auto' | 'smooth' }, + instance: Virtualizer, +) => void +``` + +Una función opcional que (si se proporciona) debe implementar el comportamiento de desplazamiento para su scrollElement. Se llamará con los siguientes argumentos: + +- Un `offset` (en píxeles) hacia el cual desplazarse. +- Un objeto que indica si hubo una diferencia entre el tamaño estimado y el tamaño real (`adjustments`) y/o si el desplazamiento se llamó con una animación suave (`behavior`). +- La instancia del virtualizador en sí. + +Tenga en cuenta que las implementaciones de desplazamiento incorporadas se exportan como `elementScroll` y `windowScroll`, que se configuran automáticamente mediante las funciones del adaptador de framework como `useVirtualizer` o `useWindowVirtualizer`. + +> ⚠️ Intentar usar smoothScroll con elementos medidos dinámicamente no funcionará. + +### `observeElementRect` + +```tsx +observeElementRect: ( + instance: Virtualizer, + cb: (rect: Rect) => void, +) => void | (() => void) +``` + +Una función opcional que, si se proporciona, se llama cuando cambia el scrollElement y debe implementar la medición inicial y el monitoreo continuo del `Rect` del scrollElement (un objeto con `width` y `height`). Se llama con la instancia (que también le da acceso al scrollElement mediante `instance.scrollElement`). Las implementaciones incorporadas se exportan como `observeElementRect` y `observeWindowRect`, que se configuran automáticamente para usted mediante las funciones exportadas del adaptador de framework como `useVirtualizer` o `useWindowVirtualizer`. + +### `observeElementOffset` + +```tsx +observeElementOffset: ( + instance: Virtualizer, + cb: (offset: number) => void, + ) => void | (() => void) +``` + +Una función opcional que, si se proporciona, se llama cuando cambia el scrollElement y debe implementar la medición inicial y el monitoreo continuo del desplazamiento del scrollElement (un número). Se llama con la instancia (que también le da acceso al scrollElement mediante `instance.scrollElement`). Las implementaciones incorporadas se exportan como `observeElementOffset` y `observeWindowOffset`, que se configuran automáticamente para usted mediante las funciones exportadas del adaptador de framework como `useVirtualizer` o `useWindowVirtualizer`. + +### `measureElement` + +```tsx +measureElement?: ( + element: TItemElement, + entry: ResizeObserverEntry | undefined, + instance: Virtualizer, +) => number +``` + +Esta función opcional se llama cuando el virtualizador necesita medir dinámicamente el tamaño (ancho o alto) de un elemento. + +> 🧠 Puede usar `instance.options.horizontal` para determinar si se debe medir el ancho o el alto del elemento. + +### `scrollMargin` + +```tsx +scrollMargin?: number +``` + +Con esta opción, puede especificar de dónde debe originarse el desplazamiento. Normalmente, este valor representa el espacio entre el inicio del elemento desplazable y el comienzo de la lista. Esto es especialmente útil en escenarios comunes, como cuando tiene un encabezado antes de un virtualizador de ventana o cuando se utilizan múltiples virtualizadores dentro de un solo elemento desplazable. Si está utilizando posicionamiento absoluto de elementos, debe tener en cuenta el `scrollMargin` en su transformación CSS: +```tsx +transform: `translateY(${ + virtualRow.start - rowVirtualizer.options.scrollMargin +}px)` +``` +Para medir dinámicamente el valor de `scrollMargin`, puede usar `getBoundingClientRect()` o ResizeObserver. Esto es útil en escenarios donde los elementos encima de su lista virtual pueden cambiar su altura. + +### `gap` + +```tsx +gap?: number +``` + +Esta opción le permite establecer el espacio entre los elementos en la lista virtualizada. Es particularmente útil para mantener una separación visual consistente entre los elementos sin tener que ajustar manualmente el margen o el relleno de cada elemento. El valor se especifica en píxeles. + +### `lanes` + +```tsx +lanes: number +``` + +El número de carriles en los que se divide la lista (también conocidos como columnas para listas verticales y filas para listas horizontales). + +### `isScrollingResetDelay` + +```tsx +isScrollingResetDelay: number +``` + +Esta opción le permite especificar la duración a esperar después del último evento de desplazamiento antes de reiniciar la propiedad de instancia isScrolling. El valor predeterminado es 150 milisegundos. + +La implementación de esta opción está impulsada por la necesidad de un mecanismo confiable para manejar el comportamiento de desplazamiento en diferentes navegadores. Hasta que todos los navegadores admitan uniformemente el evento scrollEnd. + +### `useScrollendEvent` + +```tsx +useScrollendEvent: boolean +``` + +Determina si se debe usar el evento nativo scrollend para detectar cuándo se ha detenido el desplazamiento. Si se establece en false, se usa una alternativa con debounce para reiniciar la propiedad de instancia isScrolling después de isScrollingResetDelay milisegundos. El valor predeterminado es `false`. + +La implementación de esta opción está impulsada por la necesidad de un mecanismo confiable para manejar el comportamiento de desplazamiento en diferentes navegadores. Hasta que todos los navegadores admitan uniformemente el evento scrollEnd. + +### `isRtl` + +```tsx +isRtl: boolean +``` + +Si se debe invertir el desplazamiento horizontal para admitir configuraciones regionales de idioma de derecha a izquierda. + +### `useAnimationFrameWithResizeObserver` + +```tsx +useAnimationFrameWithResizeObserver: boolean +``` + +Esta opción habilita el envolver las mediciones de ResizeObserver en requestAnimationFrame para actualizaciones más suaves y menos bloqueos de diseño. El valor predeterminado es `false`. + +Ayuda a prevenir el error "ResizeObserver loop completed with undelivered notifications" al asegurar que las mediciones se alineen con el ciclo de renderizado. Esto puede mejorar el rendimiento y reducir el temblor en la interfaz de usuario, especialmente al redimensionar elementos dinámicamente. Sin embargo, dado que ResizeObserver ya se ejecuta de forma asíncrona, agregar requestAnimationFrame puede introducir un ligero retraso en las mediciones, lo que podría ser notable en algunos casos. Si las operaciones de redimensionamiento son ligeras y no causan reflujos, habilitar esta opción puede no proporcionar beneficios significativos. + +## Instancia del Virtualizer + +Las siguientes propiedades y métodos están disponibles en la instancia del virtualizador: + +### `options` + +```tsx +options: readonly Required> +``` + +Las opciones actuales para el virtualizador. Esta propiedad se actualiza mediante su adaptador de framework y es de solo lectura. + +### `scrollElement` + +```tsx +scrollElement: readonly TScrollElement | null +``` + +El scrollElement actual para el virtualizador. Esta propiedad se actualiza mediante su adaptador de framework y es de solo lectura. + +### `getVirtualItems` + +```tsx +type getVirtualItems = () => VirtualItem[] +``` + +Devuelve los elementos virtuales para el estado actual del virtualizador. + +### `getVirtualIndexes` + +```tsx +type getVirtualIndexes = () => number[] +``` + +Devuelve los índices de fila virtual para el estado actual del virtualizador. + +### `scrollToOffset` + +```tsx +scrollToOffset: ( + toOffset: number, + options?: { + align?: 'start' | 'center' | 'end' | 'auto', + behavior?: 'auto' | 'smooth' + } +) => void +``` + +Desplaza el virtualizador al desplazamiento en píxeles proporcionado. Opcionalmente, puede pasar un modo de alineación para anclar el desplazamiento a una parte específica del scrollElement. + +### `scrollToIndex` + +```tsx +scrollToIndex: ( + index: number, + options?: { + align?: 'start' | 'center' | 'end' | 'auto', + behavior?: 'auto' | 'smooth' + } +) => void +``` + +Desplaza el virtualizador al elemento del índice proporcionado. Opcionalmente, puede pasar un modo de alineación para anclar el desplazamiento a una parte específica del scrollElement. + +### `getTotalSize` + +```tsx +getTotalSize: () => number +``` + +Devuelve el tamaño total en píxeles para los elementos virtualizados. Esta medida cambiará incrementalmente si elige medir dinámicamente sus elementos a medida que se renderizan. + +### `measure` + +```tsx +measure: () => void +``` + +Reinicia cualquier medición previa de elementos. + +### `measureElement` + +```tsx +measureElement: (el: TItemElement | null) => void +``` + +Mide el elemento usando su opción `measureElement` configurada en el virtualizador. Usted es responsable de llamar a esto en su marcado del virtualizador cuando el componente se renderiza (por ejemplo, usando algo como la propiedad de callback ref de React) y también agregando `data-index` + +```tsx +
...
+``` + +Por defecto, la opción `measureElement` del virtualizador está configurada para medir elementos con `getBoundingClientRect()`. + +### `resizeItem` + +```tsx +resizeItem: (index: number, size: number) => void +``` + +Cambia manualmente el tamaño del elemento virtualizado. Use esta función para establecer manualmente el tamaño calculado para este índice. Útil en ocasiones cuando se usa alguna transición de transformación personalizada y conoce el tamaño del elemento transformado de antemano. + +También puede usar este método con un ResizeObserver limitado en lugar de `Virtualizer.measureElement` para reducir los re-renderizados. + +> ⚠️ Tenga en cuenta que cambiar manualmente el tamaño de un elemento cuando usa `Virtualizer.measureElement` para monitorear ese elemento resultará en un comportamiento impredecible, ya que `Virtualizer.measureElement` también está cambiando el tamaño. Sin embargo, puede usar uno de resizeItem o measureElement en la misma instancia de virtualizador pero en diferentes índices de elementos. + +### `scrollRect` + +```tsx +scrollRect: Rect +``` + +`Rect` actual del elemento de desplazamiento. + +### `shouldAdjustScrollPositionOnItemSizeChange` + +```tsx +shouldAdjustScrollPositionOnItemSizeChange: undefined | ((item: VirtualItem, delta: number, instance: Virtualizer) => boolean) +``` + +El método shouldAdjustScrollPositionOnItemSizeChange permite un control detallado sobre el ajuste de la posición de desplazamiento cuando el tamaño de los elementos renderizados dinámicamente difiere del tamaño estimado. Al saltar en medio de la lista y desplazarse hacia atrás, los nuevos elementos pueden tener un tamaño diferente al tamaño estimado inicialmente. Esta discrepancia puede hacer que los elementos subsiguientes se desplacen, lo que podría interrumpir la experiencia de desplazamiento del usuario, especialmente al navegar hacia atrás en la lista. + +### `isScrolling` + +```tsx +isScrolling: boolean +``` + +Bandera booleana que indica si la lista se está desplazando actualmente. + +### `scrollDirection` + +```tsx +scrollDirection: 'forward' | 'backward' | null +``` + +Esta opción indica la dirección del desplazamiento, con posibles valores 'forward' para desplazarse hacia abajo y 'backward' para desplazarse hacia arriba. El valor se establece en null cuando no hay un desplazamiento activo. + +### `scrollOffset` + +```tsx +scrollOffset: number +``` + +Esta opción representa la posición actual de desplazamiento a lo largo del eje de desplazamiento. Se mide en píxeles desde el punto de inicio del área desplazable. diff --git a/docs/es/config.json b/docs/es/config.json new file mode 100644 index 000000000..ed6d13c3a --- /dev/null +++ b/docs/es/config.json @@ -0,0 +1,258 @@ +{ + "$schema": "https://raw.githubusercontent.com/TanStack/tanstack.com/main/tanstack-docs-config.schema.json", + "docSearch": { + "appId": "", + "indexName": "", + "apiKey": "" + }, + "sections": [ + { + "label": "Comienzo", + "children": [ + { + "label": "Introducción", + "to": "introduction" + }, + { + "label": "Instalación", + "to": "installation" + } + ], + "frameworks": [ + { + "label": "react", + "children": [ + { + "label": "React Virtual", + "to": "framework/react/react-virtual" + } + ] + }, + { + "label": "angular", + "children": [ + { + "label": "Angular Virtual", + "to": "framework/angular/angular-virtual" + } + ] + }, + { + "label": "solid", + "children": [ + { + "label": "Solid Virtual", + "to": "framework/solid/solid-virtual" + } + ] + }, + { + "label": "svelte", + "children": [ + { + "label": "Svelte Virtual", + "to": "framework/svelte/svelte-virtual" + } + ] + }, + { + "label": "vue", + "children": [ + { + "label": "Vue Virtual", + "to": "framework/vue/vue-virtual" + } + ] + } + ] + }, + { + "label": "API principales", + "children": [ + { + "label": "Virtualizador", + "to": "api/virtualizer" + }, + { + "label": "Elemento virtual", + "to": "api/virtual-item" + } + ] + }, + { + "label": "Ejemplos", + "children": [], + "frameworks": [ + { + "label": "angular", + "children": [ + { + "to": "framework/angular/examples/fixed", + "label": "Fijo" + }, + { + "to": "framework/angular/examples/variable", + "label": "Variable" + }, + { + "to": "framework/angular/examples/dynamic", + "label": "Dinámico" + }, + { + "to": "framework/angular/examples/padding", + "label": "Relleno" + }, + { + "to": "framework/angular/examples/sticky", + "label": "Pegajoso" + }, + { + "to": "framework/angular/examples/infinite-scroll", + "label": "Desplazamiento infinito" + }, + { + "to": "framework/angular/examples/smooth-scroll", + "label": "Desplazamiento suave" + }, + { + "to": "framework/angular/examples/table", + "label": "Tabla" + }, + { + "to": "framework/angular/examples/window", + "label": "Ventana" + } + ] + }, + { + "label": "react", + "children": [ + { + "to": "framework/react/examples/fixed", + "label": "Fijo" + }, + { + "to": "framework/react/examples/variable", + "label": "Variable" + }, + { + "to": "framework/react/examples/dynamic", + "label": "Dinámico" + }, + { + "to": "framework/react/examples/padding", + "label": "Relleno" + }, + { + "to": "framework/react/examples/sticky", + "label": "Pegajoso" + }, + { + "to": "framework/react/examples/infinite-scroll", + "label": "Desplazamiento infinito" + }, + { + "to": "framework/react/examples/smooth-scroll", + "label": "Desplazamiento suave" + }, + { + "to": "framework/react/examples/table", + "label": "Tabla" + }, + { + "to": "framework/react/examples/window", + "label": "Ventana" + } + ] + }, + { + "label": "svelte", + "children": [ + { + "to": "framework/svelte/examples/fixed", + "label": "Fijo" + }, + { + "to": "framework/svelte/examples/variable", + "label": "Variable" + }, + { + "to": "framework/svelte/examples/dynamic", + "label": "Dinámico" + }, + { + "to": "framework/svelte/examples/sticky", + "label": "Pegajoso" + }, + { + "to": "framework/svelte/examples/infinite-scroll", + "label": "Desplazamiento infinito" + }, + { + "to": "framework/svelte/examples/smooth-scroll", + "label": "Desplazamiento suave" + }, + { + "to": "framework/svelte/examples/table", + "label": "Tabla" + } + ] + }, + { + "label": "vue", + "children": [ + { + "to": "framework/vue/examples/fixed", + "label": "Fijo" + }, + { + "to": "framework/vue/examples/variable", + "label": "Variable" + }, + { + "to": "framework/vue/examples/dynamic", + "label": "Dinámico" + }, + { + "to": "framework/vue/examples/sticky", + "label": "Pegajoso" + }, + { + "to": "framework/vue/examples/infinite-scroll", + "label": "Desplazamiento infinito" + }, + { + "to": "framework/vue/examples/smooth-scroll", + "label": "Desplazamiento suave" + }, + { + "to": "framework/vue/examples/table", + "label": "Tabla" + }, + { + "to": "framework/vue/examples/padding", + "label": "Relleno" + }, + { + "to": "framework/vue/examples/scroll-padding", + "label": "Relleno de desplazamiento" + } + ] + }, + { + "label": "lit", + "children": [ + { + "to": "framework/lit/examples/fixed", + "label": "Fijo" + }, + { + "to": "framework/lit/examples/dynamic", + "label": "Dinámico" + } + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/docs/es/framework/angular/angular-virtual.md b/docs/es/framework/angular/angular-virtual.md new file mode 100644 index 000000000..ae1777f05 --- /dev/null +++ b/docs/es/framework/angular/angular-virtual.md @@ -0,0 +1,35 @@ +--- +source-updated-at: '2024-08-19T19:18:26.000Z' +translation-updated-at: '2025-05-02T20:34:52.175Z' +title: Angular Virtual +--- +El adaptador `@tanstack/angular-virtual` es un envoltorio alrededor de la lógica virtual principal. + +## `injectVirtualizer` + +```ts +function injectVirtualizer( + options: PartialKeys< + Omit, 'getScrollElement'>, + 'observeElementRect' | 'observeElementOffset' | 'scrollToFn' + > & { scrollElement: ElementRef | TScrollElement | undefined }, +): AngularVirtualizer +``` + +Esta función devuelve una instancia de `AngularVirtualizer` configurada para trabajar con un elemento HTML como scrollElement. + +## `injectWindowVirtualizer` + +```ts +function injectWindowVirtualizer( + options: PartialKeys< + VirtualizerOptions, + | 'getScrollElement' + | 'observeElementRect' + | 'observeElementOffset' + | 'scrollToFn' + >, +): AngularVirtualizer +``` + +Esta función devuelve una instancia de `AngularVirtualizer` basada en la ventana, configurada para trabajar con la ventana como scrollElement. diff --git a/docs/es/framework/lit/lit-virtual.md b/docs/es/framework/lit/lit-virtual.md new file mode 100644 index 000000000..d236cff3f --- /dev/null +++ b/docs/es/framework/lit/lit-virtual.md @@ -0,0 +1,37 @@ +--- +source-updated-at: '2024-06-24T18:08:48.000Z' +translation-updated-at: '2025-05-06T23:02:41.438Z' +title: Lit Virtual +--- +El adaptador `@tanstack/lit-virtual` es un envoltorio alrededor de la lógica virtual principal. + +## `createVirtualizer` + +```tsx + +private virtualizerController = new VirtualizerController( + options: PartialKeys< VirtualizerOptions, + 'observeElementRect' | 'observeElementOffset' | 'scrollToFn' +) +``` + +Esta clase representa una instancia estándar de `Virtualizer` configurada para funcionar con un elemento HTML como scrollElement. +Esto creará un Lit Controller (Controlador de Lit) que puede ser accedido en el método render del elemento. + +```tsx +render() { + const virtualizer = this.virtualizerController.getVirtualizer(); + const virtualItems = virtualizer.getVirtualItems(); +} +) +``` + +## `createWindowVirtualizer` + +```tsx +private windowVirtualizerController = new WindowVirtualizerController( + options: PartialKeys< VirtualizerOptions, + 'getScrollElement' | 'observeElementRect' | 'observeElementOffset' | 'scrollToFn' +``` + +Esta clase representa una instancia de `Virtualizer` basada en ventana, configurada para funcionar con un elemento HTML como scrollElement. diff --git a/docs/es/framework/react/react-virtual.md b/docs/es/framework/react/react-virtual.md new file mode 100644 index 000000000..0d7e8589d --- /dev/null +++ b/docs/es/framework/react/react-virtual.md @@ -0,0 +1,35 @@ +--- +source-updated-at: '2024-01-25T21:23:10.000Z' +translation-updated-at: '2025-05-02T20:34:24.079Z' +title: React Virtual +--- +El adaptador `@tanstack/react-virtual` es un envoltorio alrededor de la lógica central de virtualización. + +## `useVirtualizer` + +```tsx +function useVirtualizer( + options: PartialKeys< + VirtualizerOptions, + 'observeElementRect' | 'observeElementOffset' | 'scrollToFn' + >, +): Virtualizer +``` + +Esta función retorna una instancia estándar de `Virtualizer` configurada para trabajar con un elemento HTML como el scrollElement. + +## `useWindowVirtualizer` + +```tsx +function useWindowVirtualizer( + options: PartialKeys< + VirtualizerOptions, + | 'getScrollElement' + | 'observeElementRect' + | 'observeElementOffset' + | 'scrollToFn' + >, +): Virtualizer +``` + +Esta función retorna una instancia de `Virtualizer` basada en la ventana, configurada para trabajar con el objeto window como el scrollElement. diff --git a/docs/es/framework/solid/solid-virtual.md b/docs/es/framework/solid/solid-virtual.md new file mode 100644 index 000000000..f9f13f74a --- /dev/null +++ b/docs/es/framework/solid/solid-virtual.md @@ -0,0 +1,35 @@ +--- +source-updated-at: '2024-01-25T21:23:10.000Z' +translation-updated-at: '2025-05-02T20:35:18.258Z' +title: Solid Virtual +--- +El adaptador `@tanstack/solid-virtual` es un envoltorio alrededor de la lógica virtual principal. + +## `createVirtualizer` + +```tsx +function createVirtualizer( + options: PartialKeys< + VirtualizerOptions, + 'observeElementRect' | 'observeElementOffset' | 'scrollToFn' + >, +): Virtualizer +``` + +Esta función devuelve una instancia estándar de `Virtualizer` configurada para trabajar con un elemento HTML como el scrollElement. + +## `createWindowVirtualizer` + +```tsx +function createWindowVirtualizer( + options: PartialKeys< + VirtualizerOptions, + | 'getScrollElement' + | 'observeElementRect' + | 'observeElementOffset' + | 'scrollToFn' + >, +): Virtualizer +``` + +Esta función devuelve una instancia de `Virtualizer` basada en la ventana, configurada para trabajar con la ventana como el scrollElement. diff --git a/docs/es/framework/svelte/svelte-virtual.md b/docs/es/framework/svelte/svelte-virtual.md new file mode 100644 index 000000000..4c16a1ca5 --- /dev/null +++ b/docs/es/framework/svelte/svelte-virtual.md @@ -0,0 +1,37 @@ +--- +source-updated-at: '2024-01-25T21:23:10.000Z' +translation-updated-at: '2025-05-02T20:35:05.271Z' +title: Svelte Virtual +--- +# Svelte Virtual + +El adaptador `@tanstack/svelte-virtual` es un envoltorio alrededor de la lógica virtual principal. + +## `createVirtualizer` + +```tsx +function createVirtualizer( + options: PartialKeys< + VirtualizerOptions, + 'observeElementRect' | 'observeElementOffset' | 'scrollToFn' + >, +): Virtualizer +``` + +Esta función devuelve una instancia estándar de `Virtualizer` configurada para trabajar con un elemento HTML como scrollElement. + +## `createWindowVirtualizer` + +```tsx +function createWindowVirtualizer( + options: PartialKeys< + VirtualizerOptions, + | 'getScrollElement' + | 'observeElementRect' + | 'observeElementOffset' + | 'scrollToFn' + >, +): Virtualizer +``` + +Esta función devuelve una instancia de `Virtualizer` basada en la ventana, configurada para trabajar con window como scrollElement. diff --git a/docs/es/framework/vue/vue-virtual.md b/docs/es/framework/vue/vue-virtual.md new file mode 100644 index 000000000..6e829233f --- /dev/null +++ b/docs/es/framework/vue/vue-virtual.md @@ -0,0 +1,37 @@ +--- +source-updated-at: '2024-06-01T09:52:04.000Z' +translation-updated-at: '2025-05-02T20:34:37.416Z' +title: Vue Virtual +--- +# Vue Virtual + +El adaptador `@tanstack/vue-virtual` es un envoltorio alrededor de la lógica virtual principal. + +## `useVirtualizer` + +```tsx +function useVirtualizer( + options: PartialKeys< + VirtualizerOptions, + 'observeElementRect' | 'observeElementOffset' | 'scrollToFn' + >, +): Virtualizer +``` + +Esta función retorna una instancia estándar de `Virtualizer` configurada para trabajar con un elemento HTML como scrollElement. + +## `useWindowVirtualizer` + +```tsx +function useWindowVirtualizer( + options: PartialKeys< + VirtualizerOptions, + | 'getScrollElement' + | 'observeElementRect' + | 'observeElementOffset' + | 'scrollToFn' + >, +): Virtualizer +``` + +Esta función retorna una instancia de `Virtualizer` basada en la ventana, configurada para trabajar con window como scrollElement. diff --git a/docs/es/installation.md b/docs/es/installation.md new file mode 100644 index 000000000..dd72c5edb --- /dev/null +++ b/docs/es/installation.md @@ -0,0 +1,52 @@ +--- +source-updated-at: '2025-03-07T09:19:44.000Z' +translation-updated-at: '2025-05-02T20:33:47.770Z' +title: Instalación +--- +# Instalación + +Antes de profundizar en la API, ¡vamos a configurar su entorno! + +Instale su adaptador de TanStack Virtual como una dependencia utilizando su gestor de paquetes npm favorito. + +## React Virtual + +```bash +npm install @tanstack/react-virtual +``` + +## Solid Virtual + +```bash +npm install @tanstack/solid-virtual +``` + +## Svelte Virtual + +```bash +npm install @tanstack/svelte-virtual +``` + +## Vue Virtual + +```bash +npm install @tanstack/vue-virtual +``` + +## Lit Virtual + +```bash +$ npm install @tanstack/lit-virtual +``` + +## Angular Virtual + +```bash +$ npm install @tanstack/angular-virtual +``` + +## Virtual Core (sin framework) + +```bash +npm install @tanstack/virtual-core +``` diff --git a/docs/es/introduction.md b/docs/es/introduction.md new file mode 100644 index 000000000..dabcae95e --- /dev/null +++ b/docs/es/introduction.md @@ -0,0 +1,71 @@ +--- +source-updated-at: '2024-11-25T13:01:52.000Z' +translation-updated-at: '2025-05-02T20:33:34.311Z' +title: Introducción +--- +# Introducción + +TanStack Virtual es una utilidad de interfaz de usuario sin cabeza (headless UI) para virtualizar listas largas de elementos en JS/TS, React, Vue, Svelte, Solid, Lit y Angular. No es un componente, por lo tanto no incluye ni renderiza ningún marcado o estilos por usted. Si bien esto requiere un poco de marcado y estilos de su parte, usted conservará el 100% de control sobre sus estilos, diseño e implementación. + +## El Virtualizador + +En el núcleo de TanStack Virtual se encuentra el `Virtualizer`. Los virtualizadores pueden orientarse en los ejes vertical (predeterminado) u horizontal, lo que hace posible lograr virtualización vertical, horizontal e incluso similar a una cuadrícula al combinar las dos configuraciones de ejes. + +Aquí hay un ejemplo rápido de cómo se ve la virtualización de una lista larga dentro de un div usando TanStack Virtual en React: + +```tsx +import { useVirtualizer } from '@tanstack/react-virtual'; + +function App() { + // The scrollable element for your list + const parentRef = React.useRef(null) + + // The virtualizer + const rowVirtualizer = useVirtualizer({ + count: 10000, + getScrollElement: () => parentRef.current, + estimateSize: () => 35, + }) + + return ( + <> + {/* The scrollable element for your list */} +
+ {/* The large inner element to hold all of the items */} +
+ {/* Only the visible items in the virtualizer, manually positioned to be in view */} + {rowVirtualizer.getVirtualItems().map((virtualItem) => ( +
+ Row {virtualItem.index} +
+ ))} +
+
+ + ) +} +``` + +¡Profundicemos en más ejemplos! diff --git a/docs/fr/api/virtual-item.md b/docs/fr/api/virtual-item.md new file mode 100644 index 000000000..3ce37e6e8 --- /dev/null +++ b/docs/fr/api/virtual-item.md @@ -0,0 +1,68 @@ +--- +source-updated-at: '2024-08-29T09:26:23.000Z' +translation-updated-at: '2025-05-02T20:42:27.650Z' +title: VirtualItem +--- +# VirtualItem + +L'objet `VirtualItem` représente un élément unique renvoyé par le virtualiseur. Il contient les informations nécessaires pour afficher l'élément dans l'espace de coordonnées du scrollElement de votre virtualiseur, ainsi que d'autres propriétés et fonctions utiles. + +```tsx +export interface VirtualItem { + key: string | number | bigint + index: number + start: number + end: number + size: number +} +``` + +Les propriétés et méthodes suivantes sont disponibles sur chaque objet VirtualItem : + +### `key` + +```tsx +key: string | number | bigint +``` + +La clé unique de l'élément. Par défaut, il s'agit de l'index de l'élément, mais cela peut être configuré via l'option `getItemKey` du Virtualizer. + +### `index` + +```tsx +index: number +``` + +L'index de l'élément. + +### `start` + +```tsx +start: number +``` + +Le décalage en pixels du début de l'élément. Cela est généralement mappé à une propriété CSS ou à une transformation comme `top/left` ou `translateX/translateY`. + +### `end` + +```tsx +end: number +``` + +Le décalage en pixels de la fin de l'élément. Cette valeur n'est pas nécessaire pour la plupart des mises en page, mais peut être utile, c'est pourquoi nous l'avons incluse. + +### `size` + +```tsx +size: number +``` + +La taille de l'élément. Cela est généralement mappé à une propriété CSS comme `width/height`. Avant qu'un élément ne soit mesuré avec la méthode `VirtualItem.measureElement`, cette valeur correspondra à la taille estimée renvoyée par votre option `estimateSize` du virtualiseur. Après la mesure d'un élément (si vous choisissez de le mesurer), cette valeur sera le nombre renvoyé par votre option `measureElement` du virtualiseur (qui par défaut est configurée pour mesurer les éléments avec `getBoundingClientRect()`). + +### `lane` + +```tsx +lane: number +``` + +L'index de la ligne (lane) de l'élément. Dans les listes régulières, il sera toujours défini sur `0`, mais devient utile pour les mises en page de type maçonnerie (voir les exemples variables pour plus de détails). diff --git a/docs/fr/api/virtualizer.md b/docs/fr/api/virtualizer.md new file mode 100644 index 000000000..b20e18412 --- /dev/null +++ b/docs/fr/api/virtualizer.md @@ -0,0 +1,425 @@ +--- +source-updated-at: '2025-05-05T15:05:35.000Z' +translation-updated-at: '2025-05-06T23:10:21.592Z' +title: Virtualizer +--- +# Virtualizer + +La classe `Virtualizer` est au cœur de TanStack Virtual. Les instances de Virtualizer sont généralement créées pour vous par l'adaptateur de votre framework, mais vous recevez directement le virtualizer. + +```tsx +export class Virtualizer { + constructor(options: VirtualizerOptions) +} +``` + +## Options obligatoires + +### `count` + +```tsx +count: number +``` + +Le nombre total d'éléments à virtualiser. + +### `getScrollElement` + +```tsx +getScrollElement: () => TScrollElement +``` + +Une fonction qui retourne l'élément scrollable pour le virtualizer. Elle peut retourner null si l'élément n'est pas encore disponible. + +### `estimateSize` + +```tsx +estimateSize: (index: number) => number +``` + +> 🧠 Si vous mesurez dynamiquement vos éléments, il est recommandé d'estimer la taille maximale possible (largeur/hauteur, dans une limite raisonnable) de vos éléments. Cela garantira que des fonctionnalités comme le défilement fluide auront plus de chances de fonctionner correctement. + +Cette fonction reçoit l'index de chaque élément et doit retourner la taille réelle (ou estimée si vous mesurez dynamiquement les éléments avec `virtualItem.measureElement`) pour chaque élément. Cette mesure doit retourner soit la largeur soit la hauteur selon l'orientation de votre virtualizer. + +## Options optionnelles + +### `enabled` + +```tsx +enabled?: boolean +``` + +Définissez à `false` pour désactiver les observateurs de scrollElement et réinitialiser l'état du virtualizer. + +### `debug` + +```tsx +debug?: boolean +``` + +Définissez à `true` pour activer les logs de débogage. + +### `initialRect` + +```tsx +initialRect?: Rect +``` + +Le `Rect` initial du scrollElement. Ceci est surtout utile si vous avez besoin d'exécuter le virtualizer dans un environnement SSR (Server-Side Rendering), sinon le initialRect sera calculé au montage par l'implémentation de `observeElementRect`. + +### `onChange` + +```tsx +onChange?: (instance: Virtualizer, sync: boolean) => void +``` + +Une fonction de rappel qui se déclenche lorsque l'état interne du virtualizer change. Elle reçoit l'instance du virtualizer et le paramètre sync. + +Le paramètre sync indique si le défilement est en cours. Il est `true` lorsque le défilement est en cours, et `false` lorsque le défilement est arrêté ou que d'autres actions (comme un redimensionnement) sont en cours. + +### `overscan` + +```tsx +overscan?: number +``` + +Le nombre d'éléments à rendre au-dessus et en dessous de la zone visible. Augmenter ce nombre augmentera le temps nécessaire pour rendre le virtualizer, mais pourrait réduire la probabilité de voir des éléments vides à rendu lent en haut et en bas du virtualizer lors du défilement. La valeur par défaut est `1`. + +### `horizontal` + +```tsx +horizontal?: boolean +``` + +Définissez ceci à `true` si votre virtualizer est orienté horizontalement. + +### `paddingStart` + +```tsx +paddingStart?: number +``` + +Le padding à appliquer au début du virtualizer en pixels. + +### `paddingEnd` + +```tsx +paddingEnd?: number +``` + +Le padding à appliquer à la fin du virtualizer en pixels. + +### `scrollPaddingStart` + +```tsx +scrollPaddingStart?: number +``` + +Le padding à appliquer au début du virtualizer en pixels lors du défilement vers un élément. + +### `scrollPaddingEnd` + +```tsx +scrollPaddingEnd?: number +``` + +Le padding à appliquer à la fin du virtualizer en pixels lors du défilement vers un élément. + +### `initialOffset` + +```tsx +initialOffset?: number | (() => number) +``` + +L'offset initial à appliquer au virtualizer. Ceci n'est généralement utile que si vous rendez le virtualizer dans un environnement SSR. + +### `getItemKey` + +```tsx +getItemKey?: (index: number) => Key +``` + +Cette fonction reçoit l'index de chaque élément et doit retourner une clé unique pour cet élément. La fonctionnalité par défaut de cette fonction est de retourner l'index de l'élément, mais vous devriez la remplacer si possible pour retourner un identifiant unique pour chaque élément dans l'ensemble complet. Cette fonction doit être mémoïsée pour éviter des rendus inutiles. + +### `rangeExtractor` + +```tsx +rangeExtractor?: (range: Range) => number[] +``` + +Cette fonction reçoit les index de la plage visible et doit retourner un tableau d'index à rendre. Ceci est utile si vous avez besoin d'ajouter ou de supprimer des éléments du virtualizer manuellement indépendamment de la plage visible, par exemple pour rendre des éléments fixes, des en-têtes, des pieds de page, etc. L'implémentation par défaut de l'extracteur de plage retourne les index de la plage visible et est exportée sous le nom `defaultRangeExtractor`. + +### `scrollToFn` + +```tsx +scrollToFn?: ( + offset: number, + options: { adjustments?: number; behavior?: 'auto' | 'smooth' }, + instance: Virtualizer, +) => void +``` + +Une fonction optionnelle qui (si fournie) doit implémenter le comportement de défilement pour votre scrollElement. Elle sera appelée avec les arguments suivants : + +- Un `offset` (en pixels) vers lequel faire défiler. +- Un objet indiquant s'il y a eu une différence entre la taille estimée et la taille réelle (`adjustments`) et/ou si le défilement a été appelé avec une animation fluide (`behavior`). +- L'instance du virtualizer elle-même. + +Notez que les implémentations de défilement intégrées sont exportées sous les noms `elementScroll` et `windowScroll`, qui sont automatiquement configurées par les fonctions d'adaptateur de framework comme `useVirtualizer` ou `useWindowVirtualizer`. + +> ⚠️ Tenter d'utiliser smoothScroll avec des éléments mesurés dynamiquement ne fonctionnera pas. + +### `observeElementRect` + +```tsx +observeElementRect: ( + instance: Virtualizer, + cb: (rect: Rect) => void, +) => void | (() => void) +``` + +Une fonction optionnelle qui, si elle est fournie, est appelée lorsque le scrollElement change et doit implémenter la mesure initiale et la surveillance continue du `Rect` du scrollElement (un objet avec `width` et `height`). Elle est appelée avec l'instance (qui vous donne également accès au scrollElement via `instance.scrollElement`). Les implémentations intégrées sont exportées sous les noms `observeElementRect` et `observeWindowRect` et sont automatiquement configurées pour vous par les fonctions exportées de votre adaptateur de framework comme `useVirtualizer` ou `useWindowVirtualizer`. + +### `observeElementOffset` + +```tsx +observeElementOffset: ( + instance: Virtualizer, + cb: (offset: number) => void, + ) => void | (() => void) +``` + +Une fonction optionnelle qui, si elle est fournie, est appelée lorsque le scrollElement change et doit implémenter la mesure initiale et la surveillance continue de l'offset de défilement du scrollElement (un nombre). Elle est appelée avec l'instance (qui vous donne également accès au scrollElement via `instance.scrollElement`). Les implémentations intégrées sont exportées sous les noms `observeElementOffset` et `observeWindowOffset` et sont automatiquement configurées pour vous par les fonctions exportées de votre adaptateur de framework comme `useVirtualizer` ou `useWindowVirtualizer`. + +### `measureElement` + +```tsx +measureElement?: ( + element: TItemElement, + entry: ResizeObserverEntry | undefined, + instance: Virtualizer, +) => number +``` + +Cette fonction optionnelle est appelée lorsque le virtualizer a besoin de mesurer dynamiquement la taille (largeur ou hauteur) d'un élément. + +> 🧠 Vous pouvez utiliser `instance.options.horizontal` pour déterminer si la largeur ou la hauteur de l'élément doit être mesurée. + +### `scrollMargin` + +```tsx +scrollMargin?: number +``` + +Avec cette option, vous pouvez spécifier d'où doit provenir l'offset de défilement. Typiquement, cette valeur représente l'espace entre le début de l'élément scrollable et le début de la liste. Ceci est particulièrement utile dans des scénarios courants comme lorsque vous avez un en-tête précédant un virtualizer de fenêtre ou lorsque plusieurs virtualizers sont utilisés dans un seul élément scrollable. Si vous utilisez un positionnement absolu des éléments, vous devez prendre en compte le `scrollMargin` dans votre transformation CSS : +```tsx +transform: `translateY(${ + virtualRow.start - rowVirtualizer.options.scrollMargin +}px)` +``` +Pour mesurer dynamiquement la valeur de `scrollMargin`, vous pouvez utiliser `getBoundingClientRect()` ou ResizeObserver. Ceci est utile dans les scénarios où les éléments au-dessus de votre liste virtuelle pourraient changer de hauteur. + +### `gap` + +```tsx +gap?: number +``` + +Cette option vous permet de définir l'espacement entre les éléments de la liste virtualisée. Elle est particulièrement utile pour maintenir une séparation visuelle cohérente entre les éléments sans avoir à ajuster manuellement la marge ou le padding de chaque élément. La valeur est spécifiée en pixels. + +### `lanes` + +```tsx +lanes: number +``` + +Le nombre de voies dans lesquelles la liste est divisée (également appelées colonnes pour les listes verticales et lignes pour les listes horizontales). + +### `isScrollingResetDelay` + +```tsx +isScrollingResetDelay: number +``` + +Cette option vous permet de spécifier la durée à attendre après le dernier événement de défilement avant de réinitialiser la propriété isScrolling de l'instance. La valeur par défaut est 150 millisecondes. + +L'implémentation de cette option est motivée par le besoin d'un mécanisme fiable pour gérer le comportement de défilement sur différents navigateurs. Jusqu'à ce que tous les navigateurs prennent en charge uniformément l'événement scrollEnd. + +### `useScrollendEvent` + +```tsx +useScrollendEvent: boolean +``` + +Détermine s'il faut utiliser l'événement natif scrollend pour détecter quand le défilement s'est arrêté. Si défini à false, un fallback avec debounce est utilisé pour réinitialiser la propriété isScrolling de l'instance après isScrollingResetDelay millisecondes. La valeur par défaut est `false`. + +L'implémentation de cette option est motivée par le besoin d'un mécanisme fiable pour gérer le comportement de défilement sur différents navigateurs. Jusqu'à ce que tous les navigateurs prennent en charge uniformément l'événement scrollEnd. + +### `isRtl` + +```tsx +isRtl: boolean +``` + +Détermine s'il faut inverser le défilement horizontal pour prendre en charge les locales de langue de droite à gauche. + +### `useAnimationFrameWithResizeObserver` + +```tsx +useAnimationFrameWithResizeObserver: boolean +``` + +Cette option permet d'encapsuler les mesures de ResizeObserver dans requestAnimationFrame pour des mises à jour plus fluides et une réduction du layout thrashing. La valeur par défaut est `false`. + +Elle aide à prévenir l'erreur "ResizeObserver loop completed with undelivered notifications" en s'assurant que les mesures s'alignent avec le cycle de rendu. Cela peut améliorer les performances et réduire les saccades de l'interface, surtout lors du redimensionnement dynamique d'éléments. Cependant, comme ResizeObserver s'exécute déjà de manière asynchrone, l'ajout de requestAnimationFrame peut introduire un léger délai dans les mesures, qui pourrait être perceptible dans certains cas. Si les opérations de redimensionnement sont légères et ne provoquent pas de reflows, activer cette option pourrait ne pas apporter de bénéfices significatifs. + +## Instance de Virtualizer + +Les propriétés et méthodes suivantes sont disponibles sur l'instance du virtualizer : + +### `options` + +```tsx +options: readonly Required> +``` + +Les options actuelles du virtualizer. Cette propriété est mise à jour via votre adaptateur de framework et est en lecture seule. + +### `scrollElement` + +```tsx +scrollElement: readonly TScrollElement | null +``` + +Le scrollElement actuel du virtualizer. Cette propriété est mise à jour via votre adaptateur de framework et est en lecture seule. + +### `getVirtualItems` + +```tsx +type getVirtualItems = () => VirtualItem[] +``` + +Retourne les éléments virtuels pour l'état actuel du virtualizer. + +### `getVirtualIndexes` + +```tsx +type getVirtualIndexes = () => number[] +``` + +Retourne les index des lignes virtuelles pour l'état actuel du virtualizer. + +### `scrollToOffset` + +```tsx +scrollToOffset: ( + toOffset: number, + options?: { + align?: 'start' | 'center' | 'end' | 'auto', + behavior?: 'auto' | 'smooth' + } +) => void +``` + +Fait défiler le virtualizer vers l'offset en pixels fourni. Vous pouvez optionnellement passer un mode d'alignement pour ancrer le défilement à une partie spécifique du scrollElement. + +### `scrollToIndex` + +```tsx +scrollToIndex: ( + index: number, + options?: { + align?: 'start' | 'center' | 'end' | 'auto', + behavior?: 'auto' | 'smooth' + } +) => void +``` + +Fait défiler le virtualizer vers l'élément de l'index fourni. Vous pouvez optionnellement passer un mode d'alignement pour ancrer le défilement à une partie spécifique du scrollElement. + +### `getTotalSize` + +```tsx +getTotalSize: () => number +``` + +Retourne la taille totale en pixels pour les éléments virtualisés. Cette mesure changera progressivement si vous choisissez de mesurer dynamiquement vos éléments lors de leur rendu. + +### `measure` + +```tsx +measure: () => void +``` + +Réinitialise toutes les mesures précédentes des éléments. + +### `measureElement` + +```tsx +measureElement: (el: TItemElement | null) => void +``` + +Mesure l'élément en utilisant votre option `measureElement` configurée du virtualizer. Vous êtes responsable d'appeler ceci dans votre balisage de virtualizer lorsque le composant est rendu (par exemple en utilisant quelque chose comme la prop de rappel ref de React) en ajoutant également `data-index` + +```tsx +
...
+``` + +Par défaut, l'option `measureElement` du virtualizer est configurée pour mesurer les éléments avec `getBoundingClientRect()`. + +### `resizeItem` + +```tsx +resizeItem: (index: number, size: number) => void +``` + +Change manuellement la taille de l'élément virtualisé. Utilisez cette fonction pour définir manuellement la taille calculée pour cet index. Utile dans les cas où vous utilisez une transition de morphing personnalisée et que vous connaissez à l'avance la taille de l'élément morphé. + +Vous pouvez également utiliser cette méthode avec un ResizeObserver throttlé au lieu de `Virtualizer.measureElement` pour réduire les re-rendus. + +> ⚠️ Soyez conscient que changer manuellement la taille d'un élément lors de l'utilisation de `Virtualizer.measureElement` pour surveiller cet élément entraînera un comportement imprévisible car `Virtualizer.measureElement` modifie également la taille. Cependant, vous pouvez utiliser l'une des méthodes resizeItem ou measureElement dans la même instance de virtualizer mais sur des index d'éléments différents. + +### `scrollRect` + +```tsx +scrollRect: Rect +``` + +`Rect` actuel de l'élément scrollable. + +### `shouldAdjustScrollPositionOnItemSizeChange` + +```tsx +shouldAdjustScrollPositionOnItemSizeChange: undefined | ((item: VirtualItem, delta: number, instance: Virtualizer) => boolean) +``` + +La méthode shouldAdjustScrollPositionOnItemSizeChange permet un contrôle précis de l'ajustement de la position de défilement lorsque la taille des éléments rendus dynamiquement diffère de la taille estimée. Lors d'un saut au milieu de la liste et d'un défilement vers l'arrière, les nouveaux éléments peuvent avoir une taille différente de la taille initialement estimée. Cette divergence peut provoquer un décalage des éléments suivants, perturbant potentiellement l'expérience de défilement de l'utilisateur, en particulier lors de la navigation vers l'arrière dans la liste. + +### `isScrolling` + +```tsx +isScrolling: boolean +``` + +Indicateur booléen indiquant si la liste est actuellement en cours de défilement. + +### `scrollDirection` + +```tsx +scrollDirection: 'forward' | 'backward' | null +``` + +Cette option indique la direction du défilement, avec les valeurs possibles 'forward' pour un défilement vers le bas et 'backward' pour un défilement vers le haut. La valeur est définie à null lorsqu'il n'y a pas de défilement actif. + +### `scrollOffset` + +```tsx +scrollOffset: number +``` + +Cette option représente la position actuelle de défilement le long de l'axe de défilement. Elle est mesurée en pixels à partir du point de départ de la zone scrollable. diff --git a/docs/fr/config.json b/docs/fr/config.json new file mode 100644 index 000000000..57084f02b --- /dev/null +++ b/docs/fr/config.json @@ -0,0 +1,258 @@ +{ + "$schema": "https://raw.githubusercontent.com/TanStack/tanstack.com/main/tanstack-docs-config.schema.json", + "docSearch": { + "appId": "", + "indexName": "", + "apiKey": "" + }, + "sections": [ + { + "label": "Premiers pas", + "children": [ + { + "label": "Introduction", + "to": "introduction" + }, + { + "label": "Installation", + "to": "installation" + } + ], + "frameworks": [ + { + "label": "react", + "children": [ + { + "label": "React Virtual", + "to": "framework/react/react-virtual" + } + ] + }, + { + "label": "angular", + "children": [ + { + "label": "Angular Virtual", + "to": "framework/angular/angular-virtual" + } + ] + }, + { + "label": "solid", + "children": [ + { + "label": "Solid Virtual", + "to": "framework/solid/solid-virtual" + } + ] + }, + { + "label": "svelte", + "children": [ + { + "label": "Svelte Virtual", + "to": "framework/svelte/svelte-virtual" + } + ] + }, + { + "label": "vue", + "children": [ + { + "label": "Vue Virtual", + "to": "framework/vue/vue-virtual" + } + ] + } + ] + }, + { + "label": "API principales", + "children": [ + { + "label": "Virtualizer", + "to": "api/virtualizer" + }, + { + "label": "VirtualItem", + "to": "api/virtual-item" + } + ] + }, + { + "label": "Exemples", + "children": [], + "frameworks": [ + { + "label": "angular", + "children": [ + { + "to": "framework/angular/examples/fixed", + "label": "Fixe" + }, + { + "to": "framework/angular/examples/variable", + "label": "Variable" + }, + { + "to": "framework/angular/examples/dynamic", + "label": "Dynamique" + }, + { + "to": "framework/angular/examples/padding", + "label": "Rembourrage" + }, + { + "to": "framework/angular/examples/sticky", + "label": "Collant" + }, + { + "to": "framework/angular/examples/infinite-scroll", + "label": "Défilement infini" + }, + { + "to": "framework/angular/examples/smooth-scroll", + "label": "Défilement fluide" + }, + { + "to": "framework/angular/examples/table", + "label": "Tableau" + }, + { + "to": "framework/angular/examples/window", + "label": "Fenêtre" + } + ] + }, + { + "label": "react", + "children": [ + { + "to": "framework/react/examples/fixed", + "label": "Fixe" + }, + { + "to": "framework/react/examples/variable", + "label": "Variable" + }, + { + "to": "framework/react/examples/dynamic", + "label": "Dynamique" + }, + { + "to": "framework/react/examples/padding", + "label": "Rembourrage" + }, + { + "to": "framework/react/examples/sticky", + "label": "Collant" + }, + { + "to": "framework/react/examples/infinite-scroll", + "label": "Défilement infini" + }, + { + "to": "framework/react/examples/smooth-scroll", + "label": "Défilement fluide" + }, + { + "to": "framework/react/examples/table", + "label": "Tableau" + }, + { + "to": "framework/react/examples/window", + "label": "Fenêtre" + } + ] + }, + { + "label": "svelte", + "children": [ + { + "to": "framework/svelte/examples/fixed", + "label": "Fixe" + }, + { + "to": "framework/svelte/examples/variable", + "label": "Variable" + }, + { + "to": "framework/svelte/examples/dynamic", + "label": "Dynamique" + }, + { + "to": "framework/svelte/examples/sticky", + "label": "Collant" + }, + { + "to": "framework/svelte/examples/infinite-scroll", + "label": "Défilement infini" + }, + { + "to": "framework/svelte/examples/smooth-scroll", + "label": "Défilement fluide" + }, + { + "to": "framework/svelte/examples/table", + "label": "Tableau" + } + ] + }, + { + "label": "vue", + "children": [ + { + "to": "framework/vue/examples/fixed", + "label": "Fixe" + }, + { + "to": "framework/vue/examples/variable", + "label": "Variable" + }, + { + "to": "framework/vue/examples/dynamic", + "label": "Dynamique" + }, + { + "to": "framework/vue/examples/sticky", + "label": "Collant" + }, + { + "to": "framework/vue/examples/infinite-scroll", + "label": "Défilement infini" + }, + { + "to": "framework/vue/examples/smooth-scroll", + "label": "Défilement fluide" + }, + { + "to": "framework/vue/examples/table", + "label": "Tableau" + }, + { + "to": "framework/vue/examples/padding", + "label": "Rembourrage" + }, + { + "to": "framework/vue/examples/scroll-padding", + "label": "Rembourrage de défilement" + } + ] + }, + { + "label": "lit", + "children": [ + { + "to": "framework/lit/examples/fixed", + "label": "Fixe" + }, + { + "to": "framework/lit/examples/dynamic", + "label": "Dynamique" + } + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/docs/fr/framework/angular/angular-virtual.md b/docs/fr/framework/angular/angular-virtual.md new file mode 100644 index 000000000..11fe93ba9 --- /dev/null +++ b/docs/fr/framework/angular/angular-virtual.md @@ -0,0 +1,35 @@ +--- +source-updated-at: '2024-08-19T19:18:26.000Z' +translation-updated-at: '2025-05-02T20:42:16.497Z' +title: Angular Virtual +--- +L'adaptateur `@tanstack/angular-virtual` est un wrapper autour de la logique virtuelle principale. + +## `injectVirtualizer` + +```ts +function injectVirtualizer( + options: PartialKeys< + Omit, 'getScrollElement'>, + 'observeElementRect' | 'observeElementOffset' | 'scrollToFn' + > & { scrollElement: ElementRef | TScrollElement | undefined }, +): AngularVirtualizer +``` + +Cette fonction retourne une instance `AngularVirtualizer` configurée pour fonctionner avec un élément HTML comme scrollElement. + +## `injectWindowVirtualizer` + +```ts +function injectWindowVirtualizer( + options: PartialKeys< + VirtualizerOptions, + | 'getScrollElement' + | 'observeElementRect' + | 'observeElementOffset' + | 'scrollToFn' + >, +): AngularVirtualizer +``` + +Cette fonction retourne une instance `AngularVirtualizer` basée sur la fenêtre, configurée pour utiliser la fenêtre comme scrollElement. diff --git a/docs/fr/framework/lit/lit-virtual.md b/docs/fr/framework/lit/lit-virtual.md new file mode 100644 index 000000000..6b611a41f --- /dev/null +++ b/docs/fr/framework/lit/lit-virtual.md @@ -0,0 +1,38 @@ +--- +source-updated-at: '2024-06-24T18:08:48.000Z' +translation-updated-at: '2025-05-06T23:07:51.071Z' +title: Lit Virtual +--- +# Lit Virtual + +L'adaptateur `@tanstack/lit-virtual` est un wrapper autour de la logique virtuelle principale. + +## `createVirtualizer` + +```tsx +private virtualizerController = new VirtualizerController( + options: PartialKeys< VirtualizerOptions, + 'observeElementRect' | 'observeElementOffset' | 'scrollToFn' +) +``` + +Cette classe représente une instance standard de `Virtualizer` configurée pour fonctionner avec un élément HTML comme scrollElement. +Cela créera un contrôleur Lit qui peut être accédé dans la méthode render de l'élément. + +```tsx +render() { + const virtualizer = this.virtualizerController.getVirtualizer(); + const virtualItems = virtualizer.getVirtualItems(); +} +) +``` + +## `createWindowVirtualizer` + +```tsx +private windowVirtualizerController = new WindowVirtualizerController( + options: PartialKeys< VirtualizerOptions, + 'getScrollElement' | 'observeElementRect' | 'observeElementOffset' | 'scrollToFn' +``` + +Cette classe représente une instance de `Virtualizer` basée sur la fenêtre, configurée pour fonctionner avec un élément HTML comme scrollElement. diff --git a/docs/fr/framework/react/react-virtual.md b/docs/fr/framework/react/react-virtual.md new file mode 100644 index 000000000..0d5734b1f --- /dev/null +++ b/docs/fr/framework/react/react-virtual.md @@ -0,0 +1,37 @@ +--- +source-updated-at: '2024-01-25T21:23:10.000Z' +translation-updated-at: '2025-05-02T20:42:15.674Z' +title: React Virtual +--- +# React Virtual + +L'adaptateur `@tanstack/react-virtual` est un wrapper autour de la logique virtuelle principale. + +## `useVirtualizer` + +```tsx +function useVirtualizer( + options: PartialKeys< + VirtualizerOptions, + 'observeElementRect' | 'observeElementOffset' | 'scrollToFn' + >, +): Virtualizer +``` + +Cette fonction retourne une instance standard de `Virtualizer` configurée pour fonctionner avec un élément HTML comme scrollElement. + +## `useWindowVirtualizer` + +```tsx +function useWindowVirtualizer( + options: PartialKeys< + VirtualizerOptions, + | 'getScrollElement' + | 'observeElementRect' + | 'observeElementOffset' + | 'scrollToFn' + >, +): Virtualizer +``` + +Cette fonction retourne une instance de `Virtualizer` basée sur la fenêtre, configurée pour utiliser la fenêtre comme scrollElement. diff --git a/docs/fr/framework/solid/solid-virtual.md b/docs/fr/framework/solid/solid-virtual.md new file mode 100644 index 000000000..0853e8035 --- /dev/null +++ b/docs/fr/framework/solid/solid-virtual.md @@ -0,0 +1,37 @@ +--- +source-updated-at: '2024-01-25T21:23:10.000Z' +translation-updated-at: '2025-05-02T20:42:15.781Z' +title: Solid Virtual +--- +# Solid Virtual + +L'adaptateur `@tanstack/solid-virtual` est un wrapper autour de la logique virtuelle principale. + +## `createVirtualizer` + +```tsx +function createVirtualizer( + options: PartialKeys< + VirtualizerOptions, + 'observeElementRect' | 'observeElementOffset' | 'scrollToFn' + >, +): Virtualizer +``` + +Cette fonction retourne une instance standard de `Virtualizer` configurée pour fonctionner avec un élément HTML comme scrollElement. + +## `createWindowVirtualizer` + +```tsx +function createWindowVirtualizer( + options: PartialKeys< + VirtualizerOptions, + | 'getScrollElement' + | 'observeElementRect' + | 'observeElementOffset' + | 'scrollToFn' + >, +): Virtualizer +``` + +Cette fonction retourne une instance de `Virtualizer` basée sur la fenêtre, configurée pour utiliser la fenêtre comme scrollElement. diff --git a/docs/fr/framework/svelte/svelte-virtual.md b/docs/fr/framework/svelte/svelte-virtual.md new file mode 100644 index 000000000..7edaab248 --- /dev/null +++ b/docs/fr/framework/svelte/svelte-virtual.md @@ -0,0 +1,37 @@ +--- +source-updated-at: '2024-01-25T21:23:10.000Z' +translation-updated-at: '2025-05-02T20:42:15.716Z' +title: Svelte Virtual +--- +# Svelte Virtual + +L'adaptateur `@tanstack/svelte-virtual` est un wrapper autour de la logique virtuelle principale. + +## `createVirtualizer` + +```tsx +function createVirtualizer( + options: PartialKeys< + VirtualizerOptions, + 'observeElementRect' | 'observeElementOffset' | 'scrollToFn' + >, +): Virtualizer +``` + +Cette fonction retourne une instance standard de `Virtualizer` configurée pour fonctionner avec un élément HTML comme scrollElement. + +## `createWindowVirtualizer` + +```tsx +function createWindowVirtualizer( + options: PartialKeys< + VirtualizerOptions, + | 'getScrollElement' + | 'observeElementRect' + | 'observeElementOffset' + | 'scrollToFn' + >, +): Virtualizer +``` + +Cette fonction retourne une instance de `Virtualizer` basée sur la fenêtre, configurée pour utiliser la fenêtre comme scrollElement. diff --git a/docs/fr/framework/vue/vue-virtual.md b/docs/fr/framework/vue/vue-virtual.md new file mode 100644 index 000000000..e46b280d1 --- /dev/null +++ b/docs/fr/framework/vue/vue-virtual.md @@ -0,0 +1,37 @@ +--- +source-updated-at: '2024-06-01T09:52:04.000Z' +translation-updated-at: '2025-05-02T20:42:15.863Z' +title: Vue Virtual +--- +# Vue Virtual + +L'adaptateur `@tanstack/vue-virtual` est un wrapper autour de la logique virtuelle principale. + +## `useVirtualizer` + +```tsx +function useVirtualizer( + options: PartialKeys< + VirtualizerOptions, + 'observeElementRect' | 'observeElementOffset' | 'scrollToFn' + >, +): Virtualizer +``` + +Cette fonction retourne une instance standard de `Virtualizer` configurée pour fonctionner avec un élément HTML comme scrollElement. + +## `useWindowVirtualizer` + +```tsx +function useWindowVirtualizer( + options: PartialKeys< + VirtualizerOptions, + | 'getScrollElement' + | 'observeElementRect' + | 'observeElementOffset' + | 'scrollToFn' + >, +): Virtualizer +``` + +Cette fonction retourne une instance de `Virtualizer` basée sur la fenêtre, configurée pour utiliser la fenêtre comme scrollElement. diff --git a/docs/fr/installation.md b/docs/fr/installation.md new file mode 100644 index 000000000..8d10f39ae --- /dev/null +++ b/docs/fr/installation.md @@ -0,0 +1,50 @@ +--- +source-updated-at: '2025-03-07T09:19:44.000Z' +translation-updated-at: '2025-05-02T20:41:40.875Z' +title: Installation +--- +Avant de plonger dans l'API, commençons par la configuration ! + +Installez votre adaptateur TanStack Virtual comme dépendance à l'aide de votre gestionnaire de paquets npm préféré. + +## React Virtual + +```bash +npm install @tanstack/react-virtual +``` + +## Solid Virtual + +```bash +npm install @tanstack/solid-virtual +``` + +## Svelte Virtual + +```bash +npm install @tanstack/svelte-virtual +``` + +## Vue Virtual + +```bash +npm install @tanstack/vue-virtual +``` + +## Lit Virtual + +```bash +$ npm install @tanstack/lit-virtual +``` + +## Angular Virtual + +```bash +$ npm install @tanstack/angular-virtual +``` + +## Virtual Core (sans framework) + +```bash +npm install @tanstack/virtual-core +``` diff --git a/docs/fr/introduction.md b/docs/fr/introduction.md new file mode 100644 index 000000000..cd4c846c1 --- /dev/null +++ b/docs/fr/introduction.md @@ -0,0 +1,69 @@ +--- +source-updated-at: '2024-11-25T13:01:52.000Z' +translation-updated-at: '2025-05-02T20:42:06.258Z' +title: Introduction +--- +TanStack Virtual est une utilitaire d'interface sans interface prédéfinie (headless UI) pour virtualiser de longues listes d'éléments en JS/TS, React, Vue, Svelte, Solid, Lit et Angular. Ce n'est pas un composant et ne fournit donc aucun balisage (markup) ou style pour vous. Bien que cela nécessite un peu de balisage et de styles de votre part, vous conservez un contrôle à 100 % sur vos styles, votre design et votre implémentation. + +## Le Virtualizer + +Au cœur de TanStack Virtual se trouve le `Virtualizer`. Les virtualiseurs peuvent être orientés sur les axes vertical (par défaut) ou horizontal, ce qui permet d'atteindre une virtualisation verticale, horizontale et même sous forme de grille en combinant les deux configurations d'axes. + +Voici un exemple rapide de ce à quoi ressemble la virtualisation d'une longue liste dans une div en utilisant TanStack Virtual avec React : + +```tsx +import { useVirtualizer } from '@tanstack/react-virtual'; + +function App() { + // L'élément scrollable pour votre liste + const parentRef = React.useRef(null) + + // Le virtualiseur + const rowVirtualizer = useVirtualizer({ + count: 10000, + getScrollElement: () => parentRef.current, + estimateSize: () => 35, + }) + + return ( + <> + {/* L'élément scrollable pour votre liste */} +
+ {/* Le grand élément intérieur pour contenir tous les éléments */} +
+ {/* Seuls les éléments visibles dans le virtualiseur, positionnés manuellement pour être visibles */} + {rowVirtualizer.getVirtualItems().map((virtualItem) => ( +
+ Ligne {virtualItem.index} +
+ ))} +
+
+ + ) +} +``` + +Explorons maintenant quelques exemples supplémentaires ! diff --git a/docs/ja/api/virtual-item.md b/docs/ja/api/virtual-item.md new file mode 100644 index 000000000..6118b3a90 --- /dev/null +++ b/docs/ja/api/virtual-item.md @@ -0,0 +1,68 @@ +--- +source-updated-at: '2024-08-29T09:26:23.000Z' +translation-updated-at: '2025-05-02T20:29:56.520Z' +title: バーチャルアイテム +--- +# VirtualItem + +`VirtualItem` オブジェクトは、バーチャライザーによって返される単一のアイテムを表します。このオブジェクトには、バーチャライザーの `scrollElement` 内の座標空間でアイテムをレンダリングするために必要な情報や、その他の便利なプロパティ/関数が含まれています。 + +```tsx +export interface VirtualItem { + key: string | number | bigint + index: number + start: number + end: number + size: number +} +``` + +各 `VirtualItem` オブジェクトで利用可能なプロパティとメソッドは以下の通りです: + +### `key` + +```tsx +key: string | number | bigint +``` + +アイテムの一意のキー。デフォルトではアイテムのインデックスですが、`getItemKey` バーチャライザーオプションで設定する必要があります。 + +### `index` + +```tsx +index: number +``` + +アイテムのインデックス。 + +### `start` + +```tsx +start: number +``` + +アイテムの開始ピクセルオフセット。通常、`top/left` や `translateX/translateY` などのCSSプロパティやトランスフォームにマッピングされます。 + +### `end` + +```tsx +end: number +``` + +アイテムの終了ピクセルオフセット。ほとんどのレイアウトではこの値は必要ありませんが、参考のために提供されています。 + +### `size` + +```tsx +size: number +``` + +アイテムのサイズ。通常、`width/height` などのCSSプロパティにマッピングされます。`VirtualItem.measureElement` メソッドでアイテムが測定される前は、この値は `estimateSize` バーチャライザーオプションから返される推定サイズになります。アイテムが測定された後(測定する場合)は、この値は `measureElement` バーチャライザーオプションから返される値になります(デフォルトでは `getBoundingClientRect()` で要素を測定するように設定されています)。 + +### `lane` + +```tsx +lane: number +``` + +アイテムのレーンインデックス。通常のリストでは常に `0` に設定されますが、メゾンリーレイアウトでは有用です(詳細は変数例を参照してください)。 diff --git a/docs/ja/api/virtualizer.md b/docs/ja/api/virtualizer.md new file mode 100644 index 000000000..5f09c1a74 --- /dev/null +++ b/docs/ja/api/virtualizer.md @@ -0,0 +1,409 @@ +--- +source-updated-at: '2025-05-05T15:05:35.000Z' +translation-updated-at: '2025-05-06T23:02:25.839Z' +title: バーチャライザー +--- +`Virtualizer` クラスは TanStack Virtual のコアです。通常、Virtualizer インスタンスはフレームワークアダプタによって作成されますが、直接 virtualizer を受け取ることもできます。 + +```tsx +export class Virtualizer { + constructor(options: VirtualizerOptions) +} +``` + +## 必須オプション + +### `count` + +```tsx +count: number +``` + +仮想化するアイテムの総数。 + +### `getScrollElement` + +```tsx +getScrollElement: () => TScrollElement +``` + +virtualizer のスクロール可能な要素を返す関数。要素がまだ利用できない場合は null を返すことがあります。 + +### `estimateSize` + +```tsx +estimateSize: (index: number) => number +``` + +> 🧠 要素を動的に計測する場合、アイテムの可能な限り大きいサイズ(快適な範囲内での幅/高さ)を見積もることを推奨します。これにより、スムーズスクロールなどの機能が正しく動作する可能性が高まります。 + +この関数は各アイテムのインデックスを受け取り、各アイテムの実際のサイズ(または `virtualItem.measureElement` で動的に計測する場合は推定サイズ)を返す必要があります。この計測は、virtualizer の向きに応じて幅または高さを返す必要があります。 + +## オプション + +### `enabled` + +```tsx +enabled?: boolean +``` + +`false` に設定すると、scrollElement のオブザーバーが無効になり、virtualizer の状態がリセットされます + +### `debug` + +```tsx +debug?: boolean +``` + +`true` に設定するとデバッグログが有効になります + +### `initialRect` + +```tsx +initialRect?: Rect +``` + +scrollElement の初期 `Rect`。主に SSR 環境で virtualizer を実行する必要がある場合に有用です。それ以外の場合は、初期 Rect は `observeElementRect` の実装によってマウント時に計算されます。 + +### `onChange` + +```tsx +onChange?: (instance: Virtualizer, sync: boolean) => void +``` + +virtualizer の内部状態が変化したときに発火するコールバック関数。virtualizer インスタンスと sync パラメータが渡されます。 + +sync パラメータは、スクロールが現在進行中かどうかを示します。スクロール中は `true`、スクロールが停止したときやリサイズなどの他のアクションが実行されているときは `false` になります。 + +### `overscan` + +```tsx +overscan?: number +``` + +可視領域の上下にレンダリングするアイテムの数。この数を増やすと virtualizer のレンダリング時間が増加しますが、スクロール時に virtualizer の上部や下部でレンダリングが遅い空白アイテムが表示される可能性が減少します。デフォルト値は `1` です。 + +### `horizontal` + +```tsx +horizontal?: boolean +``` + +virtualizer が水平方向の場合、これを `true` に設定します。 + +### `paddingStart` + +```tsx +paddingStart?: number +``` + +virtualizer の開始部分に適用するパディング(ピクセル単位)。 + +### `paddingEnd` + +```tsx +paddingEnd?: number +``` + +virtualizer の終了部分に適用するパディング(ピクセル単位)。 + +### `scrollPaddingStart` + +```tsx +scrollPaddingStart?: number +``` + +要素にスクロールするときに virtualizer の開始部分に適用するパディング(ピクセル単位)。 + +### `scrollPaddingEnd` + +```tsx +scrollPaddingEnd?: number +``` + +要素にスクロールするときに virtualizer の終了部分に適用するパディング(ピクセル単位)。 + +### `initialOffset` + +```tsx +initialOffset?: number | (() => number) +``` + +virtualizer に適用する初期オフセット。通常、SSR 環境で virtualizer をレンダリングする場合にのみ有用です。 + +### `getItemKey` + +```tsx +getItemKey?: (index: number) => Key +``` + +この関数は各アイテムのインデックスを受け取り、そのアイテムの一意のキーを返す必要があります。この関数のデフォルト機能はアイテムのインデックスを返すことですが、可能であればセット全体で各アイテムの一意の識別子を返すようにオーバーライドする必要があります。この関数は不要な再レンダリングを防ぐためにメモ化する必要があります。 + +### `rangeExtractor` + +```tsx +rangeExtractor?: (range: Range) => number[] +``` + +この関数は可視範囲のインデックスを受け取り、レンダリングするインデックスの配列を返す必要があります。これは、可視範囲に関係なく手動でアイテムを追加または削除する必要がある場合(例: 固定アイテム、ヘッダー、フッターなどをレンダリングする場合)に有用です。デフォルトの range extractor 実装は可視範囲のインデックスを返し、`defaultRangeExtractor` としてエクスポートされます。 + +### `scrollToFn` + +```tsx +scrollToFn?: ( + offset: number, + options: { adjustments?: number; behavior?: 'auto' | 'smooth' }, + instance: Virtualizer, +) => void +``` + +オプションの関数で、(提供されている場合)scrollElement のスクロール動作を実装する必要があります。以下の引数で呼び出されます: + +- スクロール先の `offset`(ピクセル単位)。 +- 推定サイズと実際のサイズの差 (`adjustments`) やスムーズアニメーションでスクロールが呼び出されたかどうか (`behaviour`) を示すオブジェクト。 +- virtualizer インスタンス自体。 + +組み込みのスクロール実装は `elementScroll` および `windowScroll` としてエクスポートされており、`useVirtualizer` や `useWindowVirtualizer` などのフレームワークアダプタ関数によって自動的に構成されます。 + +> ⚠️ 動的に計測される要素で smoothScroll を使用しようとしても動作しません。 + +### `observeElementRect` + +```tsx +observeElementRect: ( + instance: Virtualizer, + cb: (rect: Rect) => void, +) => void | (() => void) +``` + +オプションの関数で、(提供されている場合)scrollElement が変更されたときに呼び出され、scrollElement の `Rect`(`width` と `height` を持つオブジェクト)の初期計測と継続的な監視を実装する必要があります。インスタンス(`instance.scrollElement` を介して scrollElement にアクセス可能)とともに呼び出されます。組み込みの実装は `observeElementRect` および `observeWindowRect` としてエクスポートされており、`useVirtualizer` や `useWindowVirtualizer` などのフレームワークアダプタのエクスポート関数によって自動的に構成されます。 + +### `observeElementOffset` + +```tsx +observeElementOffset: ( + instance: Virtualizer, + cb: (offset: number) => void, + ) => void | (() => void) +``` + +オプションの関数で、(提供されている場合)scrollElement が変更されたときに呼び出され、scrollElement のスクロールオフセット(数値)の初期計測と継続的な監視を実装する必要があります。インスタンス(`instance.scrollElement` を介して scrollElement にアクセス可能)とともに呼び出されます。組み込みの実装は `observeElementOffset` および `observeWindowOffset` としてエクスポートされており、`useVirtualizer` や `useWindowVirtualizer` などのフレームワークアダプタのエクスポート関数によって自動的に構成されます。 + +### `measureElement` + +```tsx +measureElement?: ( + element: TItemElement, + entry: ResizeObserverEntry | undefined, + instance: Virtualizer, +) => number +``` + +このオプション関数は、virtualizer がアイテムのサイズ(幅または高さ)を動的に計測する必要があるときに呼び出されます。 + +> 🧠 `instance.options.horizontal` を使用して、アイテムの幅または高さを計測するかどうかを判断できます。 + +### `scrollMargin` + +```tsx +scrollMargin?: number +``` + +このオプションを使用すると、スクロールオフセットの起点を指定できます。通常、この値はスクロール要素の先頭とリストの開始位置の間のスペースを表します。これは、ウィンドウ virtualizer の前にヘッダーがある一般的なシナリオや、単一のスクロール要素内で複数の virtualizer が使用されている場合に特に有用です。要素を絶対位置指定で配置する場合は、CSS トランスフォームで `scrollMargin` を考慮する必要があります: +```tsx +transform: `translateY(${ + virtualRow.start - rowVirtualizer.options.scrollMargin +}px)` +``` +`scrollMargin` の値を動的に計測するには、`getBoundingClientRect()` または ResizeObserver を使用できます。これは、仮想リストの上のアイテムの高さが変更される可能性があるシナリオで役立ちます。 + +### `gap` + +```tsx +gap?: number +``` + +このオプションを使用すると、仮想化リスト内のアイテム間のスペースを設定できます。各アイテムのマージンやパディングを手動で調整することなく、一貫した視覚的な間隔を維持するのに特に便利です。値はピクセル単位で指定します。 + +### `lanes` + +```tsx +lanes: number +``` + +リストが分割されるレーン数(垂直リストの場合は列、水平リストの場合は行)。 + +### `isScrollingResetDelay` + +```tsx +isScrollingResetDelay: number +``` + +このオプションを使用すると、最後のスクロールイベントから isScrolling インスタンスプロパティをリセットするまでの待機時間を指定できます。デフォルト値は 150 ミリ秒です。 + +このオプションの実装は、さまざまなブラウザ間でスクロール動作を処理する信頼性の高いメカニズムの必要性によって推進されています。すべてのブラウザが scrollEnd イベントを一様にサポートするまで。 + +### `useScrollendEvent` + +```tsx +useScrollendEvent: boolean +``` + +スクロールが停止したことを検出するためにネイティブの scrollend イベントを使用するかどうかを決定します。false に設定すると、isScrollingResetDelay ミリ秒後に isScrolling インスタンスプロパティをリセットするためにデバウンスされたフォールバックが使用されます。デフォルト値は `false` です。 + +このオプションの実装は、さまざまなブラウザ間でスクロール動作を処理する信頼性の高いメカニズムの必要性によって推進されています。すべてのブラウザが scrollEnd イベントを一様にサポートするまで。 + +### `isRtl` + +```tsx +isRtl: boolean +``` + +右から左への言語ロケールをサポートするために水平スクロールを反転するかどうか。 + +### `useAnimationFrameWithResizeObserver` + +```tsx +useAnimationFrameWithResizeObserver: boolean +``` + +このオプションを有効にすると、ResizeObserver の計測を requestAnimationFrame でラップし、更新をスムーズにし、レイアウトスラッシングを減らします。デフォルト値は `false` です。 + +これにより、計測がレンダリングサイクルに合わせられることで、"ResizeObserver loop completed with undelivered notifications" エラーを防ぐことができます。これは、特に要素を動的にリサイズする場合に、パフォーマンスを向上させ、UI のジャターを減らすことができます。ただし、ResizeObserver はすでに非同期で実行されるため、requestAnimationFrame を追加すると計測にわずかな遅延が生じ、場合によっては目立つ可能性があります。リサイズ操作が軽量でリフローを引き起こさない場合、このオプションを有効にしても大きな利点は得られない可能性があります。 + +## Virtualizer インスタンス + +以下のプロパティとメソッドが virtualizer インスタンスで利用可能です: + +### `options` + +```tsx +options: readonly Required> +``` + +virtualizer の現在のオプション。このプロパティはフレームワークアダプタによって更新され、読み取り専用です。 + +### `scrollElement` + +```tsx +scrollElement: readonly TScrollElement | null +``` + +virtualizer の現在の scrollElement。このプロパティはフレームワークアダプタによって更新され、読み取り専用です。 + +### `getVirtualItems` + +```tsx +type getVirtualItems = () => VirtualItem[] +``` + +virtualizer の現在の状態に対する仮想アイテムを返します。 + +### `getVirtualIndexes` + +```tsx +type getVirtualIndexes = () => number[] +``` + +virtualizer の現在の状態に対する仮想行インデックスを返します。 + +### `scrollToOffset` + +```tsx +scrollToOffset: ( + toOffset: number, + options?: { + align?: 'start' | 'center' | 'end' | 'auto', + behavior?: 'auto' | 'smooth' + } +) => void +``` + +virtualizer を指定されたピクセルオフセットにスクロールします。オプションで、スクロールを scrollElement の特定の部分にアンカーするためのアラインモードを渡すことができます。 + +### `scrollToIndex` + +```tsx +scrollToIndex: ( + index: number, + options?: { + align?: 'start' | 'center' | 'end' | 'auto', + behavior?: 'auto' | 'smooth' + } +) => void +``` + +virtualizer を指定されたインデックスのアイテムにスクロールします。オプションで、スクロールを scrollElement の特定の部分にアンカーするためのアラインモードを渡すことができます。 + +### `getTotalSize` + +```tsx +getTotalSize: () => number +``` + +仮想化アイテムの合計サイズをピクセル単位で返します。この計測は、レンダリング時に要素を動的に計測するように選択した場合、段階的に変化します。 + +### `measure` + +```tsx +measure: () => void +``` + +以前のアイテム計測をすべてリセットします。 + +### `measureElement` + +```tsx +measureElement: (el: TItemElement | null) => void +``` + +構成された `measureElement` virtualizer オプションを使用して要素を計測します。コンポーネントがレンダリングされたときに(例えば React の ref コールバックプロップを使用して)virtualizer マークアップでこれを呼び出す責任があります。また `data-index` を追加する必要があります。 + +```tsx +
...
+``` + +デフォルトでは、`measureElement` virtualizer オプションは `getBoundingClientRect()` で要素を計測するように構成されています。 + +### `resizeItem` + +```tsx +resizeItem: (index: number, size: number) => void +``` + +仮想化アイテムのサイズを手動で変更します。この関数を使用して、このインデックスに対して計算されたサイズを手動で設定します。カスタムモーフィングトランジションを使用していて、モーフィングされたアイテムのサイズを事前に知っている場合などに便利です。 + +また、再レンダリングを減らすために、`Virtualizer.measureElement` の代わりにスロットルされた ResizeObserver とこのメソッドを使用することもできます。 + +> ⚠️ `Virtualizer.measureElement` を使用してアイテムを監視しているときにアイテムのサイズを手動で変更すると、`Virtualizer.measureElement` もサイズを変更するため、予測不可能な動作が発生します。ただし、同じ virtualizer インスタンスで resizeItem または measureElement のいずれかを異なるアイテムインデックスで使用することはできます。 + +### `scrollRect` + +```tsx +scrollRect: Rect +``` + +スクロール要素の現在の `Rect`。 + +### `shouldAdjustScrollPositionOnItemSizeChange` + +```tsx +shouldAdjustScrollPositionOnItemSizeChange: undefined | ((item: VirtualItem, delta: number, instance: Virtualizer) => boolean) +``` + +shouldAdjustScrollPositionOnItemSizeChange メソッドは、動的にレンダリングされたアイテムのサイズが推定サイズと異なる場合に、スクロール位置の調整を細かく制御できます。リストの途中にジャンプして後方にスクロールすると、新しい要素のサイズが最初に推定されたサイズと異なる場合があります。この不一致により、後続のアイテムがシフトし、特にリストを後方にナビゲートするときにユーザーのスクロール体験が乱れる可能性があります。 + +### `isScrolling` + +```tsx +isScrolling: boolean +``` + +リストが現在スクロール中かどうかを示すブール値フラグ。 + +### ` diff --git a/docs/ja/config.json b/docs/ja/config.json new file mode 100644 index 000000000..14ee4880f --- /dev/null +++ b/docs/ja/config.json @@ -0,0 +1,258 @@ +{ + "$schema": "https://raw.githubusercontent.com/TanStack/tanstack.com/main/tanstack-docs-config.schema.json", + "docSearch": { + "appId": "", + "indexName": "", + "apiKey": "" + }, + "sections": [ + { + "label": "はじめに", + "children": [ + { + "label": "イントロダクション", + "to": "introduction" + }, + { + "label": "インストール", + "to": "installation" + } + ], + "frameworks": [ + { + "label": "react", + "children": [ + { + "label": "React Virtual", + "to": "framework/react/react-virtual" + } + ] + }, + { + "label": "angular", + "children": [ + { + "label": "Angular Virtual", + "to": "framework/angular/angular-virtual" + } + ] + }, + { + "label": "solid", + "children": [ + { + "label": "Solid Virtual", + "to": "framework/solid/solid-virtual" + } + ] + }, + { + "label": "svelte", + "children": [ + { + "label": "Svelte Virtual", + "to": "framework/svelte/svelte-virtual" + } + ] + }, + { + "label": "vue", + "children": [ + { + "label": "Vue Virtual", + "to": "framework/vue/vue-virtual" + } + ] + } + ] + }, + { + "label": "コアAPI", + "children": [ + { + "label": "バーチャライザー", + "to": "api/virtualizer" + }, + { + "label": "バーチャルアイテム", + "to": "api/virtual-item" + } + ] + }, + { + "label": "例", + "children": [], + "frameworks": [ + { + "label": "angular", + "children": [ + { + "to": "framework/angular/examples/fixed", + "label": "固定" + }, + { + "to": "framework/angular/examples/variable", + "label": "可変" + }, + { + "to": "framework/angular/examples/dynamic", + "label": "動的" + }, + { + "to": "framework/angular/examples/padding", + "label": "パディング" + }, + { + "to": "framework/angular/examples/sticky", + "label": "スティッキー" + }, + { + "to": "framework/angular/examples/infinite-scroll", + "label": "無限スクロール" + }, + { + "to": "framework/angular/examples/smooth-scroll", + "label": "スムーススクロール" + }, + { + "to": "framework/angular/examples/table", + "label": "テーブル" + }, + { + "to": "framework/angular/examples/window", + "label": "ウィンドウ" + } + ] + }, + { + "label": "react", + "children": [ + { + "to": "framework/react/examples/fixed", + "label": "固定" + }, + { + "to": "framework/react/examples/variable", + "label": "可変" + }, + { + "to": "framework/react/examples/dynamic", + "label": "動的" + }, + { + "to": "framework/react/examples/padding", + "label": "パディング" + }, + { + "to": "framework/react/examples/sticky", + "label": "スティッキー" + }, + { + "to": "framework/react/examples/infinite-scroll", + "label": "無限スクロール" + }, + { + "to": "framework/react/examples/smooth-scroll", + "label": "スムーススクロール" + }, + { + "to": "framework/react/examples/table", + "label": "テーブル" + }, + { + "to": "framework/react/examples/window", + "label": "ウィンドウ" + } + ] + }, + { + "label": "svelte", + "children": [ + { + "to": "framework/svelte/examples/fixed", + "label": "固定" + }, + { + "to": "framework/svelte/examples/variable", + "label": "可変" + }, + { + "to": "framework/svelte/examples/dynamic", + "label": "動的" + }, + { + "to": "framework/svelte/examples/sticky", + "label": "スティッキー" + }, + { + "to": "framework/svelte/examples/infinite-scroll", + "label": "無限スクロール" + }, + { + "to": "framework/svelte/examples/smooth-scroll", + "label": "スムーススクロール" + }, + { + "to": "framework/svelte/examples/table", + "label": "テーブル" + } + ] + }, + { + "label": "vue", + "children": [ + { + "to": "framework/vue/examples/fixed", + "label": "固定" + }, + { + "to": "framework/vue/examples/variable", + "label": "可変" + }, + { + "to": "framework/vue/examples/dynamic", + "label": "動的" + }, + { + "to": "framework/vue/examples/sticky", + "label": "スティッキー" + }, + { + "to": "framework/vue/examples/infinite-scroll", + "label": "無限スクロール" + }, + { + "to": "framework/vue/examples/smooth-scroll", + "label": "スムーススクロール" + }, + { + "to": "framework/vue/examples/table", + "label": "テーブル" + }, + { + "to": "framework/vue/examples/padding", + "label": "パディング" + }, + { + "to": "framework/vue/examples/scroll-padding", + "label": "スクロールパディング" + } + ] + }, + { + "label": "lit", + "children": [ + { + "to": "framework/lit/examples/fixed", + "label": "固定" + }, + { + "to": "framework/lit/examples/dynamic", + "label": "動的" + } + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/docs/ja/framework/angular/angular-virtual.md b/docs/ja/framework/angular/angular-virtual.md new file mode 100644 index 000000000..510f18abd --- /dev/null +++ b/docs/ja/framework/angular/angular-virtual.md @@ -0,0 +1,35 @@ +--- +source-updated-at: '2024-08-19T19:18:26.000Z' +translation-updated-at: '2025-05-02T20:30:23.449Z' +title: Angular Virtual +--- +`@tanstack/angular-virtual`アダプターは、コアの仮想ロジックをラップしたものです。 + +## `injectVirtualizer` + +```ts +function injectVirtualizer( + options: PartialKeys< + Omit, 'getScrollElement'>, + 'observeElementRect' | 'observeElementOffset' | 'scrollToFn' + > & { scrollElement: ElementRef | TScrollElement | undefined }, +): AngularVirtualizer +``` + +この関数は、スクロール要素としてHTML要素と連携するように設定された`AngularVirtualizer`インスタンスを返します。 + +## `injectWindowVirtualizer` + +```ts +function injectWindowVirtualizer( + options: PartialKeys< + VirtualizerOptions, + | 'getScrollElement' + | 'observeElementRect' + | 'observeElementOffset' + | 'scrollToFn' + >, +): AngularVirtualizer +``` + +この関数は、スクロール要素としてウィンドウと連携するように設定されたウィンドウベースの`AngularVirtualizer`インスタンスを返します。 diff --git a/docs/ja/framework/lit/lit-virtual.md b/docs/ja/framework/lit/lit-virtual.md new file mode 100644 index 000000000..e80dbe951 --- /dev/null +++ b/docs/ja/framework/lit/lit-virtual.md @@ -0,0 +1,36 @@ +--- +source-updated-at: '2024-06-24T18:08:48.000Z' +translation-updated-at: '2025-05-06T23:00:01.826Z' +title: Lit Virtual +--- +`@tanstack/lit-virtual`アダプターは、コアの仮想ロジックをラップしたものです。 + +## `createVirtualizer` + +```tsx +private virtualizerController = new VirtualizerController( + options: PartialKeys< VirtualizerOptions, + 'observeElementRect' | 'observeElementOffset' | 'scrollToFn' +) +``` + +このクラスは、スクロール要素としてHTML要素と連携するように設定された標準的な`Virtualizer`インスタンスを表します。 +これはLitコントローラーを作成し、要素のレンダーメソッド内でアクセス可能です。 + +```tsx +render() { + const virtualizer = this.virtualizerController.getVirtualizer(); + const virtualItems = virtualizer.getVirtualItems(); +} +) +``` + +## `createWindowVirtualizer` + +```tsx +private windowVirtualizerController = new WindowVirtualizerController( + options: PartialKeys< VirtualizerOptions, + 'getScrollElement' | 'observeElementRect' | 'observeElementOffset' | 'scrollToFn' +``` + +このクラスは、スクロール要素としてHTML要素と連携するように設定されたウィンドウベースの`Virtualizer`インスタンスを表します。 diff --git a/docs/ja/framework/react/react-virtual.md b/docs/ja/framework/react/react-virtual.md new file mode 100644 index 000000000..674f15cc7 --- /dev/null +++ b/docs/ja/framework/react/react-virtual.md @@ -0,0 +1,35 @@ +--- +source-updated-at: '2024-01-25T21:23:10.000Z' +translation-updated-at: '2025-05-02T20:28:44.218Z' +title: React Virtual +--- +`@tanstack/react-virtual`アダプターは、コアのバーチャルロジックをラップしたものです。 + +## `useVirtualizer` + +```tsx +function useVirtualizer( + options: PartialKeys< + VirtualizerOptions, + 'observeElementRect' | 'observeElementOffset' | 'scrollToFn' + >, +): Virtualizer +``` + +この関数は、スクロール要素としてHTML要素と連携するように設定された標準の`Virtualizer`インスタンスを返します。 + +## `useWindowVirtualizer` + +```tsx +function useWindowVirtualizer( + options: PartialKeys< + VirtualizerOptions, + | 'getScrollElement' + | 'observeElementRect' + | 'observeElementOffset' + | 'scrollToFn' + >, +): Virtualizer +``` + +この関数は、スクロール要素としてウィンドウと連携するように設定されたウィンドウベースの`Virtualizer`インスタンスを返します。 diff --git a/docs/ja/framework/solid/solid-virtual.md b/docs/ja/framework/solid/solid-virtual.md new file mode 100644 index 000000000..3f601357a --- /dev/null +++ b/docs/ja/framework/solid/solid-virtual.md @@ -0,0 +1,35 @@ +--- +source-updated-at: '2024-01-25T21:23:10.000Z' +translation-updated-at: '2025-05-02T20:29:22.370Z' +title: Solid Virtual +--- +`@tanstack/solid-virtual`アダプターは、コアの仮想化ロジックをラップしたものです。 + +## `createVirtualizer` + +```tsx +function createVirtualizer( + options: PartialKeys< + VirtualizerOptions, + 'observeElementRect' | 'observeElementOffset' | 'scrollToFn' + >, +): Virtualizer +``` + +この関数は、HTML要素を`scrollElement`として動作するように設定された標準の`Virtualizer`インスタンスを返します。 + +## `createWindowVirtualizer` + +```tsx +function createWindowVirtualizer( + options: PartialKeys< + VirtualizerOptions, + | 'getScrollElement' + | 'observeElementRect' + | 'observeElementOffset' + | 'scrollToFn' + >, +): Virtualizer +``` + +この関数は、ウィンドウを`scrollElement`として動作するように設定されたウィンドウベースの`Virtualizer`インスタンスを返します。 diff --git a/docs/ja/framework/svelte/svelte-virtual.md b/docs/ja/framework/svelte/svelte-virtual.md new file mode 100644 index 000000000..bc563fcf3 --- /dev/null +++ b/docs/ja/framework/svelte/svelte-virtual.md @@ -0,0 +1,35 @@ +--- +source-updated-at: '2024-01-25T21:23:10.000Z' +translation-updated-at: '2025-05-02T20:30:35.940Z' +title: Svelte Virtual +--- +`@tanstack/svelte-virtual`アダプターは、コアのバーチャルロジックをラップしたものです。 + +## `createVirtualizer` + +```tsx +function createVirtualizer( + options: PartialKeys< + VirtualizerOptions, + 'observeElementRect' | 'observeElementOffset' | 'scrollToFn' + >, +): Virtualizer +``` + +この関数は、スクロール要素としてHTML要素と連携するように設定された標準的な`Virtualizer`インスタンスを返します。 + +## `createWindowVirtualizer` + +```tsx +function createWindowVirtualizer( + options: PartialKeys< + VirtualizerOptions, + | 'getScrollElement' + | 'observeElementRect' + | 'observeElementOffset' + | 'scrollToFn' + >, +): Virtualizer +``` + +この関数は、スクロール要素としてウィンドウと連携するように設定されたウィンドウベースの`Virtualizer`インスタンスを返します。 diff --git a/docs/ja/framework/vue/vue-virtual.md b/docs/ja/framework/vue/vue-virtual.md new file mode 100644 index 000000000..5fb09baf8 --- /dev/null +++ b/docs/ja/framework/vue/vue-virtual.md @@ -0,0 +1,35 @@ +--- +source-updated-at: '2024-06-01T09:52:04.000Z' +translation-updated-at: '2025-05-02T20:30:09.521Z' +title: Vue Virtual +--- +`@tanstack/vue-virtual`アダプターは、コアの仮想化ロジックをラップしたものです。 + +## `useVirtualizer` + +```tsx +function useVirtualizer( + options: PartialKeys< + VirtualizerOptions, + 'observeElementRect' | 'observeElementOffset' | 'scrollToFn' + >, +): Virtualizer +``` + +この関数は、スクロール要素としてHTML要素と連携するように設定された標準の`Virtualizer`インスタンスを返します。 + +## `useWindowVirtualizer` + +```tsx +function useWindowVirtualizer( + options: PartialKeys< + VirtualizerOptions, + | 'getScrollElement' + | 'observeElementRect' + | 'observeElementOffset' + | 'scrollToFn' + >, +): Virtualizer +``` + +この関数は、スクロール要素としてウィンドウと連携するように設定されたウィンドウベースの`Virtualizer`インスタンスを返します。 diff --git a/docs/ja/installation.md b/docs/ja/installation.md new file mode 100644 index 000000000..67247207f --- /dev/null +++ b/docs/ja/installation.md @@ -0,0 +1,50 @@ +--- +source-updated-at: '2025-03-07T09:19:44.000Z' +translation-updated-at: '2025-05-02T20:29:32.444Z' +title: インストール +--- +APIの詳細に入る前に、まずはセットアップをしましょう! + +お好みのnpmパッケージマネージャーを使って、TanStack Virtualアダプターを依存関係としてインストールします。 + +## React Virtual + +```bash +npm install @tanstack/react-virtual +``` + +## Solid Virtual + +```bash +npm install @tanstack/solid-virtual +``` + +## Svelte Virtual + +```bash +npm install @tanstack/svelte-virtual +``` + +## Vue Virtual + +```bash +npm install @tanstack/vue-virtual +``` + +## Lit Virtual + +```bash +$ npm install @tanstack/lit-virtual +``` + +## Angular Virtual + +```bash +$ npm install @tanstack/angular-virtual +``` + +## Virtual Core (フレームワーク不要) + +```bash +npm install @tanstack/virtual-core +``` diff --git a/docs/ja/introduction.md b/docs/ja/introduction.md new file mode 100644 index 000000000..6231580c4 --- /dev/null +++ b/docs/ja/introduction.md @@ -0,0 +1,69 @@ +--- +source-updated-at: '2024-11-25T13:01:52.000Z' +translation-updated-at: '2025-05-02T20:29:09.327Z' +title: イントロダクション +--- +TanStack Virtualは、JS/TS、React、Vue、Svelte、Solid、Lit、Angular向けのヘッドレスUIユーティリティで、長い要素リストの仮想化を実現します。これはコンポーネントではないため、マークアップやスタイルを提供・レンダリングすることはありません。このため、マークアップとスタイルをある程度自身で実装する必要がありますが、スタイル・デザイン・実装を100%コントロールできるという利点があります。 + +## バーチャライザー (Virtualizer) + +TanStack Virtualの中核となるのが`Virtualizer`です。バーチャライザーは垂直(デフォルト)または水平軸に沿って設定可能で、2つの軸設定を組み合わせることで、垂直・水平方向の仮想化やグリッド状の仮想化も実現できます。 + +以下は、ReactでTanStack Virtualを使用して長いリストをdiv内で仮想化する簡単な例です: + +```tsx +import { useVirtualizer } from '@tanstack/react-virtual'; + +function App() { + // リストのスクロール可能な要素 + const parentRef = React.useRef(null) + + // バーチャライザー + const rowVirtualizer = useVirtualizer({ + count: 10000, + getScrollElement: () => parentRef.current, + estimateSize: () => 35, + }) + + return ( + <> + {/* リストのスクロール可能な要素 */} +
+ {/* すべてのアイテムを保持する大きな内部要素 */} +
+ {/* バーチャライザー内で表示されるアイテムのみ、ビュー内に手動で配置 */} + {rowVirtualizer.getVirtualItems().map((virtualItem) => ( +
+ Row {virtualItem.index} +
+ ))} +
+
+ + ) +} +``` + +さらにいくつかの例を見ていきましょう! diff --git a/docs/ru/api/virtual-item.md b/docs/ru/api/virtual-item.md new file mode 100644 index 000000000..5250354ba --- /dev/null +++ b/docs/ru/api/virtual-item.md @@ -0,0 +1,66 @@ +--- +source-updated-at: '2024-08-29T09:26:23.000Z' +translation-updated-at: '2025-05-02T20:45:13.807Z' +title: Виртуальный элемент +--- +Объект `VirtualItem` представляет отдельный элемент, возвращаемый виртуализатором. Он содержит информацию, необходимую для рендеринга элемента в системе координат внутри `scrollElement` виртуализатора, а также другие полезные свойства и функции. + +```tsx +export interface VirtualItem { + key: string | number | bigint + index: number + start: number + end: number + size: number +} +``` + +Каждый объект `VirtualItem` имеет следующие свойства и методы: + +### `key` + +```tsx +key: string | number | bigint +``` + +Уникальный ключ элемента. По умолчанию это индекс элемента, но его можно настроить через опцию `getItemKey` виртуализатора. + +### `index` + +```tsx +index: number +``` + +Индекс элемента. + +### `start` + +```tsx +start: number +``` + +Начальное смещение элемента в пикселях. Обычно используется для CSS-свойств или трансформаций, таких как `top/left` или `translateX/translateY`. + +### `end` + +```tsx +end: number +``` + +Конечное смещение элемента в пикселях. Это значение не всегда необходимо для большинства макетов, но может быть полезным, поэтому мы его предоставляем. + +### `size` + +```tsx +size: number +``` + +Размер элемента. Обычно соответствует CSS-свойствам, таким как `width/height`. До измерения элемента с помощью метода `VirtualItem.measureElement` это значение будет примерной оценкой, возвращаемой опцией `estimateSize` виртуализатора. После измерения (если оно выполняется) значение будет соответствовать результату, возвращаемому опцией `measureElement` виртуализатора (по умолчанию используется `getBoundingClientRect()`). + +### `lane` + +```tsx +lane: number +``` + +Индекс дорожки (lane) элемента. В обычных списках всегда равен `0`, но становится полезным для кирпичных (masonry) макетов (подробнее см. примеры с переменными). diff --git a/docs/ru/api/virtualizer.md b/docs/ru/api/virtualizer.md new file mode 100644 index 000000000..920cd1e12 --- /dev/null +++ b/docs/ru/api/virtualizer.md @@ -0,0 +1,423 @@ +--- +source-updated-at: '2025-05-05T15:05:35.000Z' +translation-updated-at: '2025-05-06T23:12:59.160Z' +title: Виртуализатор +--- +Класс `Virtualizer` является ядром TanStack Virtual. Обычно экземпляры Virtualizer создаются для вас адаптером вашего фреймворка, но вы получаете виртуализатор напрямую. + +```tsx +export class Virtualizer { + constructor(options: VirtualizerOptions) +} +``` + +## Обязательные параметры + +### `count` + +```tsx +count: number +``` + +Общее количество элементов для виртуализации. + +### `getScrollElement` + +```tsx +getScrollElement: () => TScrollElement +``` + +Функция, возвращающая прокручиваемый элемент для виртуализатора. Может вернуть null, если элемент еще недоступен. + +### `estimateSize` + +```tsx +estimateSize: (index: number) => number +``` + +> 🧠 Если вы динамически измеряете размеры элементов, рекомендуется оценить максимально возможный размер (ширину/высоту, в разумных пределах) ваших элементов. Это обеспечит корректную работу таких функций, как плавная прокрутка. + +Эта функция получает индекс каждого элемента и должна возвращать фактический размер (или предполагаемый размер, если вы будете динамически измерять элементы с помощью `virtualItem.measureElement`) для каждого элемента. Измерение должно возвращать либо ширину, либо высоту в зависимости от ориентации вашего виртуализатора. + +## Дополнительные параметры + +### `enabled` + +```tsx +enabled?: boolean +``` + +Установите `false`, чтобы отключить наблюдатели scrollElement и сбросить состояние виртуализатора. + +### `debug` + +```tsx +debug?: boolean +``` + +Установите `true`, чтобы включить логи отладки. + +### `initialRect` + +```tsx +initialRect?: Rect +``` + +Начальный `Rect` для scrollElement. В основном полезен, если вам нужно запустить виртуализатор в среде SSR (рендеринг на стороне сервера), в противном случае initialRect будет вычислен при монтировании реализацией `observeElementRect`. + +### `onChange` + +```tsx +onChange?: (instance: Virtualizer, sync: boolean) => void +``` + +Функция обратного вызова, которая срабатывает при изменении внутреннего состояния виртуализатора. Получает экземпляр виртуализатора и параметр sync. + +Параметр sync указывает, происходит ли в данный момент прокрутка. Он равен `true`, когда прокрутка активна, и `false`, когда прокрутка остановлена или выполняются другие действия (например, изменение размера). + +### `overscan` + +```tsx +overscan?: number +``` + +Количество элементов для рендеринга выше и ниже видимой области. Увеличение этого числа увеличит время рендеринга виртуализатора, но может снизить вероятность появления медленно рендерящихся пустых элементов вверху и внизу виртуализатора при прокрутке. Значение по умолчанию — `1`. + +### `horizontal` + +```tsx +horizontal?: boolean +``` + +Установите `true`, если ваш виртуализатор ориентирован горизонтально. + +### `paddingStart` + +```tsx +paddingStart?: number +``` + +Отступ в пикселях, применяемый к началу виртуализатора. + +### `paddingEnd` + +```tsx +paddingEnd?: number +``` + +Отступ в пикселях, применяемый к концу виртуализатора. + +### `scrollPaddingStart` + +```tsx +scrollPaddingStart?: number +``` + +Отступ в пикселях, применяемый к началу виртуализатора при прокрутке к элементу. + +### `scrollPaddingEnd` + +```tsx +scrollPaddingEnd?: number +``` + +Отступ в пикселях, применяемый к концу виртуализатора при прокрутке к элементу. + +### `initialOffset` + +```tsx +initialOffset?: number | (() => number) +``` + +Начальное смещение, применяемое к виртуализатору. Обычно полезно только при рендеринге виртуализатора в среде SSR. + +### `getItemKey` + +```tsx +getItemKey?: (index: number) => Key +``` + +Эта функция получает индекс каждого элемента и должна возвращать уникальный ключ для этого элемента. По умолчанию функция возвращает индекс элемента, но рекомендуется переопределить её, чтобы возвращать уникальный идентификатор для каждого элемента во всем наборе. Функция должна быть мемоизирована, чтобы избежать лишних перерендеров. + +### `rangeExtractor` + +```tsx +rangeExtractor?: (range: Range) => number[] +``` + +Эта функция получает индексы видимого диапазона и должна возвращать массив индексов для рендеринга. Полезна, если вам нужно вручную добавлять или удалять элементы из виртуализатора независимо от видимого диапазона, например, для рендеринга sticky-элементов, заголовков, подвалов и т. д. Реализация по умолчанию возвращает индексы видимого диапазона и экспортируется как `defaultRangeExtractor`. + +### `scrollToFn` + +```tsx +scrollToFn?: ( + offset: number, + options: { adjustments?: number; behavior?: 'auto' | 'smooth' }, + instance: Virtualizer, +) => void +``` + +Опциональная функция, которая (если предоставлена) должна реализовывать поведение прокрутки для вашего scrollElement. Вызывается со следующими аргументами: + +- `offset` (в пикселях) для прокрутки. +- Объект, указывающий, была ли разница между предполагаемым и фактическим размером (`adjustments`) и/или была ли прокрутка вызвана с плавной анимацией (`behaviour`). +- Сам экземпляр виртуализатора. + +Встроенные реализации прокрутки экспортируются как `elementScroll` и `windowScroll` и автоматически настраиваются функциями адаптера фреймворка, такими как `useVirtualizer` или `useWindowVirtualizer`. + +> ⚠️ Попытка использовать smoothScroll с динамически измеряемыми элементами не сработает. + +### `observeElementRect` + +```tsx +observeElementRect: ( + instance: Virtualizer, + cb: (rect: Rect) => void, +) => void | (() => void) +``` + +Опциональная функция, которая (если предоставлена) вызывается при изменении scrollElement и должна реализовывать начальное измерение и непрерывный мониторинг `Rect` scrollElement (объект с `width` и `height`). Вызывается с экземпляром (который также дает доступ к scrollElement через `instance.scrollElement`). Встроенные реализации экспортируются как `observeElementRect` и `observeWindowRect` и автоматически настраиваются функциями адаптера фреймворка, такими как `useVirtualizer` или `useWindowVirtualizer`. + +### `observeElementOffset` + +```tsx +observeElementOffset: ( + instance: Virtualizer, + cb: (offset: number) => void, + ) => void | (() => void) +``` + +Опциональная функция, которая (если предоставлена) вызывается при изменении scrollElement и должна реализовывать начальное измерение и непрерывный мониторинг смещения прокрутки scrollElement (число). Вызывается с экземпляром (который также дает доступ к scrollElement через `instance.scrollElement`). Встроенные реализации экспортируются как `observeElementOffset` и `observeWindowOffset` и автоматически настраиваются функциями адаптера фреймворка, такими как `useVirtualizer` или `useWindowVirtualizer`. + +### `measureElement` + +```tsx +measureElement?: ( + element: TItemElement, + entry: ResizeObserverEntry | undefined, + instance: Virtualizer, +) => number +``` + +Эта опциональная функция вызывается, когда виртуализатору нужно динамически измерить размер (ширину или высоту) элемента. + +> 🧠 Вы можете использовать `instance.options.horizontal`, чтобы определить, нужно ли измерять ширину или высоту элемента. + +### `scrollMargin` + +```tsx +scrollMargin?: number +``` + +С помощью этой опции вы можете указать, откуда должно начинаться смещение прокрутки. Обычно это значение представляет собой пространство между началом прокручиваемого элемента и началом списка. Особенно полезно в распространенных сценариях, таких как наличие заголовка перед window-виртуализатором или использование нескольких виртуализаторов в одном прокручиваемом элементе. Если вы используете абсолютное позиционирование элементов, вам следует учитывать `scrollMargin` в вашем CSS transform: +```tsx +transform: `translateY(${ + virtualRow.start - rowVirtualizer.options.scrollMargin +}px)` +``` +Для динамического измерения значения `scrollMargin` вы можете использовать `getBoundingClientRect()` или ResizeObserver. Это полезно в сценариях, когда элементы выше вашего виртуального списка могут изменять свою высоту. + +### `gap` + +```tsx +gap?: number +``` + +Эта опция позволяет задать расстояние между элементами в виртуализированном списке. Особенно полезна для поддержания единообразного визуального разделения между элементами без необходимости ручной настройки margin или padding каждого элемента. Значение указывается в пикселях. + +### `lanes` + +```tsx +lanes: number +``` + +Количество дорожек (lanes), на которые разделен список (также известных как колонки для вертикальных списков и строки для горизонтальных списков). + +### `isScrollingResetDelay` + +```tsx +isScrollingResetDelay: number +``` + +Эта опция позволяет указать продолжительность ожидания после последнего события прокрутки перед сбросом свойства экземпляра isScrolling. Значение по умолчанию — 150 миллисекунд. + +Реализация этой опции обусловлена необходимостью надежного механизма обработки поведения прокрутки в разных браузерах. Пока все браузеры не будут единообразно поддерживать событие scrollEnd. + +### `useScrollendEvent` + +```tsx +useScrollendEvent: boolean +``` + +Определяет, использовать ли нативное событие scrollend для обнаружения остановки прокрутки. Если установлено в false, используется debounced-запасной вариант для сброса свойства экземпляра isScrolling после isScrollingResetDelay миллисекунд. Значение по умолчанию — `false`. + +Реализация этой опции обусловлена необходимостью надежного механизма обработки поведения прокрутки в разных браузерах. Пока все браузеры не будут единообразно поддерживать событие scrollEnd. + +### `isRtl` + +```tsx +isRtl: boolean +``` + +Определяет, нужно ли инвертировать горизонтальную прокрутку для поддержки языков с письмом справа налево. + +### `useAnimationFrameWithResizeObserver` + +```tsx +useAnimationFrameWithResizeObserver: boolean +``` + +Эта опция включает оборачивание измерений ResizeObserver в requestAnimationFrame для более плавных обновлений и уменьшения "thrashing" (частых пересчетов) макета. Значение по умолчанию — `false`. + +Помогает избежать ошибки "ResizeObserver loop completed with undelivered notifications", обеспечивая соответствие измерений циклу рендеринга. Это может улучшить производительность и уменьшить дрожание интерфейса, особенно при динамическом изменении размеров элементов. Однако, поскольку ResizeObserver уже работает асинхронно, добавление requestAnimationFrame может вызвать небольшую задержку в измерениях, что может быть заметно в некоторых случаях. Если операции изменения размера легковесны и не вызывают перерасчетов, включение этой опции может не дать значительных преимуществ. + +## Экземпляр Virtualizer + +Следующие свойства и методы доступны в экземпляре виртуализатора: + +### `options` + +```tsx +options: readonly Required> +``` + +Текущие параметры виртуализатора. Это свойство обновляется через адаптер вашего фреймворка и доступно только для чтения. + +### `scrollElement` + +```tsx +scrollElement: readonly TScrollElement | null +``` + +Текущий scrollElement виртуализатора. Это свойство обновляется через адаптер вашего фреймворка и доступно только для чтения. + +### `getVirtualItems` + +```tsx +type getVirtualItems = () => VirtualItem[] +``` + +Возвращает виртуальные элементы для текущего состояния виртуализатора. + +### `getVirtualIndexes` + +```tsx +type getVirtualIndexes = () => number[] +``` + +Возвращает индексы виртуальных строк для текущего состояния виртуализатора. + +### `scrollToOffset` + +```tsx +scrollToOffset: ( + toOffset: number, + options?: { + align?: 'start' | 'center' | 'end' | 'auto', + behavior?: 'auto' | 'smooth' + } +) => void +``` + +Прокручивает виртуализатор до указанного смещения в пикселях. Можно дополнительно указать режим выравнивания, чтобы закрепить прокрутку к определенной части scrollElement. + +### `scrollToIndex` + +```tsx +scrollToIndex: ( + index: number, + options?: { + align?: 'start' | 'center' | 'end' | 'auto', + behavior?: 'auto' | 'smooth' + } +) => void +``` + +Прокручивает виртуализатор до элемента с указанным индексом. Можно дополнительно указать режим выравнивания, чтобы закрепить прокрутку к определенной части scrollElement. + +### `getTotalSize` + +```tsx +getTotalSize: () => number +``` + +Возвращает общий размер в пикселях для виртуализированных элементов. Это измерение будет постепенно изменяться, если вы выберете динамическое измерение элементов при их рендеринге. + +### `measure` + +```tsx +measure: () => void +``` + +Сбрасывает все предыдущие измерения элементов. + +### `measureElement` + +```tsx +measureElement: (el: TItemElement | null) => void +``` + +Измеряет элемент с использованием настроенной опции `measureElement` виртуализатора. Вы должны вызывать эту функцию в разметке виртуализатора при рендеринге компонента (например, используя что-то вроде callback-пропа ref в React), а также добавлять `data-index`. + +```tsx +
...
+``` + +По умолчанию опция `measureElement` виртуализатора настроена на измерение элементов с помощью `getBoundingClientRect()`. + +### `resizeItem` + +```tsx +resizeItem: (index: number, size: number) => void +``` + +Изменяет размер виртуализированного элемента вручную. Используйте эту функцию, чтобы вручную установить размер, рассчитанный для этого индекса. Полезно в случаях, когда используется кастомная morphing-анимация, и вы заранее знаете размер преобразованного элемента. + +Также можно использовать этот метод с throttled ResizeObserver вместо `Virtualizer.measureElement`, чтобы уменьшить количество перерендеров. + +> ⚠️ Учтите, что ручное изменение размера элемента при использовании `Virtualizer.measureElement` для мониторинга этого элемента приведет к непредсказуемому поведению, так как `Virtualizer.measureElement` также изменяет размер. Однако вы можете использовать либо resizeItem, либо measureElement в одном экземпляре виртуализатора, но на разных индексах элементов. + +### `scrollRect` + +```tsx +scrollRect: Rect +``` + +Текущий `Rect` scroll-элемента. + +### `shouldAdjustScrollPositionOnItemSizeChange` + +```tsx +shouldAdjustScrollPositionOnItemSizeChange: undefined | ((item: VirtualItem, delta: number, instance: Virtualizer) => boolean) +``` + +Метод shouldAdjustScrollPositionOnItemSizeChange позволяет тонко контролировать корректировку позиции прокрутки, когда размер динамически рендерящихся элементов отличается от предполагаемого размера. При переходе в середину списка и прокрутке назад новые элементы могут иметь размер, отличный от первоначально предполагаемого. Это несоответствие может вызвать смещение последующих элементов, потенциально нарушая пользовательский опыт прокрутки, особенно при навигации назад по списку. + +### `isScrolling` + +```tsx +isScrolling: boolean +``` + +Флаг, указывающий, происходит ли в данный момент прокрутка списка. + +### `scrollDirection` + +```tsx +scrollDirection: 'forward' | 'backward' | null +``` + +Эта опция указывает направление прокрутки, возможные значения: 'forward' для прокрутки вниз и 'backward' для прокрутки вверх. Значение равно null, когда активная прокрутка отсутствует. + +### `scrollOffset` + +```tsx +scrollOffset: number +``` + +Эта опция представляет текущую позицию прокрутки вдоль оси прокрутки. Измеряется в пикселях от начальной точки прокручиваемой области. diff --git a/docs/ru/config.json b/docs/ru/config.json new file mode 100644 index 000000000..9595e00e0 --- /dev/null +++ b/docs/ru/config.json @@ -0,0 +1,258 @@ +{ + "$schema": "https://raw.githubusercontent.com/TanStack/tanstack.com/main/tanstack-docs-config.schema.json", + "docSearch": { + "appId": "", + "indexName": "", + "apiKey": "" + }, + "sections": [ + { + "label": "Начало работы", + "children": [ + { + "label": "Введение", + "to": "introduction" + }, + { + "label": "Установка", + "to": "installation" + } + ], + "frameworks": [ + { + "label": "react", + "children": [ + { + "label": "React Virtual", + "to": "framework/react/react-virtual" + } + ] + }, + { + "label": "angular", + "children": [ + { + "label": "Angular Virtual", + "to": "framework/angular/angular-virtual" + } + ] + }, + { + "label": "solid", + "children": [ + { + "label": "Solid Virtual", + "to": "framework/solid/solid-virtual" + } + ] + }, + { + "label": "svelte", + "children": [ + { + "label": "Svelte Virtual", + "to": "framework/svelte/svelte-virtual" + } + ] + }, + { + "label": "vue", + "children": [ + { + "label": "Vue Virtual", + "to": "framework/vue/vue-virtual" + } + ] + } + ] + }, + { + "label": "Основные API", + "children": [ + { + "label": "Виртуализатор", + "to": "api/virtualizer" + }, + { + "label": "Виртуальный элемент", + "to": "api/virtual-item" + } + ] + }, + { + "label": "Примеры", + "children": [], + "frameworks": [ + { + "label": "angular", + "children": [ + { + "to": "framework/angular/examples/fixed", + "label": "Фиксированный" + }, + { + "to": "framework/angular/examples/variable", + "label": "Переменный" + }, + { + "to": "framework/angular/examples/dynamic", + "label": "Динамический" + }, + { + "to": "framework/angular/examples/padding", + "label": "Отступы" + }, + { + "to": "framework/angular/examples/sticky", + "label": "Закрепленный" + }, + { + "to": "framework/angular/examples/infinite-scroll", + "label": "Бесконечная прокрутка" + }, + { + "to": "framework/angular/examples/smooth-scroll", + "label": "Плавная прокрутка" + }, + { + "to": "framework/angular/examples/table", + "label": "Таблица" + }, + { + "to": "framework/angular/examples/window", + "label": "Окно" + } + ] + }, + { + "label": "react", + "children": [ + { + "to": "framework/react/examples/fixed", + "label": "Фиксированный" + }, + { + "to": "framework/react/examples/variable", + "label": "Переменный" + }, + { + "to": "framework/react/examples/dynamic", + "label": "Динамический" + }, + { + "to": "framework/react/examples/padding", + "label": "Отступы" + }, + { + "to": "framework/react/examples/sticky", + "label": "Закрепленный" + }, + { + "to": "framework/react/examples/infinite-scroll", + "label": "Бесконечная прокрутка" + }, + { + "to": "framework/react/examples/smooth-scroll", + "label": "Плавная прокрутка" + }, + { + "to": "framework/react/examples/table", + "label": "Таблица" + }, + { + "to": "framework/react/examples/window", + "label": "Окно" + } + ] + }, + { + "label": "svelte", + "children": [ + { + "to": "framework/svelte/examples/fixed", + "label": "Фиксированный" + }, + { + "to": "framework/svelte/examples/variable", + "label": "Переменный" + }, + { + "to": "framework/svelte/examples/dynamic", + "label": "Динамический" + }, + { + "to": "framework/svelte/examples/sticky", + "label": "Закрепленный" + }, + { + "to": "framework/svelte/examples/infinite-scroll", + "label": "Бесконечная прокрутка" + }, + { + "to": "framework/svelte/examples/smooth-scroll", + "label": "Плавная прокрутка" + }, + { + "to": "framework/svelte/examples/table", + "label": "Таблица" + } + ] + }, + { + "label": "vue", + "children": [ + { + "to": "framework/vue/examples/fixed", + "label": "Фиксированный" + }, + { + "to": "framework/vue/examples/variable", + "label": "Переменный" + }, + { + "to": "framework/vue/examples/dynamic", + "label": "Динамический" + }, + { + "to": "framework/vue/examples/sticky", + "label": "Закрепленный" + }, + { + "to": "framework/vue/examples/infinite-scroll", + "label": "Бесконечная прокрутка" + }, + { + "to": "framework/vue/examples/smooth-scroll", + "label": "Плавная прокрутка" + }, + { + "to": "framework/vue/examples/table", + "label": "Таблица" + }, + { + "to": "framework/vue/examples/padding", + "label": "Отступы" + }, + { + "to": "framework/vue/examples/scroll-padding", + "label": "Отступы прокрутки" + } + ] + }, + { + "label": "lit", + "children": [ + { + "to": "framework/lit/examples/fixed", + "label": "Фиксированный" + }, + { + "to": "framework/lit/examples/dynamic", + "label": "Динамический" + } + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/docs/ru/framework/angular/angular-virtual.md b/docs/ru/framework/angular/angular-virtual.md new file mode 100644 index 000000000..c77ca3bdc --- /dev/null +++ b/docs/ru/framework/angular/angular-virtual.md @@ -0,0 +1,35 @@ +--- +source-updated-at: '2024-08-19T19:18:26.000Z' +translation-updated-at: '2025-05-02T20:45:06.569Z' +title: Angular Virtual +--- +Адаптер `@tanstack/angular-virtual` является обёрткой вокруг базовой логики виртуализации. + +## `injectVirtualizer` + +```ts +function injectVirtualizer( + options: PartialKeys< + Omit, 'getScrollElement'>, + 'observeElementRect' | 'observeElementOffset' | 'scrollToFn' + > & { scrollElement: ElementRef | TScrollElement | undefined }, +): AngularVirtualizer +``` + +Эта функция возвращает экземпляр `AngularVirtualizer`, настроенный для работы с HTML-элементом в качестве `scrollElement`. + +## `injectWindowVirtualizer` + +```ts +function injectWindowVirtualizer( + options: PartialKeys< + VirtualizerOptions, + | 'getScrollElement' + | 'observeElementRect' + | 'observeElementOffset' + | 'scrollToFn' + >, +): AngularVirtualizer +``` + +Эта функция возвращает экземпляр `AngularVirtualizer`, работающий с окном браузера (`window`) в качестве `scrollElement`. diff --git a/docs/ru/framework/lit/lit-virtual.md b/docs/ru/framework/lit/lit-virtual.md new file mode 100644 index 000000000..0d1aa8e37 --- /dev/null +++ b/docs/ru/framework/lit/lit-virtual.md @@ -0,0 +1,36 @@ +--- +source-updated-at: '2024-06-24T18:08:48.000Z' +translation-updated-at: '2025-05-06T23:10:35.943Z' +title: Lit Virtual +--- +Адаптер `@tanstack/lit-virtual` является обёрткой над основной логикой виртуализации. + +## `createVirtualizer` + +```tsx +private virtualizerController = new VirtualizerController( + options: PartialKeys< VirtualizerOptions, + 'observeElementRect' | 'observeElementOffset' | 'scrollToFn' +) +``` + +Этот класс представляет стандартный экземпляр `Virtualizer`, настроенный для работы с HTML-элементом в качестве scrollElement. +Он создаёт Lit Controller, доступный в методе render элемента. + +```tsx +render() { + const virtualizer = this.virtualizerController.getVirtualizer(); + const virtualItems = virtualizer.getVirtualItems(); +} +) +``` + +## `createWindowVirtualizer` + +```tsx +private windowVirtualizerController = new WindowVirtualizerController( + options: PartialKeys< VirtualizerOptions, + 'getScrollElement' | 'observeElementRect' | 'observeElementOffset' | 'scrollToFn' +``` + +Этот класс представляет window-based (основанный на окне) экземпляр `Virtualizer`, настроенный для работы с HTML-элементом в качестве scrollElement. diff --git a/docs/ru/framework/react/react-virtual.md b/docs/ru/framework/react/react-virtual.md new file mode 100644 index 000000000..232e3a2c1 --- /dev/null +++ b/docs/ru/framework/react/react-virtual.md @@ -0,0 +1,35 @@ +--- +source-updated-at: '2024-01-25T21:23:10.000Z' +translation-updated-at: '2025-05-02T20:45:05.408Z' +title: React Virtual +--- +Адаптер `@tanstack/react-virtual` — это обёртка над основной логикой виртуализации. + +## `useVirtualizer` + +```tsx +function useVirtualizer( + options: PartialKeys< + VirtualizerOptions, + 'observeElementRect' | 'observeElementOffset' | 'scrollToFn' + >, +): Virtualizer +``` + +Эта функция возвращает стандартный экземпляр `Virtualizer`, настроенный для работы с HTML-элементом в качестве `scrollElement`. + +## `useWindowVirtualizer` + +```tsx +function useWindowVirtualizer( + options: PartialKeys< + VirtualizerOptions, + | 'getScrollElement' + | 'observeElementRect' + | 'observeElementOffset' + | 'scrollToFn' + >, +): Virtualizer +``` + +Эта функция возвращает экземпляр `Virtualizer`, работающий с окном браузера в качестве `scrollElement`. diff --git a/docs/ru/framework/solid/solid-virtual.md b/docs/ru/framework/solid/solid-virtual.md new file mode 100644 index 000000000..2622d1f04 --- /dev/null +++ b/docs/ru/framework/solid/solid-virtual.md @@ -0,0 +1,37 @@ +--- +source-updated-at: '2024-01-25T21:23:10.000Z' +translation-updated-at: '2025-05-02T20:45:05.501Z' +title: Solid Virtual +--- +# Solid Virtual + +Адаптер `@tanstack/solid-virtual` является обёрткой вокруг основной логики виртуализации. + +## `createVirtualizer` + +```tsx +function createVirtualizer( + options: PartialKeys< + VirtualizerOptions, + 'observeElementRect' | 'observeElementOffset' | 'scrollToFn' + >, +): Virtualizer +``` + +Эта функция возвращает стандартный экземпляр `Virtualizer`, настроенный для работы с HTML-элементом в качестве scrollElement. + +## `createWindowVirtualizer` + +```tsx +function createWindowVirtualizer( + options: PartialKeys< + VirtualizerOptions, + | 'getScrollElement' + | 'observeElementRect' + | 'observeElementOffset' + | 'scrollToFn' + >, +): Virtualizer +``` + +Эта функция возвращает экземпляр `Virtualizer`, работающий с окном браузера (window) в качестве scrollElement. diff --git a/docs/ru/framework/svelte/svelte-virtual.md b/docs/ru/framework/svelte/svelte-virtual.md new file mode 100644 index 000000000..f68ad50d8 --- /dev/null +++ b/docs/ru/framework/svelte/svelte-virtual.md @@ -0,0 +1,37 @@ +--- +source-updated-at: '2024-01-25T21:23:10.000Z' +translation-updated-at: '2025-05-02T20:45:05.269Z' +title: Svelte Virtual +--- +# Svelte Virtual + +Адаптер `@tanstack/svelte-virtual` представляет собой обёртку над основной логикой виртуализации. + +## `createVirtualizer` + +```tsx +function createVirtualizer( + options: PartialKeys< + VirtualizerOptions, + 'observeElementRect' | 'observeElementOffset' | 'scrollToFn' + >, +): Virtualizer +``` + +Эта функция возвращает стандартный экземпляр `Virtualizer`, настроенный для работы с HTML-элементом в качестве `scrollElement`. + +## `createWindowVirtualizer` + +```tsx +function createWindowVirtualizer( + options: PartialKeys< + VirtualizerOptions, + | 'getScrollElement' + | 'observeElementRect' + | 'observeElementOffset' + | 'scrollToFn' + >, +): Virtualizer +``` + +Эта функция возвращает экземпляр `Virtualizer`, работающий с окном браузера (`window`) в качестве `scrollElement`. diff --git a/docs/ru/framework/vue/vue-virtual.md b/docs/ru/framework/vue/vue-virtual.md new file mode 100644 index 000000000..076f5b5c7 --- /dev/null +++ b/docs/ru/framework/vue/vue-virtual.md @@ -0,0 +1,35 @@ +--- +source-updated-at: '2024-06-01T09:52:04.000Z' +translation-updated-at: '2025-05-02T20:45:05.097Z' +title: Vue Virtual +--- +Адаптер `@tanstack/vue-virtual` — это обёртка над основной логикой виртуализации. + +## `useVirtualizer` + +```tsx +function useVirtualizer( + options: PartialKeys< + VirtualizerOptions, + 'observeElementRect' | 'observeElementOffset' | 'scrollToFn' + >, +): Virtualizer +``` + +Эта функция возвращает стандартный экземпляр `Virtualizer`, настроенный для работы с HTML-элементом в качестве `scrollElement`. + +## `useWindowVirtualizer` + +```tsx +function useWindowVirtualizer( + options: PartialKeys< + VirtualizerOptions, + | 'getScrollElement' + | 'observeElementRect' + | 'observeElementOffset' + | 'scrollToFn' + >, +): Virtualizer +``` + +Эта функция возвращает экземпляр `Virtualizer`, работающий с окном браузера в качестве `scrollElement`. diff --git a/docs/ru/installation.md b/docs/ru/installation.md new file mode 100644 index 000000000..fc64f5f6d --- /dev/null +++ b/docs/ru/installation.md @@ -0,0 +1,50 @@ +--- +source-updated-at: '2025-03-07T09:19:44.000Z' +translation-updated-at: '2025-05-02T20:45:02.422Z' +title: Установка +--- +Прежде чем углубиться в API, давайте настроим окружение! + +Установите адаптер TanStack Virtual как зависимость с помощью вашего любимого менеджера пакетов npm. + +## React Virtual + +```bash +npm install @tanstack/react-virtual +``` + +## Solid Virtual + +```bash +npm install @tanstack/solid-virtual +``` + +## Svelte Virtual + +```bash +npm install @tanstack/svelte-virtual +``` + +## Vue Virtual + +```bash +npm install @tanstack/vue-virtual +``` + +## Lit Virtual + +```bash +$ npm install @tanstack/lit-virtual +``` + +## Angular Virtual + +```bash +$ npm install @tanstack/angular-virtual +``` + +## Virtual Core (без фреймворка) + +```bash +npm install @tanstack/virtual-core +``` diff --git a/docs/ru/introduction.md b/docs/ru/introduction.md new file mode 100644 index 000000000..81aeebeb8 --- /dev/null +++ b/docs/ru/introduction.md @@ -0,0 +1,69 @@ +--- +source-updated-at: '2024-11-25T13:01:52.000Z' +translation-updated-at: '2025-05-02T20:45:20.080Z' +title: Введение +--- +TanStack Virtual — это headless-утилита (headless UI utility) для виртуализации длинных списков элементов в JS/TS, React, Vue, Svelte, Solid, Lit и Angular. Это не компонент, поэтому он не предоставляет и не рендерит разметку или стили за вас. Хотя это требует небольшой разметки и стилей с вашей стороны, вы сохраняете 100% контроль над стилями, дизайном и реализацией. + +## Виртуализатор (Virtualizer) + +В основе TanStack Virtual лежит `Virtualizer`. Виртуализаторы могут быть ориентированы по вертикальной (по умолчанию) или горизонтальной осям, что позволяет достичь вертикальной, горизонтальной и даже грид-подобной виртуализации, комбинируя конфигурации обеих осей. + +Вот краткий пример того, как выглядит виртуализация длинного списка внутри div с использованием TanStack Virtual в React: + +```tsx +import { useVirtualizer } from '@tanstack/react-virtual'; + +function App() { + // Прокручиваемый элемент для вашего списка + const parentRef = React.useRef(null) + + // Виртуализатор + const rowVirtualizer = useVirtualizer({ + count: 10000, + getScrollElement: () => parentRef.current, + estimateSize: () => 35, + }) + + return ( + <> + {/* Прокручиваемый элемент для вашего списка */} +
+ {/* Большой внутренний элемент для хранения всех элементов */} +
+ {/* Только видимые элементы в виртуализаторе, вручную позиционированные для отображения */} + {rowVirtualizer.getVirtualItems().map((virtualItem) => ( +
+ Строка {virtualItem.index} +
+ ))} +
+
+ + ) +} +``` + +Давайте рассмотрим больше примеров! diff --git a/docs/zh-hans/api/virtual-item.md b/docs/zh-hans/api/virtual-item.md new file mode 100644 index 000000000..77190a2cb --- /dev/null +++ b/docs/zh-hans/api/virtual-item.md @@ -0,0 +1,66 @@ +--- +source-updated-at: '2024-08-29T09:26:23.000Z' +translation-updated-at: '2025-04-08T03:44:10.055Z' +title: 虚拟项 (virtual item) +--- +`VirtualItem` 对象表示由虚拟化器 (virtualizer) 返回的单个虚拟项 (virtual item)。它包含在虚拟化器的滚动元素 (scroll element) 坐标空间中渲染该项所需的信息以及其他有用的属性/方法。 + +```tsx +export interface VirtualItem { + key: string | number | bigint + index: number + start: number + end: number + size: number +} +``` + +每个 `VirtualItem` 对象上可用的属性和方法如下: + +### `key` + +```tsx +key: string | number | bigint +``` + +该项的唯一键 (key)。默认情况下为该项的索引 (index),但应通过虚拟化器 (virtualizer) 的 `getItemKey` 选项进行配置。 + +### `index` + +```tsx +index: number +``` + +该项的索引 (index)。 + +### `start` + +```tsx +start: number +``` + +该项的起始像素偏移量 (offset)。通常映射到 CSS 属性或变换 (transform),如 `top/left` 或 `translateX/translateY`。 + +### `end` + +```tsx +end: number +``` + +该项的结束像素偏移量 (offset)。大多数布局不需要此值,但为了提供便利,我们仍然保留了它。 + +### `size` + +```tsx +size: number +``` + +该项的大小 (size)。通常映射到 CSS 属性如 `width/height`。在使用 `VirtualItem.measureElement` 方法测量该项之前,此值为虚拟化器 (virtualizer) 的 `estimateSize` 选项返回的估计大小。测量后(如果选择测量),此值将变为 `measureElement` 虚拟化器选项返回的数字(默认配置为使用 `getBoundingClientRect()` 测量元素)。 + +### `lane` + +```tsx +lane: number +``` + +该项的通道 (lane) 索引 (index)。在常规列表中始终为 `0`,但在瀑布流布局 (masonry) 中会变得有用(详见变量示例)。 diff --git a/docs/zh-hans/api/virtualizer.md b/docs/zh-hans/api/virtualizer.md new file mode 100644 index 000000000..d0860bdb9 --- /dev/null +++ b/docs/zh-hans/api/virtualizer.md @@ -0,0 +1,423 @@ +--- +source-updated-at: '2025-05-05T15:05:35.000Z' +translation-updated-at: '2025-05-06T22:57:33.100Z' +title: 虚拟化器 (virtualizer) +--- +`Virtualizer` 类是 TanStack Virtual 的核心。通常由框架适配器为您创建 Virtualizer 实例,但您也可以直接获取虚拟化器。 + +```tsx +export class Virtualizer { + constructor(options: VirtualizerOptions) +} +``` + +## 必填选项 + +### `count` + +```tsx +count: number +``` + +需要虚拟化的总项目数。 + +### `getScrollElement` + +```tsx +getScrollElement: () => TScrollElement +``` + +返回虚拟化器可滚动元素的函数。如果元素尚未可用,可能返回 null。 + +### `estimateSize` + +```tsx +estimateSize: (index: number) => number +``` + +> 🧠 如果动态测量元素,建议估算项目可能的最大尺寸(宽度/高度,在合理范围内)。这将确保平滑滚动等功能更有可能正常工作。 + +此函数接收每个项目的索引,应返回每个项目的实际尺寸(如果使用 `virtualItem.measureElement` 动态测量项目,则返回估算尺寸)。根据虚拟化器的方向,此测量应返回宽度或高度。 + +## 可选选项 + +### `enabled` + +```tsx +enabled?: boolean +``` + +设置为 `false` 可禁用 scrollElement 观察器并重置虚拟化器的状态 + +### `debug` + +```tsx +debug?: boolean +``` + +设置为 `true` 可启用调试日志 + +### `initialRect` + +```tsx +initialRect?: Rect +``` + +scrollElement 的初始 `Rect`。主要在 SSR 环境中运行虚拟化器时有用,否则 initialRect 将在挂载时通过 `observeElementRect` 实现计算。 + +### `onChange` + +```tsx +onChange?: (instance: Virtualizer, sync: boolean) => void +``` + +当虚拟化器内部状态变化时触发的回调函数。接收虚拟化器实例和 sync 参数。 + +sync 参数表示当前是否正在进行滚动。滚动时为 `true`,滚动停止或执行其他操作(如调整大小)时为 `false`。 + +### `overscan` + +```tsx +overscan?: number +``` + +在可见区域上方和下方渲染的项目数。增加此数值会增加渲染虚拟化器所需的时间,但可能减少滚动时在虚拟化器顶部和底部看到渲染缓慢的空白项目的可能性。默认值为 `1`。 + +### `horizontal` + +```tsx +horizontal?: boolean +``` + +如果虚拟化器为水平方向,则设置为 `true`。 + +### `paddingStart` + +```tsx +paddingStart?: number +``` + +应用于虚拟化器起始端的像素填充。 + +### `paddingEnd` + +```tsx +paddingEnd?: number +``` + +应用于虚拟化器末端的像素填充。 + +### `scrollPaddingStart` + +```tsx +scrollPaddingStart?: number +``` + +滚动到元素时应用于虚拟化器起始端的像素填充。 + +### `scrollPaddingEnd` + +```tsx +scrollPaddingEnd?: number +``` + +滚动到元素时应用于虚拟化器末端的像素填充。 + +### `initialOffset` + +```tsx +initialOffset?: number | (() => number) +``` + +应用于虚拟化器的初始偏移量。通常仅在 SSR 环境中渲染虚拟化器时有用。 + +### `getItemKey` + +```tsx +getItemKey?: (index: number) => Key +``` + +此函数接收每个项目的索引,应返回该项目的唯一键。此函数的默认功能是返回项目的索引,但应尽可能覆盖此功能以返回整个集合中每个项目的唯一标识符。此函数应被记忆化以防止不必要的重新渲染。 + +### `rangeExtractor` + +```tsx +rangeExtractor?: (range: Range) => number[] +``` + +此函数接收可见范围索引,应返回要渲染的索引数组。如果需要手动添加或删除虚拟化器中的项目(例如渲染粘性项目、页眉、页脚等),此功能非常有用。默认的范围提取器实现将返回可见范围索引,并导出为 `defaultRangeExtractor`。 + +### `scrollToFn` + +```tsx +scrollToFn?: ( + offset: number, + options: { adjustments?: number; behavior?: 'auto' | 'smooth' }, + instance: Virtualizer, +) => void +``` + +可选函数(如果提供)应实现 scrollElement 的滚动行为。调用时将传入以下参数: + +- 要滚动到的 `offset`(以像素为单位)。 +- 一个对象,指示估算尺寸与实际尺寸之间是否存在差异(`adjustments`)和/或是否以平滑动画调用滚动(`behaviour`)。 +- 虚拟化器实例本身。 + +注意,内置的滚动实现导出为 `elementScroll` 和 `windowScroll`,它们由框架适配器函数(如 `useVirtualizer` 或 `useWindowVirtualizer`)自动配置。 + +> ⚠️ 尝试将 smoothScroll 与动态测量的元素一起使用将无效。 + +### `observeElementRect` + +```tsx +observeElementRect: ( + instance: Virtualizer, + cb: (rect: Rect) => void, +) => void | (() => void) +``` + +如果提供,此可选函数在 scrollElement 更改时调用,并应实现 scrollElement 的 `Rect`(包含 `width` 和 `height` 的对象)的初始测量和持续监控。调用时传入实例(您也可以通过 `instance.scrollElement` 访问 scrollElement)。内置实现导出为 `observeElementRect` 和 `observeWindowRect`,它们由框架适配器的导出函数(如 `useVirtualizer` 或 `useWindowVirtualizer`)自动配置。 + +### `observeElementOffset` + +```tsx +observeElementOffset: ( + instance: Virtualizer, + cb: (offset: number) => void, + ) => void | (() => void) +``` + +如果提供,此可选函数在 scrollElement 更改时调用,并应实现 scrollElement 的滚动偏移量(数字)的初始测量和持续监控。调用时传入实例(您也可以通过 `instance.scrollElement` 访问 scrollElement)。内置实现导出为 `observeElementOffset` 和 `observeWindowOffset`,它们由框架适配器的导出函数(如 `useVirtualizer` 或 `useWindowVirtualizer`)自动配置。 + +### `measureElement` + +```tsx +measureElement?: ( + element: TItemElement, + entry: ResizeObserverEntry | undefined, + instance: Virtualizer, +) => number +``` + +当虚拟化器需要动态测量项目的尺寸(宽度或高度)时调用此可选函数。 + +> 🧠 您可以使用 `instance.options.horizontal` 来确定应测量项目的宽度还是高度。 + +### `scrollMargin` + +```tsx +scrollMargin?: number +``` + +通过此选项,可以指定滚动偏移量的起始位置。通常,此值表示滚动元素开始处与列表开始处之间的空间。这在常见场景中特别有用,例如在窗口虚拟化器前有页眉或在单个滚动元素中使用多个虚拟化器时。如果使用元素的绝对定位,应在 CSS 变换中考虑 `scrollMargin`: +```tsx +transform: `translateY(${ + virtualRow.start - rowVirtualizer.options.scrollMargin +}px)` +``` +要为 `scrollMargin` 动态测量值,可以使用 `getBoundingClientRect()` 或 ResizeObserver。这在虚拟列表上方的项目可能更改高度的情况下非常有用。 + +### `gap` + +```tsx +gap?: number +``` + +此选项允许您设置虚拟化列表中项目之间的间距。特别适用于保持项目之间一致的视觉分隔,而无需手动调整每个项目的边距或填充。值以像素为单位指定。 + +### `lanes` + +```tsx +lanes: number +``` + +列表划分的通道数(垂直列表为列,水平列表为行)。 + +### `isScrollingResetDelay` + +```tsx +isScrollingResetDelay: number +``` + +此选项允许您指定在最后一个滚动事件后等待重置 isScrolling 实例属性的持续时间。默认值为 150 毫秒。 + +此选项的实现是为了需要一个可靠的机制来处理不同浏览器中的滚动行为。直到所有浏览器统一支持 scrollEnd 事件。 + +### `useScrollendEvent` + +```tsx +useScrollendEvent: boolean +``` + +确定是否使用原生 scrollend 事件来检测滚动何时停止。如果设置为 false,则使用防抖回退在 isScrollingResetDelay 毫秒后重置 isScrolling 实例属性。默认值为 `false`。 + +此选项的实现是为了需要一个可靠的机制来处理不同浏览器中的滚动行为。直到所有浏览器统一支持 scrollEnd 事件。 + +### `isRtl` + +```tsx +isRtl: boolean +``` + +是否反转水平滚动以支持从右到左的语言区域设置。 + +### `useAnimationFrameWithResizeObserver` + +```tsx +useAnimationFrameWithResizeObserver: boolean +``` + +此选项启用将 ResizeObserver 测量包装在 requestAnimationFrame 中,以实现更平滑的更新和减少布局抖动。默认值为 `false`。 + +通过确保测量与渲染周期对齐,有助于防止“ResizeObserver 循环完成但未传递通知”错误。这可以提高性能并减少 UI 抖动,特别是在动态调整元素大小时。然而,由于 ResizeObserver 已经异步运行,添加 requestAnimationFrame 可能会引入轻微的测量延迟,在某些情况下可能会被注意到。如果调整大小操作轻量且不会导致重排,启用此选项可能不会带来显著好处。 + +## 虚拟化器实例 + +虚拟化器实例上提供以下属性和方法: + +### `options` + +```tsx +options: readonly Required> +``` + +虚拟化器的当前选项。此属性通过框架适配器更新,为只读。 + +### `scrollElement` + +```tsx +scrollElement: readonly TScrollElement | null +``` + +虚拟化器的当前 scrollElement。此属性通过框架适配器更新,为只读。 + +### `getVirtualItems` + +```tsx +type getVirtualItems = () => VirtualItem[] +``` + +返回虚拟化器当前状态的虚拟项目。 + +### `getVirtualIndexes` + +```tsx +type getVirtualIndexes = () => number[] +``` + +返回虚拟化器当前状态的虚拟行索引。 + +### `scrollToOffset` + +```tsx +scrollToOffset: ( + toOffset: number, + options?: { + align?: 'start' | 'center' | 'end' | 'auto', + behavior?: 'auto' | 'smooth' + } +) => void +``` + +将虚拟化器滚动到提供的像素偏移量。可以可选地传递对齐模式以将滚动锚定到 scrollElement 的特定部分。 + +### `scrollToIndex` + +```tsx +scrollToIndex: ( + index: number, + options?: { + align?: 'start' | 'center' | 'end' | 'auto', + behavior?: 'auto' | 'smooth' + } +) => void +``` + +将虚拟化器滚动到提供的索引项目。可以可选地传递对齐模式以将滚动锚定到 scrollElement 的特定部分。 + +### `getTotalSize` + +```tsx +getTotalSize: () => number +``` + +返回虚拟化项目的总像素尺寸。如果选择在渲染时动态测量元素,此测量将逐步变化。 + +### `measure` + +```tsx +measure: () => void +``` + +重置任何先前的项目测量。 + +### `measureElement` + +```tsx +measureElement: (el: TItemElement | null) => void +``` + +使用配置的 `measureElement` 虚拟化器选项测量元素。您负责在虚拟化器标记中渲染组件时调用此函数(例如使用类似 React 的 ref 回调 prop)并添加 `data-index` + +```tsx +
...
+``` + +默认情况下,`measureElement` 虚拟化器选项配置为使用 `getBoundingClientRect()` 测量元素。 + +### `resizeItem` + +```tsx +resizeItem: (index: number, size: number) => void +``` + +手动更改虚拟化项目的尺寸。使用此函数手动设置为此索引计算的大小。在使用某些自定义变形过渡且事先知道变形项目的大小时非常有用。 + +您还可以将此方法与节流的 ResizeObserver 一起使用,而不是 `Virtualizer.measureElement`,以减少重新渲染。 + +> ⚠️ 请注意,在使用 `Virtualizer.measureElement` 监控该项目时手动更改项目的大小将导致不可预测的行为,因为 `Virtualizer.measureElement` 也在更改大小。但是,您可以在同一虚拟化器实例上使用 resizeItem 或 measureElement,但用于不同的项目索引。 + +### `scrollRect` + +```tsx +scrollRect: Rect +``` + +滚动元素的当前 `Rect`。 + +### `shouldAdjustScrollPositionOnItemSizeChange` + +```tsx +shouldAdjustScrollPositionOnItemSizeChange: undefined | ((item: VirtualItem, delta: number, instance: Virtualizer) => boolean) +``` + +shouldAdjustScrollPositionOnItemSizeChange 方法允许在动态渲染项目的尺寸与估算尺寸不同时精细控制滚动位置的调整。当跳转到列表中间并向后滚动时,新元素的尺寸可能与初始估算尺寸不同。这种差异可能导致后续项目移位,可能破坏用户的滚动体验,特别是在向后浏览列表时。 + +### `isScrolling` + +```tsx +isScrolling: boolean +``` + +布尔标志,指示列表当前是否正在滚动。 + +### `scrollDirection` + +```tsx +scrollDirection: 'forward' | 'backward' | null +``` + +此选项指示滚动的方向,可能值为 'forward'(向下滚动)和 'backward'(向上滚动)。没有活动滚动时值为 null。 + +### `scrollOffset` + +```tsx +scrollOffset: number +``` + +此选项表示沿滚动轴的当前滚动位置。从可滚动区域的起点以像素为单位测量。 diff --git a/docs/zh-hans/config.json b/docs/zh-hans/config.json new file mode 100644 index 000000000..42514f323 --- /dev/null +++ b/docs/zh-hans/config.json @@ -0,0 +1,258 @@ +{ + "$schema": "https://raw.githubusercontent.com/TanStack/tanstack.com/main/tanstack-docs-config.schema.json", + "docSearch": { + "appId": "", + "indexName": "", + "apiKey": "" + }, + "sections": [ + { + "label": "入门指南", + "children": [ + { + "label": "介绍", + "to": "introduction" + }, + { + "label": "安装", + "to": "installation" + } + ], + "frameworks": [ + { + "label": "react", + "children": [ + { + "label": "React Virtual", + "to": "framework/react/react-virtual" + } + ] + }, + { + "label": "angular", + "children": [ + { + "label": "Angular Virtual", + "to": "framework/angular/angular-virtual" + } + ] + }, + { + "label": "solid", + "children": [ + { + "label": "Solid Virtual", + "to": "framework/solid/solid-virtual" + } + ] + }, + { + "label": "svelte", + "children": [ + { + "label": "Svelte Virtual", + "to": "framework/svelte/svelte-virtual" + } + ] + }, + { + "label": "vue", + "children": [ + { + "label": "Vue Virtual", + "to": "framework/vue/vue-virtual" + } + ] + } + ] + }, + { + "label": "核心 API", + "children": [ + { + "label": "虚拟化器 (virtualizer)", + "to": "api/virtualizer" + }, + { + "label": "虚拟项 (virtual item)", + "to": "api/virtual-item" + } + ] + }, + { + "label": "示例", + "children": [], + "frameworks": [ + { + "label": "angular", + "children": [ + { + "to": "framework/angular/examples/fixed", + "label": "固定的" + }, + { + "to": "framework/angular/examples/variable", + "label": "可变的" + }, + { + "to": "framework/angular/examples/dynamic", + "label": "动态的" + }, + { + "to": "framework/angular/examples/padding", + "label": "内边距" + }, + { + "to": "framework/angular/examples/sticky", + "label": "粘性的" + }, + { + "to": "framework/angular/examples/infinite-scroll", + "label": "无限滚动" + }, + { + "to": "framework/angular/examples/smooth-scroll", + "label": "平滑滚动" + }, + { + "to": "framework/angular/examples/table", + "label": "表格" + }, + { + "to": "framework/angular/examples/window", + "label": "窗口" + } + ] + }, + { + "label": "react", + "children": [ + { + "to": "framework/react/examples/fixed", + "label": "固定的" + }, + { + "to": "framework/react/examples/variable", + "label": "可变的" + }, + { + "to": "framework/react/examples/dynamic", + "label": "动态的" + }, + { + "to": "framework/react/examples/padding", + "label": "内边距" + }, + { + "to": "framework/react/examples/sticky", + "label": "粘性的" + }, + { + "to": "framework/react/examples/infinite-scroll", + "label": "无限滚动" + }, + { + "to": "framework/react/examples/smooth-scroll", + "label": "平滑滚动" + }, + { + "to": "framework/react/examples/table", + "label": "表格" + }, + { + "to": "framework/react/examples/window", + "label": "窗口" + } + ] + }, + { + "label": "svelte", + "children": [ + { + "to": "framework/svelte/examples/fixed", + "label": "固定的" + }, + { + "to": "framework/svelte/examples/variable", + "label": "可变的" + }, + { + "to": "framework/svelte/examples/dynamic", + "label": "动态的" + }, + { + "to": "framework/svelte/examples/sticky", + "label": "粘性的" + }, + { + "to": "framework/svelte/examples/infinite-scroll", + "label": "无限滚动" + }, + { + "to": "framework/svelte/examples/smooth-scroll", + "label": "平滑滚动" + }, + { + "to": "framework/svelte/examples/table", + "label": "表格" + } + ] + }, + { + "label": "vue", + "children": [ + { + "to": "framework/vue/examples/fixed", + "label": "固定的" + }, + { + "to": "framework/vue/examples/variable", + "label": "可变的" + }, + { + "to": "framework/vue/examples/dynamic", + "label": "动态的" + }, + { + "to": "framework/vue/examples/sticky", + "label": "粘性的" + }, + { + "to": "framework/vue/examples/infinite-scroll", + "label": "无限滚动" + }, + { + "to": "framework/vue/examples/smooth-scroll", + "label": "平滑滚动" + }, + { + "to": "framework/vue/examples/table", + "label": "表格" + }, + { + "to": "framework/vue/examples/padding", + "label": "内边距" + }, + { + "to": "framework/vue/examples/scroll-padding", + "label": "滚动内边距" + } + ] + }, + { + "label": "lit", + "children": [ + { + "to": "framework/lit/examples/fixed", + "label": "固定的" + }, + { + "to": "framework/lit/examples/dynamic", + "label": "动态的" + } + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/docs/zh-hans/framework/angular/angular-virtual.md b/docs/zh-hans/framework/angular/angular-virtual.md new file mode 100644 index 000000000..145797457 --- /dev/null +++ b/docs/zh-hans/framework/angular/angular-virtual.md @@ -0,0 +1,35 @@ +--- +source-updated-at: '2024-08-19T19:18:26.000Z' +translation-updated-at: '2025-04-08T03:44:10.219Z' +title: Angular Virtual +--- +`@tanstack/angular-virtual` 适配器是对核心虚拟化逻辑的封装。 + +## `injectVirtualizer` + +```ts +function injectVirtualizer( + options: PartialKeys< + Omit, 'getScrollElement'>, + 'observeElementRect' | 'observeElementOffset' | 'scrollToFn' + > & { scrollElement: ElementRef | TScrollElement | undefined }, +): AngularVirtualizer +``` + +该函数返回一个配置为使用 HTML 元素作为 滚动元素 (scroll element) 的 `AngularVirtualizer` 实例。 + +## `injectWindowVirtualizer` + +```ts +function injectWindowVirtualizer( + options: PartialKeys< + VirtualizerOptions, + | 'getScrollElement' + | 'observeElementRect' + | 'observeElementOffset' + | 'scrollToFn' + >, +): AngularVirtualizer +``` + +该函数返回一个基于窗口的 `AngularVirtualizer` 实例,配置为使用窗口作为 滚动元素 (scroll element)。 diff --git a/docs/zh-hans/framework/lit/lit-virtual.md b/docs/zh-hans/framework/lit/lit-virtual.md new file mode 100644 index 000000000..74a18c70d --- /dev/null +++ b/docs/zh-hans/framework/lit/lit-virtual.md @@ -0,0 +1,36 @@ +--- +source-updated-at: '2024-06-24T18:08:48.000Z' +translation-updated-at: '2025-05-06T22:55:43.560Z' +title: Lit Virtual +--- +`@tanstack/lit-virtual` 适配器是对核心虚拟逻辑的封装。 + +## `createVirtualizer` + +```tsx +private virtualizerController = new VirtualizerController( + options: PartialKeys< VirtualizerOptions, + 'observeElementRect' | 'observeElementOffset' | 'scrollToFn' +) +``` + +该类代表一个标准的 `Virtualizer` 实例,配置为使用 HTML 元素作为 scrollElement。 +这将创建一个可在元素渲染方法中访问的 Lit 控制器 (Lit Controller)。 + +```tsx +render() { + const virtualizer = this.virtualizerController.getVirtualizer(); + const virtualItems = virtualizer.getVirtualItems(); +} +) +``` + +## `createWindowVirtualizer` + +```tsx +private windowVirtualizerController = new WindowVirtualizerController( + options: PartialKeys< VirtualizerOptions, + 'getScrollElement' | 'observeElementRect' | 'observeElementOffset' | 'scrollToFn' +``` + +该类代表基于窗口的 `Virtualizer` 实例,配置为使用 HTML 元素作为 scrollElement。 diff --git a/docs/zh-hans/framework/react/react-virtual.md b/docs/zh-hans/framework/react/react-virtual.md new file mode 100644 index 000000000..3bc3a4962 --- /dev/null +++ b/docs/zh-hans/framework/react/react-virtual.md @@ -0,0 +1,35 @@ +--- +source-updated-at: '2024-01-25T21:23:10.000Z' +translation-updated-at: '2025-04-08T03:44:10.180Z' +title: React Virtual +--- +`@tanstack/react-virtual` 适配器是核心虚拟逻辑的封装层。 + +## `useVirtualizer` + +```tsx +function useVirtualizer( + options: PartialKeys< + VirtualizerOptions, + 'observeElementRect' | 'observeElementOffset' | 'scrollToFn' + >, +): Virtualizer +``` + +该函数返回一个标准的 `Virtualizer` 实例,该实例被配置为与 HTML 元素作为 滚动元素 (scroll element) 一起工作。 + +## `useWindowVirtualizer` + +```tsx +function useWindowVirtualizer( + options: PartialKeys< + VirtualizerOptions, + | 'getScrollElement' + | 'observeElementRect' + | 'observeElementOffset' + | 'scrollToFn' + >, +): Virtualizer +``` + +该函数返回一个基于窗口的 `Virtualizer` 实例,该实例被配置为与窗口作为 滚动元素 (scroll element) 一起工作。 diff --git a/docs/zh-hans/framework/solid/solid-virtual.md b/docs/zh-hans/framework/solid/solid-virtual.md new file mode 100644 index 000000000..4f4c0ce6e --- /dev/null +++ b/docs/zh-hans/framework/solid/solid-virtual.md @@ -0,0 +1,35 @@ +--- +source-updated-at: '2024-01-25T21:23:10.000Z' +translation-updated-at: '2025-04-08T03:44:10.263Z' +title: Solid Virtual +--- +`@tanstack/solid-virtual` 适配器是核心虚拟化逻辑的封装层。 + +## `createVirtualizer` + +```tsx +function createVirtualizer( + options: PartialKeys< + VirtualizerOptions, + 'observeElementRect' | 'observeElementOffset' | 'scrollToFn' + >, +): Virtualizer +``` + +该函数返回一个标准的 `Virtualizer` 实例,配置为使用 HTML 元素作为 滚动元素 (scroll element)。 + +## `createWindowVirtualizer` + +```tsx +function createWindowVirtualizer( + options: PartialKeys< + VirtualizerOptions, + | 'getScrollElement' + | 'observeElementRect' + | 'observeElementOffset' + | 'scrollToFn' + >, +): Virtualizer +``` + +该函数返回一个基于窗口的 `Virtualizer` 实例,配置为使用 window 对象作为 滚动元素 (scroll element)。 diff --git a/docs/zh-hans/framework/svelte/svelte-virtual.md b/docs/zh-hans/framework/svelte/svelte-virtual.md new file mode 100644 index 000000000..1e4069540 --- /dev/null +++ b/docs/zh-hans/framework/svelte/svelte-virtual.md @@ -0,0 +1,35 @@ +--- +source-updated-at: '2024-01-25T21:23:10.000Z' +translation-updated-at: '2025-04-08T03:44:10.308Z' +title: Svelte Virtual +--- +`@tanstack/svelte-virtual` 适配器是对核心虚拟化逻辑的封装。 + +## `createVirtualizer` + +```tsx +function createVirtualizer( + options: PartialKeys< + VirtualizerOptions, + 'observeElementRect' | 'observeElementOffset' | 'scrollToFn' + >, +): Virtualizer +``` + +该函数返回一个标准的 `Virtualizer` 实例,配置为使用 HTML 元素作为 滚动元素 (scrollElement)。 + +## `createWindowVirtualizer` + +```tsx +function createWindowVirtualizer( + options: PartialKeys< + VirtualizerOptions, + | 'getScrollElement' + | 'observeElementRect' + | 'observeElementOffset' + | 'scrollToFn' + >, +): Virtualizer +``` + +该函数返回一个基于窗口的 `Virtualizer` 实例,配置为使用窗口作为 滚动元素 (scrollElement)。 diff --git a/docs/zh-hans/framework/vue/vue-virtual.md b/docs/zh-hans/framework/vue/vue-virtual.md new file mode 100644 index 000000000..4d1473f54 --- /dev/null +++ b/docs/zh-hans/framework/vue/vue-virtual.md @@ -0,0 +1,35 @@ +--- +source-updated-at: '2024-06-01T09:52:04.000Z' +translation-updated-at: '2025-04-08T03:44:10.140Z' +title: Vue Virtual +--- +`@tanstack/vue-virtual` 适配器是核心虚拟逻辑的封装层。 + +## `useVirtualizer` + +```tsx +function useVirtualizer( + options: PartialKeys< + VirtualizerOptions, + 'observeElementRect' | 'observeElementOffset' | 'scrollToFn' + >, +): Virtualizer +``` + +该函数返回一个标准的 `Virtualizer` 实例,该实例配置为使用 HTML 元素作为 滚动元素 (scrollElement)。 + +## `useWindowVirtualizer` + +```tsx +function useWindowVirtualizer( + options: PartialKeys< + VirtualizerOptions, + | 'getScrollElement' + | 'observeElementRect' + | 'observeElementOffset' + | 'scrollToFn' + >, +): Virtualizer +``` + +该函数返回一个基于窗口的 `Virtualizer` 实例,该实例配置为使用窗口作为 滚动元素 (scrollElement)。 diff --git a/docs/zh-hans/installation.md b/docs/zh-hans/installation.md new file mode 100644 index 000000000..4c1b40829 --- /dev/null +++ b/docs/zh-hans/installation.md @@ -0,0 +1,50 @@ +--- +source-updated-at: '2025-03-07T09:19:44.000Z' +translation-updated-at: '2025-04-08T03:44:10.003Z' +title: 安装 +--- +在深入探讨 API 之前,我们先完成安装配置! + +使用你喜欢的 npm 包管理器安装 TanStack Virtual 适配器作为依赖项 + +## React Virtual + +```bash +npm install @tanstack/react-virtual +``` + +## Solid Virtual + +```bash +npm install @tanstack/solid-virtual +``` + +## Svelte Virtual + +```bash +npm install @tanstack/svelte-virtual +``` + +## Vue Virtual + +```bash +npm install @tanstack/vue-virtual +``` + +## Lit Virtual + +```bash +$ npm install @tanstack/lit-virtual +``` + +## Angular Virtual + +```bash +$ npm install @tanstack/angular-virtual +``` + +## Virtual Core (无框架版本) + +```bash +npm install @tanstack/virtual-core +``` diff --git a/docs/zh-hans/introduction.md b/docs/zh-hans/introduction.md new file mode 100644 index 000000000..91bf8e465 --- /dev/null +++ b/docs/zh-hans/introduction.md @@ -0,0 +1,69 @@ +--- +source-updated-at: '2024-11-25T13:01:52.000Z' +translation-updated-at: '2025-04-08T03:44:09.958Z' +title: 介绍 +--- +TanStack Virtual 是一个用于在 JS/TS、React、Vue、Svelte、Solid、Lit 和 Angular 中虚拟化长元素列表的无头 UI 工具 (headless UI utility)。它不是一个组件,因此不会提供或渲染任何标记或样式。虽然这需要您自行处理一些标记和样式,但您将保留对样式、设计和实现的 100% 控制权。 + +## 虚拟化器 (Virtualizer) + +TanStack Virtual 的核心是 `Virtualizer`。虚拟化器 (virtualizer) 可以设置为垂直(默认)或水平方向,这使得通过结合两种轴向配置,可以实现垂直、水平甚至类似网格的虚拟化 (virtualization)。 + +以下是一个在 React 中使用 TanStack Virtual 虚拟化长列表的简单示例: + +```tsx +import { useVirtualizer } from '@tanstack/react-virtual'; + +function App() { + // 列表的可滚动元素 (scroll element) + const parentRef = React.useRef(null) + + // 虚拟化器 (virtualizer) + const rowVirtualizer = useVirtualizer({ + count: 10000, + getScrollElement: () => parentRef.current, + estimateSize: () => 35, + }) + + return ( + <> + {/* 列表的可滚动元素 (scroll element) */} +
+ {/* 容纳所有项的大型内部元素 */} +
+ {/* 仅虚拟化器 (virtualizer) 中可见的项,手动定位以显示在视图中 */} + {rowVirtualizer.getVirtualItems().map((virtualItem) => ( +
+ 行 {virtualItem.index} +
+ ))} +
+
+ + ) +} +``` + +让我们深入探讨更多示例! diff --git a/docs/zh-hant/api/virtual-item.md b/docs/zh-hant/api/virtual-item.md new file mode 100644 index 000000000..9f6771c72 --- /dev/null +++ b/docs/zh-hant/api/virtual-item.md @@ -0,0 +1,66 @@ +--- +source-updated-at: '2024-08-29T09:26:23.000Z' +translation-updated-at: '2025-05-02T15:23:10.370Z' +title: 虛擬項目 (VirtualItem) +--- +`VirtualItem` 物件代表虛擬化器 (virtualizer) 返回的單一項目,其中包含在虛擬化器的 scrollElement 座標空間內渲染該項目所需的資訊,以及其他實用的屬性/方法。 + +```tsx +export interface VirtualItem { + key: string | number | bigint + index: number + start: number + end: number + size: number +} +``` + +每個 VirtualItem 物件都提供以下屬性和方法: + +### `key` + +```tsx +key: string | number | bigint +``` + +項目的唯一鍵值 (key)。預設為項目索引,但應透過 Virtualizer 選項中的 `getItemKey` 進行設定。 + +### `index` + +```tsx +index: number +``` + +項目的索引值。 + +### `start` + +```tsx +start: number +``` + +項目的起始像素偏移量。通常會對應到 CSS 屬性或變形效果,例如 `top/left` 或 `translateX/translateY`。 + +### `end` + +```tsx +end: number +``` + +項目的結束像素偏移量。大多數佈局不需要此值,但我們仍提供此屬性以備不時之需。 + +### `size` + +```tsx +size: number +``` + +項目的尺寸。通常會對應到 CSS 屬性如 `width/height`。在使用 `VirtualItem.measureElement` 方法測量項目之前,此值會是虛擬化器選項 `estimateSize` 返回的預估尺寸。測量項目後(如有進行測量),此值會變成虛擬化器選項 `measureElement` 返回的數值(預設設定為使用 `getBoundingClientRect()` 測量元素)。 + +### `lane` + +```tsx +lane: number +``` + +項目的通道索引 (lane index)。在一般清單中此值始終為 `0`,但在瀑布流佈局 (masonry layouts) 中會變得有用(詳見變數範例)。 diff --git a/docs/zh-hant/api/virtualizer.md b/docs/zh-hant/api/virtualizer.md new file mode 100644 index 000000000..3b2511939 --- /dev/null +++ b/docs/zh-hant/api/virtualizer.md @@ -0,0 +1,423 @@ +--- +source-updated-at: '2025-05-05T15:05:35.000Z' +translation-updated-at: '2025-05-06T22:59:44.428Z' +title: 虛擬化器 (Virtualizer) +--- +`Virtualizer` 類別是 TanStack Virtual 的核心。通常框架適配器會自動為你建立 Virtualizer 實例,但你也可以直接取得 virtualizer。 + +```tsx +export class Virtualizer { + constructor(options: VirtualizerOptions) +} +``` + +## 必要選項 + +### `count` + +```tsx +count: number +``` + +要虛擬化的項目總數。 + +### `getScrollElement` + +```tsx +getScrollElement: () => TScrollElement +``` + +回傳 virtualizer 可滾動元素的函式。如果元素尚未可用,可能回傳 null。 + +### `estimateSize` + +```tsx +estimateSize: (index: number) => number +``` + +> 🧠 如果你要動態測量元素,建議估計項目可能的最大尺寸(在合理範圍內的寬度/高度)。這將確保平滑滾動等功能有更高的機率正常運作。 + +此函式接收每個項目的索引,應回傳每個項目的實際尺寸(或如果你打算使用 `virtualItem.measureElement` 動態測量項目,則回傳估計尺寸)。此測量應根據 virtualizer 的方向回傳寬度或高度。 + +## 選用選項 + +### `enabled` + +```tsx +enabled?: boolean +``` + +設為 `false` 可停用 scrollElement 觀察器並重置 virtualizer 的狀態 + +### `debug` + +```tsx +debug?: boolean +``` + +設為 `true` 可啟用除錯日誌 + +### `initialRect` + +```tsx +initialRect?: Rect +``` + +scrollElement 的初始 `Rect`。這主要在需要在 SSR 環境中執行 virtualizer 時有用,否則 initialRect 會在掛載時由 `observeElementRect` 實作計算。 + +### `onChange` + +```tsx +onChange?: (instance: Virtualizer, sync: boolean) => void +``` + +當 virtualizer 內部狀態變更時觸發的回呼函式。它接收 virtualizer 實例和 sync 參數。 + +sync 參數表示當前是否正在滾動。滾動進行中時為 `true`,滾動停止或執行其他操作(如調整大小)時為 `false`。 + +### `overscan` + +```tsx +overscan?: number +``` + +在可見區域上方和下方渲染的項目數量。增加此數字會增加渲染 virtualizer 所需的時間,但可能減少在滾動時看到頂部和底部渲染緩慢的空白項目的可能性。預設值為 `1`。 + +### `horizontal` + +```tsx +horizontal?: boolean +``` + +如果你的 virtualizer 是水平方向,請設為 `true`。 + +### `paddingStart` + +```tsx +paddingStart?: number +``` + +套用到 virtualizer 起始處的內距(像素)。 + +### `paddingEnd` + +```tsx +paddingEnd?: number +``` + +套用到 virtualizer 結束處的內距(像素)。 + +### `scrollPaddingStart` + +```tsx +scrollPaddingStart?: number +``` + +滾動到元素時套用到 virtualizer 起始處的內距(像素)。 + +### `scrollPaddingEnd` + +```tsx +scrollPaddingEnd?: number +``` + +滾動到元素時套用到 virtualizer 結束處的內距(像素)。 + +### `initialOffset` + +```tsx +initialOffset?: number | (() => number) +``` + +套用到 virtualizer 的初始偏移量。這通常只在 SSR 環境中渲染 virtualizer 時有用。 + +### `getItemKey` + +```tsx +getItemKey?: (index: number) => Key +``` + +此函式接收每個項目的索引,應回傳該項目的唯一鍵。此函式的預設功能是回傳項目的索引,但應盡可能覆寫此功能以回傳整個集合中每個項目的唯一識別碼。此函式應被記憶化以防止不必要的重新渲染。 + +### `rangeExtractor` + +```tsx +rangeExtractor?: (range: Range) => number[] +``` + +此函式接收可見範圍的索引,應回傳要渲染的索引陣列。這在需要手動新增或移除 virtualizer 中的項目時很有用,例如渲染固定項目、頁首、頁尾等。預設的範圍提取器實作會回傳可見範圍的索引,並以 `defaultRangeExtractor` 匯出。 + +### `scrollToFn` + +```tsx +scrollToFn?: ( + offset: number, + options: { adjustments?: number; behavior?: 'auto' | 'smooth' }, + instance: Virtualizer, +) => void +``` + +一個選用函式(如果提供)應實作 scrollElement 的滾動行為。它會以以下參數呼叫: + +- 要滾動到的 `offset`(像素)。 +- 一個物件,表示估計尺寸與實際尺寸之間是否有差異(`adjustments`)和/或滾動是否以平滑動畫呼叫(`behaviour`)。 +- virtualizer 實例本身。 + +請注意,內建的滾動實作以 `elementScroll` 和 `windowScroll` 匯出,這些會由框架適配器函式(如 `useVirtualizer` 或 `useWindowVirtualizer`)自動配置。 + +> ⚠️ 嘗試將 smoothScroll 與動態測量的元素一起使用將無法運作。 + +### `observeElementRect` + +```tsx +observeElementRect: ( + instance: Virtualizer, + cb: (rect: Rect) => void, +) => void | (() => void) +``` + +一個選用函式,如果提供,會在 scrollElement 變更時呼叫,並應實作 scrollElement 的 `Rect`(具有 `width` 和 `height` 的物件)的初始測量和持續監控。它會以實例呼叫(你也可以透過 `instance.scrollElement` 存取 scrollElement)。內建實作以 `observeElementRect` 和 `observeWindowRect` 匯出,這些會由框架適配器的匯出函式(如 `useVirtualizer` 或 `useWindowVirtualizer`)自動配置。 + +### `observeElementOffset` + +```tsx +observeElementOffset: ( + instance: Virtualizer, + cb: (offset: number) => void, + ) => void | (() => void) +``` + +一個選用函式,如果提供,會在 scrollElement 變更時呼叫,並應實作 scrollElement 的滾動偏移量(數字)的初始測量和持續監控。它會以實例呼叫(你也可以透過 `instance.scrollElement` 存取 scrollElement)。內建實作以 `observeElementOffset` 和 `observeWindowOffset` 匯出,這些會由框架適配器的匯出函式(如 `useVirtualizer` 或 `useWindowVirtualizer`)自動配置。 + +### `measureElement` + +```tsx +measureElement?: ( + element: TItemElement, + entry: ResizeObserverEntry | undefined, + instance: Virtualizer, +) => number +``` + +此選用函式在 virtualizer 需要動態測量項目尺寸(寬度或高度)時呼叫。 + +> 🧠 你可以使用 `instance.options.horizontal` 來決定應測量項目的寬度或高度。 + +### `scrollMargin` + +```tsx +scrollMargin?: number +``` + +透過此選項,你可以指定滾動偏移量的起始位置。通常,此值代表滾動元素開頭與清單起始處之間的空間。這在常見情境中特別有用,例如當你在視窗 virtualizer 前有頁首,或在單一滾動元素中使用多個 virtualizer 時。如果你使用元素的絕對定位,應在 CSS transform 中考慮 `scrollMargin`: +```tsx +transform: `translateY(${ + virtualRow.start - rowVirtualizer.options.scrollMargin +}px)` +``` +要動態測量 `scrollMargin` 的值,可以使用 `getBoundingClientRect()` 或 ResizeObserver。這在虛擬清單上方的項目可能變更高度時很有幫助。 + +### `gap` + +```tsx +gap?: number +``` + +此選項允許你設定虛擬化清單中項目之間的間距。這對於在不手動調整每個項目的 margin 或 padding 的情況下保持一致的視覺分隔特別有用。值以像素為單位。 + +### `lanes` + +```tsx +lanes: number +``` + +清單劃分的通道數(垂直清單為列,水平清單為行)。 + +### `isScrollingResetDelay` + +```tsx +isScrollingResetDelay: number +``` + +此選項允許你指定在最後一個滾動事件後等待多久才重置 isScrolling 實例屬性。預設值為 150 毫秒。 + +此選項的實作是出於需要一個可靠的機制來處理不同瀏覽器間的滾動行為。直到所有瀏覽器都統一支援 scrollEnd 事件。 + +### `useScrollendEvent` + +```tsx +useScrollendEvent: boolean +``` + +決定是否使用原生 scrollend 事件來偵測滾動何時停止。如果設為 false,則使用防抖回退在 isScrollingResetDelay 毫秒後重置 isScrolling 實例屬性。預設值為 `false`。 + +此選項的實作是出於需要一個可靠的機制來處理不同瀏覽器間的滾動行為。直到所有瀏覽器都統一支援 scrollEnd 事件。 + +### `isRtl` + +```tsx +isRtl: boolean +``` + +是否反轉水平滾動以支援從右到左的語言環境。 + +### `useAnimationFrameWithResizeObserver` + +```tsx +useAnimationFrameWithResizeObserver: boolean +``` + +此選項啟用將 ResizeObserver 測量包裝在 requestAnimationFrame 中,以實現更平滑的更新和減少佈局抖動。預設值為 `false`。 + +它有助於防止「ResizeObserver loop completed with undelivered notifications」錯誤,確保測量與渲染週期對齊。這可以提高效能並減少 UI 抖動,特別是在動態調整元素大小時。然而,由於 ResizeObserver 已經是異步執行,加入 requestAnimationFrame 可能會引入輕微的測量延遲,在某些情況下可能明顯。如果調整大小操作輕量且不會導致重排,啟用此選項可能不會帶來顯著好處。 + +## Virtualizer 實例 + +以下屬性和方法可在 virtualizer 實例上使用: + +### `options` + +```tsx +options: readonly Required> +``` + +virtualizer 的當前選項。此屬性透過框架適配器更新且為唯讀。 + +### `scrollElement` + +```tsx +scrollElement: readonly TScrollElement | null +``` + +virtualizer 的當前 scrollElement。此屬性透過框架適配器更新且為唯讀。 + +### `getVirtualItems` + +```tsx +type getVirtualItems = () => VirtualItem[] +``` + +回傳 virtualizer 當前狀態的虛擬項目。 + +### `getVirtualIndexes` + +```tsx +type getVirtualIndexes = () => number[] +``` + +回傳 virtualizer 當前狀態的虛擬列索引。 + +### `scrollToOffset` + +```tsx +scrollToOffset: ( + toOffset: number, + options?: { + align?: 'start' | 'center' | 'end' | 'auto', + behavior?: 'auto' | 'smooth' + } +) => void +``` + +將 virtualizer 滾動到提供的像素偏移量。你可以選擇傳遞對齊模式以將滾動錨定到 scrollElement 的特定部分。 + +### `scrollToIndex` + +```tsx +scrollToIndex: ( + index: number, + options?: { + align?: 'start' | 'center' | 'end' | 'auto', + behavior?: 'auto' | 'smooth' + } +) => void +``` + +將 virtualizer 滾動到提供的索引項目。你可以選擇傳遞對齊模式以將滾動錨定到 scrollElement 的特定部分。 + +### `getTotalSize` + +```tsx +getTotalSize: () => number +``` + +回傳虛擬化項目的總尺寸(像素)。如果你選擇在渲染時動態測量元素,此測量會逐步變更。 + +### `measure` + +```tsx +measure: () => void +``` + +重置任何先前的項目測量。 + +### `measureElement` + +```tsx +measureElement: (el: TItemElement | null) => void +``` + +使用你配置的 `measureElement` virtualizer 選項測量元素。你負責在 virtualizer 標記中渲染元件時呼叫此函式(例如使用類似 React 的 ref 回呼 prop)並新增 `data-index` + +```tsx +
...
+``` + +預設情況下,`measureElement` virtualizer 選項配置為使用 `getBoundingClientRect()` 測量元素。 + +### `resizeItem` + +```tsx +resizeItem: (index: number, size: number) => void +``` + +手動變更虛擬化項目的尺寸。使用此函式手動設定此索引的計算尺寸。在使用某些自訂變形轉換且你事先知道變形項目的尺寸時很有用。 + +你也可以將此方法與節流的 ResizeObserver 一起使用,而不是 `Virtualizer.measureElement`,以減少重新渲染。 + +> ⚠️ 請注意,當使用 `Virtualizer.measureElement` 監控該項目時,手動變更項目的尺寸會導致不可預測的行為,因為 `Virtualizer.measureElement` 也在變更尺寸。然而,你可以在同一個 virtualizer 實例中的不同項目索引上使用 resizeItem 或 measureElement 其中之一。 + +### `scrollRect` + +```tsx +scrollRect: Rect +``` + +scroll 元素的當前 `Rect`。 + +### `shouldAdjustScrollPositionOnItemSizeChange` + +```tsx +shouldAdjustScrollPositionOnItemSizeChange: undefined | ((item: VirtualItem, delta: number, instance: Virtualizer) => boolean) +``` + +shouldAdjustScrollPositionOnItemSizeChange 方法可在動態渲染項目的尺寸與估計尺寸不同時,精細控制滾動位置的調整。當跳到清單中間並向後滾動時,新元素的尺寸可能與初始估計尺寸不同。這種差異可能導致後續項目移位,可能干擾使用者的滾動體驗,特別是在向後滾動清單時。 + +### `isScrolling` + +```tsx +isScrolling: boolean +``` + +表示清單當前是否正在滾動的布林旗標。 + +### `scrollDirection` + +```tsx +scrollDirection: 'forward' | 'backward' | null +``` + +此選項表示滾動方向,可能值為向下滾動的 'forward' 和向上滾動的 'backward'。沒有活動滾動時值為 null。 + +### `scrollOffset` + +```tsx +scrollOffset: number +``` + +此選項表示沿滾動軸的當前滾動位置。從可滾動區域的起始點以像素為單位測量。 diff --git a/docs/zh-hant/config.json b/docs/zh-hant/config.json new file mode 100644 index 000000000..75d66a068 --- /dev/null +++ b/docs/zh-hant/config.json @@ -0,0 +1,258 @@ +{ + "$schema": "https://raw.githubusercontent.com/TanStack/tanstack.com/main/tanstack-docs-config.schema.json", + "docSearch": { + "appId": "", + "indexName": "", + "apiKey": "" + }, + "sections": [ + { + "label": "開始使用", + "children": [ + { + "label": "介紹", + "to": "introduction" + }, + { + "label": "安裝", + "to": "installation" + } + ], + "frameworks": [ + { + "label": "react", + "children": [ + { + "label": "React Virtual", + "to": "framework/react/react-virtual" + } + ] + }, + { + "label": "angular", + "children": [ + { + "label": "Angular Virtual", + "to": "framework/angular/angular-virtual" + } + ] + }, + { + "label": "solid", + "children": [ + { + "label": "Solid Virtual", + "to": "framework/solid/solid-virtual" + } + ] + }, + { + "label": "svelte", + "children": [ + { + "label": "Svelte Virtual", + "to": "framework/svelte/svelte-virtual" + } + ] + }, + { + "label": "vue", + "children": [ + { + "label": "Vue Virtual", + "to": "framework/vue/vue-virtual" + } + ] + } + ] + }, + { + "label": "核心 API", + "children": [ + { + "label": "虛擬化器 (Virtualizer)", + "to": "api/virtualizer" + }, + { + "label": "虛擬項目 (VirtualItem)", + "to": "api/virtual-item" + } + ] + }, + { + "label": "範例", + "children": [], + "frameworks": [ + { + "label": "angular", + "children": [ + { + "to": "framework/angular/examples/fixed", + "label": "固定 (Fixed)" + }, + { + "to": "framework/angular/examples/variable", + "label": "可變 (Variable)" + }, + { + "to": "framework/angular/examples/dynamic", + "label": "動態 (Dynamic)" + }, + { + "to": "framework/angular/examples/padding", + "label": "填充 (Padding)" + }, + { + "to": "framework/angular/examples/sticky", + "label": "黏性 (Sticky)" + }, + { + "to": "framework/angular/examples/infinite-scroll", + "label": "無限滾動 (Infinite Scroll)" + }, + { + "to": "framework/angular/examples/smooth-scroll", + "label": "平滑滾動 (Smooth Scroll)" + }, + { + "to": "framework/angular/examples/table", + "label": "表格 (Table)" + }, + { + "to": "framework/angular/examples/window", + "label": "視窗 (Window)" + } + ] + }, + { + "label": "react", + "children": [ + { + "to": "framework/react/examples/fixed", + "label": "固定 (Fixed)" + }, + { + "to": "framework/react/examples/variable", + "label": "可變 (Variable)" + }, + { + "to": "framework/react/examples/dynamic", + "label": "動態 (Dynamic)" + }, + { + "to": "framework/react/examples/padding", + "label": "填充 (Padding)" + }, + { + "to": "framework/react/examples/sticky", + "label": "黏性 (Sticky)" + }, + { + "to": "framework/react/examples/infinite-scroll", + "label": "無限滾動 (Infinite Scroll)" + }, + { + "to": "framework/react/examples/smooth-scroll", + "label": "平滑滾動 (Smooth Scroll)" + }, + { + "to": "framework/react/examples/table", + "label": "表格 (Table)" + }, + { + "to": "framework/react/examples/window", + "label": "視窗 (Window)" + } + ] + }, + { + "label": "svelte", + "children": [ + { + "to": "framework/svelte/examples/fixed", + "label": "固定 (Fixed)" + }, + { + "to": "framework/svelte/examples/variable", + "label": "可變 (Variable)" + }, + { + "to": "framework/svelte/examples/dynamic", + "label": "動態 (Dynamic)" + }, + { + "to": "framework/svelte/examples/sticky", + "label": "黏性 (Sticky)" + }, + { + "to": "framework/svelte/examples/infinite-scroll", + "label": "無限滾動 (Infinite Scroll)" + }, + { + "to": "framework/svelte/examples/smooth-scroll", + "label": "平滑滾動 (Smooth Scroll)" + }, + { + "to": "framework/svelte/examples/table", + "label": "表格 (Table)" + } + ] + }, + { + "label": "vue", + "children": [ + { + "to": "framework/vue/examples/fixed", + "label": "固定 (Fixed)" + }, + { + "to": "framework/vue/examples/variable", + "label": "可變 (Variable)" + }, + { + "to": "framework/vue/examples/dynamic", + "label": "動態 (Dynamic)" + }, + { + "to": "framework/vue/examples/sticky", + "label": "黏性 (Sticky)" + }, + { + "to": "framework/vue/examples/infinite-scroll", + "label": "無限滾動 (Infinite Scroll)" + }, + { + "to": "framework/vue/examples/smooth-scroll", + "label": "平滑滾動 (Smooth Scroll)" + }, + { + "to": "framework/vue/examples/table", + "label": "表格 (Table)" + }, + { + "to": "framework/vue/examples/padding", + "label": "填充 (Padding)" + }, + { + "to": "framework/vue/examples/scroll-padding", + "label": "滾動填充 (Scroll Padding)" + } + ] + }, + { + "label": "lit", + "children": [ + { + "to": "framework/lit/examples/fixed", + "label": "固定 (Fixed)" + }, + { + "to": "framework/lit/examples/dynamic", + "label": "動態 (Dynamic)" + } + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/docs/zh-hant/framework/angular/angular-virtual.md b/docs/zh-hant/framework/angular/angular-virtual.md new file mode 100644 index 000000000..549f50058 --- /dev/null +++ b/docs/zh-hant/framework/angular/angular-virtual.md @@ -0,0 +1,35 @@ +--- +source-updated-at: '2024-08-19T19:18:26.000Z' +translation-updated-at: '2025-05-02T15:24:47.795Z' +title: Angular Virtual +--- +`@tanstack/angular-virtual` 配接器是核心虛擬邏輯的封裝層。 + +## `injectVirtualizer` + +```ts +function injectVirtualizer( + options: PartialKeys< + Omit, 'getScrollElement'>, + 'observeElementRect' | 'observeElementOffset' | 'scrollToFn' + > & { scrollElement: ElementRef | TScrollElement | undefined }, +): AngularVirtualizer +``` + +此函數會回傳一個 `AngularVirtualizer` 實例,該實例配置為以 HTML 元素作為 scrollElement 運作。 + +## `injectWindowVirtualizer` + +```ts +function injectWindowVirtualizer( + options: PartialKeys< + VirtualizerOptions, + | 'getScrollElement' + | 'observeElementRect' + | 'observeElementOffset' + | 'scrollToFn' + >, +): AngularVirtualizer +``` + +此函數會回傳一個基於視窗的 `AngularVirtualizer` 實例,該實例配置為以視窗作為 scrollElement 運作。 diff --git a/docs/zh-hant/framework/lit/lit-virtual.md b/docs/zh-hant/framework/lit/lit-virtual.md new file mode 100644 index 000000000..8be804fea --- /dev/null +++ b/docs/zh-hant/framework/lit/lit-virtual.md @@ -0,0 +1,35 @@ +--- +source-updated-at: '2024-06-24T18:08:48.000Z' +translation-updated-at: '2025-05-06T22:57:47.358Z' +title: Lit Virtual +--- +`@tanstack/lit-virtual` 配接器是核心虛擬邏輯的封裝層。 + +## `createVirtualizer` + +```tsx +private virtualizerController = new VirtualizerController( + options: PartialKeys< VirtualizerOptions, + 'observeElementRect' | 'observeElementOffset' | 'scrollToFn' +) +``` + +此類別代表一個標準的 `Virtualizer` 實例,配置為與 HTML 元素作為 scrollElement 協同工作。這將建立一個可在元素渲染方法中存取的 Lit 控制器 (Lit Controller)。 + +```tsx +render() { + const virtualizer = this.virtualizerController.getVirtualizer(); + const virtualItems = virtualizer.getVirtualItems(); +} +) +``` + +## `createWindowVirtualizer` + +```tsx +private windowVirtualizerController = new WindowVirtualizerController( + options: PartialKeys< VirtualizerOptions, + 'getScrollElement' | 'observeElementRect' | 'observeElementOffset' | 'scrollToFn' +``` + +此類別代表一個基於視窗 (window-based) 的 `Virtualizer` 實例,配置為與 HTML 元素作為 scrollElement 協同工作。 diff --git a/docs/zh-hant/framework/react/react-virtual.md b/docs/zh-hant/framework/react/react-virtual.md new file mode 100644 index 000000000..7c5e41027 --- /dev/null +++ b/docs/zh-hant/framework/react/react-virtual.md @@ -0,0 +1,35 @@ +--- +source-updated-at: '2024-01-25T21:23:10.000Z' +translation-updated-at: '2025-05-02T15:25:01.231Z' +title: React Virtual +--- +`@tanstack/react-virtual` 轉接器是核心虛擬邏輯的封裝層。 + +## `useVirtualizer` + +```tsx +function useVirtualizer( + options: PartialKeys< + VirtualizerOptions, + 'observeElementRect' | 'observeElementOffset' | 'scrollToFn' + >, +): Virtualizer +``` + +此函數會返回一個標準的 `Virtualizer` 實例,該實例配置為以 HTML 元素作為 scrollElement 運作。 + +## `useWindowVirtualizer` + +```tsx +function useWindowVirtualizer( + options: PartialKeys< + VirtualizerOptions, + | 'getScrollElement' + | 'observeElementRect' + | 'observeElementOffset' + | 'scrollToFn' + >, +): Virtualizer +``` + +此函數會返回一個基於視窗的 `Virtualizer` 實例,該實例配置為以視窗作為 scrollElement 運作。 diff --git a/docs/zh-hant/framework/solid/solid-virtual.md b/docs/zh-hant/framework/solid/solid-virtual.md new file mode 100644 index 000000000..d61144417 --- /dev/null +++ b/docs/zh-hant/framework/solid/solid-virtual.md @@ -0,0 +1,35 @@ +--- +source-updated-at: '2024-01-25T21:23:10.000Z' +translation-updated-at: '2025-05-02T15:24:16.620Z' +title: Solid Virtual +--- +`@tanstack/solid-virtual` 配接器是核心虛擬邏輯的封裝層。 + +## `createVirtualizer` + +```tsx +function createVirtualizer( + options: PartialKeys< + VirtualizerOptions, + 'observeElementRect' | 'observeElementOffset' | 'scrollToFn' + >, +): Virtualizer +``` + +此函式會回傳一個標準的 `Virtualizer` 實例,該實例配置為以 HTML 元素作為 scrollElement 運作。 + +## `createWindowVirtualizer` + +```tsx +function createWindowVirtualizer( + options: PartialKeys< + VirtualizerOptions, + | 'getScrollElement' + | 'observeElementRect' + | 'observeElementOffset' + | 'scrollToFn' + >, +): Virtualizer +``` + +此函式會回傳一個基於視窗的 `Virtualizer` 實例,該實例配置為以視窗作為 scrollElement 運作。 diff --git a/docs/zh-hant/framework/svelte/svelte-virtual.md b/docs/zh-hant/framework/svelte/svelte-virtual.md new file mode 100644 index 000000000..2076e7901 --- /dev/null +++ b/docs/zh-hant/framework/svelte/svelte-virtual.md @@ -0,0 +1,35 @@ +--- +source-updated-at: '2024-01-25T21:23:10.000Z' +translation-updated-at: '2025-05-02T15:24:32.469Z' +title: Svelte Virtual +--- +`@tanstack/svelte-virtual` 配接器是核心虛擬邏輯的封裝層。 + +## `createVirtualizer` + +```tsx +function createVirtualizer( + options: PartialKeys< + VirtualizerOptions, + 'observeElementRect' | 'observeElementOffset' | 'scrollToFn' + >, +): Virtualizer +``` + +此函數會回傳一個標準的 `Virtualizer` 實例,該實例配置為以 HTML 元素作為 scrollElement 來運作。 + +## `createWindowVirtualizer` + +```tsx +function createWindowVirtualizer( + options: PartialKeys< + VirtualizerOptions, + | 'getScrollElement' + | 'observeElementRect' + | 'observeElementOffset' + | 'scrollToFn' + >, +): Virtualizer +``` + +此函數會回傳一個基於視窗的 `Virtualizer` 實例,該實例配置為以視窗作為 scrollElement 來運作。 diff --git a/docs/zh-hant/framework/vue/vue-virtual.md b/docs/zh-hant/framework/vue/vue-virtual.md new file mode 100644 index 000000000..e4655eaab --- /dev/null +++ b/docs/zh-hant/framework/vue/vue-virtual.md @@ -0,0 +1,35 @@ +--- +source-updated-at: '2024-06-01T09:52:04.000Z' +translation-updated-at: '2025-05-02T15:23:49.906Z' +title: Vue Virtual +--- +`@tanstack/vue-virtual` 配接器是對核心虛擬邏輯的封裝。 + +## `useVirtualizer` + +```tsx +function useVirtualizer( + options: PartialKeys< + VirtualizerOptions, + 'observeElementRect' | 'observeElementOffset' | 'scrollToFn' + >, +): Virtualizer +``` + +此函數返回一個標準的 `Virtualizer` 實例,該實例配置為以 HTML 元素作為 scrollElement 運作。 + +## `useWindowVirtualizer` + +```tsx +function useWindowVirtualizer( + options: PartialKeys< + VirtualizerOptions, + | 'getScrollElement' + | 'observeElementRect' + | 'observeElementOffset' + | 'scrollToFn' + >, +): Virtualizer +``` + +此函數返回一個基於視窗的 `Virtualizer` 實例,該實例配置為以視窗作為 scrollElement 運作。 diff --git a/docs/zh-hant/installation.md b/docs/zh-hant/installation.md new file mode 100644 index 000000000..589c3111e --- /dev/null +++ b/docs/zh-hant/installation.md @@ -0,0 +1,50 @@ +--- +source-updated-at: '2025-03-07T09:19:44.000Z' +translation-updated-at: '2025-05-02T15:24:01.259Z' +title: 安裝 +--- +在深入探討 API 之前,讓我們先幫您完成設定! + +使用您喜愛的 npm 套件管理工具,將 TanStack Virtual 適配器安裝為依賴項: + +## React Virtual + +```bash +npm install @tanstack/react-virtual +``` + +## Solid Virtual + +```bash +npm install @tanstack/solid-virtual +``` + +## Svelte Virtual + +```bash +npm install @tanstack/svelte-virtual +``` + +## Vue Virtual + +```bash +npm install @tanstack/vue-virtual +``` + +## Lit Virtual + +```bash +$ npm install @tanstack/lit-virtual +``` + +## Angular Virtual + +```bash +$ npm install @tanstack/angular-virtual +``` + +## Virtual Core (無框架版本) + +```bash +npm install @tanstack/virtual-core +``` diff --git a/docs/zh-hant/introduction.md b/docs/zh-hant/introduction.md new file mode 100644 index 000000000..8a41a207a --- /dev/null +++ b/docs/zh-hant/introduction.md @@ -0,0 +1,69 @@ +--- +source-updated-at: '2024-11-25T13:01:52.000Z' +translation-updated-at: '2025-05-02T15:23:35.442Z' +title: 介紹 +--- +TanStack Virtual 是一個無頭 UI (headless UI) 工具,用於在 JS/TS、React、Vue、Svelte、Solid、Lit 和 Angular 中虛擬化長列表元素。它並非一個元件,因此不會為您提供或渲染任何標記或樣式。雖然這需要您自行處理一些標記和樣式,但您將能 100% 掌控自己的樣式、設計與實作。 + +## 虛擬化器 (Virtualizer) + +TanStack Virtual 的核心是 `Virtualizer`。虛擬化器 (Virtualizer) 可以設定為垂直(預設)或水平軸向,這使得結合兩種軸向配置,可以實現垂直、水平甚至網格狀的虛擬化。 + +以下是一個快速範例,展示如何在 React 中使用 TanStack Virtual 虛擬化一個長列表: + +```tsx +import { useVirtualizer } from '@tanstack/react-virtual'; + +function App() { + // 列表的可滾動元素 + const parentRef = React.useRef(null) + + // 虛擬化器 (Virtualizer) + const rowVirtualizer = useVirtualizer({ + count: 10000, + getScrollElement: () => parentRef.current, + estimateSize: () => 35, + }) + + return ( + <> + {/* 列表的可滾動元素 */} +
+ {/* 用來容納所有項目的內部大型元素 */} +
+ {/* 僅顯示虛擬化器中可見的項目,手動定位使其出現在視野中 */} + {rowVirtualizer.getVirtualItems().map((virtualItem) => ( +
+ Row {virtualItem.index} +
+ ))} +
+
+ + ) +} +``` + +讓我們深入探討更多範例! diff --git a/translation.config.mjs b/translation.config.mjs new file mode 100644 index 000000000..1c190e4d1 --- /dev/null +++ b/translation.config.mjs @@ -0,0 +1,115 @@ +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 Form is the ultimate solution for handling forms in web applications, providing a powerful and flexible approach to form management. Designed with first-class TypeScript support, headless UI components, and a framework-agnostic design, it streamlines form handling and ensures a seamless experience across various front-end frameworks. + +## Motivation + +Most web frameworks do not offer a comprehensive solution for form handling, leaving developers to create their own custom implementations or rely on less-capable libraries. This often results in a lack of consistency, poor performance, and increased development time. TanStack Form aims to address these challenges by providing an all-in-one solution for managing forms that is both powerful and easy to use. + +With TanStack Form, developers can tackle common form-related challenges such as: + +- Reactive data binding and state management +- Complex validation and error handling +- Accessibility and responsive design +- Internationalization and localization +- Cross-platform compatibility and custom styling + +By providing a complete solution for these challenges, TanStack Form empowers developers to build robust and user-friendly forms with ease.`, + copyPath: 'reference/**,framework/*/reference/**', +}