Data Components
JavaScript components for filtering/searching and rating interactions.
Filter Manager
Filters and searches items in lists, tables, or grids with debouncing.
Apple
Red fruit
Banana
Yellow fruit
Carrot
Orange vegetable
Tomato
Red vegetable
HTML
<!-- Search input with filter -->
<div style="margin-bottom: 20px">
<input
type="text"
data-ss="filter"
data-ss-filter-items=".filter-item"
data-ss-filter-debounce="300"
data-ss-filter-min-chars="1"
placeholder="Search items..."
style="
width: 100%;
padding: 12px 16px;
border: 1px solid var(--color_line_secondary);
border-radius: 8px;
font-size: 16px;
"
/>
</div>
<!-- Filterable grid -->
<div
style="
display: grid;
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
gap: 16px;
"
>
<div
class="ss-c-filter-item"
data-filter-text="apple fruit red"
style="
padding: 20px;
background: var(--color_fill_secondary);
border-radius: 12px;
"
>
<strong>Apple</strong>
<p style="margin: 8px 0 0; font-size: 14px; opacity: 0.7">
Red fruit
</p>
</div>
<div
class="ss-c-filter-item"
data-filter-text="banana fruit yellow"
style="
padding: 20px;
background: var(--color_fill_secondary);
border-radius: 12px;
"
>
<strong>Banana</strong>
<p style="margin: 8px 0 0; font-size: 14px; opacity: 0.7">
Yellow fruit
</p>
</div>
<div
class="ss-c-filter-item"
data-filter-text="carrot vegetable orange"
style="
padding: 20px;
background: var(--color_fill_secondary);
border-radius: 12px;
"
>
<strong>Carrot</strong>
<p style="margin: 8px 0 0; font-size: 14px; opacity: 0.7">
Orange vegetable
</p>
</div>
<div
class="ss-c-filter-item"
data-filter-text="tomato vegetable red"
style="
padding: 20px;
background: var(--color_fill_secondary);
border-radius: 12px;
"
>
<strong>Tomato</strong>
<p style="margin: 8px 0 0; font-size: 14px; opacity: 0.7">
Red vegetable
</p>
</div>
</div>
Filter with Categories
Combined text search with category filtering.
Laptop
Electronics
T-Shirt
Clothing
Novel
Books
Headphones
Electronics
HTML
<div
style="
display: flex;
gap: 16px;
margin-bottom: 20px;
flex-wrap: wrap;
"
>
<!-- Search input -->
<input
type="text"
data-ss="filter"
data-ss-filter-items=".product-card"
placeholder="Search products..."
style="
flex: 1;
min-width: 200px;
padding: 12px 16px;
border: 1px solid var(--color_line_secondary);
border-radius: 8px;
"
/>
<!-- Category buttons -->
<div style="display: flex; gap: 8px">
<button
class="ss-c-filter-button active"
data-category="all"
style="
padding: 10px 16px;
border: 1px solid var(--color_line_secondary);
border-radius: 6px;
background: var(--color_fill_primary);
color: white;
cursor: pointer;
"
>
All
</button>
<button
class="ss-c-filter-button"
data-category="electronics"
style="
padding: 10px 16px;
border: 1px solid var(--color_line_secondary);
border-radius: 6px;
background: white;
cursor: pointer;
"
>
Electronics
</button>
<button
class="ss-c-filter-button"
data-category="clothing"
style="
padding: 10px 16px;
border: 1px solid var(--color_line_secondary);
border-radius: 6px;
background: white;
cursor: pointer;
"
>
Clothing
</button>
<button
class="ss-c-filter-button"
data-category="books"
style="
padding: 10px 16px;
border: 1px solid var(--color_line_secondary);
border-radius: 6px;
background: white;
cursor: pointer;
"
>
Books
</button>
</div>
</div>
<!-- Product grid -->
<div
style="
display: grid;
grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
gap: 16px;
"
>
<div
class="ss-c-product-card"
data-category="electronics"
data-filter-text="laptop computer technology"
style="
padding: 16px;
background: var(--color_fill_secondary);
border-radius: 12px;
"
>
<div
style="
height: 100px;
background: linear-gradient(135deg, #667eea, #764ba2);
border-radius: 8px;
margin-bottom: 12px;
"
></div>
<strong>Laptop</strong>
<span
style="
display: block;
font-size: 12px;
color: var(--color_fill_primary);
margin-top: 4px;
"
>
Electronics
</span>
</div>
<div
class="ss-c-product-card"
data-category="clothing"
data-filter-text="t-shirt fashion apparel"
style="
padding: 16px;
background: var(--color_fill_secondary);
border-radius: 12px;
"
>
<div
style="
height: 100px;
background: linear-gradient(135deg, #f093fb, #f5576c);
border-radius: 8px;
margin-bottom: 12px;
"
></div>
<strong>T-Shirt</strong>
<span
style="
display: block;
font-size: 12px;
color: var(--color_fill_primary);
margin-top: 4px;
"
>
Clothing
</span>
</div>
<div
class="ss-c-product-card"
data-category="books"
data-filter-text="novel fiction reading"
style="
padding: 16px;
background: var(--color_fill_secondary);
border-radius: 12px;
"
>
<div
style="
height: 100px;
background: linear-gradient(135deg, #4facfe, #00f2fe);
border-radius: 8px;
margin-bottom: 12px;
"
></div>
<strong>Novel</strong>
<span
style="
display: block;
font-size: 12px;
color: var(--color_fill_primary);
margin-top: 4px;
"
>
Books
</span>
</div>
<div
class="ss-c-product-card"
data-category="electronics"
data-filter-text="headphones audio music"
style="
padding: 16px;
background: var(--color_fill_secondary);
border-radius: 12px;
"
>
<div
style="
height: 100px;
background: linear-gradient(135deg, #43e97b, #38f9d7);
border-radius: 8px;
margin-bottom: 12px;
"
></div>
<strong>Headphones</strong>
<span
style="
display: block;
font-size: 12px;
color: var(--color_fill_primary);
margin-top: 4px;
"
>
Electronics
</span>
</div>
</div>
Rating Manager
Star rating component with keyboard accessibility.
★
★
★
★
★
★
★
★
★
★
★★★★
★
4.5
(2,345 reviews)
HTML
<!-- Basic star rating -->
<div
data-ss="rating"
data-ss-rating-max="5"
data-ss-rating-value="3"
role="slider"
aria-label="Rating"
aria-valuemin="0"
aria-valuemax="5"
aria-valuenow="3"
tabindex="0"
style="
display: inline-flex;
gap: 4px;
cursor: pointer;
font-size: 24px;
"
>
<span class="ss-c-star active" data-value="1" style="color: #fbbf24">
★
</span>
<span class="ss-c-star active" data-value="2" style="color: #fbbf24">
★
</span>
<span class="ss-c-star active" data-value="3" style="color: #fbbf24">
★
</span>
<span
class="ss-c-star"
data-value="4"
style="color: var(--color_line_secondary)"
>
★
</span>
<span
class="ss-c-star"
data-value="5"
style="color: var(--color_line_secondary)"
>
★
</span>
</div>
<!-- Rating with half stars -->
<div
data-ss="rating"
data-ss-rating-max="5"
data-ss-rating-value="3.5"
data-ss-rating-half="true"
style="
display: inline-flex;
gap: 4px;
cursor: pointer;
font-size: 28px;
margin-top: 16px;
"
>
<span class="ss-c-star active" data-value="1" style="color: #fbbf24">
★
</span>
<span class="ss-c-star active" data-value="2" style="color: #fbbf24">
★
</span>
<span class="ss-c-star active" data-value="3" style="color: #fbbf24">
★
</span>
<span
class="ss-c-star ss-c-half"
data-value="3.5"
style="
background: linear-gradient(
90deg,
#fbbf24 50%,
var(--color_line_secondary) 50%
);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
"
>
★
</span>
<span
class="ss-c-star"
data-value="5"
style="color: var(--color_line_secondary)"
>
★
</span>
</div>
<!-- Rating display with count -->
<div
style="
display: flex;
align-items: center;
gap: 12px;
margin-top: 24px;
"
>
<div
data-ss="rating"
data-ss-rating-value="4.5"
data-ss-rating-readonly="true"
style="display: inline-flex; gap: 2px; font-size: 18px"
>
<span style="color: #fbbf24">★★★★</span>
<span style="color: var(--color_line_secondary)">★</span>
</div>
<span style="font-weight: 600">4.5</span>
<span style="opacity: 0.6">(2,345 reviews)</span>
</div>
Rating Styles
Various rating display styles.
♥
♥
♥
♥
♥
:(
:/
:|
:)
<3
HTML
<div style="display: flex; flex-direction: column; gap: 24px">
<!-- Hearts -->
<div>
<label
style="
display: block;
margin-bottom: 8px;
font-size: 14px;
opacity: 0.7;
"
>
Favorite
</label>
<div
data-ss="rating"
data-ss-rating-max="5"
data-ss-rating-value="4"
style="
display: inline-flex;
gap: 6px;
cursor: pointer;
font-size: 24px;
"
>
<span data-value="1" style="color: #ef4444">♥</span>
<span data-value="2" style="color: #ef4444">♥</span>
<span data-value="3" style="color: #ef4444">♥</span>
<span data-value="4" style="color: #ef4444">♥</span>
<span
data-value="5"
style="color: var(--color_line_secondary)"
>
♥
</span>
</div>
</div>
<!-- Emojis -->
<div>
<label
style="
display: block;
margin-bottom: 8px;
font-size: 14px;
opacity: 0.7;
"
>
How was your experience?
</label>
<div
data-ss="rating"
data-ss-rating-max="5"
data-ss-rating-value="0"
style="
display: inline-flex;
gap: 12px;
cursor: pointer;
font-size: 32px;
"
>
<span
data-value="1"
style="
filter: grayscale(100%);
transition: filter 0.2s;
"
>
:(
</span>
<span
data-value="2"
style="
filter: grayscale(100%);
transition: filter 0.2s;
"
>
:/
</span>
<span
data-value="3"
style="
filter: grayscale(100%);
transition: filter 0.2s;
"
>
:|
</span>
<span
data-value="4"
style="
filter: grayscale(100%);
transition: filter 0.2s;
"
>
:)
</span>
<span
data-value="5"
style="
filter: grayscale(100%);
transition: filter 0.2s;
"
>
<3
</span>
</div>
</div>
<!-- Thumbs -->
<div>
<label
style="
display: block;
margin-bottom: 8px;
font-size: 14px;
opacity: 0.7;
"
>
Was this helpful?
</label>
<div style="display: flex; gap: 16px">
<button
data-ss="rating"
data-value="1"
style="
display: flex;
align-items: center;
gap: 8px;
padding: 10px 20px;
border: 1px solid var(--color_line_secondary);
border-radius: 8px;
background: white;
cursor: pointer;
"
>
<span style="font-size: 20px">✓</span>
<span>Yes</span>
<span style="font-size: 14px; opacity: 0.6">(42)</span>
</button>
<button
data-ss="rating"
data-value="0"
style="
display: flex;
align-items: center;
gap: 8px;
padding: 10px 20px;
border: 1px solid var(--color_line_secondary);
border-radius: 8px;
background: white;
cursor: pointer;
"
>
<span style="font-size: 20px">✗</span>
<span>No</span>
<span style="font-size: 14px; opacity: 0.6">(8)</span>
</button>
</div>
</div>
</div>
JavaScript API
Programmatic control of data components.
JavaScript
<script>
// FilterManager
import { FilterManager } from "stylescape";
const filter = new FilterManager(inputElement, {
items: ".filterable-item",
debounce: 300,
minChars: 2,
filterAttribute: "data-filter-text",
noResultsText: "No items found",
onFilter: (matches, query) => {
console.log(
`Found ${matches.length} items for "${query}"`,
);
},
});
filter.setQuery("search term"); // Set search programmatically
filter.clear(); // Clear filter
filter.refresh(); // Re-scan items
// RatingManager
import { RatingManager } from "stylescape";
const rating = new RatingManager(element, {
max: 5,
value: 0,
allowHalf: true,
readonly: false,
onChange: (value) => {
console.log("Rating changed:", value);
// Submit to API
fetch("/api/rating", {
method: "POST",
body: JSON.stringify({ rating: value }),
});
},
});
rating.getValue(); // Get current rating
rating.setValue(4.5); // Set rating
rating.setReadonly(true); // Make readonly
</script>