scroll-area
Scroll area with fade effect
Scroll area with fade effect
Загрузка превью…
src/scroll-area/c-scroll-area-4.vue
<!--
ПОРТ (registry-reui/bases/radix/components/scroll-area/c-scroll-area-4.tsx).
cn(...) в оригинале — чистая конкатенация строк без условной логики,
поэтому результат инлайнен шаблонным литералом напрямую в class,
без обращения к cn(): итоговая строка классов совпадает с оригиналом
посимвольно (правило 1, docs/PORTING.md), а cn() в React-версии здесь
использован только ради читаемости многострочного списка классов.
-->
<script setup lang="ts">
// picsum.photos?random=N — НЕ сид, а обход кеша: каждый запрос отдаёт другое
// фото. В стенде это давало 15% расхождения. Статичный 1x1 пиксель, как
// в ui-avatar/block-card.
const PIXEL =
"data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAUwAOw=="
import { ScrollArea } from "@/components/ui/scroll-area"
</script>
<template>
<ScrollArea
:class="`rounded-2xl h-72 w-48 border **:data-[slot=scroll-area-thumb]:bg-foreground/15 **:data-[slot=scroll-area-thumb]:rounded-full **:data-[slot=scroll-area-viewport]:mask-t-from-[calc(100%-min(var(--fade-size),var(--scroll-area-overflow-y-start)))] **:data-[slot=scroll-area-viewport]:mask-r-from-[calc(100%-min(var(--fade-size),var(--scroll-area-overflow-x-end)))] **:data-[slot=scroll-area-viewport]:mask-b-from-[calc(100%-min(var(--fade-size),var(--scroll-area-overflow-y-end)))] **:data-[slot=scroll-area-viewport]:mask-l-from-[calc(100%-min(var(--fade-size),var(--scroll-area-overflow-x-start)))] **:data-[slot=scroll-area-viewport]:[--fade-size:1.5rem]`"
>
<div class="flex w-max flex-col gap-4 p-4">
<div
v-for="i in 10"
:key="i"
class="rounded-2xl relative h-36 w-40 shrink-0 overflow-hidden border"
>
<img
:src="PIXEL"
:alt="`Image ${i}`"
class="h-full w-full object-cover"
/>
</div>
</div>
</ScrollArea>
</template>
Установка
npx shadcn-vue@latest add https://revueui.rootapi.dev/r/c-scroll-area-4.jsonЗависимости реестра
Источник: порт из ReUI (Keenthemes, MIT)