Skip to content

Select Supports Generic Option Type#281

Merged
LittleLittleCloud merged 8 commits intoRazorConsole:mainfrom
claybrooks:u/claybrooks/complex-select
Jan 25, 2026
Merged

Select Supports Generic Option Type#281
LittleLittleCloud merged 8 commits intoRazorConsole:mainfrom
claybrooks:u/claybrooks/complex-select

Conversation

@claybrooks
Copy link
Contributor

Added generic type param to Select.

Added the following Parameters

  • TItem: Specifies the Type of options
  • Formatter: Optional formatter for the display, object.ToString() called by default
  • Comparer: Optional comparer for options, object.Equals() called by default.
    • For strings, this equates to str1.Equals(str2, Ordinal), so previous functionality is preserved

Considerations

  • It's very likely existing <Select/> code will break due to not being able to infer type of TItem, especially in the ValueChanged parameter.
    • I thought I could fix this with public class Select : Select<string>{} but razor doesn't like that. Seems like there is no way around a breaking change
  • I initially implemented a cache for all of the formatted options, but managing the cache was difficult especially when dealing with modified option objects outside the scope of the Select. So for now, each render pass calls Format(). I can revisit this if it's something you'd prefer

@github-actions
Copy link

github-actions bot commented Jan 14, 2026

🚀 Preview Deployment

A preview build has been generated for this PR from CI run #21182647521!

Download the artifact:
website-preview-281-0a09f90acf29645309fb933aa7f3f18c47d0bca6

To view the preview locally:

  1. Download the artifact from the CI workflow run
  2. Extract the ZIP file
  3. Serve the files with a local web server
    (e.g., npx serve dist)

🌐 Live Preview URL: https://c07a232c.razorconsole.pages.dev

The live preview will be automatically updated when you push new
commits to this PR.

TeseySTD
TeseySTD previously approved these changes Jan 14, 2026
private string? FocusedOption = null;
private bool IsFocused;
private static readonly string _exampleCode = @"<Rows>
<Select TItem=""string"" Options=""@(new[] { ""Align"", ""Border"", ""Columns"", ""Panel"", ""Select"", ""Text Input"" })""
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it necessary to pass TItem here? The code above that actually render the component doesn't expliclty pass the TItem parameter.

Copy link
Contributor Author

@claybrooks claybrooks Jan 14, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, in this case it is not necessary. I've removed it. It seems like the only time you need to specify TItem is when you have an explicit ValueChanged binding. For whatever reason, the compiler can't deduce TITem. But if you use @bind-Value, it's fine.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR makes the Select component generic (Select<TItem>) so it can operate on arbitrary item types, with support for custom display formatting and equality comparison, and updates call sites/tests accordingly.

Changes:

  • Generalized Select to Select<TItem> with new Formatter and Comparer parameters and internal helpers to use these for rendering, selection, and type-ahead behavior.
  • Updated tests and sample usage (gallery and website) to construct Select<string> explicitly or rely on inference, and added a NavBar example that binds Select<Tab> with a custom formatter.
  • Performed minor layout/copy improvements in the select gallery page (panel title, indentation).

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
src/RazorConsole.Core/Components/Select.razor Core change: converts Select to Select<TItem>, wires in Comparer/Formatter, and updates selection, focus, and type-ahead logic to work with generic items instead of hard-coded string.
src/RazorConsole.Gallery/Components/NavBar.razor Switches NavBar to use Select<Tab> with a Formatter projecting labels, demonstrating generic Select with a complex item type.
src/RazorConsole.Gallery/Pages/SelectGallery.razor Keeps the gallery example using string options and updates panel labeling/formatting to clarify it’s the string-based select example.
src/RazorConsole.Tests/Components/SelectTests.cs Adjusts the test hosts to construct Select<string> explicitly so existing behavior tests still compile against the generic component.
src/RazorConsole.Website/Components/Select_1.razor Updates the website sample to declare TItem="string" for the basic select demo so it binds correctly to the new generic component.

private string? FocusedOption = null;
private bool IsFocused;
private static readonly string _exampleCode = @"<Rows>
private string Select = "Align";
Copy link

Copilot AI Jan 18, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Field 'Select' can be 'readonly'.

Copilot uses AI. Check for mistakes.
private bool IsFocused;
private static readonly string _exampleCode = @"<Rows>
private string Select = "Align";
private string? FocusedOption = null;
Copy link

Copilot AI Jan 18, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Field 'FocusedOption' can be 'readonly'.

Copilot uses AI. Check for mistakes.
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Signed-off-by: Xiaoyun Zhang <bigmiao.zhang@gmail.com>
@LittleLittleCloud LittleLittleCloud merged commit dee3998 into RazorConsole:main Jan 25, 2026
7 checks passed
@github-actions github-actions bot added this to the v0.3.0 milestone Jan 25, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants