Editor/Contracts/ControlContract.cs
using System;
using System.Collections.Generic;
using System.Linq;
using Grains.RazorDesigner.Document;
namespace Grains.RazorDesigner.Contracts;
public readonly record struct ControlContract(
ControlType Kind,
Type PayloadType,
string LibraryTag,
bool IsContainer,
string InspectorIcon,
IReadOnlyList<SlotDefinition> Slots,
IReadOnlyList<ContractField> PayloadFields,
PreviewStrategy PreviewStrategy )
{
// Distinct, non-empty [Group] names across all PayloadFields, in first-seen order.
public IEnumerable<string> Groups()
{
var seen = new HashSet<string>( StringComparer.Ordinal );
foreach ( var f in PayloadFields )
{
if ( !string.IsNullOrEmpty( f.Group ) && seen.Add( f.Group ) )
yield return f.Group;
}
}
public IReadOnlyList<string> PropertyNamesIn( string group ) =>
PayloadFields
.Where( f => string.Equals( f.Group, group, StringComparison.Ordinal ) && !f.IsOverrideGate )
.Select( f => f.Name )
.ToList();
public string GatedByGroupOf( string propertyName )
{
var field = PayloadFields.FirstOrDefault( f =>
string.Equals( f.Name, propertyName, StringComparison.Ordinal ) );
return field.Name is null ? "" : field.GatedByGroup;
}
}
public readonly record struct ContractField(
string Name,
Type ClrType,
string Group,
bool IsOverrideGate,
string GatedByGroup );
public readonly record struct SlotDefinition(
string Name,
string CssClass,
string Description );
public enum PreviewStrategy
{
// Rendered via the real Sandbox.UI engine type (most controls).
Native,
LabelSubstitute,
// Rendered as an icon glyph (IconPanel — the glyph string is the content).
IconGlyph,
}