Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 28 additions & 5 deletions Source/DotNET/Model/Profiles/UiProfile.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,36 @@
namespace Cratis.Scene.Model.Profiles;

/// <summary>
/// A named target: a platform, a default size class, and an ordered list of component packages. Declaration
/// order in <see cref="Packages"/> is override priority — a later package shadows an earlier one when both
/// resolve the same bare component name. <c>core</c> is always the final fallback, so a minimum vocabulary
/// resolves regardless of which packages a profile lists.
/// A named target: a platform, a default size class, an ordered list of component packages, and the
/// application shell and visual theme it selects. Declaration order in <see cref="Packages"/> is override
/// priority - a later package shadows an earlier one when both resolve the same bare component name.
/// <c>core</c> is always the final fallback, so a minimum vocabulary resolves regardless of which packages
/// a profile lists.
/// </summary>
/// <param name="Name">The profile's name.</param>
/// <param name="TargetPlatform">The platform this profile targets (e.g. <c>web</c>, <c>ios</c>, <c>android</c>, <c>desktop</c>).</param>
/// <param name="Packages">The component packages this profile draws from, in override-priority order.</param>
/// <param name="DefaultSizeClass">The size class assumed when the renderer cannot otherwise determine one.</param>
public record UiProfile(string Name, string TargetPlatform, IReadOnlyList<string> Packages, SizeClass? DefaultSizeClass = null);
/// <param name="Layout">
/// The name of the <see cref="Layouts.Layout"/> this profile renders inside - the application's base
/// navigational shell, normally provided by a <see cref="Packages.PackageKind.Blueprint"/> in
/// <paramref name="Packages"/>. <see langword="null"/> when the profile does not select one.
/// </param>
/// <param name="Theme">
/// The name of the <see cref="Theme"/> this profile applies, or <see langword="null"/> when it selects
/// none. A theme is only meaningful relative to a set of packages, which is why it is chosen here rather
/// than by a screen.
/// </param>
/// <remarks>
/// A profile is where the choices that make a description concrete are made: which component vocabulary,
/// which shell, which theme. Deliberately none of them are stated by a <see cref="Screens.Screen"/> - that
/// is what keeps a screen portable across targets, and what lets one application ship a different shell to
/// the web than to a phone.
/// </remarks>
public record UiProfile(
string Name,
string TargetPlatform,
IReadOnlyList<string> Packages,
SizeClass? DefaultSizeClass = null,
string? Layout = null,
string? Theme = null);
49 changes: 44 additions & 5 deletions Source/JavaScript/model/profiles/UiProfile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,55 @@
import { SizeClass } from '../sizeClasses';

/**
* A named target: a platform, a default size class, and an ordered list of component packages.
* Declaration order in `packages` is override priority — a later package shadows an earlier one when
* both resolve the same bare component name. `core` is always the final fallback, so a minimum
* vocabulary resolves regardless of which packages a profile lists.
* A named target: a platform, a default size class, an ordered list of component packages, and the
* application shell and visual theme it selects. Declaration order in `packages` is override priority — a
* later package shadows an earlier one when both resolve the same bare component name. `core` is always
* the final fallback, so a minimum vocabulary resolves regardless of which packages a profile lists.
*
* A profile is where the choices that make a description concrete are made: which component vocabulary,
* which shell, which theme. Deliberately none of them are stated by a {@link Screen} — that is what keeps
* a screen portable across targets, and what lets one application ship a different shell to the web than
* to a phone.
*/
export interface UiProfile {
/**
* The profile's name.
*/
name: string;

/**
* The platform this profile targets (e.g. `web`, `ios`, `android`, `desktop`).
*/
targetPlatform: string;

/**
* The component packages this profile draws from, in override-priority order.
*/
packages: string[];

/**
* The size class assumed when the renderer cannot otherwise determine one.
*/
defaultSizeClass?: SizeClass;

/**
* The name of the {@link Layout} this profile renders inside — the application's base navigational
* shell, normally provided by a blueprint in `packages`. Absent when the profile does not select one.
*/
layout?: string;

/**
* The name of the {@link Theme} this profile applies, or absent when it selects none. A theme is only
* meaningful relative to a set of packages, which is why it is chosen here rather than by a screen.
*/
theme?: string;
}

export const UiProfilePropertyNames: (keyof UiProfile)[] = ['name', 'targetPlatform', 'packages', 'defaultSizeClass'];
export const UiProfilePropertyNames: (keyof UiProfile)[] = [
'name',
'targetPlatform',
'packages',
'defaultSizeClass',
'layout',
'theme',
];
4 changes: 3 additions & 1 deletion scene-model-shape.json
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,9 @@
"name",
"targetPlatform",
"packages",
"defaultSizeClass"
"defaultSizeClass",
"layout",
"theme"
],
"Theme": [
"name",
Expand Down
Loading