diff --git a/.nvmrc b/.nvmrc new file mode 100644 index 0000000..020fc41 --- /dev/null +++ b/.nvmrc @@ -0,0 +1 @@ +v20.12.1 diff --git a/Directory.Packages.props b/Directory.Packages.props index 1ddf323..2045462 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -38,6 +38,7 @@ + diff --git a/css.sh b/css.sh index 40a0bbd..1c0c078 100755 --- a/css.sh +++ b/css.sh @@ -1,4 +1,6 @@ #!/bin/bash # file: css.sh - -./tailwindcss-macos-arm64 -c src/Pure.Blazor.Components/tailwind.config.js -i src/Pure.Blazor.Components/wwwroot/app.css -o src/Pure.Blazor.Components/wwwroot/pureblazor.css +source ~/.zshrc +nvm use +npm install tailwindcss@next @tailwindcss/vite@next +npx @tailwindcss/cli@next -i src/Pure.Blazor.Components/tailwind.css -o src/Pure.Blazor.Components/wwwroot/pureblazor.css --watch \ No newline at end of file diff --git a/src/Pure.Blazor.Components.AspNetCore/HostApplicationBuilderExtensions.cs b/src/Pure.Blazor.Components.AspNetCore/HostApplicationBuilderExtensions.cs index 6ffc000..b42d734 100644 --- a/src/Pure.Blazor.Components.AspNetCore/HostApplicationBuilderExtensions.cs +++ b/src/Pure.Blazor.Components.AspNetCore/HostApplicationBuilderExtensions.cs @@ -1,14 +1,18 @@ -using Microsoft.Extensions.DependencyInjection; +using Microsoft.AspNetCore.Components; +using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; +using Pure.Blazor.Components.Buttons; using Pure.Blazor.Components.Common; using Pure.Blazor.Components.Dialogs; using Pure.Blazor.Components.Feedback; +using Pure.Blazor.Components.Primitives; namespace Pure.Blazor.Components.AspNetCore; public static class HostApplicationBuilderExtensions { - public static IHostApplicationBuilder AddPureBlazorComponents(this IHostApplicationBuilder builder) + public static IHostApplicationBuilder AddPureBlazorComponents(this IHostApplicationBuilder builder, + IPureTheme? theme = null) { // javascript builder.Services.AddScoped(); @@ -17,6 +21,13 @@ public static IHostApplicationBuilder AddPureBlazorComponents(this IHostApplicat builder.Services.AddScoped(); builder.Services.AddScoped(); + builder.Services.AddCascadingValue(sp => + { + theme ??= new DefaultTheme(); + var source = new CascadingValueSource(theme, isFixed: true); + return source; + }); + return builder; } } diff --git a/src/Pure.Blazor.Components.Icons/Pure.Blazor.Components.Icons.csproj b/src/Pure.Blazor.Components.Icons/Pure.Blazor.Components.Icons.csproj new file mode 100644 index 0000000..0d5e915 --- /dev/null +++ b/src/Pure.Blazor.Components.Icons/Pure.Blazor.Components.Icons.csproj @@ -0,0 +1,30 @@ + + + + net8.0 + preview + enable + enable + Nullable + True + PureBlazor Icons + 0.21 + PureBlazor.Components.Icons + Blazor Icons + https://pureblazor.com + https://github.com/pureblazor/components + blazor, icons, maui, ssr, wasm, tailwind, tailwindcss, heroicons, pureblazor + True + snupkg + Component Library Updates + MIT + PureBlazor + codymullins + Copyright 2024 PureBlazor + + + + + + + diff --git a/src/Pure.Blazor.Components/Icons/PureIcon.cs b/src/Pure.Blazor.Components.Icons/PureIcon.cs similarity index 99% rename from src/Pure.Blazor.Components/Icons/PureIcon.cs rename to src/Pure.Blazor.Components.Icons/PureIcon.cs index 4b86c76..fb99d62 100644 --- a/src/Pure.Blazor.Components/Icons/PureIcon.cs +++ b/src/Pure.Blazor.Components.Icons/PureIcon.cs @@ -1,6 +1,6 @@ -using Microsoft.AspNetCore.Components; +using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components.Rendering; -using Pure.Blazor.Components.Common; +using Pure.Blazor.Components.Primitives; namespace Pure.Blazor.Components.Icons; diff --git a/src/Pure.Blazor.Components/Icons/PureIcons.cs b/src/Pure.Blazor.Components.Icons/PureIcons.cs similarity index 93% rename from src/Pure.Blazor.Components/Icons/PureIcons.cs rename to src/Pure.Blazor.Components.Icons/PureIcons.cs index 54093cb..5da02d7 100644 --- a/src/Pure.Blazor.Components/Icons/PureIcons.cs +++ b/src/Pure.Blazor.Components.Icons/PureIcons.cs @@ -2,7 +2,7 @@ namespace Pure.Blazor.Components.Icons; public enum PureIcons { - IconCheck, + IconNone, IconSpin, IconOpenCircle, IconChevronDoubleLeft, @@ -39,5 +39,6 @@ public enum PureIcons IconCheckCircle, IconFile, IconFolder, - IconFolderOpen + IconFolderOpen, + IconCheck } diff --git a/src/Pure.Blazor.Components/Common/Accent.cs b/src/Pure.Blazor.Components.Primitives/Accent.cs similarity index 64% rename from src/Pure.Blazor.Components/Common/Accent.cs rename to src/Pure.Blazor.Components.Primitives/Accent.cs index 29378a0..eba407e 100644 --- a/src/Pure.Blazor.Components/Common/Accent.cs +++ b/src/Pure.Blazor.Components.Primitives/Accent.cs @@ -1,4 +1,4 @@ -namespace Pure.Blazor.Components.Common; +namespace Pure.Blazor.Components.Primitives; public enum Accent { @@ -7,4 +7,4 @@ public enum Accent Success, Danger, Warning, -} +} \ No newline at end of file diff --git a/src/Pure.Blazor.Components.Primitives/ButtonDefaults.cs b/src/Pure.Blazor.Components.Primitives/ButtonDefaults.cs new file mode 100644 index 0000000..eb8e074 --- /dev/null +++ b/src/Pure.Blazor.Components.Primitives/ButtonDefaults.cs @@ -0,0 +1,7 @@ +namespace Pure.Blazor.Components.Primitives; + +public class ButtonDefaults +{ + public Effect PressEffect { get; set; } + public Effect HoverEffect { get; set; } +} \ No newline at end of file diff --git a/src/Pure.Blazor.Components.Primitives/ComponentStyle.cs b/src/Pure.Blazor.Components.Primitives/ComponentStyle.cs new file mode 100644 index 0000000..032bb8a --- /dev/null +++ b/src/Pure.Blazor.Components.Primitives/ComponentStyle.cs @@ -0,0 +1,56 @@ +namespace Pure.Blazor.Components.Primitives; + +public class ComponentStyle +{ + private readonly IReadOnlyDictionary accents; + private readonly IReadOnlyDictionary> variants; + private readonly IReadOnlyDictionary sizes; + + public ComponentStyle(string baseStyle, + IReadOnlyDictionary? accents, + IReadOnlyDictionary>? variants, + IReadOnlyDictionary? sizes) + { + this.accents = accents ?? new Dictionary(); + this.variants = variants ?? new Dictionary>(); + this.sizes = sizes ?? new Dictionary(); + Base = baseStyle; + } + + /// + /// Basic style applied to the outer container of the component. + /// + public string Base { get; set; } + + /// + /// Optional advanced style for the outer container of the component. + /// Not all components with an outer container have this, only if the outer container requires Accent or Variant + /// modifications. + /// + public ComponentStyle? OuterContainer { get; set; } + + /// + /// Optional advanced style for the inner container of the component. Not all components have an inner container. + /// + public ComponentStyle? InnerContainer { get; set; } + + public string Accent(Accent accent) + { + return accents.TryGetValue(accent, out var value) ? value : string.Empty; + } + + public string Variant(PureVariant variant, Accent accent) + { + if (variants.TryGetValue(variant, out var value) && value.TryGetValue(accent, out var style)) + { + return style; + } + + return string.Empty; // or return a default style + } + + public string Size(PureSize size) + { + return sizes.TryGetValue(size, out var value) ? value : string.Empty; + } +} \ No newline at end of file diff --git a/src/Pure.Blazor.Components.Primitives/Effect.cs b/src/Pure.Blazor.Components.Primitives/Effect.cs new file mode 100644 index 0000000..19e1062 --- /dev/null +++ b/src/Pure.Blazor.Components.Primitives/Effect.cs @@ -0,0 +1,33 @@ +namespace Pure.Blazor.Components.Primitives; + +/// +/// Animation effects that can be applied to any component that supports it. +/// +public enum Effect +{ + /// + /// Unset effect. Default values will be inherited from ancestors. + /// + Unset, + + /// + /// Explicitly indicates no effect. + /// + None, + + // what's the best name here? + Jiggle, + + /// + /// Fade in and out effect. + /// + Pulse, + + /// + /// + /// + Ping + + // TODO: https://github.com/pureblazor/components/issues/57 + //Ripple, +} \ No newline at end of file diff --git a/src/Pure.Blazor.Components.Primitives/IPureTheme.cs b/src/Pure.Blazor.Components.Primitives/IPureTheme.cs new file mode 100644 index 0000000..6715625 --- /dev/null +++ b/src/Pure.Blazor.Components.Primitives/IPureTheme.cs @@ -0,0 +1,19 @@ +namespace Pure.Blazor.Components.Primitives; + +public interface IPureTheme +{ + public ButtonDefaults ButtonDefaults { get; set; } + public IStylePrioritizer StylePrioritizer { get; set; } + public Dictionary Styles { get; set; } + + public ComponentStyle GetStyle(Type type) + { + return GetStyleByName(type.Name); + } + + public ComponentStyle GetStyleByName(string name) + { + // TODO: decide if we want this to be an exceptional event + return Styles.GetValueOrDefault(name) ?? new ComponentStyle("", null, null, null); + } +} diff --git a/src/Pure.Blazor.Components.Primitives/IStylePrioritizer.cs b/src/Pure.Blazor.Components.Primitives/IStylePrioritizer.cs new file mode 100644 index 0000000..723058b --- /dev/null +++ b/src/Pure.Blazor.Components.Primitives/IStylePrioritizer.cs @@ -0,0 +1,6 @@ +namespace Pure.Blazor.Components.Primitives; + +public interface IStylePrioritizer +{ + public string PrioritizeStyles(string style1, string style2); +} \ No newline at end of file diff --git a/src/Pure.Blazor.Components.Primitives/Pure.Blazor.Components.Primitives.csproj b/src/Pure.Blazor.Components.Primitives/Pure.Blazor.Components.Primitives.csproj new file mode 100644 index 0000000..5f89abb --- /dev/null +++ b/src/Pure.Blazor.Components.Primitives/Pure.Blazor.Components.Primitives.csproj @@ -0,0 +1,30 @@ + + + + net8.0 + preview + enable + enable + Nullable + True + PureBlazor Icons + 0.21 + PureBlazor.Components.Primitives + PureBlazor.Components.Primitives + https://pureblazor.com + https://github.com/pureblazor/components + blazor, icons, maui, ssr, wasm, tailwind, tailwindcss, heroicons, pureblazor + True + snupkg + Component Library Updates + MIT + PureBlazor + codymullins + Copyright 2024 PureBlazor + + + + + + + diff --git a/src/Pure.Blazor.Components.Primitives/PureAlign.cs b/src/Pure.Blazor.Components.Primitives/PureAlign.cs new file mode 100644 index 0000000..0bdaf81 --- /dev/null +++ b/src/Pure.Blazor.Components.Primitives/PureAlign.cs @@ -0,0 +1,8 @@ +namespace Pure.Blazor.Components.Primitives; + +public enum PureAlign +{ + Start, + Center, + End +} \ No newline at end of file diff --git a/src/Pure.Blazor.Components/Common/PureAnimate.cs b/src/Pure.Blazor.Components.Primitives/PureAnimate.cs similarity index 56% rename from src/Pure.Blazor.Components/Common/PureAnimate.cs rename to src/Pure.Blazor.Components.Primitives/PureAnimate.cs index 887d5ed..ce37a45 100644 --- a/src/Pure.Blazor.Components/Common/PureAnimate.cs +++ b/src/Pure.Blazor.Components.Primitives/PureAnimate.cs @@ -1,8 +1,8 @@ -namespace Pure.Blazor.Components.Common; +namespace Pure.Blazor.Components.Primitives; public enum PureAnimate { None, Default, Spin -} +} \ No newline at end of file diff --git a/src/Pure.Blazor.Components/Common/PureComponent.cs b/src/Pure.Blazor.Components.Primitives/PureComponent.cs similarity index 75% rename from src/Pure.Blazor.Components/Common/PureComponent.cs rename to src/Pure.Blazor.Components.Primitives/PureComponent.cs index 1118d88..99f8229 100644 --- a/src/Pure.Blazor.Components/Common/PureComponent.cs +++ b/src/Pure.Blazor.Components.Primitives/PureComponent.cs @@ -1,7 +1,6 @@ -using Microsoft.AspNetCore.Components; -using Pure.Blazor.Components.Buttons; +using Microsoft.AspNetCore.Components; -namespace Pure.Blazor.Components.Common; +namespace Pure.Blazor.Components.Primitives; public class PureComponent : ComponentBase { @@ -11,8 +10,6 @@ protected override void OnParametersSet() BuildCss(); } - [CascadingParameter] public ThemeProvider? ThemeProvider { get; set; } = new(); - /// /// Add additional css classes to this component /// @@ -29,7 +26,7 @@ protected override void OnParametersSet() /// The current theme styles /// [CascadingParameter] - public PureTheme PureTheme { get; set; } = new(); + public required IPureTheme PureTheme { get; set; } [Parameter] public RenderFragment? ChildContent { get; set; } @@ -45,6 +42,13 @@ protected virtual void BuildCss() { } + /// + /// Gets the component style from the theme for the specific type of component. + /// + protected ComponentStyle Css => PureTheme.GetStyle(GetType()); + + protected ComponentStyle CssStyle(string name) => PureTheme.GetStyleByName(name); + /// /// Applies the style based on the theme settings. /// @@ -65,9 +69,9 @@ protected virtual string ApplyStyle(string? style) return Styles ?? ""; } - if (ThemeProvider?.StylePrioritizer != null && Styles != null) + if (PureTheme?.StylePrioritizer != null && Styles != null) { - return ThemeProvider.StylePrioritizer.PrioritizeStyles(style, Styles); + return PureTheme.StylePrioritizer.PrioritizeStyles(style, Styles); } return $"{style} {Styles}"; diff --git a/src/Pure.Blazor.Components.Primitives/PureSize.cs b/src/Pure.Blazor.Components.Primitives/PureSize.cs new file mode 100644 index 0000000..2effe32 --- /dev/null +++ b/src/Pure.Blazor.Components.Primitives/PureSize.cs @@ -0,0 +1,10 @@ +namespace Pure.Blazor.Components.Primitives; + +public enum PureSize +{ + ExtraSmall, + Small, + Medium, + Large, + ExtraLarge +} \ No newline at end of file diff --git a/src/Pure.Blazor.Components/Display/BadgeVariant.cs b/src/Pure.Blazor.Components.Primitives/PureVariant.cs similarity index 58% rename from src/Pure.Blazor.Components/Display/BadgeVariant.cs rename to src/Pure.Blazor.Components.Primitives/PureVariant.cs index 2e8c05d..467f681 100644 --- a/src/Pure.Blazor.Components/Display/BadgeVariant.cs +++ b/src/Pure.Blazor.Components.Primitives/PureVariant.cs @@ -1,8 +1,8 @@ -namespace Pure.Blazor.Components.Display; +namespace Pure.Blazor.Components.Primitives; public enum PureVariant { Default, Outline, Subtle -} +} \ No newline at end of file diff --git a/src/Pure.Blazor.Components.Primitives/RenderTreeBuilderExtensions.cs b/src/Pure.Blazor.Components.Primitives/RenderTreeBuilderExtensions.cs new file mode 100644 index 0000000..fe835ad --- /dev/null +++ b/src/Pure.Blazor.Components.Primitives/RenderTreeBuilderExtensions.cs @@ -0,0 +1,16 @@ +using System.Runtime.CompilerServices; +using Microsoft.AspNetCore.Components.Rendering; + +namespace Pure.Blazor.Components.Primitives; + +public static class RenderTreeBuilderExtensions +{ + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void AddAttributeIfNotNullOrEmpty(this RenderTreeBuilder builder, int sequence, string name, string? value) + { + if (!string.IsNullOrEmpty(value)) + { + builder.AddAttribute(sequence, name, value); + } + } +} diff --git a/src/Pure.Blazor.Components.Primitives/Theme.cs b/src/Pure.Blazor.Components.Primitives/Theme.cs new file mode 100644 index 0000000..4654030 --- /dev/null +++ b/src/Pure.Blazor.Components.Primitives/Theme.cs @@ -0,0 +1,8 @@ +namespace Pure.Blazor.Components.Primitives; + +public enum Theme +{ + Off, + On, + Auto +} \ No newline at end of file diff --git a/src/Pure.Blazor.Components/Buttons/ButtonProps.cs b/src/Pure.Blazor.Components/Buttons/ButtonProps.cs index 010dbce..1aa2e48 100644 --- a/src/Pure.Blazor.Components/Buttons/ButtonProps.cs +++ b/src/Pure.Blazor.Components/Buttons/ButtonProps.cs @@ -1,5 +1,6 @@ using Microsoft.AspNetCore.Components; using Pure.Blazor.Components.Common; +using Pure.Blazor.Components.Primitives; namespace Pure.Blazor.Components.Buttons; @@ -46,13 +47,6 @@ public interface IButtonProps public string Styles { get; set; } } -public enum ButtonVariant -{ - Default, - Outline, - Subtle -} - public enum TabVariant { Default, diff --git a/src/Pure.Blazor.Components/Buttons/ButtonStyles.cs b/src/Pure.Blazor.Components/Buttons/ButtonStyles.cs index 72cac51..e86f9b8 100644 --- a/src/Pure.Blazor.Components/Buttons/ButtonStyles.cs +++ b/src/Pure.Blazor.Components/Buttons/ButtonStyles.cs @@ -1,8 +1,8 @@ -using Pure.Blazor.Components.Common; +using Pure.Blazor.Components.Primitives; namespace Pure.Blazor.Components.Buttons; -public class ButtonStyles +internal class ButtonStyles { private const string ExtraSmallButton = "rounded px-1 py-0.5 text-xs font-normal"; private const string SmallButton = "px-3 py-2 text-xs"; @@ -40,7 +40,7 @@ public class ButtonStyles private const string SuccessSubtleButton = "border-transparent bg-transparent hover:bg-green-400/10 text-green-700 font-medium"; - public readonly Dictionary Sizes = new() + public static readonly Dictionary Sizes = new() { { PureSize.Large, LargeButton }, { PureSize.Small, SmallButton }, @@ -48,10 +48,10 @@ public class ButtonStyles { PureSize.ExtraSmall, ExtraSmallButton } }; - public readonly Dictionary> Variants = new() + public static readonly Dictionary> Variants = new() { { - ButtonVariant.Default, + PureVariant.Default, new Dictionary { { Accent.Brand, PrimaryButton }, @@ -62,7 +62,7 @@ public class ButtonStyles } }, { - ButtonVariant.Outline, + PureVariant.Outline, new Dictionary { { Accent.Brand, PrimaryOutlineButton }, @@ -73,7 +73,7 @@ public class ButtonStyles } }, { - ButtonVariant.Subtle, + PureVariant.Subtle, new Dictionary { { Accent.Brand, PrimarySubtleButton }, @@ -85,6 +85,6 @@ public class ButtonStyles } }; - public string Base => + public static string Base => "flex justify-center items-center cursor-pointer gap-1 rounded-sm md:rounded-xs text-sm focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-brand-900 border-1"; } diff --git a/src/Pure.Blazor.Components/Buttons/CustomTheme.cs b/src/Pure.Blazor.Components/Buttons/CustomTheme.cs deleted file mode 100644 index 196dd88..0000000 --- a/src/Pure.Blazor.Components/Buttons/CustomTheme.cs +++ /dev/null @@ -1,9 +0,0 @@ -using Pure.Blazor.Components.Common; - -namespace Pure.Blazor.Components.Buttons; - -public class CustomTheme : PureTheme -{ - public CustomTheme() => Button.Variants[ButtonVariant.Default][Accent.Brand] = - "bg-brand-200 hover:bg-brand-300 text-gray-700"; -} diff --git a/src/Pure.Blazor.Components/Buttons/DropdownMenuItemStyles.cs b/src/Pure.Blazor.Components/Buttons/DropdownMenuItemStyles.cs index b9aa09a..a21ada2 100644 --- a/src/Pure.Blazor.Components/Buttons/DropdownMenuItemStyles.cs +++ b/src/Pure.Blazor.Components/Buttons/DropdownMenuItemStyles.cs @@ -1,4 +1,4 @@ -using Pure.Blazor.Components.Common; +using Pure.Blazor.Components.Primitives; namespace Pure.Blazor.Components.Buttons; @@ -27,4 +27,4 @@ public class DropdownMenuItemStyles { PureSize.Medium, MediumMenuItem }, { PureSize.ExtraSmall, ExtraSmallMenuItem } }; -} \ No newline at end of file +} diff --git a/src/Pure.Blazor.Components/Buttons/DropdownStyles.cs b/src/Pure.Blazor.Components/Buttons/DropdownStyles.cs index 1cba206..985949c 100644 --- a/src/Pure.Blazor.Components/Buttons/DropdownStyles.cs +++ b/src/Pure.Blazor.Components/Buttons/DropdownStyles.cs @@ -1,4 +1,4 @@ -using Pure.Blazor.Components.Common; +using Pure.Blazor.Components.Primitives; namespace Pure.Blazor.Components.Buttons; @@ -9,13 +9,13 @@ public class DropdownStyles private const string MediumButton = "px-2 py-2 text-sm"; private const string LargeButton = "px-2 py-2 text-sm"; - public string Base { get; set; } = + public static string Base { get; set; } = "inline-flex gap-2 justify-center rounded-md font-semibold text-gray-700 border-1 border-gray-200 hover:border-gray-400 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-gray-300 group-focus-within/dropdown:rounded-b-none"; - public DropdownMenuContainerStyles Container { get; set; } = new(); - public DropdownMenuItemStyles MenuItem { get; set; } = new(); + public static DropdownMenuContainerStyles Container { get; set; } = new(); + public static DropdownMenuItemStyles MenuItem { get; set; } = new(); - public readonly Dictionary Sizes = new() + public static readonly Dictionary Sizes = new() { { PureSize.ExtraLarge, LargeButton }, { PureSize.Large, LargeButton }, @@ -23,4 +23,4 @@ public class DropdownStyles { PureSize.Medium, MediumButton }, { PureSize.ExtraSmall, ExtraSmallButton } }; -} \ No newline at end of file +} diff --git a/src/Pure.Blazor.Components/Buttons/LinkStyles.cs b/src/Pure.Blazor.Components/Buttons/LinkStyles.cs index 59a3ba7..6bfa18d 100644 --- a/src/Pure.Blazor.Components/Buttons/LinkStyles.cs +++ b/src/Pure.Blazor.Components/Buttons/LinkStyles.cs @@ -2,5 +2,5 @@ namespace Pure.Blazor.Components.Buttons; public class LinkStyles { - public string Base => "text-brand-800 hover:underline"; + public static string Base => "text-brand-800 hover:underline"; } diff --git a/src/Pure.Blazor.Components/Buttons/PureButton.cs b/src/Pure.Blazor.Components/Buttons/PureButton.cs new file mode 100644 index 0000000..d87b76e --- /dev/null +++ b/src/Pure.Blazor.Components/Buttons/PureButton.cs @@ -0,0 +1,137 @@ +using Microsoft.AspNetCore.Components; +using Microsoft.AspNetCore.Components.Rendering; +using Microsoft.AspNetCore.Components.Web; +using Pure.Blazor.Components.Icons; +using Pure.Blazor.Components.Primitives; + +namespace Pure.Blazor.Components.Buttons; + +public class PureButton : PureButtonBase +{ + private bool IsPressed { get; set; } + + [Parameter] public PureIcons? LeftIcon { get; set; } + [Parameter] public PureIcons? RightIcon { get; set; } + [Parameter] public Effect PressEffect { get; set; } + [Parameter] public Effect HoverEffect { get; set; } + + private void SetPressed(bool pressed) + { + IsPressed = pressed; + } + + protected override void BuildRenderTree(RenderTreeBuilder builder) + { + builder.OpenElement(0, "button"); + builder.AddAttributeIfNotNullOrEmpty(1, "id", Id); + builder.AddAttributeIfNotNullOrEmpty(2, "aria-label", Label); + + if (Disabled) + { + builder.AddAttribute(3, "disabled", "disabled"); + } + + builder.AddAttribute(4, "onclick", EventCallback.Factory.Create(this, OnClicked)); + if (PressEffect is not Effect.None || PureTheme.ButtonDefaults.PressEffect is not Effect.None) + { + builder.AddAttribute(5, "onmousedown", + EventCallback.Factory.Create(this, () => SetPressed(true))); + builder.AddAttribute(6, "onmouseup", + EventCallback.Factory.Create(this, () => SetPressed(false))); + } + + + var effect = HoverEffect; + if (effect is Effect.Unset) + { + effect = PureTheme.ButtonDefaults.HoverEffect; + } + + var hoverEffectCss = GetHoverEffect(effect); + var buttonType = ButtonType switch + { + ButtonType.Submit => "submit", + ButtonType.Button => "button", + _ => "" + }; + + var pressEffect = PressEffect; + if (pressEffect is Effect.Unset) + { + pressEffect = PureTheme.ButtonDefaults.PressEffect; + } + + var pressEffectCss = GetPressEffect(pressEffect, IsPressed); + + builder.AddAttributeIfNotNullOrEmpty(10, "type", buttonType); + builder.AddAttributeIfNotNullOrEmpty(11, "name", Name); + builder.AddAttributeIfNotNullOrEmpty(12, "title", Title); + builder.AddAttributeIfNotNullOrEmpty(13, "value", Value); + + builder.AddAttributeIfNotNullOrEmpty(14, "class", + $"{ApplyStyle(InternalCss)} {pressEffectCss} {hoverEffectCss}"); + if (StopPropagation) + { + builder.AddEventPreventDefaultAttribute(15, "onclick", true); + builder.AddEventStopPropagationAttribute(16, "onclick", true); + } + + if (LeftIcon is not null) + { + builder.OpenRegion(17); + builder.OpenComponent(1); + builder.AddAttribute(2, "Icon", LeftIcon); + builder.AddAttribute(3, "Size", Size); + builder.CloseComponent(); + builder.CloseRegion(); + } + + if (LoadingText is not null && Loading) + { + builder.AddContent(18, LoadingText); + } + else if (ChildContent is not null) + { + builder.AddContent(19, ChildContent); + } + else + { + builder.AddContent(20, Text); + } + + if (RightIcon is not null) + { + builder.OpenRegion(21); + builder.OpenComponent(1); + builder.AddAttribute(2, "Icon", RightIcon); + builder.AddAttribute(3, "Size", Size); + builder.CloseComponent(); + builder.CloseRegion(); + } + + builder.CloseElement(); + } + + private static string GetPressEffect(Effect effect, bool pressed) + { + return effect switch + { + Effect.Jiggle when pressed => "translate-y-px", + Effect.Jiggle => "translate-y-0", + Effect.Pulse when pressed => "animate-pulse", + Effect.Ping when pressed => "animate-ping", + _ => "" + }; + } + + private static string GetHoverEffect(Effect effect) + { + return effect switch + { + Effect.Jiggle => "hover:translate-y-px", + Effect.Pulse => "hover:animate-pulse", + Effect.Ping => "hover:animate-ping", + _ => "" + }; + } +} diff --git a/src/Pure.Blazor.Components/Buttons/PureButton.razor b/src/Pure.Blazor.Components/Buttons/PureButton.razor deleted file mode 100644 index ac90e28..0000000 --- a/src/Pure.Blazor.Components/Buttons/PureButton.razor +++ /dev/null @@ -1,61 +0,0 @@ -@inherits PureButtonBase - -@if (Loading) -{ - -} -else -{ - -} diff --git a/src/Pure.Blazor.Components/Buttons/PureButton.razor.cs b/src/Pure.Blazor.Components/Buttons/PureButton.razor.cs deleted file mode 100644 index 1405a6d..0000000 --- a/src/Pure.Blazor.Components/Buttons/PureButton.razor.cs +++ /dev/null @@ -1,11 +0,0 @@ -using Microsoft.AspNetCore.Components; -using Pure.Blazor.Components.Icons; - -namespace Pure.Blazor.Components.Buttons; - -public partial class PureButton -{ - [Parameter] public PureIcons? LeftIcon { get; set; } - - [Parameter] public PureIcons? RightIcon { get; set; } -} diff --git a/src/Pure.Blazor.Components/Buttons/PureButtonBase.cs b/src/Pure.Blazor.Components/Buttons/PureButtonBase.cs index 02004bf..cd5fda6 100644 --- a/src/Pure.Blazor.Components/Buttons/PureButtonBase.cs +++ b/src/Pure.Blazor.Components/Buttons/PureButtonBase.cs @@ -1,15 +1,16 @@ using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components.Web; -using Microsoft.Extensions.Logging; -using Pure.Blazor.Components.Common; +using Pure.Blazor.Components.Primitives; namespace Pure.Blazor.Components.Buttons; public class PureButtonBase : PureComponent { + [Parameter] + public string? Id { get; set; } [Parameter] public ButtonType ButtonType { get; set; } [Parameter] public PureSize Size { get; set; } = PureSize.Medium; - [Parameter] public ButtonVariant Variant { get; set; } = ButtonVariant.Default; + [Parameter] public PureVariant Variant { get; set; } = PureVariant.Default; [Parameter] public Accent Accent { get; set; } [Parameter] public string? Title { get; set; } [Parameter] public string? Name { get; set; } @@ -42,7 +43,7 @@ public class PureButtonBase : PureComponent [Parameter] public EventCallback OnClick { get; set; } - [Parameter] public bool PropagateClicks { get; set; } + [Parameter] public bool StopPropagation { get; set; } [Parameter] public bool Disabled { get; set; } protected string? InternalCss { get; set; } @@ -58,7 +59,6 @@ protected void OnClicked(MouseEventArgs e) protected override void BuildCss() { - InternalCss = ApplyStyle( - $"{PureTheme.Button.Base} {PureTheme.Button.Variants[Variant][Accent]} {PureTheme.Button.Sizes[Size]}"); + InternalCss = ApplyStyle($"{Css.Base} {Css.Variant(Variant, Accent)} {Css.Size(Size)}"); } } diff --git a/src/Pure.Blazor.Components/Buttons/PureDropdown.razor b/src/Pure.Blazor.Components/Buttons/PureDropdown.razor index dfd3148..662a9c7 100644 --- a/src/Pure.Blazor.Components/Buttons/PureDropdown.razor +++ b/src/Pure.Blazor.Components/Buttons/PureDropdown.razor @@ -2,14 +2,14 @@
-
-