@@ -15,11 +15,15 @@ namespace MudExtensions;
1515public partial class MudCodeViewer : MudComponentBase
1616{
1717 private ElementReference _codeRef ;
18+ private ElementReference _textAreaRef ;
1819 private string ? _copyIcon = Icons . Material . Filled . ContentCopy ;
20+ private bool _shouldHighlight ;
21+ private bool _tabEnabled ;
1922
2023 private readonly ParameterState < string ? > _code ;
2124 private readonly ParameterState < bool > _showLineNumbers ;
2225 private readonly ParameterState < bool > _wrap ;
26+ private readonly ParameterState < bool > _header ;
2327 private readonly ParameterState < CodeLanguage > _language ;
2428
2529 /// <summary>
@@ -30,13 +34,17 @@ public MudCodeViewer()
3034 using var registerScope = CreateRegisterScope ( ) ;
3135 _code = registerScope . RegisterParameter < string ? > ( nameof ( Code ) )
3236 . WithParameter ( ( ) => Code )
33- . WithChangeHandler ( ParameterChanged ) ;
37+ . WithChangeHandler ( ParameterChanged )
38+ . WithEventCallback ( ( ) => CodeChanged ) ;
3439 _showLineNumbers = registerScope . RegisterParameter < bool > ( nameof ( ShowLineNumbers ) )
3540 . WithParameter ( ( ) => ShowLineNumbers )
3641 . WithChangeHandler ( ParameterChanged ) ;
3742 _wrap = registerScope . RegisterParameter < bool > ( nameof ( Wrap ) )
3843 . WithParameter ( ( ) => Wrap )
3944 . WithChangeHandler ( ParameterChanged ) ;
45+ _header = registerScope . RegisterParameter < bool > ( nameof ( ShowHeader ) )
46+ . WithParameter ( ( ) => ShowHeader )
47+ . WithChangeHandler ( ParameterChanged ) ;
4048 _language = registerScope . RegisterParameter < CodeLanguage > ( nameof ( Language ) )
4149 . WithParameter ( ( ) => Language )
4250 . WithChangeHandler ( ParameterChanged ) ;
@@ -58,6 +66,19 @@ public MudCodeViewer()
5866 . AddClass ( HeaderClass )
5967 . Build ( ) ;
6068
69+ /// <summary>
70+ /// Gets the CSS class name representing the current programming language for syntax highlighting.
71+ /// </summary>
72+ protected string CodeClass => $ "language-{ _language . Value . ToDescriptionString ( ) } ";
73+
74+ /// <summary>
75+ /// Gets the CSS class string used for the pre element based on the selected language and line number display settings.
76+ /// </summary>
77+ private string PreClass => new CssBuilder ( )
78+ . AddClass ( $ "line-numbers language-{ _language . Value . ToDescriptionString ( ) } ", _showLineNumbers . Value )
79+ . AddClass ( $ "language-{ _language . Value . ToDescriptionString ( ) } ", ! _showLineNumbers . Value )
80+ . Build ( ) ;
81+
6182 /// <summary>
6283 /// Gets or sets the code snippet to be displayed or processed by the component.
6384 /// </summary>
@@ -72,9 +93,15 @@ public MudCodeViewer()
7293 [ Parameter ]
7394 public CodeLanguage Language { get ; set ; } = CodeLanguage . CSharp ;
7495
96+ /// <summary>
97+ /// Gets or sets a value indicating whether line numbers are displayed in the code viewer.
98+ /// </summary>
7599 [ Parameter ]
76100 public bool ShowLineNumbers { get ; set ; }
77101
102+ /// <summary>
103+ /// Gets or sets a value indicating whether the header is displayed in the code viewer component.
104+ /// </summary>
78105 [ Parameter ]
79106 public bool ShowHeader { get ; set ; } = true ;
80107
@@ -84,6 +111,15 @@ public MudCodeViewer()
84111 [ Parameter ]
85112 public string ? HeaderClass { get ; set ; }
86113
114+ /// <summary>
115+ /// Gets or sets the content to be rendered in the header section of the component.
116+ /// </summary>
117+ [ Parameter ]
118+ public RenderFragment ? HeaderContent { get ; set ; }
119+
120+ /// <summary>
121+ /// Gets or sets a value indicating whether the copy button is displayed in the code viewer component.
122+ /// </summary>
87123 [ Parameter ]
88124 public bool ShowCopyButton { get ; set ; } = true ;
89125
@@ -106,12 +142,18 @@ public MudCodeViewer()
106142 [ Parameter ]
107143 public RenderFragment ? ChildContent { get ; set ; }
108144
145+ /// <summary>
146+ /// Gets or sets a value indicating whether the content is editable by the user.
147+ /// </summary>
148+ [ Parameter ]
149+ public bool Editable { get ; set ; }
150+
151+ /// <summary>
152+ /// Gets or sets the callback that is invoked when the code value changes.
153+ /// </summary>
154+ [ Parameter ]
155+ public EventCallback < string ? > CodeChanged { get ; set ; }
109156
110- private string CodeClass => $ "language-{ _language . Value . ToDescriptionString ( ) } ";
111- private string PreClass => new CssBuilder ( )
112- . AddClass ( $ "line-numbers language-{ _language . Value . ToDescriptionString ( ) } ", _showLineNumbers . Value )
113- . AddClass ( $ "language-{ _language . Value . ToDescriptionString ( ) } ", ! _showLineNumbers . Value )
114- . Build ( ) ;
115157
116158 /// <summary>
117159 /// Invoked after the component has rendered. Performs post-render logic, such as refreshing data, when the
@@ -123,6 +165,23 @@ protected override async Task OnAfterRenderAsync(bool firstRender)
123165 {
124166 await RefreshAsync ( ) ;
125167 }
168+
169+ if ( Editable && ! _tabEnabled )
170+ {
171+ await JS . InvokeVoidAsync ( "MudCode.enableTabIndent" , _textAreaRef ) ;
172+ _tabEnabled = true ;
173+ }
174+
175+ if ( ! Editable )
176+ {
177+ _tabEnabled = false ;
178+ }
179+
180+ if ( _shouldHighlight )
181+ {
182+ _shouldHighlight = false ;
183+ await RefreshAsync ( ) ;
184+ }
126185 }
127186
128187 /// <summary>
@@ -144,12 +203,19 @@ public async Task CopyAsync()
144203 await JS . InvokeVoidAsync ( "MudCode.copy" , Code ) ;
145204 }
146205
206+ /// <summary>
207+ /// Handles changes to component parameters asynchronously and refreshes the component state.
208+ /// </summary>
147209 protected async Task ParameterChanged ( )
148210 {
149211 await Task . Delay ( 1 ) ;
150212 await RefreshAsync ( ) ;
151213 }
152214
215+ /// <summary>
216+ /// Handles the copy button click event asynchronously, updates the copy icon to indicate success, and restores the
217+ /// original icon after a brief delay.
218+ /// </summary>
153219 protected async Task HandleCopyButtonClickAsync ( )
154220 {
155221 await CopyAsync ( ) ;
@@ -159,4 +225,10 @@ protected async Task HandleCopyButtonClickAsync()
159225 _copyIcon = Icons . Material . Filled . ContentCopy ;
160226 StateHasChanged ( ) ;
161227 }
228+
229+ private async Task OnInput ( ChangeEventArgs e )
230+ {
231+ await _code . SetValueAsync ( e . Value ? . ToString ( ) ) ;
232+ _shouldHighlight = true ;
233+ }
162234}
0 commit comments