BlazorでSkclusive-UIを使った話

GitHub Pagesで自分のポートフォリオサイト作りたいなと思い立ちましたが

* markdownで作るのはちょっと味気ない
* html書くのめんどくさいし、ReactとかVueとかはまだ使ったことない
* css書くのめんどくさい

という壁がありました。ReactやVueなどのフレームワークは身につけたいところではありますが、とりあえずは手っ取り早く作りたかったのでBlazorとUIフレームワークの一つであるSkclusive-UIで作って見ました。

この記事はUIフレームワークについての記事になります。

## 環境

* VisualStudio for Mac 2022 preview
* dotnet6

## Skclusive-UI

Github

* https://github.com/skclusive/Skclusive.Material.Component
* https://github.com/skclusive/Skclusive.Material.Layout

パーツだけ使いたいのであればComponentの方だけ使えばOKです（Button, MenuなどパーツごとにNugetパッケージになっているので部分的に利用することもできます）

今回は全部任せるつもりで、ComponentとLayoutの両方を使用しています。両方Ver.5.2.0です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2088399/7f67834a-04d4-da3c-6e7a-8021121b475a.png)

Docs

https://skclusive.github.io/Skclusive.Material.Docs/

このdocsの[ソース](https://github.com/skclusive/Skclusive.Material.Docs)を見ていれば大体できる気はします

### _import.razor

[docsのinstallation with nuget](https://skclusive.github.io/Skclusive.Material.Docs/installation)に書いてあることをすれば大丈夫ですが、[Migrating to 5.2.0 from 2.0.1](https://skclusive.github.io/Skclusive.Material.Docs/release)にあるように、`@using Skclusive.Material.Script`と`@using Skclusive.Material.Theme`を消しました。

それとは別で`@using Skclusive.Material.Link`を追加しています。`HyperLink`コンポーネント等を使うためです。

* https://github.com/sYamaz/website/blob/main/website/_Imports.razor

### MainLayout.razor

VisualStudioで新規Blazorプロジェクトと共に作成される`MainLayout.razor`は削除しています。（Skclusive.Material.Layoutで定義済みであるため）

### App.razor

`RouterLayout`を`ThemeProvider`で囲います。`Light`,`Dark`プロパティは定義しなくてもOKです。定義しない場合はデフォルトのライトテーマ、ダークテーマが割当たります。

* https://github.com/sYamaz/website/blob/main/website/App.razor

```html

@using Skclusive.Material.Theme
 
<ThemeProvider
               Light="@Light"
               Dark="@Dark">
    <RouterLayout Default="@typeof(AppLayout)"/>
</ThemeProvider>

@code{
    public static ThemeValue Light = ThemeFactory.CreateTheme(new ThemeConfig
    {
        Palette = new PaletteConfig
        {
            Type = PaletteType.Light,

            Primary = new PaletteColorConfig
            {
                Main = PaletteColors.Blue.X700
            },

            Secondary = new PaletteColorConfig
            {
                Main = PaletteColors.Pink.A400.Darken(0.1m)
            },

            Background = new PaletteBackground
            {
                Default = "#fff",

                Custom = new Dictionary<string, string>
                {
                    { "level1", "#fff" },
                    { "level2", PaletteColors.Grey.X100 },
                    { "appbar-color", "var(--theme-palette-primary-contrast-text)" },
                    { "appbar-background-color", "var(--theme-palette-primary-main)" },
                },
            }
        }
    });

    public static ThemeValue Dark = ThemeFactory.CreateTheme(new ThemeConfig
    {
        Palette = new PaletteConfig
        {
            Type = PaletteType.Dark,

            Primary = new PaletteColorConfig
            {
                Main = PaletteColors.Blue.X200
            },

            Secondary = new PaletteColorConfig
            {
                Main = PaletteColors.Pink.X200
            },

           

            Background = new PaletteBackground
            {
                Default = "#121212",

                Custom = new Dictionary<string, string>
                {
                    { "level1", PaletteColors.Grey.X900 },
                    { "level2", "#333" },
                    { "appbar-color", "#fff" },
                    { "appbar-background-color", "#333" },
                },
            }
        }
    });
}
```

### AppLayout.razor

メインのレイアウト部分です。最初に削除したMainLayout相当です。

Skclusive.Material.LayoutではMainLayoutコンポーネントが定義済みになっており、良くも悪くも強制的にこのレイアウトを使うことになりそうです。

私の場合は楽であることを追求していたのでレイアウトが決まっているのは助かりました。
一方で自由にレイアウトを決めたい人はSkclusive.Material.Componentのみを使用して好みのレイアウトにするということになりそうです。

* https://github.com/sYamaz/website/blob/main/website/Shared/AppLayout.razor

```html
@inherits MaterialLayoutComponent
@inject NavigationManager navman
@using website.Components

<style>
    .styled-menu-item:not(:active):is(:hover) {
        /*カーソル当てた時の強調*/
        background-color: var(--theme-palette-primary-main, #90caf9);
        text-decoration: underline;
        color: white;
    }
    .styled-menu-item:active {
        /*現在表示しているページのMenuItemの色変更*/
        background-color: var(--theme-palette-primary-main, #fff)
    }
    .styled-nav-item:is(:hover) {
        background-color: var(--theme-palette-primary-main, #90caf9);
        text-decoration: underline;
    }
    .styled-nav-item__active {
        background-color: var(--theme-palette-primary-main, #fff)
    }
</style>

<MainLayout TopbarClass="App-Topbar" >

    <TitleContent>
        <Button OnClick="@(s => NavTo(""))" Color="Color.Inherit" Style="text-transform:none;">
            <Typography NoWrap Variant="TypographyVariant.H6">
                sYamaz
            </Typography>
        </Button>
    </TitleContent>


    <ActionsContent>
        <Hidden ExtraSmallDown Context="HiddenContext">
            <div class="@HiddenContext.Class">
                @foreach (var navItem in navigationItems)
                {
                    <Button Style="text-transform:none;"
                            Color="Color.Inherit"
                            Class="@("styled-nav-item" + ClassActive(navItem.Path))"
                            OnClick="@(s => NavTo(navItem.Path))">
                        <Typography NoWrap Variant="TypographyVariant.Body1">@navItem.Title</Typography>
                    </Button>
                }
              
            </div>
        </Hidden>
        <ToggleTheme />
    </ActionsContent>

    <BodyContent>
        <Box Padding="3" Class="App-Body">
            @Body
        </Box>
    </BodyContent>
    <SidebarContent>
        <Navigation Items="@navigationItems"/>
    </SidebarContent>
</MainLayout>

@code {
    private void NavTo(string page)
    {
        navman.NavigateTo(page);
        HandleClose(MenuCloseReason.BackdropClick);
    }

    private bool Open { set; get; }

    private IReference ButtonRef { set; get; } = new Reference();

    private List<NavigationItem> navigationItems = new List<NavigationItem>
    {
        new NavigationItem{Path = "", Title = "About"},
        new NavigationItem{Path = "apps", Title = "Apps"},
        new NavigationItem{Path = "posts", Title = "Posts"},
        new NavigationItem{Path = "https://github.com/sYamaz/website", Title = "Source", Icon=@<GitHubIcon />},
    };

    private void HandleClose(EventArgs args)
    {

        Open = false;

        StateHasChanged();
    }

    private void HandleClose(MenuCloseReason reason)
    {
        Open = false;

        StateHasChanged();
    }

    private void OnOpen()
    {


        Open = true;

        StateHasChanged();
    }

    private string ClassActive(string page)
    {
        System.Diagnostics.Debug.WriteLine(page);
        return navman.BaseUri + page == navman.Uri ? " styled-nav-item__active" : "";

    }
}
```

## できたもの

ほぼSkclusiveのdocsのままですが、個人的に満足のいくサイトができました。

* GitHub pages: https://syamaz.github.io/website/
* GitHub: https://github.com/sYamaz/website

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2088399/7cc50db3-ed92-4e14-1be2-320c26047bae.png)


---

## GitHub pagesについて参考にさせていただいた記事

https://qiita.com/nobu17/items/116a0d1c949885e21d70