Reusable views and controls

Extract repeated UI into focused SkeleKit compositions and UIKit-backed wrappers.

The usual SkeleKit component is a small class that composes existing views. Pass required state through its constructor and keep the internal tree private.

Read views and view trees first for ownership, parentage, and binding-context inheritance.

public sealed class ProfileCard : Border
{
    readonly Label name = new()
    {
        TextStyle = TextStyle.Headline,
        MaxLines = 1
    };

    public ProfileCard(Profile profile, ICommand openCommand)
    {
        Padding = 16;
        CornerRadius = 18;
        Background = Colors.SecondaryBackground;
        TapCommand = openCommand;
        TapCommandParameter = profile;

        name.Text = profile.Name;

        Child = new StackPanel
        {
            Spacing = 4,
            Children =
            {
                name,
                new Label
                {
                    Text = profile.Email,
                    TextColor = Colors.SecondaryLabel,
                    MaxLines = 1
                }
            }
        };
    }

    public void Update(Profile profile) => name.Text = profile.Name;
}

Constructor parameters make the component's requirements visible and work naturally with collection item factories. Expose a small method or property when the parent genuinely needs to update local presentation state. Keep application state in the view model rather than creating a second state model inside the component.

Pages and nested composition

Use ContentView<TViewModel> for navigable pages. Its constructor attaches the typed view model as BindingContext and enables lambda-based Bind helpers.

For a reusable region inside a page, use Border, Overlay, StackPanel, Grid, or a custom Panel subclass. A ContentView carries page chrome and page lifecycle semantics.

Native controls

SkeleKit's built-in Control subclasses own their native creation and measurement. Application code normally extends controls through composition. If a missing capability already exists as a self-contained UIView, wrap it in NativeView. If it needs SkeleKit children and custom placement, create a Panel and implement layout.

Keep the platform-specific object behind the component boundary. This makes the rest of the page remain declarative and keeps UIKit lifetime and event handling in one place.

Use authoring layout panels when the component needs its own placement algorithm, or native interop when it needs a UIKit host or controller.