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>