Back to list
DevPossible

create-panel

by DevPossible

Cross-platform .NET LCD controller for HID-based LCD screens (Thermalright Trofeo Vision, etc.)

0🍴 0📅 Jan 17, 2026

SKILL.md


name: create-panel description: | Creates new display panels for LCDPossible LCD controller. Use when: creating a new panel, adding display panel, implementing panel type, new LCD screen content, new monitoring panel, new info panel. Guides through plugin vs core decision, consistent styling, and registration. allowed-tools: Read, Write, Edit, Glob, Grep, Bash

Creating Display Panels for LCDPossible

This skill guides the creation of new display panels for the LCDPossible LCD controller.

Panel Type Decision

Content TypeBase ClassLocation
System info widgetsWidgetPanelCore plugin
Variable item count (0-N)WidgetPanel with GetItemsAsyncCore plugin
External service dataWidgetPanelSeparate plugin
Custom canvas drawingCanvasPanelScreensavers plugin
Animated effectsCanvasPanelScreensavers plugin

Prefer WidgetPanel for new info panels - it uses HTML/CSS rendering with responsive web components.

WidgetPanel Structure

using LCDPossible.Sdk;

namespace LCDPossible.Plugins.Core.Panels;

public sealed class MyNewPanel : WidgetPanel
{
    public override string PanelId => "my-panel";       // URL-safe slug
    public override string DisplayName => "My Panel";   // Human-readable

    // Panel-level data (timestamp, totals, etc.)
    protected override Task<object> GetPanelDataAsync(CancellationToken ct)
    {
        return Task.FromResult<object>(new
        {
            timestamp = DateTime.Now.ToString("HH:mm:ss"),
            total_count = 42
        });
    }

    // Static widgets from panel data
    protected override IEnumerable<WidgetDefinition> DefineWidgets(object panelData)
    {
        // Cast or use dynamic
        dynamic data = panelData;

        yield return new WidgetDefinition("lcd-stat-card", 6, 2, new
        {
            title = "Total",
            value = data.total_count.ToString(),
            status = "success"
        });
    }
}

Variable Item Panels

For panels displaying 0-N items (network interfaces, VMs, sensors):

public sealed class MyItemsPanel : WidgetPanel
{
    public override string PanelId => "my-items";
    public override string DisplayName => "My Items";

    protected override Task<object> GetPanelDataAsync(CancellationToken ct)
        => Task.FromResult<object>(new { timestamp = DateTime.Now.ToString("HH:mm:ss") });

    // Return items to display
    protected override Task<IReadOnlyList<object>> GetItemsAsync(CancellationToken ct)
    {
        var items = GetMyItems(); // Your data source
        return Task.FromResult<IReadOnlyList<object>>(items.Cast<object>().ToList());
    }

    // Customize empty state message
    protected override string GetEmptyStateMessage() => "No items found";

    // Render each item as a widget
    protected override WidgetDefinition? DefineItemWidget(object item, int index, int totalItems)
    {
        var myItem = (MyItemType)item;

        // Auto-layout based on item count (1-4 items)
        var (colSpan, rowSpan) = WidgetLayouts.GetAutoLayout(index, totalItems);

        return new WidgetDefinition("lcd-info-list", colSpan, rowSpan, new
        {
            title = myItem.Name,
            items = new[]
            {
                new { label = "Status", value = myItem.Status },
                new { label = "Value", value = myItem.Value }
            }
        });
    }
}

Available Web Components

ComponentPropsUse For
lcd-stat-cardtitle, value, unit, subtitle, status, sizeSingle value display
lcd-usage-barvalue, max, label, color, orientationProgress bars
lcd-info-listtitle, subtitle, items, statusKey-value pairs
lcd-temp-gaugevalue, max, labelTemperature gauges
lcd-sparklinevalues, color, labelTime-series charts
lcd-status-dotstatus, labelStatus indicators
lcd-donutvalue, max, label, colorCircular percentage

Component Status Values

success (green), warning (yellow), critical (red), info (blue), neutral (gray)

Widget Layout

The grid is 12 columns wide. Common patterns:

ColSpanMeaning
12Full width
6Half width (2 per row)
4Third width (3 per row)
3Quarter width (4 per row)

Auto-Layout for Variable Items

Use WidgetLayouts.GetAutoLayout(index, totalItems) for responsive layouts:

ItemsLayout
1Full width (12, 4)
2Half each (6, 4)
3First half (6, 4), second + third quarter (6, 2)
42x2 grid (6, 2)

Registration Checklist

1. Add PanelTypeInfo to Plugin

In the plugin class (e.g., CorePlugin.cs):

public IReadOnlyDictionary<string, PanelTypeInfo> PanelTypes { get; } = new Dictionary<string, PanelTypeInfo>
{
    // ... existing panels ...
    ["my-panel"] = new PanelTypeInfo
    {
        TypeId = "my-panel",
        DisplayName = "My Panel",
        Description = "Description for panel list",
        Category = "System",  // System, Network, Thermal, etc.
        IsLive = true
    }
};

2. Add CreatePanel Case

In the plugin's CreatePanel method:

IDisplayPanel? panel = panelTypeId.ToLowerInvariant() switch
{
    // ... existing cases ...
    "my-panel" => new MyNewPanel(),
    _ => null
};

3. Update plugin.json

Add detailed metadata for CLI help:

{
  "typeId": "my-panel",
  "displayName": "My Panel",
  "description": "Brief description",
  "category": "System",
  "isLive": true,
  "dependencies": ["PuppeteerSharp"],
  "helpText": "Detailed description for help command",
  "examples": [
    {
      "command": "lcdpossible show my-panel",
      "description": "Display my panel"
    }
  ]
}

Testing

# Render to file
./start-app.ps1 test my-panel --debug

# Check output
# [DEBUG] Written: C:\Users\...\my-panel.jpg (XXXX bytes)

Template Syntax

WidgetPanel uses Scriban templates internally. If you need custom templates, see the scriban-templates skill for escaping rules.

Key rule: Web components are generated automatically - you don't write Scriban templates for standard WidgetPanels.

Files to Create/Modify

FileAction
Panels/MyNewPanel.csCreate - panel implementation
CorePlugin.cs or plugin classModify - PanelTypes + CreatePanel
plugin.jsonModify - add panel metadata

Visual Appeal Standards

IMPORTANT: All panels must comply with the visual appeal rules in .claude/rules/panel-visual-appeal.md.

Key requirements:

  • Container Filling: Widgets should fill their space (no tiny text in large boxes)
  • Typography Hierarchy: Values larger than labels (text-3xl+ for values, text-lg for labels)
  • Centering: Content centered unless there's a reason not to
  • Color Contrast: High contrast for LCD viewing distance (3-6 feet)
  • Theme Compliance: Use DaisyUI classes, not hardcoded colors
  • Empty States: Handle missing data gracefully

Widget Sizing Guide

Widget ContentRecommended ColSpanValue Size
Single large value3-4text-4xl to text-5xl
Value with label4-6text-2xl to text-3xl
Info list (2-4 items)4-5text-xl values
Donut/gauge3-4text-3xl to text-4xl
Sparkline6-8N/A

After creating a panel, validate with: /ensure-panelvisualappeal <panel-id>

Common Mistakes

  1. Forgetting registration - Panel exists but isn't in PanelTypes dictionary
  2. Wrong PanelId format - Use lowercase with hyphens: my-panel not MyPanel
  3. Missing CreatePanel case - Panel registered but not instantiated
  4. Not casting panelData - Use dynamic data = panelData; or explicit cast
  5. Text too small - Use size = "large" for stat cards in 4+ column spans
  6. Hardcoded colors - Use text-primary, text-success, not #00d4ff

Score

Total Score

60/100

Based on repository quality metrics

SKILL.md

SKILL.mdファイルが含まれている

+20
LICENSE

ライセンスが設定されている

+10
説明文

100文字以上の説明がある

0/10
人気

GitHub Stars 100以上

0/15
最近の活動

3ヶ月以内に更新がある

0/10
フォーク

10回以上フォークされている

0/5
Issue管理

オープンIssueが50未満

+5
言語

プログラミング言語が設定されている

+5
タグ

1つ以上のタグが設定されている

0/5

Reviews

💬

Reviews coming soon