├── BeerCss.Blazor ├── logo.png ├── Common │ ├── VerticalPosition.cs │ ├── MenuItem.cs │ ├── Speed.cs │ ├── Orientation.cs │ ├── Space.cs │ ├── Size.cs │ ├── Color.cs │ ├── Direction.cs │ ├── HorizontalPosition.cs │ ├── Elevation.cs │ └── CssClassInjector.cs ├── Components │ ├── Spacer.razor │ ├── Padding.razor │ ├── Dialogs │ │ ├── IHaveNav.cs │ │ ├── IHaveTitle.cs │ │ ├── Sheet.razor │ │ ├── Default.razor │ │ ├── Modal.razor │ │ ├── DialogProvider.razor │ │ └── Dialog.cs │ ├── Wave.cs │ ├── Ripple.cs │ ├── Divider.razor │ ├── Shape.cs │ ├── List.razor │ ├── Page.razor │ ├── StepperButton.razor │ ├── Navigation.razor │ ├── Row.razor │ ├── Grid.razor │ ├── Buttons │ │ ├── Group.razor │ │ ├── Split.razor │ │ ├── FAB.razor │ │ └── Button.razor │ ├── Scroll.razor │ ├── Expansion.razor │ ├── NavBar.razor │ ├── SideContent.razor │ ├── AppBar.razor.css │ ├── Align.razor │ ├── Progress.razor │ ├── Position.razor │ ├── Toolbar.razor │ ├── SnackbarProvider.razor │ ├── Beer.razor │ ├── Tooltip.razor │ ├── Tab.razor │ ├── AppBar.razor │ ├── Stepper.razor │ ├── Snackbar.razor │ ├── Chip.razor │ ├── Inputs │ │ ├── SelectField.razor │ │ ├── DateField.razor │ │ ├── NumberField.razor │ │ ├── Slider.razor │ │ ├── FileField.razor │ │ ├── Switch.razor │ │ ├── TextArea.razor │ │ ├── TextField.razor │ │ └── SearchField.razor │ ├── Tabs.razor │ ├── Card.razor │ ├── Table.razor │ └── Menu.razor ├── _Imports.razor └── BeerCss.Blazor.csproj ├── BeerCss.Blazor.Stories ├── wwwroot │ ├── favicon.ico │ ├── favicon.png │ ├── beer │ │ └── dist │ │ │ └── cdn │ │ │ ├── material-symbols-outlined.woff2 │ │ │ ├── circle.svg │ │ │ ├── semicircle.svg │ │ │ ├── pixel-triangle.svg │ │ │ ├── pixel-circle.svg │ │ │ ├── pill.svg │ │ │ ├── oval.svg │ │ │ ├── arch.svg │ │ │ ├── leaf-clover8.svg │ │ │ ├── leaf-clover4.svg │ │ │ ├── bun.svg │ │ │ ├── ghost-ish.svg │ │ │ ├── triangle.svg │ │ │ ├── sided-cookie4.svg │ │ │ ├── square.svg │ │ │ ├── fan.svg │ │ │ ├── heart.svg │ │ │ ├── slanted.svg │ │ │ ├── sided-cookie6.svg │ │ │ ├── diamond.svg │ │ │ ├── arrow.svg │ │ │ ├── soft-boom.svg │ │ │ ├── flower.svg │ │ │ ├── pentagon.svg │ │ │ ├── puffy-diamond.svg │ │ │ ├── clamshell.svg │ │ │ ├── gem.svg │ │ │ ├── very-sunny.svg │ │ │ ├── soft-burst.svg │ │ │ ├── wavy.svg │ │ │ ├── sided-cookie7.svg │ │ │ ├── puffy.svg │ │ │ ├── sided-cookie9.svg │ │ │ ├── sunny.svg │ │ │ ├── sided-cookie12.svg │ │ │ ├── wavy-circle.svg │ │ │ ├── burst.svg │ │ │ └── boom.svg │ ├── iframe.html │ ├── index.html │ └── css │ │ └── blazor-ui.css ├── Shared │ └── DefaultLayout.razor ├── App.razor ├── Stories │ ├── NavBar.stories.razor │ ├── Align.stories.razor │ ├── Spacer.stories.razor │ ├── Wave.stories.razor │ ├── Divider.stories.razor │ ├── Ripple.stories.razor │ ├── Toolbar.stores.razor │ ├── AppBar.stories.razor │ ├── Expansion.stories.razor │ ├── Progress.stories.razor │ ├── Snackbar.stories.razor │ ├── Dialogs │ │ ├── Sheet.stories.razor │ │ ├── Default.stories.razor │ │ └── Modal.stories.razor │ ├── Menu.stories.razor │ ├── Welcome.md │ ├── Buttons │ │ ├── Group.stories.razor │ │ ├── Split.stories.razor │ │ ├── Button.stories.razor │ │ └── FAB.stories.razor │ ├── Row.stories.razor │ ├── Inputs │ │ ├── FileField.stories.razor │ │ ├── NumberField.stories.razor │ │ ├── TextArea.stories.razor │ │ ├── TextField.stories.razor │ │ ├── DateField.stories.razor │ │ ├── Slider.stories.razor │ │ ├── SearchField.stories.razor │ │ ├── Select.stories.razor │ │ └── Switch.stories.razor │ ├── Chip.stories.razor │ ├── Shape.stories.razor │ ├── Tabs.stories.razor │ ├── Navigation.stories.razor │ ├── List.stories.razor │ ├── Grid.stories.razor │ ├── SideContent.stories.razor │ ├── Stepper.stories.razor │ ├── Card.stories.razor │ ├── Tooltip.stores.razor │ ├── Table.stories.razor │ └── Scroll.stories.razor ├── libman.json ├── Program.cs ├── Properties │ └── launchSettings.json ├── _Imports.razor └── BeerCss.Blazor.Stories.csproj ├── BeerCss.Blazor.slnx ├── LICENSE ├── .github └── workflows │ ├── demo.yml │ └── nuget.yml └── README.md /BeerCss.Blazor/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dibble-james/beercss-blazor/main/BeerCss.Blazor/logo.png -------------------------------------------------------------------------------- /BeerCss.Blazor.Stories/wwwroot/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dibble-james/beercss-blazor/main/BeerCss.Blazor.Stories/wwwroot/favicon.ico -------------------------------------------------------------------------------- /BeerCss.Blazor.Stories/wwwroot/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dibble-james/beercss-blazor/main/BeerCss.Blazor.Stories/wwwroot/favicon.png -------------------------------------------------------------------------------- /BeerCss.Blazor/Common/VerticalPosition.cs: -------------------------------------------------------------------------------- 1 | namespace BeerCss.Blazor.Common; 2 | 3 | public enum VerticalPosition 4 | { 5 | Middle, 6 | Top, 7 | Bottom, 8 | } 9 | -------------------------------------------------------------------------------- /BeerCss.Blazor/Components/Spacer.razor: -------------------------------------------------------------------------------- 1 | @code { 2 | [Parameter] 3 | public Space Spacing { get; set; } = Space.None; 4 | } 5 | 6 |
-------------------------------------------------------------------------------- /BeerCss.Blazor/_Imports.razor: -------------------------------------------------------------------------------- 1 | @using BeerCss.Blazor.Common; 2 | @using BeerCss.Blazor.Components.Buttons; 3 | @using BlazorComponentUtilities 4 | @using Microsoft.AspNetCore.Components.Web -------------------------------------------------------------------------------- /BeerCss.Blazor.slnx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /BeerCss.Blazor.Stories/Shared/DefaultLayout.razor: -------------------------------------------------------------------------------- 1 | @inherits LayoutComponentBase 2 | @* See also: https://github.com/jsakamoto/BlazingStory#%EF%B8%8F-configure-layouts *@ 3 | 4 | @Body 5 | 6 | -------------------------------------------------------------------------------- /BeerCss.Blazor.Stories/wwwroot/beer/dist/cdn/material-symbols-outlined.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dibble-james/beercss-blazor/main/BeerCss.Blazor.Stories/wwwroot/beer/dist/cdn/material-symbols-outlined.woff2 -------------------------------------------------------------------------------- /BeerCss.Blazor/Components/Padding.razor: -------------------------------------------------------------------------------- 1 | @code { 2 | [Parameter, EditorRequired] 3 | public required RenderFragment ChildContent { get; set; } 4 | } 5 | 6 |
7 | @ChildContent 8 |
-------------------------------------------------------------------------------- /BeerCss.Blazor/Components/Dialogs/IHaveNav.cs: -------------------------------------------------------------------------------- 1 | namespace BeerCss.Blazor.Components.Dialogs; 2 | 3 | using Microsoft.AspNetCore.Components; 4 | 5 | public interface IHaveNav 6 | { 7 | public RenderFragment? Nav { get; set; } 8 | } -------------------------------------------------------------------------------- /BeerCss.Blazor/Components/Dialogs/IHaveTitle.cs: -------------------------------------------------------------------------------- 1 | namespace BeerCss.Blazor.Components.Dialogs; 2 | 3 | using Microsoft.AspNetCore.Components; 4 | 5 | public interface IHaveTitle 6 | { 7 | public RenderFragment Title { get; set; } 8 | } -------------------------------------------------------------------------------- /BeerCss.Blazor/Components/Dialogs/Sheet.razor: -------------------------------------------------------------------------------- 1 | @inherits Dialog 2 | @code { 3 | [Parameter] 4 | public Direction Direction { get; set; } = Direction.Bottom; 5 | 6 | public override CssBuilder CssClass => base.CssClass.AddClass(Direction.ToCssClass()); 7 | } -------------------------------------------------------------------------------- /BeerCss.Blazor.Stories/App.razor: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /BeerCss.Blazor/Common/MenuItem.cs: -------------------------------------------------------------------------------- 1 | namespace BeerCss.Blazor.Common; 2 | 3 | public abstract record MenuItem(string Text); 4 | public record LinkMenuItem(string Text, string? Href) : MenuItem(Text); 5 | public record ActionMenuItem(string Text, Action OnClick) : MenuItem(Text); -------------------------------------------------------------------------------- /BeerCss.Blazor.Stories/Stories/NavBar.stories.razor: -------------------------------------------------------------------------------- 1 | @attribute [Stories("Components/NavBar")] 2 | 3 | 4 | 5 | 8 | 9 | -------------------------------------------------------------------------------- /BeerCss.Blazor/Components/Dialogs/Default.razor: -------------------------------------------------------------------------------- 1 | @inherits Dialog 2 | @implements IHaveTitle 3 | @implements IHaveNav 4 | @code { 5 | [Parameter, EditorRequired] 6 | public required RenderFragment Title { get; set; } 7 | 8 | [Parameter] 9 | public RenderFragment? Nav { get; set; } 10 | } -------------------------------------------------------------------------------- /BeerCss.Blazor.Stories/wwwroot/beer/dist/cdn/circle.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /BeerCss.Blazor.Stories/wwwroot/beer/dist/cdn/semicircle.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /BeerCss.Blazor/Components/Wave.cs: -------------------------------------------------------------------------------- 1 | namespace BeerCss.Blazor.Components; 2 | 3 | using BeerCss.Blazor.Common; 4 | using Microsoft.AspNetCore.Components; 5 | 6 | public class Wave : CssClassInjector 7 | { 8 | [Parameter] 9 | public Speed Speed { get; set; } 10 | 11 | protected override string CssClass => $"{this.Speed.ToCssClass()}wave"; 12 | } -------------------------------------------------------------------------------- /BeerCss.Blazor/Components/Ripple.cs: -------------------------------------------------------------------------------- 1 | namespace BeerCss.Blazor.Components; 2 | 3 | using BeerCss.Blazor.Common; 4 | using Microsoft.AspNetCore.Components; 5 | 6 | public class Ripple : CssClassInjector 7 | { 8 | [Parameter] 9 | public Speed Speed { get; set; } 10 | 11 | protected override string CssClass => $"{this.Speed.ToCssClass()}ripple"; 12 | } -------------------------------------------------------------------------------- /BeerCss.Blazor.Stories/wwwroot/beer/dist/cdn/pixel-triangle.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /BeerCss.Blazor/Components/Divider.razor: -------------------------------------------------------------------------------- 1 | @code { 2 | [Parameter] 3 | public Space Spacing { get; set; } 4 | 5 | private string CssClass => Spacing switch 6 | { 7 | Space.Small => "small", 8 | Space.Medium => "medium", 9 | Space.Large => "large", 10 | _ => string.Empty, 11 | }; 12 | } 13 | 14 |
-------------------------------------------------------------------------------- /BeerCss.Blazor.Stories/Stories/Align.stories.razor: -------------------------------------------------------------------------------- 1 | @attribute [Stories("Components/Align")] 2 | 3 | 4 | 5 | 10 | 11 | -------------------------------------------------------------------------------- /BeerCss.Blazor.Stories/wwwroot/beer/dist/cdn/pixel-circle.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /BeerCss.Blazor/Components/Shape.cs: -------------------------------------------------------------------------------- 1 | namespace BeerCss.Blazor.Components; 2 | 3 | using BeerCss.Blazor.Common; 4 | using Microsoft.AspNetCore.Components; 5 | 6 | public class Shape : CssClassInjector 7 | { 8 | [Parameter, EditorRequired] 9 | public required string ShapeType { get; set; } 10 | 11 | protected override string CssClass => $"shape {this.ShapeType}"; 12 | } -------------------------------------------------------------------------------- /BeerCss.Blazor.Stories/wwwroot/beer/dist/cdn/pill.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /BeerCss.Blazor.Stories/wwwroot/beer/dist/cdn/oval.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /BeerCss.Blazor/Common/Speed.cs: -------------------------------------------------------------------------------- 1 | namespace BeerCss.Blazor.Common; 2 | 3 | public enum Speed 4 | { 5 | Default, 6 | Slow, 7 | Fast, 8 | } 9 | 10 | public static class SpeedExtensions 11 | { 12 | public static string ToCssClass(this Speed speed) => speed switch 13 | { 14 | Speed.Slow => "slow-", 15 | Speed.Fast => "fast-", 16 | Speed.Default => string.Empty, 17 | _ => string.Empty, 18 | }; 19 | } -------------------------------------------------------------------------------- /BeerCss.Blazor.Stories/libman.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "3.0", 3 | "defaultProvider": "cdnjs", 4 | "libraries": [ 5 | { 6 | "provider": "jsdelivr", 7 | "library": "beercss@3.13.1", 8 | "destination": "wwwroot/beer", 9 | "files": [ 10 | "dist/cdn/beer.scoped.min.css", 11 | "dist/cdn/beer.min.js", 12 | "dist/cdn/material-symbols-outlined.woff2", 13 | "dist/cdn/*.svg" 14 | ] 15 | } 16 | ] 17 | } -------------------------------------------------------------------------------- /BeerCss.Blazor/Common/Orientation.cs: -------------------------------------------------------------------------------- 1 | namespace BeerCss.Blazor.Common; 2 | 3 | public enum Orientation 4 | { 5 | Horizontal, 6 | Vertical, 7 | } 8 | 9 | public static class OrientationExtensions 10 | { 11 | public static string ToCssClass(this Orientation orientation) => orientation switch 12 | { 13 | Orientation.Horizontal => "horizontal", 14 | Orientation.Vertical => "vertical", 15 | _ => string.Empty, 16 | }; 17 | } -------------------------------------------------------------------------------- /BeerCss.Blazor.Stories/Stories/Spacer.stories.razor: -------------------------------------------------------------------------------- 1 | @attribute [Stories("Components/Spacer")] 2 | 3 | 4 | 5 | 12 | 13 | -------------------------------------------------------------------------------- /BeerCss.Blazor.Stories/Stories/Wave.stories.razor: -------------------------------------------------------------------------------- 1 | @attribute [Stories("Components/Wave")] 2 | 3 | 4 | 5 | 11 | 12 | -------------------------------------------------------------------------------- /BeerCss.Blazor.Stories/Stories/Divider.stories.razor: -------------------------------------------------------------------------------- 1 | @attribute [Stories("Components/Divider")] 2 | 3 | 4 | 5 | 12 | 13 | -------------------------------------------------------------------------------- /BeerCss.Blazor/Common/Space.cs: -------------------------------------------------------------------------------- 1 | namespace BeerCss.Blazor.Common; 2 | 3 | public enum Space 4 | { 5 | Small, 6 | None, 7 | Medium, 8 | Large, 9 | } 10 | 11 | public static class SpaceExtensions 12 | { 13 | public static string ToCssClass(this Space elevation) => elevation switch 14 | { 15 | Space.None => "no-space", 16 | Space.Medium => "medium-space", 17 | Space.Large => "large-space", 18 | _ => string.Empty, 19 | }; 20 | } -------------------------------------------------------------------------------- /BeerCss.Blazor.Stories/Stories/Ripple.stories.razor: -------------------------------------------------------------------------------- 1 | @attribute [Stories("Components/Ripple")] 2 | 3 | 4 | 5 | 11 | 12 | -------------------------------------------------------------------------------- /BeerCss.Blazor.Stories/wwwroot/beer/dist/cdn/arch.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /BeerCss.Blazor/Common/Size.cs: -------------------------------------------------------------------------------- 1 | namespace BeerCss.Blazor.Common; 2 | 3 | public enum Size 4 | { 5 | Medium, 6 | Tiny, 7 | Small, 8 | Large, 9 | Extra, 10 | } 11 | 12 | public static class SizeExtensions 13 | { 14 | public static string ToCssClass(this Size elevation) => elevation switch 15 | { 16 | Size.Tiny => "tiny", 17 | Size.Small => "small", 18 | Size.Large => "large", 19 | Size.Extra => "extra", 20 | _ => string.Empty, 21 | }; 22 | } -------------------------------------------------------------------------------- /BeerCss.Blazor.Stories/Program.cs: -------------------------------------------------------------------------------- 1 | using BeerCss.Blazor.Stories; 2 | using Microsoft.AspNetCore.Components.Web; 3 | using Microsoft.AspNetCore.Components.WebAssembly.Hosting; 4 | 5 | var builder = WebAssemblyHostBuilder.CreateDefault(args); 6 | builder.RootComponents.Add("#app"); 7 | builder.RootComponents.Add("head::after"); 8 | 9 | builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) }); 10 | 11 | await builder.Build().RunAsync(); 12 | -------------------------------------------------------------------------------- /BeerCss.Blazor/Components/Dialogs/Modal.razor: -------------------------------------------------------------------------------- 1 | @inherits Dialog 2 | @implements IHaveTitle 3 | @implements IHaveNav 4 | 5 | @code { 6 | [Parameter, EditorRequired] 7 | public required RenderFragment Title { get; set; } 8 | 9 | [Parameter] 10 | public bool FullScreen { get; set; } 11 | 12 | [Parameter] 13 | public RenderFragment? Nav { get; set; } 14 | 15 | public override CssBuilder CssClass => base.CssClass 16 | .AddClass("max", FullScreen) 17 | .AddClass("modal"); 18 | } -------------------------------------------------------------------------------- /BeerCss.Blazor.Stories/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "profiles": { 3 | "https": { 4 | "commandName": "Project", 5 | "dotnetRunMessages": true, 6 | "launchBrowser": true, 7 | "inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}", 8 | "applicationUrl": "https://localhost:7238;http://localhost:5196", 9 | "environmentVariables": { 10 | "ASPNETCORE_ENVIRONMENT": "Development" 11 | } 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /BeerCss.Blazor/Components/List.razor: -------------------------------------------------------------------------------- 1 | @code { 2 | [Parameter] 3 | public Space Spacing { get; set; } = Space.None; 4 | 5 | [Parameter] 6 | public bool Border { get; set; } 7 | 8 | [Parameter] 9 | public RenderFragment? ChildContent { get; set; } 10 | 11 | private CssBuilder CssClass => new CssBuilder() 12 | .AddClass("list") 13 | .AddClass("border", Border) 14 | .AddClass(Spacing.ToCssClass()); 15 | } 16 | 17 | -------------------------------------------------------------------------------- /BeerCss.Blazor.Stories/Stories/Toolbar.stores.razor: -------------------------------------------------------------------------------- 1 | @attribute [Stories("Components/Toolbar")] 2 | 3 | 4 | 5 | 13 | 14 | -------------------------------------------------------------------------------- /BeerCss.Blazor.Stories/wwwroot/beer/dist/cdn/leaf-clover8.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /BeerCss.Blazor/Common/Color.cs: -------------------------------------------------------------------------------- 1 | namespace BeerCss.Blazor.Common; 2 | 3 | public enum Color 4 | { 5 | Default, 6 | Primary, 7 | Secondary, 8 | Tertiary, 9 | Error, 10 | } 11 | 12 | public static class ColorExtensions 13 | { 14 | public static string ToCssClass(this Color elevation) => elevation switch 15 | { 16 | Color.Primary => "primary", 17 | Color.Secondary => "secondary", 18 | Color.Tertiary => "tertiary", 19 | Color.Error => "error", 20 | _ => string.Empty, 21 | }; 22 | } -------------------------------------------------------------------------------- /BeerCss.Blazor/Common/Direction.cs: -------------------------------------------------------------------------------- 1 | namespace BeerCss.Blazor.Common; 2 | 3 | public enum Direction 4 | { 5 | Default, 6 | Left, 7 | Right, 8 | Top, 9 | Bottom, 10 | } 11 | 12 | public static class DirectionExtensions 13 | { 14 | public static string ToCssClass(this Direction elevation) => elevation switch 15 | { 16 | Direction.Left => "left", 17 | Direction.Right => "right", 18 | Direction.Top => "top", 19 | Direction.Bottom => "bottom", 20 | _ => string.Empty, 21 | }; 22 | } -------------------------------------------------------------------------------- /BeerCss.Blazor/Components/Page.razor: -------------------------------------------------------------------------------- 1 | @code { 2 | [Parameter, EditorRequired] 3 | public required RenderFragment ChildContent { get; set; } 4 | 5 | [Parameter] 6 | public Direction Direction { get; set; } 7 | 8 | [Parameter] 9 | public bool IsActive { get; set; } = true; 10 | 11 | private CssBuilder CssClass => new CssBuilder() 12 | .AddClass("page") 13 | .AddClass("active", IsActive) 14 | .AddClass(Direction.ToCssClass()); 15 | } 16 | 17 |
18 | @ChildContent 19 |
-------------------------------------------------------------------------------- /BeerCss.Blazor/Common/HorizontalPosition.cs: -------------------------------------------------------------------------------- 1 | namespace BeerCss.Blazor.Common; 2 | 3 | public enum HorizontalPosition 4 | { 5 | Left, 6 | Center, 7 | Right, 8 | } 9 | 10 | public static class HorizontalPositionExtensions 11 | { 12 | public static string ToCssClass(this HorizontalPosition position) => position switch 13 | { 14 | HorizontalPosition.Center => "center-align", 15 | HorizontalPosition.Right => "right-align", 16 | HorizontalPosition.Left => string.Empty, 17 | _ => string.Empty, 18 | }; 19 | } -------------------------------------------------------------------------------- /BeerCss.Blazor/Common/Elevation.cs: -------------------------------------------------------------------------------- 1 | namespace BeerCss.Blazor.Common; 2 | 3 | public enum Elevation 4 | { 5 | NoElevate, 6 | SmallElevate, 7 | MediumElevate, 8 | LargeElevate, 9 | } 10 | 11 | public static class ElevationExtensions 12 | { 13 | public static string ToCssClass(this Elevation elevation) => elevation switch 14 | { 15 | Elevation.SmallElevate => "small-elevate", 16 | Elevation.MediumElevate => "medium-elevate", 17 | Elevation.LargeElevate => "large-elevate", 18 | _ => string.Empty, 19 | }; 20 | } -------------------------------------------------------------------------------- /BeerCss.Blazor.Stories/Stories/AppBar.stories.razor: -------------------------------------------------------------------------------- 1 | @attribute [Stories("Components/AppBar")] 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 12 | 13 | 14 | 15 | @code { 16 | string _headline = "MyApp"; 17 | string _iconUrl = "https://www.beercss.com/favicon.png"; 18 | } -------------------------------------------------------------------------------- /BeerCss.Blazor.Stories/wwwroot/beer/dist/cdn/leaf-clover4.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /BeerCss.Blazor.Stories/wwwroot/beer/dist/cdn/bun.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /BeerCss.Blazor/Components/StepperButton.razor: -------------------------------------------------------------------------------- 1 | @code { 2 | [Parameter] 3 | public Color Color { get; set; } 4 | 5 | [Parameter, EditorRequired] 6 | public required Stepper.Step Step { get; set; } 7 | 8 | [Parameter, EditorRequired] 9 | public EventCallback OnStepSelect { get; set; } 10 | } 11 | 12 | -------------------------------------------------------------------------------- /BeerCss.Blazor.Stories/wwwroot/beer/dist/cdn/ghost-ish.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /BeerCss.Blazor.Stories/wwwroot/beer/dist/cdn/triangle.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /BeerCss.Blazor.Stories/Stories/Expansion.stories.razor: -------------------------------------------------------------------------------- 1 | @attribute [Stories("Components/Expansion")] 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 12 | 13 | 14 | 15 | @code { 16 | RenderFragment _title = @Click me; 17 | RenderFragment _content = @I was hidden, now you see me; 18 | } -------------------------------------------------------------------------------- /BeerCss.Blazor.Stories/Stories/Progress.stories.razor: -------------------------------------------------------------------------------- 1 | @attribute [Stories("Components/Progress")] 2 | 3 | 4 | 5 | 8 | 9 | 10 | 11 | 14 | 15 | 16 | 17 | 20 | 21 | -------------------------------------------------------------------------------- /BeerCss.Blazor/Components/Navigation.razor: -------------------------------------------------------------------------------- 1 | @code { 2 | [Parameter] 3 | public HorizontalPosition Align { get; set; } 4 | 5 | [Parameter, EditorRequired] 6 | public RenderFragment ChildContent { get; set; } 7 | 8 | [Parameter(CaptureUnmatchedValues = true)] 9 | public IReadOnlyDictionary AdditionalAttributes { get; set; } = new Dictionary(); 10 | 11 | private CssBuilder CssClass => new CssBuilder() 12 | .AddClass(Align.ToCssClass()) 13 | .AddClassFromAttributes(AdditionalAttributes); 14 | } 15 | 16 | -------------------------------------------------------------------------------- /BeerCss.Blazor.Stories/_Imports.razor: -------------------------------------------------------------------------------- 1 | @using System.Net.Http 2 | @using System.Net.Http.Json 3 | @using Microsoft.AspNetCore.Components.Forms 4 | @using Microsoft.AspNetCore.Components.Routing 5 | @using Microsoft.AspNetCore.Components.Web 6 | @using Microsoft.AspNetCore.Components.Web.Virtualization 7 | @using Microsoft.AspNetCore.Components.WebAssembly.Http 8 | @using Microsoft.JSInterop 9 | @using BlazingStory.Components 10 | @using BlazingStory.Types 11 | @using BeerCss.Blazor.Stories 12 | @using BeerCss.Blazor.Stories.Shared 13 | @using BeerCss.Blazor.Components 14 | @using BeerCss.Blazor.Components.Buttons 15 | @using BeerCss.Blazor.Common 16 | -------------------------------------------------------------------------------- /BeerCss.Blazor.Stories/wwwroot/beer/dist/cdn/sided-cookie4.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /BeerCss.Blazor/Components/Row.razor: -------------------------------------------------------------------------------- 1 | @code { 2 | [Parameter] 3 | public HorizontalPosition Align { get; set; } 4 | 5 | [Parameter, EditorRequired] 6 | public RenderFragment ChildContent { get; set; } 7 | 8 | [Parameter(CaptureUnmatchedValues = true)] 9 | public IReadOnlyDictionary AdditionalAttributes { get; set; } = new Dictionary(); 10 | 11 | private CssBuilder CssClass => new CssBuilder() 12 | .AddClass("row") 13 | .AddClass(Align.ToCssClass()) 14 | .AddClassFromAttributes(AdditionalAttributes); 15 | } 16 | 17 |
18 | @ChildContent 19 |
-------------------------------------------------------------------------------- /BeerCss.Blazor.Stories/wwwroot/beer/dist/cdn/square.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /BeerCss.Blazor.Stories/wwwroot/beer/dist/cdn/fan.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /BeerCss.Blazor.Stories/wwwroot/beer/dist/cdn/heart.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /BeerCss.Blazor/Components/Grid.razor: -------------------------------------------------------------------------------- 1 | @code { 2 | [Parameter] 3 | public Space Space { get; set; } 4 | 5 | [Parameter, EditorRequired] 6 | public required RenderFragment ChildContent { get; set; } 7 | 8 | [Parameter(CaptureUnmatchedValues = true)] 9 | public IReadOnlyDictionary AdditionalAttributes { get; set; } = new Dictionary(); 10 | 11 | private CssBuilder CssClass => new CssBuilder() 12 | .AddClass("grid") 13 | .AddClass(this.Space.ToCssClass()) 14 | .AddClassFromAttributes(AdditionalAttributes); 15 | } 16 | 17 |
18 | @ChildContent 19 |
-------------------------------------------------------------------------------- /BeerCss.Blazor.Stories/Stories/Snackbar.stories.razor: -------------------------------------------------------------------------------- 1 | @attribute [Stories("Components/Snackbar")] 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 14 | 15 | 16 | 17 | @code { 18 | RenderFragment _content = @Mmmm... Snacks...; 19 | TimeSpan _timeout = TimeSpan.FromHours(1); 20 | } -------------------------------------------------------------------------------- /BeerCss.Blazor/Components/Buttons/Group.razor: -------------------------------------------------------------------------------- 1 | @code { 2 | [Parameter, EditorRequired] 3 | public required RenderFragment ChildContent { get; set; } 4 | 5 | [Parameter] 6 | public bool Connected { get; set; } 7 | 8 | [Parameter(CaptureUnmatchedValues = true)] 9 | public IReadOnlyDictionary AdditionalAttributes { get; set; } = new Dictionary(); 10 | 11 | private CssBuilder CssClass => new CssBuilder() 12 | .AddClass("group") 13 | .AddClass("connected", Connected) 14 | .AddClassFromAttributes(AdditionalAttributes); 15 | } 16 | 17 | -------------------------------------------------------------------------------- /BeerCss.Blazor.Stories/Stories/Dialogs/Sheet.stories.razor: -------------------------------------------------------------------------------- 1 | @using BeerCss.Blazor.Components.Dialogs 2 | @attribute [Stories("Components/Dialogs/Sheet")] 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 15 | 16 | 17 | 18 | @code { 19 | bool _open = true; 20 | RenderFragment _content = @I am dialog content; 21 | } -------------------------------------------------------------------------------- /BeerCss.Blazor/Components/Scroll.razor: -------------------------------------------------------------------------------- 1 | @using Microsoft.AspNetCore.Components.Routing 2 | @code { 3 | [Parameter] 4 | public bool Row { get; set; } 5 | 6 | [Parameter, EditorRequired] 7 | public RenderFragment ChildContent { get; set; } 8 | 9 | [Parameter(CaptureUnmatchedValues = true)] 10 | public IReadOnlyDictionary AdditionalAttributes { get; set; } = new Dictionary(); 11 | 12 | 13 | private CssBuilder CssClass => new CssBuilder() 14 | .AddClass("scroll") 15 | .AddClass("row", Row) 16 | .AddClassFromAttributes(AdditionalAttributes); 17 | } 18 | 19 | -------------------------------------------------------------------------------- /BeerCss.Blazor.Stories/wwwroot/beer/dist/cdn/slanted.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /BeerCss.Blazor/Components/Expansion.razor: -------------------------------------------------------------------------------- 1 | @using Microsoft.AspNetCore.Components.Routing 2 | @code { 3 | [Parameter, EditorRequired] 4 | public required RenderFragment Title { get; set; } 5 | 6 | [Parameter, EditorRequired] 7 | public required RenderFragment Content { get; set; } 8 | 9 | [Parameter(CaptureUnmatchedValues = true)] 10 | public IReadOnlyDictionary AdditionalAttributes { get; set; } = new Dictionary(); 11 | 12 | private CssBuilder CssClass => new CssBuilder() 13 | .AddClassFromAttributes(AdditionalAttributes); 14 | } 15 | 16 |
17 | @Title 18 | @Content 19 |
-------------------------------------------------------------------------------- /BeerCss.Blazor/Components/NavBar.razor: -------------------------------------------------------------------------------- 1 | @code { 2 | [Parameter, EditorRequired] 3 | public required RenderFragment ChildContent { get; set; } 4 | 5 | [Parameter] 6 | public RenderFragment? Header { get; set; } 7 | 8 | private bool Open { get; set; } = false; 9 | 10 | private CssBuilder CssClass => new CssBuilder() 11 | .AddClass("max", Open); 12 | } 13 | 14 | 25 | -------------------------------------------------------------------------------- /BeerCss.Blazor/Components/SideContent.razor: -------------------------------------------------------------------------------- 1 | @code { 2 | [Parameter] 3 | public bool Padding { get; set; } 4 | 5 | [Parameter] 6 | public Direction Direction { get; set; } 7 | 8 | [Parameter, EditorRequired] 9 | public RenderFragment ChildContent { get; set; } 10 | 11 | [Parameter(CaptureUnmatchedValues = true)] 12 | public IReadOnlyDictionary AdditionalAttributes { get; set; } = new Dictionary(); 13 | 14 | private CssBuilder CssClass => new CssBuilder() 15 | .AddClass("padding", Padding) 16 | .AddClass(Direction.ToCssClass()) 17 | .AddClassFromAttributes(AdditionalAttributes); 18 | } 19 | 20 | -------------------------------------------------------------------------------- /BeerCss.Blazor/Components/AppBar.razor.css: -------------------------------------------------------------------------------- 1 | .beer header nav button { 2 | order: -1; 3 | } 4 | 5 | .beer div.icon { 6 | position: relative; 7 | margin: auto; 8 | margin-top: 5px; 9 | } 10 | 11 | .beer div.icon:has(+ button) { 12 | transform: translateX(-1.5rem); 13 | } 14 | 15 | .beer div.icon ::deep a { 16 | position: absolute; 17 | border-radius: 100%; 18 | padding: 0.5rem; 19 | transform: translateX(-2.5rem); 20 | background: var(--surface); 21 | } 22 | 23 | .beer div.icon img { 24 | height: 4rem; 25 | background: var(--surface-container-low); 26 | border-radius: 100%; 27 | transition: box-shadow 0.5s; 28 | } 29 | 30 | .beer div.icon img:hover { 31 | box-shadow: var(--elevate2); 32 | } -------------------------------------------------------------------------------- /BeerCss.Blazor.Stories/Stories/Menu.stories.razor: -------------------------------------------------------------------------------- 1 | @attribute [Stories("Components/Menu")] 2 | 3 | 4 | 5 | 6 | 7 | 8 | 15 | 16 | 17 | 18 | @code { 19 | RenderFragment _content = @Menu; 20 | } -------------------------------------------------------------------------------- /BeerCss.Blazor.Stories/wwwroot/beer/dist/cdn/sided-cookie6.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /BeerCss.Blazor.Stories/wwwroot/beer/dist/cdn/diamond.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /BeerCss.Blazor.Stories/Stories/Welcome.md: -------------------------------------------------------------------------------- 1 | --- 2 | $attribute: CustomPage("Welcome") 3 | --- 4 | 5 | # BeerCss.Blazor 6 | 7 | Here we have a Blazor wrapper for the amazing [BeerCSS](https://www.beercss.com/) Material UI CSS library 8 | 9 | ## Installation 10 | Grab the package from Nuget [![NuGet Version](https://img.shields.io/nuget/v/BeerCss.Blazor)](https://www.nuget.org/packages/BeerCss.Blazor) 11 | 12 | Install the BeerCss CSS & Javascript files into your app in your favourite style (CDN, libman etc...) 13 | 14 | Soak your app with beer (AKA add the namespace your your `_Imports.razor` and the root component to your `_MainLayout.razor`) 15 | 16 | ```razor 17 | @using BeerCss.Blazor.Components 18 | @using BeerCss.Blazor.Common 19 | ``` 20 | 21 | ```razor 22 | @inherits LayoutComponentBase 23 | 24 | @Body 25 | 26 | ``` -------------------------------------------------------------------------------- /BeerCss.Blazor/Components/Buttons/Split.razor: -------------------------------------------------------------------------------- 1 | @code { 2 | [Parameter, EditorRequired] 3 | public required RenderFragment Button { get; set; } 4 | 5 | [Parameter, EditorRequired] 6 | public required RenderFragment Menu { get; set; } 7 | 8 | [Parameter] 9 | public Color Color { get; set; } = Color.Default; 10 | 11 | [Parameter(CaptureUnmatchedValues = true)] 12 | public IReadOnlyDictionary AdditionalAttributes { get; set; } = new Dictionary(); 13 | 14 | private CssBuilder CssClass => new CssBuilder() 15 | .AddClass("group") 16 | .AddClass("split") 17 | .AddClass(Color.ToCssClass()) 18 | .AddClassFromAttributes(AdditionalAttributes); 19 | } 20 | 21 | -------------------------------------------------------------------------------- /BeerCss.Blazor.Stories/wwwroot/beer/dist/cdn/arrow.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /BeerCss.Blazor.Stories/wwwroot/beer/dist/cdn/soft-boom.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /BeerCss.Blazor.Stories/wwwroot/beer/dist/cdn/flower.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /BeerCss.Blazor/Components/Align.razor: -------------------------------------------------------------------------------- 1 | @code { 2 | [Parameter] 3 | public VerticalPosition Vertical { get; set; } 4 | 5 | [Parameter] 6 | public HorizontalPosition Horizontal { get; set; } 7 | 8 | [Parameter] 9 | public bool Padding { get; set; } 10 | 11 | [Parameter(CaptureUnmatchedValues = true)] 12 | public IReadOnlyDictionary AdditionalAttributes { get; set; } = new Dictionary(); 13 | 14 | [Parameter, EditorRequired] 15 | public required RenderFragment ChildContent { get; set; } 16 | 17 | private CssBuilder CssClass => new CssBuilder() 18 | .AddClass($"{Vertical.ToString().ToLower()}-align") 19 | .AddClass($"{Horizontal.ToString().ToLower()}-align") 20 | .AddClassFromAttributes(AdditionalAttributes); 21 | } 22 | 23 |
24 | @ChildContent 25 |
-------------------------------------------------------------------------------- /BeerCss.Blazor.Stories/Stories/Buttons/Group.stories.razor: -------------------------------------------------------------------------------- 1 | @using BeerCss.Blazor.Components.Buttons; 2 | @attribute [Stories("Components/Buttons/Group")] 3 | 4 | 5 | 6 | 13 | 14 | 15 | 16 | 17 | 18 | 25 | 26 | -------------------------------------------------------------------------------- /BeerCss.Blazor.Stories/Stories/Dialogs/Default.stories.razor: -------------------------------------------------------------------------------- 1 | @using BeerCss.Blazor.Components.Dialogs 2 | @attribute [Stories("Components/Dialogs/Default")] 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 17 | 18 | 19 | 20 | @code { 21 | bool _open = true; 22 | RenderFragment _title = @I am title; 23 | RenderFragment _content = @I am dialog content; 24 | RenderFragment _nav = @; 25 | } -------------------------------------------------------------------------------- /BeerCss.Blazor.Stories/wwwroot/beer/dist/cdn/pentagon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /BeerCss.Blazor.Stories/Stories/Row.stories.razor: -------------------------------------------------------------------------------- 1 | @attribute [Stories("Components/Row")] 2 | 3 | 4 | 5 | 27 | 28 | -------------------------------------------------------------------------------- /BeerCss.Blazor.Stories/wwwroot/beer/dist/cdn/puffy-diamond.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /BeerCss.Blazor.Stories/Stories/Inputs/FileField.stories.razor: -------------------------------------------------------------------------------- 1 | @using BeerCss.Blazor.Components.Inputs 2 | @attribute [Stories("Components/Inputs/File")] 3 | 4 | 5 | 6 | 7 | 8 | 13 | 14 | 15 | 16 | 17 | 18 | 23 | 24 | 25 | 26 | @code { 27 | string? _value = "file.txt"; 28 | string _helpText = "Help me!"; 29 | } -------------------------------------------------------------------------------- /BeerCss.Blazor.Stories/wwwroot/beer/dist/cdn/clamshell.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /BeerCss.Blazor.Stories/wwwroot/beer/dist/cdn/gem.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /BeerCss.Blazor.Stories/wwwroot/beer/dist/cdn/very-sunny.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /BeerCss.Blazor/Components/Progress.razor: -------------------------------------------------------------------------------- 1 | @using Microsoft.AspNetCore.Components.Routing 2 | @code { 3 | [Parameter] 4 | public bool Circle { get; set; } 5 | 6 | [Parameter] 7 | public bool Wavy { get; set; } 8 | 9 | [Parameter] 10 | public int? ProgressPercentage { get; set; } 11 | 12 | [Parameter] 13 | public Size Size { get; set; } 14 | 15 | [Parameter(CaptureUnmatchedValues = true)] 16 | public IReadOnlyDictionary AdditionalAttributes { get; set; } = new Dictionary(); 17 | 18 | private int? ProgressPercentageValue 19 | => ProgressPercentage.HasValue 20 | ? (int)(ProgressPercentage * 0.01m) 21 | : null; 22 | 23 | private CssBuilder CssClass => new CssBuilder() 24 | .AddClass("circle", Circle) 25 | .AddClass("wavy", Wavy) 26 | .AddClass(Size.ToCssClass()) 27 | .AddClassFromAttributes(AdditionalAttributes); 28 | } 29 | 30 | -------------------------------------------------------------------------------- /BeerCss.Blazor/Components/Position.razor: -------------------------------------------------------------------------------- 1 | @code { 2 | [Parameter] 3 | public bool Fixed { get; set; } 4 | 5 | [Parameter] 6 | public VerticalPosition Vertical { get; set; } 7 | 8 | [Parameter] 9 | public HorizontalPosition Horizontal { get; set; } 10 | 11 | [Parameter] 12 | public bool Padding { get; set; } 13 | 14 | [Parameter(CaptureUnmatchedValues = true)] 15 | public IReadOnlyDictionary AdditionalAttributes { get; set; } = new Dictionary(); 16 | 17 | [Parameter, EditorRequired] 18 | public required RenderFragment ChildContent { get; set; } 19 | 20 | private CssBuilder CssClass => new CssBuilder() 21 | .AddClass("fixed", Fixed) 22 | .AddClass("absolute", !Fixed) 23 | .AddClass("padding", Padding) 24 | .AddClass(Vertical.ToString().ToLower()) 25 | .AddClass(Horizontal.ToString().ToLower()) 26 | .AddClassFromAttributes(AdditionalAttributes); 27 | } 28 | 29 |
30 | @ChildContent 31 |
-------------------------------------------------------------------------------- /BeerCss.Blazor/Components/Toolbar.razor: -------------------------------------------------------------------------------- 1 | @code { 2 | [Parameter] 3 | public bool Docked { get; set; } 4 | 5 | [Parameter] 6 | public bool Floating { get; set; } 7 | 8 | [Parameter, EditorRequired] 9 | public required RenderFragment ChildContent { get; set; } 10 | 11 | [Parameter(CaptureUnmatchedValues = true)] 12 | public IReadOnlyDictionary AdditionalAttributes { get; set; } = new Dictionary(); 13 | 14 | private CssBuilder CssClass => new CssBuilder() 15 | .AddClass("toolbar") 16 | .AddClass("max", Docked) 17 | .AddClassFromAttributes(AdditionalAttributes); 18 | } 19 | 20 | @if (Floating) 21 | { 22 | 23 | 28 | 29 | } 30 | else 31 | { 32 | 35 | } -------------------------------------------------------------------------------- /BeerCss.Blazor.Stories/Stories/Buttons/Split.stories.razor: -------------------------------------------------------------------------------- 1 | @using BeerCss.Blazor.Components.Buttons; 2 | @attribute [Stories("Components/Buttons/Split")] 3 | 4 | 5 | 6 | 7 | 8 | 25 | 26 | -------------------------------------------------------------------------------- /BeerCss.Blazor/Components/SnackbarProvider.razor: -------------------------------------------------------------------------------- 1 | @code { 2 | [Parameter] 3 | public RenderFragment? ChildContent { get; set; } 4 | 5 | public async Task AddSnackbar(Snackbar snackbar) 6 | { 7 | Snackbars.Add(snackbar); 8 | await InvokeAsync(StateHasChanged); 9 | await Task.Delay(snackbar.Timeout); 10 | await snackbar.Close(); 11 | await InvokeAsync(StateHasChanged); 12 | } 13 | 14 | public async Task RemoveSnackbar(Snackbar snackbar) 15 | => await this.InvokeAsync(() => Snackbars.Remove(snackbar)); 16 | 17 | private List Snackbars { get; } = new(); 18 | } 19 | 20 | @foreach (var snackbar in Snackbars) 21 | { 22 |
23 | @if (snackbar.Actions is null) 24 | { 25 | @snackbar.ChildContent 26 | } 27 | else 28 | { 29 |
@snackbar.ChildContent
30 | @snackbar.Actions 31 | } 32 |
33 | } 34 | 35 | 36 | @ChildContent 37 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2025 James Dibble 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /BeerCss.Blazor/Components/Beer.razor: -------------------------------------------------------------------------------- 1 | @code { 2 | [Parameter, EditorRequired] 3 | public required RenderFragment ChildContent { get; init; } 4 | 5 | [Parameter] 6 | public RenderFragment? NavBar { get; set; } 7 | 8 | [Parameter] 9 | public RenderFragment? AppBar { get; set; } 10 | 11 | [Parameter] 12 | public bool Responsive { get; set; } 13 | 14 | [Parameter] 15 | public bool NoPadding { get; set; } 16 | 17 | [Parameter] 18 | public bool Max { get; set; } 19 | 20 | [Parameter] 21 | public BeerTheme Theme { get; set; } = BeerTheme.Light; 22 | 23 | private CssBuilder CssClass => new CssBuilder() 24 | .AddClass("responsive", Responsive) 25 | .AddClass("max", Max) 26 | .AddClass("no-padding", NoPadding); 27 | } 28 | 29 | 30 | 33 | 34 | 35 | 36 |
37 | @NavBar 38 | @AppBar 39 |
40 | @ChildContent 41 |
42 |
43 |
-------------------------------------------------------------------------------- /BeerCss.Blazor.Stories/Stories/Buttons/Button.stories.razor: -------------------------------------------------------------------------------- 1 | @using BeerCss.Blazor.Components.Buttons; 2 | @attribute [Stories("Components/Buttons/Button")] 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 16 | 17 | 18 | 19 | 20 | 21 | 24 | 25 | 26 | 27 | @code 28 | { 29 | RenderFragment _childContent = @I am button; 30 | } -------------------------------------------------------------------------------- /BeerCss.Blazor/Components/Tooltip.razor: -------------------------------------------------------------------------------- 1 | @code { 2 | [Parameter, EditorRequired] 3 | public RenderFragment ChildContent { get; set; } 4 | 5 | [Parameter, EditorRequired] 6 | public RenderFragment Text { get; set; } 7 | 8 | [Parameter] 9 | public Space Space { get; set; } 10 | 11 | [Parameter] 12 | public Direction Direction { get; set; } = Direction.Top; 13 | 14 | [Parameter] 15 | public bool Max { get; set; } 16 | 17 | [Parameter(CaptureUnmatchedValues = true)] 18 | public IReadOnlyDictionary AdditionalAttributes { get; set; } = new Dictionary(); 19 | 20 | private CssBuilder ButtonCssClass => new CssBuilder() 21 | .AddClass("chip circle") 22 | .AddClassFromAttributes(AdditionalAttributes); 23 | 24 | private CssBuilder ToolipCssClass => new CssBuilder() 25 | .AddClass("tooltip") 26 | .AddClass("max", Max) 27 | .AddClass(Direction.ToCssClass()) 28 | .AddClass(Space.ToCssClass()); 29 | } 30 | 31 | -------------------------------------------------------------------------------- /BeerCss.Blazor/Components/Dialogs/DialogProvider.razor: -------------------------------------------------------------------------------- 1 | @code { 2 | [Parameter] 3 | public RenderFragment? ChildContent { get; set; } 4 | 5 | public async Task AddDialog(Dialog dialog) 6 | { 7 | Dialogs.Add(dialog); 8 | await InvokeAsync(StateHasChanged); 9 | } 10 | 11 | public async Task RemoveDialog(Dialog dialog) 12 | { 13 | Dialogs.Remove(dialog); 14 | await InvokeAsync(StateHasChanged); 15 | } 16 | 17 | private List Dialogs { get; } = new(); 18 | } 19 | 20 | @if (Dialogs.Any()) 21 | { 22 |
23 | } 24 | 25 | @foreach (var dialog in Dialogs) 26 | { 27 | 28 | @if (dialog is IHaveTitle title) 29 | { 30 |
@title.Title
31 | } 32 |
@dialog.Content
33 | @if (dialog is IHaveNav nav) 34 | { 35 | 38 | } 39 |
40 | } 41 | 42 | 43 | @ChildContent 44 | -------------------------------------------------------------------------------- /BeerCss.Blazor.Stories/Stories/Chip.stories.razor: -------------------------------------------------------------------------------- 1 | @attribute [Stories("Components/Chip")] 2 | 3 | 4 | 5 | 6 | 7 | 8 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 29 | 30 | 31 | 32 | @code 33 | { 34 | RenderFragment _childContent = @Input; 35 | string _suffix = "close"; 36 | string _prefix = "done"; 37 | } -------------------------------------------------------------------------------- /BeerCss.Blazor/Components/Tab.razor: -------------------------------------------------------------------------------- 1 | @code { 2 | [Parameter, EditorRequired] 3 | public required RenderFragment Title { get; set; } 4 | 5 | [Parameter, EditorRequired] 6 | public required RenderFragment Content { get; set; } 7 | 8 | [Parameter] 9 | public bool Active { get; set; } 10 | 11 | [CascadingParameter] 12 | public required Tabs Parent { get; set; } 13 | 14 | [Parameter(CaptureUnmatchedValues = true)] 15 | public IReadOnlyDictionary AdditionalAttributes { get; set; } = new Dictionary(); 16 | 17 | internal bool IsActive 18 | { 19 | get; 20 | set 21 | { 22 | field = value; 23 | StateHasChanged(); 24 | } 25 | } 26 | 27 | public CssBuilder CssClass => new CssBuilder() 28 | .AddClass("page") 29 | .AddClass(Parent.Direction.ToCssClass()) 30 | .AddClass("padding") 31 | .AddClass("active", IsActive) 32 | .AddClassFromAttributes(AdditionalAttributes); 33 | 34 | protected override async Task OnAfterRenderAsync(bool firstRender) 35 | { 36 | if (firstRender) 37 | { 38 | await Parent.AddTab(this); 39 | } 40 | } 41 | } -------------------------------------------------------------------------------- /BeerCss.Blazor.Stories/wwwroot/beer/dist/cdn/soft-burst.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /BeerCss.Blazor.Stories/BeerCss.Blazor.Stories.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net10.0 5 | enable 6 | enable 7 | True 8 | global::BlazingStory.Internals.Pages.MarkdownPageBase 9 | false 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | all 19 | runtime; build; native; contentfiles; analyzers 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /BeerCss.Blazor.Stories/Stories/Buttons/FAB.stories.razor: -------------------------------------------------------------------------------- 1 | @using BeerCss.Blazor.Components.Buttons; 2 | @attribute [Stories("Components/Buttons/FAB")] 3 | 4 | 5 | 6 | 11 | 12 | 13 | 21 | 22 | 23 | 24 | 25 | 26 | 33 | 34 | -------------------------------------------------------------------------------- /BeerCss.Blazor.Stories/wwwroot/iframe.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | BeerCss.Blazor.Stories 8 | 9 | 14 | 15 | 16 | 17 | 18 | 19 | 20 |
21 |
22 | 23 |
24 | An unhandled error has occurred. 25 | Reload 26 | 🗙 27 |
28 | 29 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /BeerCss.Blazor.Stories/wwwroot/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | BeerCss.Blazor 8 | 9 | 13 | 14 | 15 | 16 | 17 | 18 |
19 |
20 | 21 | 22 | 23 | 24 |
25 | 26 |
27 |
28 | 29 |
30 | An unhandled error has occurred. 31 | Reload 32 | 🗙 33 |
34 | 35 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /BeerCss.Blazor/Components/AppBar.razor: -------------------------------------------------------------------------------- 1 | @using Microsoft.AspNetCore.Components.Routing 2 | @inject NavigationManager Navigation 3 | @code { 4 | [Parameter(CaptureUnmatchedValues = true)] 5 | public IReadOnlyDictionary AdditionalAttributes { get; set; } = new Dictionary(); 6 | 7 | [Parameter] 8 | public string? Headline { get; set; } 9 | 10 | [Parameter] 11 | public string? BackUri { get; set; } 12 | 13 | [Parameter] 14 | public string? IconUri { get; set; } 15 | 16 | private CssBuilder CssClass => new CssBuilder() 17 | .AddClass("primary-container") 18 | .AddClassFromAttributes(AdditionalAttributes); 19 | } 20 | 21 |
22 | 46 |
-------------------------------------------------------------------------------- /BeerCss.Blazor/Components/Stepper.razor: -------------------------------------------------------------------------------- 1 | @code { 2 | [Parameter] 3 | public Color Color { get; set; } 4 | 5 | [Parameter] 6 | public Orientation Orientation { get; set; } 7 | 8 | [Parameter, EditorRequired] 9 | public required Step[] Steps { get; set; } 10 | 11 | [Parameter, EditorRequired] 12 | public EventCallback OnStepSelected { get; set; } 13 | 14 | public record Step(int Index, string? Title, bool Disabled, bool Complete); 15 | } 16 | 17 | -------------------------------------------------------------------------------- /BeerCss.Blazor/Components/Snackbar.razor: -------------------------------------------------------------------------------- 1 | @code { 2 | [Parameter] 3 | public TimeSpan Timeout { get; set; } = TimeSpan.FromSeconds(10); 4 | 5 | [Parameter, EditorRequired] 6 | public required RenderFragment ChildContent { get; set; } 7 | 8 | [Parameter] 9 | public Color Color { get; set; } = Color.Default; 10 | 11 | [Parameter] 12 | public RenderFragment? Actions { get; set; } 13 | 14 | [CascadingParameter] 15 | public SnackbarProvider? Provider { get; set; } 16 | 17 | private bool IsOpen { get; set; } = true; 18 | 19 | public async Task Close() 20 | { 21 | await this.InvokeAsync(() => this.IsOpen = false); 22 | await Task.Delay(TimeSpan.FromSeconds(1)); 23 | await (Provider?.RemoveSnackbar(this) ?? Task.CompletedTask); 24 | } 25 | 26 | public CssBuilder CssClass => new CssBuilder() 27 | .AddClass("active", IsOpen) 28 | .AddClass("snackbar") 29 | .AddClass(Color.ToCssClass()); 30 | 31 | protected async override Task OnAfterRenderAsync(bool isFirstRender) 32 | { 33 | Console.WriteLine("Making a snack"); 34 | 35 | if (Provider is null) 36 | { 37 | throw new InvalidOperationException("Dialog used without a parent DialogProvider"); 38 | } 39 | 40 | await (Provider?.AddSnackbar(this) ?? Task.CompletedTask); 41 | if (isFirstRender) 42 | { 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /BeerCss.Blazor.Stories/Stories/Shape.stories.razor: -------------------------------------------------------------------------------- 1 | @attribute [Stories("Components/Shapes")] 2 | 3 | 4 | 5 | 6 | 7 | 8 | 21 | 22 | -------------------------------------------------------------------------------- /.github/workflows/demo.yml: -------------------------------------------------------------------------------- 1 | name: Deploy to GitHub Pages 2 | 3 | on: 4 | workflow_dispatch: 5 | push: 6 | branches: [main] 7 | tags: "*" 8 | pull_request: 9 | branches: [main] 10 | 11 | permissions: 12 | contents: write 13 | 14 | jobs: 15 | deploy-to-github-pages: 16 | runs-on: ubuntu-latest 17 | defaults: 18 | run: 19 | working-directory: BeerCss.Blazor.Stories 20 | steps: 21 | - uses: actions/checkout@v2 22 | - name: Setup .NET Core SDK 23 | uses: actions/setup-dotnet@v1 24 | with: 25 | dotnet-version: 10.0.x 26 | - name: Restore dependencies 27 | run: dotnet restore 28 | - name: Publish .NET Core Project 29 | run: dotnet publish BeerCss.Blazor.Stories.csproj -c Release -o publish --nologo --no-restore 30 | - name: Update for GH Pages 31 | run: | 32 | sed -i 's///g' publish/wwwroot/index.html 33 | sed -i 's///g' publish/wwwroot/iframe.html 34 | cp publish/wwwroot/index.html publish/wwwroot/404.html 35 | touch publish/wwwroot/.nojekyll 36 | - name: Publish to GitHub Pages 37 | uses: JamesIves/github-pages-deploy-action@v4.2.2 38 | if: ${{ github.ref == 'refs/heads/main' }} 39 | with: 40 | branch: gh-pages 41 | folder: BeerCss.Blazor.Stories/publish/wwwroot 42 | -------------------------------------------------------------------------------- /BeerCss.Blazor/Components/Dialogs/Dialog.cs: -------------------------------------------------------------------------------- 1 | namespace BeerCss.Blazor.Components.Dialogs; 2 | 3 | using BlazorComponentUtilities; 4 | using Microsoft.AspNetCore.Components; 5 | 6 | public abstract class Dialog : ComponentBase 7 | { 8 | private bool isOpen; 9 | 10 | [Parameter, EditorRequired] 11 | public required RenderFragment Content { get; set; } 12 | 13 | [Parameter] 14 | public bool Open { get; set; } 15 | 16 | [Parameter(CaptureUnmatchedValues = true)] 17 | public IReadOnlyDictionary AdditionalAttributes { get; set; } = new Dictionary(); 18 | 19 | public virtual CssBuilder CssClass => new CssBuilder() 20 | .AddClass("active", this.Open) 21 | .AddClassFromAttributes(this.AdditionalAttributes); 22 | 23 | [CascadingParameter] 24 | public DialogProvider? Provider { get; set; } 25 | 26 | protected override async Task OnParametersSetAsync() 27 | { 28 | if (this.Provider is null) 29 | { 30 | throw new InvalidOperationException("Dialog used without a parent DialogProvider"); 31 | } 32 | 33 | if (this.Open && this.isOpen != this.Open) 34 | { 35 | this.isOpen = true; 36 | await this.Provider.AddDialog(this); 37 | } 38 | else if (!this.Open && this.isOpen != this.Open) 39 | { 40 | this.isOpen = false; 41 | await this.Provider.RemoveDialog(this); 42 | } 43 | } 44 | } -------------------------------------------------------------------------------- /.github/workflows/nuget.yml: -------------------------------------------------------------------------------- 1 | name: Nuget 2 | 3 | on: 4 | workflow_dispatch: 5 | push: 6 | branches: [main] 7 | tags: "*" 8 | paths: BeerCss.Blazor/** 9 | pull_request: 10 | branches: [main] 11 | paths: BeerCss.Blazor/** 12 | 13 | jobs: 14 | build: 15 | runs-on: ubuntu-latest 16 | defaults: 17 | run: 18 | working-directory: BeerCss.Blazor 19 | steps: 20 | - uses: actions/checkout@v2 21 | - name: Get the version 22 | id: tag 23 | run: | 24 | echo "ref: $GITHUB_REF" 25 | echo "tag: ${GITHUB_REF/refs\/tags\//}" 26 | version=$([[ "$GITHUB_REF" == *"refs/tags/"* ]] && echo ${GITHUB_REF/refs\/tags\//} || echo "1.0.0") 27 | echo $version 28 | echo ::set-output name=VERSION::$version 29 | - name: Setup .NET 30 | uses: actions/setup-dotnet@v1 31 | with: 32 | dotnet-version: 10.0.x 33 | - name: Restore dependencies 34 | run: dotnet restore 35 | - name: Pack 36 | run: dotnet pack --no-restore -c release --include-symbols /p:SymbolPackageFormat=snupkg /p:AssemblyVersion=1.0.0.0 /p:Version=${{ steps.tag.outputs.VERSION }} 37 | - name: Push 38 | if: github.ref_type == 'tag' 39 | env: 40 | NUGET_API_KEY: ${{ secrets.NUGET_API_KEY }} 41 | VERSION: ${{ steps.tag.outputs.VERSION }} 42 | run: dotnet nuget push "**/BeerCss.Blazor.$VERSION.nupkg" -s https://api.nuget.org/v3/index.json -k "$NUGET_API_KEY" 43 | -------------------------------------------------------------------------------- /BeerCss.Blazor.Stories/Stories/Dialogs/Modal.stories.razor: -------------------------------------------------------------------------------- 1 | @using BeerCss.Blazor.Components.Dialogs 2 | @attribute [Stories("Components/Dialogs/Modal")] 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 31 | 32 | 33 | 34 | @code { 35 | bool _open = true; 36 | bool _fullScreen = true; 37 | RenderFragment _title = @I am title; 38 | RenderFragment _content = @I am dialog content; 39 | RenderFragment _nav = @; 40 | } -------------------------------------------------------------------------------- /BeerCss.Blazor.Stories/Stories/Tabs.stories.razor: -------------------------------------------------------------------------------- 1 | @attribute [Stories("Components/Tabs")] 2 | 3 | 4 | 5 | 21 | 22 | 23 | 39 | 40 | -------------------------------------------------------------------------------- /BeerCss.Blazor.Stories/Stories/Navigation.stories.razor: -------------------------------------------------------------------------------- 1 | @attribute [Stories("Components/Navigations")] 2 | 3 | 4 | 5 | 34 | 35 | -------------------------------------------------------------------------------- /BeerCss.Blazor/BeerCss.Blazor.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net10.0 5 | enable 6 | enable 7 | false 8 | True 9 | CS1591 10 | BeerCss.Blazor 11 | logo.png 12 | James Dibble 13 | https://github.com/dibble-james/beercss-blazor 14 | blazor MUI3 components 15 | https://dibble-james.github.io/beercss-blazor/ 16 | README.md 17 | LICENSE 18 | A Material UI 3 Blazor component library based on the Beer CSS library 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # BeerCss.Blazor 2 | 3 | Here we have a Blazor wrapper for the amazing [BeerCSS](https://www.beercss.com/) Material UI CSS library. 4 | 5 | Source is available on [Github](https://github.com/dibble-james/beercss-blazor) 6 | 7 | ## Installation 8 | Grab the package from Nuget [![NuGet Version](https://img.shields.io/nuget/v/BeerCss.Blazor)](https://www.nuget.org/packages/BeerCss.Blazor) 9 | 10 | Install the BeerCss CSS & Javascript files into your app in your favourite style (CDN, libman etc...) 11 | 12 | Soak your app with beer (AKA add the namespace your your `_Imports.razor` and the root component to your `_MainLayout.razor`) 13 | 14 | ```razor 15 | @using BeerCss.Blazor.Components 16 | @using BeerCss.Blazor.Common 17 | ``` 18 | 19 | ```razor 20 | @inherits LayoutComponentBase 21 | 22 | @Body 23 | 24 | ``` 25 | 26 | Check out [the docs](https://dibble-james.github.io/beercss-blazor/) for the available components. 27 | 28 | ## Components 29 | - [x] Appbar 30 | - [x] Buttons 31 | - [x] FAB 32 | - [x] Standard 33 | - [x] Group 34 | - [x] Split 35 | - [x] Card 36 | - [x] Chip 37 | - [x] Container 38 | - [x] Dialogs 39 | - [x] Divider 40 | - [x] Expansion 41 | - [x] Grid 42 | - [x] Inputs 43 | - [x] Layout 44 | - [x] List 45 | - [x] Menu 46 | - [x] Navigation 47 | - [x] Page 48 | - [x] Progress 49 | - [x] Scroll 50 | - [x] Search 51 | - [x] Shapes 52 | - [ ] Shape components 53 | - [x] Snackbar 54 | - [x] Space 55 | - [x] Stepper 56 | - [x] Table 57 | - [x] Tabs 58 | - [x] Toolbar 59 | - [x] Tooltip 60 | - [x] Waves 61 | - [ ] Wave components -------------------------------------------------------------------------------- /BeerCss.Blazor.Stories/Stories/Inputs/NumberField.stories.razor: -------------------------------------------------------------------------------- 1 | @using BeerCss.Blazor.Components.Inputs 2 | @attribute [Stories("Components/Inputs/Number")] 3 | 4 | 5 | 6 | 7 | 8 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 24 | 25 | 26 | 27 | 32 | 33 | 34 | 35 | @code { 36 | int _value = 10; 37 | int _invalidValue = 100; 38 | string _helpText = "Help me!"; 39 | EditContext? _editContext; 40 | 41 | protected override void OnInitialized() 42 | { 43 | _editContext = new EditContext(_invalidValue!); 44 | var messageStore = new ValidationMessageStore(_editContext); 45 | messageStore.Add(() => _invalidValue!, "You ain't valid son"); 46 | } 47 | } -------------------------------------------------------------------------------- /BeerCss.Blazor.Stories/Stories/Inputs/TextArea.stories.razor: -------------------------------------------------------------------------------- 1 | @using BeerCss.Blazor.Components.Inputs 2 | @attribute [Stories("Components/Inputs/TextArea")] 3 | 4 | 5 | 6 | 7 | 8 |