StoreFeatures
A grid of the store's selling points, each an icon, a title and a line of text, such as fast shipping or secure payment.
import { StoreFeatures } from '@salla.sa/twilight-theme-engine/components/home';In plain words
The row of small promises many stores show: an icon, "Fast shipping", and a sentence under it. Pass the list in data.features; each feature has an icon class name, a title and a description.
It fetches nothing and has no state: what you pass is what it draws, two columns on phones and three from medium screens.
Signature
const StoreFeatures: React.MemoExoticComponent<(props: {
data: {
features: Feature[];
[key: string]: unknown;
};
}) => JSX.Element | null>
interface Feature { // @salla.sa/twilight-theme-engine/types
icon: string; // a class name, e.g. 'sicon-shipping-fast'
title: string;
description?: string;
}Try it live
Loading the home page blocks…
import { StoreFeatures } from '@salla.sa/twilight-theme-engine/components/home';
import type { HomeComponentsProps } from '@salla.sa/twilight-theme-engine/components/home';
import type { Feature } from '@salla.sa/twilight-theme-engine/types';
// Registered under "store-features". The block already carries `features`,
// so the data passes straight through.
export function ThemeStoreFeatures({ data }: HomeComponentsProps) {
const features = (data as { features?: Feature[] }).features ?? [];
return <StoreFeatures data={{ features }} />;
}
Example
import { StoreFeatures } from '@salla.sa/twilight-theme-engine/components/home';
const FEATURES = [
{ icon: 'sicon-shipping-fast', title: 'Fast shipping', description: 'Free over 350 SAR' },
{ icon: 'sicon-secure-credit-card-2', title: 'Secure payment', description: 'Mada, Visa, Apple Pay' },
];
export function Promises() {
return <StoreFeatures data={{ features: FEATURES }} />;
}
How it behaves
Each feature renders
.s-block--features__item>.feature-iconwith<i className={icon}>, an<h2>title and a<p>description. The icon must exist in the theme's icon font (sicon-*in Raed).
Gotchas
data.featuresis read asfeatures.lengthwith no guard, so a block that does not carry afeaturesarray throws — a red card in development, nothing in production. An empty array is different: the component returnsnull, drawing nothing and reporting nothing, which is what a mis-mapped block looks like on a home page.The
Featuretype's comment saysStoreFeatures.tsxmaps the API fieldtexttodescription. It does not map anything; the component rendersdescriptionas it is given.