# Grid Picker

# GridPicker

# Description

The GridPicker component creates an interactive grid of buttons, where each cell can have multiple states. It is used for building grid-based state selectors and pickers, such as scheduling interfaces or game boards. The component is part of the Tesserae UI Components group and leverages a fluent interface to configure button appearance and behavior based on the state.

# Usage

Create a GridPicker instance by providing arrays of column and row names, the number of states each cell can have, an initial state for every cell, and a function to format each button based on its state. Optionally, you can provide custom column sizes and row heights.

Below is a simple usage example:

using System;
using System.Linq;
using static H5.Core.dom;
using Tesserae;
using static Tesserae.UI;

public class SampleGridPickerUsage : IComponent
{
    public HTMLElement Render()
    {
        // Define column and row headers.
        var columns = new[] { "Mon", "Tue", "Wed", "Thu", "Fri" };
        var rows = new[] { "Morning", "Afternoon", "Evening" };

        // Create initial states (all zeros) for each cell in the grid.
        var initialStates = Enumerable.Range(0, rows.Length)
                                      .Select(_ => new int[columns.Length])
                                      .ToArray();

        // Define how each state should be formatted. In this example, we show an emoji.
        Action<Button, int, int> formatState = (btn, state, previousState) =>
        {
            string text = state switch
            {
                0 => "Off",
                1 => "On",
                _ => "?"
            };
            btn.SetText(text);
        };

        // Instantiate the GridPicker.
        var gridPicker = GridPicker(
            columnNames: columns,
            rowNames: rows,
            states: 2,
            initialStates: initialStates,
            formatState: formatState
        );

        return gridPicker.Render();
    }
}

# Methods

# GetState()

  • Description: Retrieves the current state of all grid cells.
  • Return Type: int[][] – A two-dimensional array where each element represents the state of a corresponding grid cell.
  • Usage Example:

    int[][] currentStates = gridPicker.GetState();

# SetState(int[][] state)

  • Parameters:
    • state: A two-dimensional integer array representing the new state for all cells.
  • Description: Updates the grid with new states and refreshes the UI accordingly.
  • Return Type: GridPicker – Returns the current instance for chaining.
  • Usage Example:

    gridPicker.SetState(newStates);

# OnChange(ComponentEventHandler<GridPicker, Event> onChange)

  • Parameters:
    • onChange: A callback that is invoked when any cell state changes.
  • Description: Registers an event handler for change events occurring in the grid.
  • Return Type: GridPicker – Returns the current instance for chaining.
  • Usage Example:

    gridPicker.OnChange((picker, ev) => {
        // Handle state change here.
        Console.WriteLine("Grid state changed.");
    });

# Properties

# IsDragging

  • Type: bool (read-only)
  • Description: Indicates whether a drag operation is currently in progress on the grid. When true, a batch update is in progress for a group of cells.

# Samples

# Basic GridPicker Example

The following sample demonstrates how to instantiate a simple GridPicker with two states. Each cell displays different text based on its current state.

using System;
using System.Linq;
using static H5.Core.dom;
using Tesserae;
using static Tesserae.UI;

public class BasicGridPickerExample : IComponent
{
    public HTMLElement Render()
    {
        var columns = new[] { "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun" };
        var rows = new[] { "Morning", "Afternoon", "Evening" };

        var initialStates = Enumerable.Range(0, rows.Length)
                                      .Select(_ => new int[columns.Length])
                                      .ToArray();

        Action<Button, int, int> formatState = (btn, state, previousState) =>
        {
            string text = state switch
            {
                0 => "☠",
                1 => "🐢",
                _ => "??"
            };

            // Display transition if previous state is provided
            if (previousState >= 0 && previousState != state)
            {
                string prevText = previousState switch
                {
                    0 => "☠",
                    1 => "🐢",
                    _ => "??"
                };
                text = $"{prevText} -> {text}";
            }
            btn.SetText(text);
        };

        var gridPicker = GridPicker(
            columnNames: columns,
            rowNames: rows,
            states: 2,
            initialStates: initialStates,
            formatState: formatState
        );

        return gridPicker.Render();
    }
}

# Advanced GridPicker for Hourly Schedule

This sample shows how to create an hourly schedule picker by dynamically generating column headers for each hour of the day.

using System;
using System.Linq;
using static H5.Core.dom;
using Tesserae;
using static Tesserae.UI;

public class HourlyScheduleGridPicker : IComponent
{
    public HTMLElement Render()
    {
        var days = new[] { "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday" };
        var hours = Enumerable.Range(0, 24).Select(n => $"{n:00}").ToArray();

        var initialStates = days.Select(_ => new int[hours.Length]).ToArray();

        Action<Button, int, int> formatState = (btn, state, previousState) =>
        {
            string color = state switch
            {
                0 => "#c7c5c5",
                1 => "#a3cfa5",
                2 => "#76cc79",
                3 => "#1fcc24",
                _ => "#ffffff"
            };

            btn.Background(color);
        };

        // Optional: Providing custom column sizes and row height.
        var gridPicker = GridPicker(
            rowNames: days,
            columnNames: hours,
            states: 4,
            initialStates: initialStates,
            formatState: formatState,
            columns: new[] { 128.px(), 24.px() },
            rowHeight: 24.px()
        );

        return gridPicker.Render();
    }
}

# See also

  • Button – Often used in combination with GridPicker for interactive elements.
  • TextBlock – Useful for creating header or descriptive text in grid layouts.