↔ Component
Row Scrollable
Horizontally scrollable card row with snap-scrolling, custom scrollbar, and optional section title.
Interactive Demo Playground
Configure Properties
Usage Code Generator
import RowScrollable from '@contentveda/ui/react/RowScrollable';
import '@contentveda/ui/theme.css';
const items = [
{ id: '1', title: 'Linen Dress', subtitle: '$89.00', media: { type: 'image', url: '/p1.jpg' }, mapLinks: [{ url: '/p/1' }] },
{ id: '2', title: 'Oxford Shirt', subtitle: '$55.00', media: { type: 'image', url: '/p2.jpg' }, mapLinks: [{ url: '/p/2' }] },
];
export default function Example() {
return (
<RowScrollable title="Featured Products" items={items} />
);
}
<script setup>
import RowScrollable from '@contentveda/ui/vue/RowScrollable.vue';
import '@contentveda/ui/theme.css';
const items = [
{ id: '1', title: 'Linen Dress', subtitle: '$89.00', media: { type: 'image', url: '/p1.jpg' }, mapLinks: [{ url: '/p/1' }] },
{ id: '2', title: 'Oxford Shirt', subtitle: '$55.00', media: { type: 'image', url: '/p2.jpg' }, mapLinks: [{ url: '/p/2' }] },
];
</script>
<template>
<RowScrollable title="Featured Products" :items="items" />
</template>
<script lang="ts">
import RowScrollable from '@contentveda/ui/svelte/RowScrollable.svelte';
const items = [
{ id: '1', title: 'Linen Dress', subtitle: '$89', media: { type: 'image', url: '/p1.jpg' } },
];
</script>
<RowScrollable title="Featured" {items} />
import RowScrollable from '@contentveda/ui/solid/RowScrollable';
import '@contentveda/ui/theme.css';
const items = [
{ id: '1', title: 'Linen Dress', subtitle: '$89.00', media: { type: 'image', url: '/p1.jpg' }, mapLinks: [{ url: '/p/1' }] },
{ id: '2', title: 'Oxford Shirt', subtitle: '$55.00', media: { type: 'image', url: '/p2.jpg' }, mapLinks: [{ url: '/p/2' }] },
];
export default function Example() {
return (
<RowScrollable title="Featured Products" items={items} />
);
}
import { Component } from '@angular/core';
import { RowScrollableModule } from '@contentveda/ui/angular/RowScrollable';
@Component({
selector: 'app-example',
standalone: true,
imports: [RowScrollableModule],
template: `
<row-scrollable title="Featured Products" [items]="items"></row-scrollable>
`
})
export class ExampleComponent {
items = [
{ id: '1', title: 'Linen Dress', subtitle: '$89.00', media: { type: 'image', url: '/p1.jpg' }, mapLinks: [{ url: '/p/1' }] },
{ id: '2', title: 'Oxford Shirt', subtitle: '$55.00', media: { type: 'image', url: '/p2.jpg' }, mapLinks: [{ url: '/p/2' }] },
];
}
<script type="module"
src="node_modules/@contentveda/ui/dist/webcomponent/dist/RowScrollable.js"></script>
<cv-row-scrollable
title="Featured Products"
items='[{"id":"1","title":"Linen Dress"}]'
></cv-row-scrollable>
Props API Reference
| Prop | Type | Default | Description |
|---|---|---|---|
| items required | RowScrollableItem[] | — | Array of card items to render in the scrollable row |
| title | string | undefined | Optional section heading displayed above the row |
| className | string | undefined | Additional CSS class names on the root container |
| config.showArrows | boolean | undefined | Show next/previous arrows (default: true) |
| config.hideArrowsIfNoScroll | boolean | undefined | Hide navigation arrows if content doesn't overflow container width |
| config.hideScrollbar | boolean | undefined | Hide the browser scrollbar while keeping swipe/scroll functionality |
| isLoading | boolean | undefined | Applies shimmer skeleton loading animation to all items |
| lazyLoad | boolean | undefined | Defer mounting card media until the row scrolls near the viewport (default: true) |
| lazyThreshold | number | undefined | IntersectionObserver threshold, 0-1 (default: 0.1) |
| lazyRootMargin | string | undefined | IntersectionObserver rootMargin (default: '200px') |