Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 35 additions & 1 deletion content/guide/styling.md
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,8 @@ This list of properties can be set in CSS or through the style property of each
| `border-radius` | `borderRadius` | Sets a border radius to the matched view’s. |
| `box-shadow` | `boxShadow` | Sets a box shadow to the matched view's. |
| `clip-path` | `clipPath` | Sets the clip-path. Supported shapes are circle, ellipse, rect and polygon. You can define your own shape using [clippy](http://bennettfeely.com/clippy/) |
| `color` | `color` | Sets a solid-color value to the matched view’s foreground. |
| `color` | `color` | Sets a solid-color value to the matched view’s foreground.
| `direction` | `direction` | Sets the direction of text, table and grid columns, and horizontal overflow. Use rtl for languages written from right to left (like Hebrew or Arabic), and ltr for those written from left to right (like English and most other languages). |
| `font` | `font` | Sets the font properties (this includes `font-family`, `font-size`, `font-style` and `font-weight`) of the matched view. |
| `font-family` | `fontFamily` | Sets the font family of the matched view. |
| `font-size` | `fontSize` | Sets the font size of the matched view (only supports device-independent units). |
Expand Down Expand Up @@ -259,6 +260,39 @@ This list of properties can be set in CSS or through the style property of each
| `width` | `width` | Sets the view width. |
| `z-index` | `zIndex` | Sets the z-index. (On Android API Level 21 and above.) |

## Layout direction (LTR / RTL)

NativeScript now supports an **inherited CSS `direction` property** to force the layout direction of views to either left-to-right (`ltr`) or right-to-left (`rtl`).

```css
/* Apply RTL to the entire app */
.ns-root {
direction: rtl;
}
```

What this does:

- tells NativeScript to use the **platform’s native direction APIs** so you get the OS-level behavior for RTL,
- makes navigation transitions direction-aware (slide, flip, etc.),
- makes default label/text alignment respect the direction,
- enables direction-aware layout for FlexboxLayout on iOS,
- aligns horizontal scroll views to the end in RTL,
- and allows using `start` / `end` values for `horizontalAlignment` to align relative to the current direction.

Android note:

```xml
<!-- App_Resources/Android/src/main/AndroidManifest.xml -->
<application
android:name="com.tns.NativeScriptApplication"
android:supportsRtl="true"
...>
</application>
```

You **must** enable `android:supportsRtl="true"` in the manifest for Android to actually honor RTL. On iOS this is always available.

### Accessing NativeScript View properties with CSS

You can also set NativeScript component properties value that are not part of the CSS specification. For example:
Expand Down
156 changes: 151 additions & 5 deletions content/ui/list-view.md
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
---
title: ListView
description: UI component for rendering large lists using view recycling.
description: UI component for rendering large lists using view recycling, with optional sticky headers, sectioned data, and an integrated search bar.
contributors:
- rigor789
- Ombuweb
- NathanWalker
---

`<ListView>` is a UI component that renders items in a vertically scrolling list, the template for the items can be defined via `itemTemplate` (or multiple templates via `itemTemplates` - more on that below). The ListView only renders the visible items, as the user scrolls, new items render by reusing a no-longer-visible item's view&mdash;this is usually referred to as view-recycling.
`<ListView>` is a UI component that renders items in a vertically scrolling list. The template for the items can be defined via `itemTemplate` (or multiple templates via `itemTemplates` more on that below). The ListView only renders the visible items; as the user scrolls, new items render by reusing a no-longer-visible item's viewthis is usually referred to as view-recycling.

::: tip
Newer versions of `ListView` (v9+) can also render **sectioned data** (for example, A–Z lists) with **sticky headers** and an **optional search bar** that can auto-hide on iOS.

For additional features and improved performance in certain scenarios, consider using an alternative implementation like the
::: tip
You can also explore
[CollectionView](https://github.com/nativescript-community/ui-collectionview) from the community.

:::

<DeviceFrame type="ios">
Expand Down Expand Up @@ -78,6 +79,72 @@ Individual items can be rendered using a different template. For example, let's
</Tab>
</Tabs>

### Sectioned ListView with sticky headers and search

Starting with v9, ListView can render sectioned data with sticky headers and an optional search bar. This is useful for contact lists, country lists, or any data grouped by a key.

A supported data shape looks like this:

```ts
const countries: { title: string; items: { name: string; code?: string; flag?: string }[] }[] = [
{
title: 'A',
items: [
{ name: 'Albania', code: 'AL' },
],
},
{
title: 'B',
items: [
{ name: 'Bahamas', code: 'BS' },
],
},
]
```

You can then bind this data to the ListView and enable the new props:

```xml
<ListView
items="{{ countries }}"
sectioned="true"
stickyHeader="true"
stickyHeaderHeight="45"
stickyHeaderTopPadding="false"
showSearch="true"
searchAutoHide="true"
itemTemplateSelector="{{ itemTemplateSelector }}"
stickyHeaderTemplate="
<GridLayout>
<Label text='{{ title }}'
fontSize='18'
fontWeight='bold'
color='#009bff'
padding='8 0 8 12'
borderBottomWidth='1'
borderBottomColor='#ccc'
borderTopWidth='1'
borderTopColor='#ccc'
backgroundColor='#fff' />
</GridLayout>
" />
```

In code you can listen for search changes:

```ts
listView.on('searchChange', (args: SearchEventData) => {
console.log('search text:', args.text)
// apply filtering to your backing data if desired
})
```

Notes:

- `searchAutoHide` is currently iOS-only (it will auto-hide the search on scroll).
- `stickyHeaderTemplate` accepts the same binding context as the section (`title`, etc.).
- Make sure each section’s `items` array is present; empty / null sections may not render as expected.

## Props

### items
Expand Down Expand Up @@ -128,6 +195,71 @@ Gets or sets the available itemTemplates.

See [KeyedTemplate](/api/interface/KeyedTemplate).

### sectioned

```ts
sectioned: boolean
```

Enables sectioned data rendering on the `ListView`. When `true`, the ListView expects the `items` source to be an **array of sections** where each section has a `title` (or similar field) and an `items` array:

```ts
{
title: string;
items: any[];
}
```

This allows the ListView to render grouped lists with headers.

### stickyHeader

```ts
stickyHeader: boolean
```

Enables sticky (pinned) headers while scrolling sectioned data. When enabled, the current section header stays at the top of the list until the next section header pushes it away.

### stickyHeaderTemplate

```ts
stickyHeaderTemplate: string | KeyedTemplate
```

Gets or sets the template used to render a section header when sticky headers are enabled. This accepts bindings from the current section (for example: `{{ title }}`).

### stickyHeaderHeight

```ts
stickyHeaderHeight: number
```

Explicit height for the sticky header. Providing this can improve measurement and scrolling performance, especially on iOS where headers update as you scroll.

### stickyHeaderTopPadding

```ts
stickyHeaderTopPadding: boolean | number
```

Controls the padding applied to the sticky header at the top. Set to `false` to disable the extra top padding; set to a number to supply an explicit padding value.

### showSearch

```ts
showSearch: boolean
```

Shows a built-in search bar above the ListView. This is useful when you want a declarative, per-list search input without adding a separate `SearchBar` component.

### searchAutoHide

```ts
searchAutoHide: boolean
```

(iOS only) When `true`, the built-in search bar will auto-hide when the user scrolls. This mirrors common iOS list behaviors.

### separatorColor

```ts
Expand All @@ -150,6 +282,8 @@ rowHeight: number

Gets or sets the row height of the ListView. Useful when your items have a fixed height, as the required calculations are greatly simplified and the rendering can be faster.

> Android: with the latest ListView improvements, row items will now react properly to spacing (padding and margin), so setting `rowHeight` alongside your layout spacing should behave more predictably across platforms.

### iosEstimatedRowHeight

Gets or sets the estimated height of rows in the ListView. Default value: `44px`
Expand Down Expand Up @@ -235,6 +369,18 @@ on('loadMoreItems', (args: EventData) => {

Emitted when the user reaches the end of the ListView. Useful for loading additional items (ie. infinite scroll).

### searchChange

```ts
on('searchChange', (args: SearchEventData) => {
console.log('Search text changed:', args.text)
})
```

Emitted when the built-in search bar text changes. You can use this to filter the underlying list data, or to drive remote searches.

See `SearchEventData` in the API reference for the shape of the event.

## Native component

- Android: [`android.widget.ListView`](https://developer.android.com/reference/android/widget/ListView.html)
Expand Down
1 change: 1 addition & 0 deletions content/ui/sidebar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ export default [
{ text: 'SearchBar', link: '/ui/search-bar' },
{ text: 'SegmentedBar', link: '/ui/segmented-bar' },
{ text: 'Slider', link: '/ui/slider' },
{ text: 'SplitView', link: '/ui/split-view' },
{ text: 'Switch', link: '/ui/switch' },
{ text: 'TabView', link: '/ui/tab-view' },
{ text: 'TextField', link: '/ui/text-field' },
Expand Down
Loading
Loading