Skip to content
Open
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
38 changes: 38 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -696,6 +696,44 @@ How do we solve this ? Developers love having framework overview by examples. It

</details>

<details>
<summary>
<img width="18" height="18" src="public/framework/blazor.svg" />
<b>Blazor</b>
<img src="https://us-central1-progress-markdown.cloudfunctions.net/progress/92" />
</summary>

- [x] Reactivity
- [x] Declare state
- [x] Update state
- [x] Computed state
- [x] Templating
- [x] Minimal template
- [x] Styling
- [x] Loop
- [x] Event click
- [x] Dom ref
- [x] Conditional
- [x] Lifecycle
- [x] On mount
- [x] On unmount
- [x] Component composition
- [x] Props
- [x] Emit to parent
- [x] Slot
- [x] Slot fallback
- [x] Context
- [x] Form input
- [x] Input text
- [x] Checkbox
- [x] Radio
- [x] Select
- [ ] Webapp features
- [ ] Render app
- [ ] Fetch data

</details>

<!-- progression end -->

## 🤝 Contributing
Expand Down
5 changes: 4 additions & 1 deletion build/lib/highlighter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,12 @@ async function getHighlighter(): Promise<
"jsx",
"vue",
"marko",
"csharp",
],
langAlias: {
ripple: "jsx", // until ripple is supported by shiki
ripple: "jsx",
razor: "csharp", // Csharp might not be ideal, but better? than nothing
cs: "csharp",
},
});
}
Expand Down
5 changes: 5 additions & 0 deletions content/1-reactivity/1-declare-state/blazor/Name.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<h1>Hello @name</h1>

@code {
private string name = "John";
}
10 changes: 10 additions & 0 deletions content/1-reactivity/2-update-state/blazor/Name.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<h1>Hello @name</h1>

@code {
private string name = "John";

protected override void OnInitialized()
{
name = "Jane";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<div>@doubleCount</div>

@code {
private int count = 10;
private int doubleCount => count * 2;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<h1>Hello world</h1>
8 changes: 8 additions & 0 deletions content/2-templating/2-styling/blazor/CssStyle.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<h1 class="title">I am red</h1>
<button style="font-size: 10rem;">I am a button</button>

<style>
.title {
color: red;
}
</style>
10 changes: 10 additions & 0 deletions content/2-templating/3-loop/blazor/Colors.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<ul>
@foreach (var color in colors)
{
<li>@color</li>
}
</ul>

@code {
private string[] colors = { "red", "green", "blue" };
}
11 changes: 11 additions & 0 deletions content/2-templating/4-event-click/blazor/Counter.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<p>Counter: @count</p>
<button @onclick="IncrementCount">+1</button>

@code {
private int count = 0;

private void IncrementCount()
{
count++;
}
}
13 changes: 13 additions & 0 deletions content/2-templating/5-dom-ref/blazor/InputFocused.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<input type="text" @ref="inputElement" />

@code {
private ElementReference inputElement;

protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
await inputElement.FocusAsync();
}
}
}
28 changes: 28 additions & 0 deletions content/2-templating/6-conditional/blazor/TrafficLight.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<button @onclick="NextLight">Next light</button>
<p>Light is: @light</p>
<p>
You must
@if (light == "red")
{
<span>STOP</span>
}
else if (light == "orange")
{
<span>SLOW DOWN</span>
}
else if (light == "green")
{
<span>GO</span>
}
</p>

@code {
private readonly string[] trafficLights = { "red", "orange", "green" };
private int lightIndex = 0;
private string light => trafficLights[lightIndex];

private void NextLight()
{
lightIndex = (lightIndex + 1) % trafficLights.Length;
}
}
12 changes: 12 additions & 0 deletions content/3-lifecycle/1-on-mount/blazor/PageTitle.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<p>Page title: @pageTitle</p>

@inject IJSRuntime JSRuntime

@code {
private string pageTitle = string.Empty;

protected override async Task OnInitializedAsync()
{
pageTitle = await JSRuntime.InvokeAsync<string>("eval", "document.title");
}
}
31 changes: 31 additions & 0 deletions content/3-lifecycle/2-on-unmount/blazor/Time.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
@implements IDisposable

<p>Current time: @currentTime</p>

@code {
private string currentTime = string.Empty;
private Timer? timer;

protected override void OnInitialized()
{
currentTime = DateTime.Now.ToLongTimeString();

timer = new Timer(
callback: _ => UpdateTime(),
state: null,
dueTime: TimeSpan.Zero,
period: TimeSpan.FromSeconds(1)
);
}

private void UpdateTime()
{
currentTime = DateTime.Now.ToLongTimeString();
StateHasChanged();
}

public void Dispose()
{
timer?.Dispose();
}
}
6 changes: 6 additions & 0 deletions content/4-component-composition/1-props/blazor/App.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<UserProfile
Name="John"
Age=20
FavouriteColors="@(new[] { "green", "blue", "red" })"
IsAvailable=true />

18 changes: 18 additions & 0 deletions content/4-component-composition/1-props/blazor/UserProfile.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<p>My name is @Name!</p>
<p>My age is @Age!</p>
<p>My favourite colors are @string.Join(", ", FavouriteColors)!</p>
<p>I am @(IsAvailable ? "available" : "not available")</p>

@code {
[Parameter]
public string Name { get; set; } = "";

[Parameter]
public int Age { get; set; }

[Parameter]
public string[] FavouriteColors { get; set; } = Array.Empty<string>();

[Parameter]
public bool IsAvailable { get; set; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<button @onclick="OnYes">YES</button>
<button @onclick="OnNo">NO</button>
@code {
[Parameter]
public EventCallback OnYes { get; set; }
[Parameter]
public EventCallback OnNo { get; set; }
}
17 changes: 17 additions & 0 deletions content/4-component-composition/2-emit-to-parent/blazor/App.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<p>Are you happy?</p>
<AnswerButton OnYes="OnAnswerYes" OnNo="OnAnswerNo" />
<p style="font-size: 50px;">@(isHappy ? "😀" : "😥")</p>

@code {
private bool isHappy = true;

private void OnAnswerNo()
{
isHappy = false;
}

private void OnAnswerYes()
{
isHappy = true;
}
}
1 change: 1 addition & 0 deletions content/4-component-composition/3-slot/blazor/App.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<FunnyButton>Click me!</FunnyButton>
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<button style="background: rgba(0, 0, 0, 0.4); color: #fff; padding: 10px 20px; font-size: 30px; border: 2px solid #fff; margin: 8px; transform: scale(0.9); box-shadow: 4px 4px rgba(0, 0, 0, 0.4); transition: transform 0.2s cubic-bezier(0.34, 1.65, 0.88, 0.925) 0s; outline: 0;">
@ChildContent
</button>

@code {
[Parameter]
public RenderFragment? ChildContent { get; set; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<FunnyButton />
<FunnyButton>I got content!</FunnyButton>
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<button style="background: rgba(0, 0, 0, 0.4); color: #fff; padding: 10px 20px; font-size: 30px; border: 2px solid #fff; margin: 8px; transform: scale(0.9); box-shadow: 4px 4px rgba(0, 0, 0, 0.4); transition: transform 0.2s cubic-bezier(0.34, 1.65, 0.88, 0.925) 0s; outline: 0;">
@if (ChildContent != null)
{
@ChildContent
}
else
{
<span>No content found</span>
}
</button>

@code {
[Parameter]
public RenderFragment? ChildContent { get; set; }
}
25 changes: 25 additions & 0 deletions content/4-component-composition/5-context/blazor/App.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<h1>Welcome back, @user.Username</h1>
<CascadingValue Value="@user">
<UserProfile />
</CascadingValue>

@code {
private UserInfo user = new()
{
Id = 1,
Username = "unicorn42",
Email = "[email protected]"
};

public class UserInfo
{
public int Id { get; set; }
public string Username { get; set; } = "";
public string Email { get; set; } = "";

public void UpdateUsername(string newUsername)
{
Username = newUsername;
}
}
}
16 changes: 16 additions & 0 deletions content/4-component-composition/5-context/blazor/UserProfile.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<div>
<h2>My Profile</h2>
<p>Username: @user?.Username</p>
<p>Email: @user?.Email</p>
<button @onclick="UpdateUsername">Update username to Jane</button>
</div>

@code {
[CascadingParameter]
private App.UserInfo? user { get; set; }

private void UpdateUsername()
{
user?.UpdateUsername("Jane");
}
}
6 changes: 6 additions & 0 deletions content/6-form-input/1-input-text/blazor/InputHello.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<p>@text</p>
<input @bind="text" />

@code {
private string text = "Hello world";
}
6 changes: 6 additions & 0 deletions content/6-form-input/2-checkbox/blazor/IsAvailable.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<input id="is-available" type="checkbox" @bind="isAvailable" />
<label for="is-available">Is available</label>

@code {
private bool isAvailable = false;
}
19 changes: 19 additions & 0 deletions content/6-form-input/3-radio/blazor/PickPill.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<div>Picked: @picked</div>

<input id="blue-pill"
type="radio"
name="pill"
value="blue" @onchange="@(() => picked = "blue")"
checked="@(picked == "blue")" />
<label for="blue-pill">Blue pill</label>

<input id="red-pill"
type="radio"
name="pill"
value="red" @onchange="@(() => picked = "red")"
checked="@(picked == "red")" />
<label for="red-pill">Red pill</label>

@code {
private string picked = "red";
}
25 changes: 25 additions & 0 deletions content/6-form-input/4-select/blazor/ColorSelect.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<select @bind="selectedColorId">
@foreach (var color in colors)
{
<option value="@color.Id" disabled="@color.IsDisabled">@color.Text</option>
}
</select>

@code {
private class ColorOption
{
public int Id { get; set; }
public string Text { get; set; } = "";
public bool IsDisabled { get; set; }
}

private readonly ColorOption[] colors = new[]
{
new ColorOption { Id = 1, Text = "red" },
new ColorOption { Id = 2, Text = "blue" },
new ColorOption { Id = 3, Text = "green" },
new ColorOption { Id = 4, Text = "gray", IsDisabled = true }
};

private int selectedColorId = 2;
}
Loading