diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..99dbc38 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,94 @@ +name: Release nuget and storybook on GH Pages + +on: + push: + branches: ["main"] + workflow_dispatch: + +env: + DOTNET_VERSION: "8.0.x" + NODE_VERSION: 20 + NUGET_ORG: https://api.nuget.org/v3/index.json + +jobs: + prepare-artifacts: + runs-on: ubuntu-latest + env: + PROJECT_PATH: "src/AdaptiveBlazor/AdaptiveBlazor.csproj" + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup .NET + uses: actions/setup-dotnet@v4 + with: + dotnet-version: ${{ env.DOTNET_VERSION }} + + - name: Setup node + uses: actions/setup-node@v4 + with: + node-version: ${{ env.NODE_VERSION }} + + - name: Restore dependencies + run: dotnet restore + + - name: Build sln + run: dotnet build --no-restore -c Release + + - name: Pack nugets + run: dotnet pack ${{ env.PROJECT_PATH }} --no-build -c Release -o ./artifacts/nugets + + - name: Upload nugets as artifacts + uses: actions/upload-artifact@v3 + with: + name: nugets + path: ./artifacts/nugets + + push-to-nuget-org: + needs: prepare-artifacts + runs-on: ubuntu-latest + steps: + - name: Download nugets + uses: actions/download-artifact@v3 + with: + name: nugets + + - name: Setup NuGet.exe + uses: nuget/setup-nuget@v1 + with: + nuget-version: 6.8.0 + + - name: Push nugets to github packages + run: nuget push "*.nupkg" -ApiKey ${{ secrets.NUGET_ORG_KEY }} -Source ${{ env.NUGET_ORG }} -SkipDuplicate + + push-storybook-to-gh-pages: + runs-on: ubuntu-latest + env: + STORYBOOK_PROJECT_PATH: "src/AdaptiveBlazor.Storybook/AdaptiveBlazor.Storybook.csproj" + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup .NET + uses: actions/setup-dotnet@v4 + with: + dotnet-version: ${{ env.DOTNET_VERSION }} + + - name: Install .NET WebAssembly Tools + run: dotnet workload install wasm-tools + + - name: Setup node + uses: actions/setup-node@v4 + with: + node-version: ${{ env.NODE_VERSION }} + + - name: Restore dependencies + run: dotnet restore + + - name: Generate storybook + run: dotnet publish ${{ env.STORYBOOK_PROJECT_PATH }} -c Release -o ./publish -p GHPages=true + + - name: Deploy + uses: JamesIves/github-pages-deploy-action@v4 + with: + folder: ./publish/wwwroot \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..5e57f18 --- /dev/null +++ b/.gitignore @@ -0,0 +1,484 @@ +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. +## +## Get latest from `dotnet new gitignore` + +# dotenv files +.env + +# User-specific files +*.rsuser +*.suo +*.user +*.userosscache +*.sln.docstates + +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs + +# Mono auto generated files +mono_crash.* + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +[Ww][Ii][Nn]32/ +[Aa][Rr][Mm]/ +[Aa][Rr][Mm]64/ +bld/ +[Bb]in/ +[Oo]bj/ +[Ll]og/ +[Ll]ogs/ + +# Visual Studio 2015/2017 cache/options directory +.vs/ +# Uncomment if you have tasks that create the project's static files in wwwroot +#wwwroot/ + +# Visual Studio 2017 auto generated files +Generated\ Files/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +# NUnit +*.VisualState.xml +TestResult.xml +nunit-*.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +# Benchmark Results +BenchmarkDotNet.Artifacts/ + +# .NET +project.lock.json +project.fragment.lock.json +artifacts/ + +# Tye +.tye/ + +# ASP.NET Scaffolding +ScaffoldingReadMe.txt + +# StyleCop +StyleCopReport.xml + +# Files built by Visual Studio +*_i.c +*_p.c +*_h.h +*.ilk +*.meta +*.obj +*.iobj +*.pch +*.pdb +*.ipdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*_wpftmp.csproj +*.log +*.tlog +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Chutzpah Test files +_Chutzpah* + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opendb +*.opensdf +*.sdf +*.cachefile +*.VC.db +*.VC.VC.opendb + +# Visual Studio profiler +*.psess +*.vsp +*.vspx +*.sap + +# Visual Studio Trace Files +*.e2e + +# TFS 2012 Local Workspace +$tf/ + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# AxoCover is a Code Coverage Tool +.axoCover/* +!.axoCover/settings.json + +# Coverlet is a free, cross platform Code Coverage Tool +coverage*.json +coverage*.xml +coverage*.info + +# Visual Studio code coverage results +*.coverage +*.coveragexml + +# NCrunch +_NCrunch_* +.*crunch*.local.xml +nCrunchTemp_* + +# MightyMoose +*.mm.* +AutoTest.Net/ + +# Web workbench (sass) +.sass-cache/ + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.[Pp]ublish.xml +*.azurePubxml +# Note: Comment the next line if you want to checkin your web deploy settings, +# but database connection strings (with potential passwords) will be unencrypted +*.pubxml +*.publishproj + +# Microsoft Azure Web App publish settings. Comment the next line if you want to +# checkin your Azure Web App publish settings, but sensitive information contained +# in these scripts will be unencrypted +PublishScripts/ + +# NuGet Packages +*.nupkg +# NuGet Symbol Packages +*.snupkg +# The packages folder can be ignored because of Package Restore +**/[Pp]ackages/* +# except build/, which is used as an MSBuild target. +!**/[Pp]ackages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/[Pp]ackages/repositories.config +# NuGet v3's project.json files produces more ignorable files +*.nuget.props +*.nuget.targets + +# Microsoft Azure Build Output +csx/ +*.build.csdef + +# Microsoft Azure Emulator +ecf/ +rcf/ + +# Windows Store app package directories and files +AppPackages/ +BundleArtifacts/ +Package.StoreAssociation.xml +_pkginfo.txt +*.appx +*.appxbundle +*.appxupload + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!?*.[Cc]ache/ + +# Others +ClientBin/ +~$* +*~ +*.dbmdl +*.dbproj.schemaview +*.jfm +*.pfx +*.publishsettings +orleans.codegen.cs + +# Including strong name files can present a security risk +# (https://github.com/github/gitignore/pull/2483#issue-259490424) +#*.snk + +# Since there are multiple workflows, uncomment next line to ignore bower_components +# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) +#bower_components/ + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm +ServiceFabricBackup/ +*.rptproj.bak + +# SQL Server files +*.mdf +*.ldf +*.ndf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings +*.rptproj.rsuser +*- [Bb]ackup.rdl +*- [Bb]ackup ([0-9]).rdl +*- [Bb]ackup ([0-9][0-9]).rdl + +# Microsoft Fakes +FakesAssemblies/ + +# GhostDoc plugin setting file +*.GhostDoc.xml + +# Node.js Tools for Visual Studio +.ntvs_analysis.dat +node_modules/ + +# Visual Studio 6 build log +*.plg + +# Visual Studio 6 workspace options file +*.opt + +# Visual Studio 6 auto-generated workspace file (contains which files were open etc.) +*.vbw + +# Visual Studio 6 auto-generated project file (contains which files were open etc.) +*.vbp + +# Visual Studio 6 workspace and project file (working project files containing files to include in project) +*.dsw +*.dsp + +# Visual Studio 6 technical files +*.ncb +*.aps + +# Visual Studio LightSwitch build output +**/*.HTMLClient/GeneratedArtifacts +**/*.DesktopClient/GeneratedArtifacts +**/*.DesktopClient/ModelManifest.xml +**/*.Server/GeneratedArtifacts +**/*.Server/ModelManifest.xml +_Pvt_Extensions + +# Paket dependency manager +.paket/paket.exe +paket-files/ + +# FAKE - F# Make +.fake/ + +# CodeRush personal settings +.cr/personal + +# Python Tools for Visual Studio (PTVS) +__pycache__/ +*.pyc + +# Cake - Uncomment if you are using it +# tools/** +# !tools/packages.config + +# Tabs Studio +*.tss + +# Telerik's JustMock configuration file +*.jmconfig + +# BizTalk build output +*.btp.cs +*.btm.cs +*.odx.cs +*.xsd.cs + +# OpenCover UI analysis results +OpenCover/ + +# Azure Stream Analytics local run output +ASALocalRun/ + +# MSBuild Binary and Structured Log +*.binlog + +# NVidia Nsight GPU debugger configuration file +*.nvuser + +# MFractors (Xamarin productivity tool) working folder +.mfractor/ + +# Local History for Visual Studio +.localhistory/ + +# Visual Studio History (VSHistory) files +.vshistory/ + +# BeatPulse healthcheck temp database +healthchecksdb + +# Backup folder for Package Reference Convert tool in Visual Studio 2017 +MigrationBackup/ + +# Ionide (cross platform F# VS Code tools) working folder +.ionide/ + +# Fody - auto-generated XML schema +FodyWeavers.xsd + +# VS Code files for those working on multiple tools +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json +*.code-workspace + +# Local History for Visual Studio Code +.history/ + +# Windows Installer files from build outputs +*.cab +*.msi +*.msix +*.msm +*.msp + +# JetBrains Rider +*.sln.iml +.idea + +## +## Visual studio for Mac +## + + +# globs +Makefile.in +*.userprefs +*.usertasks +config.make +config.status +aclocal.m4 +install-sh +autom4te.cache/ +*.tar.gz +tarballs/ +test-results/ + +# Mac bundle stuff +*.dmg +*.app + +# content below from: https://github.com/github/gitignore/blob/master/Global/macOS.gitignore +# General +.DS_Store +.AppleDouble +.LSOverride + +# Icon must end with two \r +Icon + + +# Thumbnails +._* + +# Files that might appear in the root of a volume +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns +.com.apple.timemachine.donotpresent + +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk + +# content below from: https://github.com/github/gitignore/blob/master/Global/Windows.gitignore +# Windows thumbnail cache files +Thumbs.db +ehthumbs.db +ehthumbs_vista.db + +# Dump file +*.stackdump + +# Folder config file +[Dd]esktop.ini + +# Recycle Bin used on file shares +$RECYCLE.BIN/ + +# Windows Installer files +*.cab +*.msi +*.msix +*.msm +*.msp + +# Windows shortcuts +*.lnk + +# Vim temporary swap files +*.swp diff --git a/AdaptiveBlazor.sln b/AdaptiveBlazor.sln new file mode 100644 index 0000000..b147da4 --- /dev/null +++ b/AdaptiveBlazor.sln @@ -0,0 +1,52 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.0.31903.59 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{138569F3-D349-48BF-91F5-D30BE9A24A5F}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AdaptiveBlazor", "src\AdaptiveBlazor\AdaptiveBlazor.csproj", "{5E82CC46-FE9F-4F43-A9AC-5D0895509D6D}" +EndProject +Project("{54A90642-561A-4BB1-A94E-469ADEE60C69}") = "AdaptiveBlazor.Assets", "src\AdaptiveBlazor.Assets\AdaptiveBlazor.Assets.esproj", "{09F55A4F-9173-4273-8DE3-EADA1ADDA724}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "examples", "examples", "{2C6CCAC2-F9EC-4529-9E19-56BB4700D670}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AdaptiveBlazor.Demo", "examples\AdaptiveBlazor.Demo\AdaptiveBlazor.Demo.csproj", "{AE96E9AB-D988-4043-B57B-A423517EA5F4}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AdaptiveBlazor.Storybook", "src\AdaptiveBlazor.Storybook\AdaptiveBlazor.Storybook.csproj", "{B161BC63-6689-4205-8E58-45D6BC84DB29}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {5E82CC46-FE9F-4F43-A9AC-5D0895509D6D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {5E82CC46-FE9F-4F43-A9AC-5D0895509D6D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {5E82CC46-FE9F-4F43-A9AC-5D0895509D6D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {5E82CC46-FE9F-4F43-A9AC-5D0895509D6D}.Release|Any CPU.Build.0 = Release|Any CPU + {09F55A4F-9173-4273-8DE3-EADA1ADDA724}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {09F55A4F-9173-4273-8DE3-EADA1ADDA724}.Debug|Any CPU.Build.0 = Debug|Any CPU + {09F55A4F-9173-4273-8DE3-EADA1ADDA724}.Debug|Any CPU.Deploy.0 = Debug|Any CPU + {09F55A4F-9173-4273-8DE3-EADA1ADDA724}.Release|Any CPU.ActiveCfg = Release|Any CPU + {09F55A4F-9173-4273-8DE3-EADA1ADDA724}.Release|Any CPU.Build.0 = Release|Any CPU + {09F55A4F-9173-4273-8DE3-EADA1ADDA724}.Release|Any CPU.Deploy.0 = Release|Any CPU + {AE96E9AB-D988-4043-B57B-A423517EA5F4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {AE96E9AB-D988-4043-B57B-A423517EA5F4}.Debug|Any CPU.Build.0 = Debug|Any CPU + {AE96E9AB-D988-4043-B57B-A423517EA5F4}.Release|Any CPU.ActiveCfg = Release|Any CPU + {AE96E9AB-D988-4043-B57B-A423517EA5F4}.Release|Any CPU.Build.0 = Release|Any CPU + {B161BC63-6689-4205-8E58-45D6BC84DB29}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B161BC63-6689-4205-8E58-45D6BC84DB29}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B161BC63-6689-4205-8E58-45D6BC84DB29}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B161BC63-6689-4205-8E58-45D6BC84DB29}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {5E82CC46-FE9F-4F43-A9AC-5D0895509D6D} = {138569F3-D349-48BF-91F5-D30BE9A24A5F} + {09F55A4F-9173-4273-8DE3-EADA1ADDA724} = {138569F3-D349-48BF-91F5-D30BE9A24A5F} + {AE96E9AB-D988-4043-B57B-A423517EA5F4} = {2C6CCAC2-F9EC-4529-9E19-56BB4700D670} + {B161BC63-6689-4205-8E58-45D6BC84DB29} = {138569F3-D349-48BF-91F5-D30BE9A24A5F} + EndGlobalSection +EndGlobal diff --git a/README.md b/README.md index 2745395..2fd8509 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,3 @@ # Adaptive Blazor + This projects intent is to create blazor wrapper around Adaptive Web Components along with implementation of Adaptive UI concept. diff --git a/Version.props b/Version.props new file mode 100644 index 0000000..1e7cf99 --- /dev/null +++ b/Version.props @@ -0,0 +1,9 @@ + + + 0.1.0-alpha.1 + Copyright © 2024 Wiktor Kubis + Wiktor Kubis + git + https://github.com/dovrol/adaptive-blazor/ + + \ No newline at end of file diff --git a/examples/AdaptiveBlazor.Demo/AdaptiveBlazor.Demo.csproj b/examples/AdaptiveBlazor.Demo/AdaptiveBlazor.Demo.csproj new file mode 100644 index 0000000..86b85c5 --- /dev/null +++ b/examples/AdaptiveBlazor.Demo/AdaptiveBlazor.Demo.csproj @@ -0,0 +1,13 @@ + + + + + + + + net8.0 + enable + enable + + + diff --git a/examples/AdaptiveBlazor.Demo/Components/App.razor b/examples/AdaptiveBlazor.Demo/Components/App.razor new file mode 100644 index 0000000..7190c63 --- /dev/null +++ b/examples/AdaptiveBlazor.Demo/Components/App.razor @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/examples/AdaptiveBlazor.Demo/Components/Layout/MainLayout.razor b/examples/AdaptiveBlazor.Demo/Components/Layout/MainLayout.razor new file mode 100644 index 0000000..4f36731 --- /dev/null +++ b/examples/AdaptiveBlazor.Demo/Components/Layout/MainLayout.razor @@ -0,0 +1,9 @@ +@inherits LayoutComponentBase + +@Body + +
+ An unhandled error has occurred. + Reload + 🗙 +
diff --git a/examples/AdaptiveBlazor.Demo/Components/Layout/MainLayout.razor.css b/examples/AdaptiveBlazor.Demo/Components/Layout/MainLayout.razor.css new file mode 100644 index 0000000..d3877a1 --- /dev/null +++ b/examples/AdaptiveBlazor.Demo/Components/Layout/MainLayout.razor.css @@ -0,0 +1,18 @@ +#blazor-error-ui { + background: lightyellow; + bottom: 0; + box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2); + display: none; + left: 0; + padding: 0.6rem 1.25rem 0.7rem 1.25rem; + position: fixed; + width: 100%; + z-index: 1000; +} + + #blazor-error-ui .dismiss { + cursor: pointer; + position: absolute; + right: 0.75rem; + top: 0.5rem; + } diff --git a/examples/AdaptiveBlazor.Demo/Components/Pages/Error.razor b/examples/AdaptiveBlazor.Demo/Components/Pages/Error.razor new file mode 100644 index 0000000..7a84043 --- /dev/null +++ b/examples/AdaptiveBlazor.Demo/Components/Pages/Error.razor @@ -0,0 +1,36 @@ +@page "/Error" +@using System.Diagnostics + +Error + +

Error.

+

An error occurred while processing your request.

+ +@if (ShowRequestId) +{ +

+ Request ID: @RequestId +

+} + +

Development Mode

+

+ Swapping to Development environment will display more detailed information about the error that occurred. +

+

+ The Development environment shouldn't be enabled for deployed applications. + It can result in displaying sensitive information from exceptions to end users. + For local debugging, enable the Development environment by setting the ASPNETCORE_ENVIRONMENT environment variable to Development + and restarting the app. +

+ +@code{ + [CascadingParameter] + private HttpContext? HttpContext { get; set; } + + private string? RequestId { get; set; } + private bool ShowRequestId => !string.IsNullOrEmpty(RequestId); + + protected override void OnInitialized() => + RequestId = Activity.Current?.Id ?? HttpContext?.TraceIdentifier; +} diff --git a/examples/AdaptiveBlazor.Demo/Components/Pages/Home.razor b/examples/AdaptiveBlazor.Demo/Components/Pages/Home.razor new file mode 100644 index 0000000..0cc9019 --- /dev/null +++ b/examples/AdaptiveBlazor.Demo/Components/Pages/Home.razor @@ -0,0 +1,56 @@ +@page "/" +@rendermode InteractiveServer + + +Home + +

Hello, world!

+ +Welcome to your new app. + +

+ Selected item is: @SelectedItem +

+ + + + + + Section 1 + + + Important ! + + + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer nec odio. Praesent libero. Sed cursus ante dapibus diam. + + + + + Section 2 + + + TODO + + + Sed nisi. Nulla quis sem at nibh elementum imperdiet. Duis sagittis ipsum. Praesent mauris. + + + + + Section 3 + + + "Fusce nec tellus sed augue semper porta. Mauris massa. Vestibulum lacinia arcu eget nulla. + + + + +@code { + private string? SelectedItem; + + private void AccordionClick(AdaptiveAccordionItem item) + { + SelectedItem = item.Id; + } +} \ No newline at end of file diff --git a/examples/AdaptiveBlazor.Demo/Components/Routes.razor b/examples/AdaptiveBlazor.Demo/Components/Routes.razor new file mode 100644 index 0000000..8d744a2 --- /dev/null +++ b/examples/AdaptiveBlazor.Demo/Components/Routes.razor @@ -0,0 +1,6 @@ + + + + + + diff --git a/examples/AdaptiveBlazor.Demo/Components/_Imports.razor b/examples/AdaptiveBlazor.Demo/Components/_Imports.razor new file mode 100644 index 0000000..5cafd8d --- /dev/null +++ b/examples/AdaptiveBlazor.Demo/Components/_Imports.razor @@ -0,0 +1,12 @@ +@using System.Net.Http +@using System.Net.Http.Json +@using Microsoft.AspNetCore.Components.Forms +@using Microsoft.AspNetCore.Components.Routing +@using Microsoft.AspNetCore.Components.Web +@using static Microsoft.AspNetCore.Components.Web.RenderMode +@using Microsoft.AspNetCore.Components.Web.Virtualization +@using Microsoft.JSInterop +@using AdaptiveBlazor.Demo +@using AdaptiveBlazor.Demo.Components + +@using AdaptiveBlazor.Components \ No newline at end of file diff --git a/examples/AdaptiveBlazor.Demo/Program.cs b/examples/AdaptiveBlazor.Demo/Program.cs new file mode 100644 index 0000000..66652d5 --- /dev/null +++ b/examples/AdaptiveBlazor.Demo/Program.cs @@ -0,0 +1,23 @@ +using AdaptiveBlazor.Demo.Components; + +var builder = WebApplication.CreateBuilder(args); + +// Add services to the container. +builder.Services.AddRazorComponents() + .AddInteractiveServerComponents(); + +var app = builder.Build(); + +// Configure the HTTP request pipeline. +if (!app.Environment.IsDevelopment()) +{ + app.UseExceptionHandler("/Error", createScopeForErrors: true); +} + +app.UseStaticFiles(); +app.UseAntiforgery(); + +app.MapRazorComponents() + .AddInteractiveServerRenderMode(); + +app.Run(); diff --git a/examples/AdaptiveBlazor.Demo/Properties/launchSettings.json b/examples/AdaptiveBlazor.Demo/Properties/launchSettings.json new file mode 100644 index 0000000..3951097 --- /dev/null +++ b/examples/AdaptiveBlazor.Demo/Properties/launchSettings.json @@ -0,0 +1,29 @@ +{ + "$schema": "http://json.schemastore.org/launchsettings.json", + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:42821", + "sslPort": 0 + } + }, + "profiles": { + "http": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "applicationUrl": "http://localhost:5064", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + } + } diff --git a/examples/AdaptiveBlazor.Demo/appsettings.Development.json b/examples/AdaptiveBlazor.Demo/appsettings.Development.json new file mode 100644 index 0000000..f042c67 --- /dev/null +++ b/examples/AdaptiveBlazor.Demo/appsettings.Development.json @@ -0,0 +1,9 @@ +{ + "DetailedErrors": true, + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + } +} diff --git a/examples/AdaptiveBlazor.Demo/appsettings.json b/examples/AdaptiveBlazor.Demo/appsettings.json new file mode 100644 index 0000000..4d56694 --- /dev/null +++ b/examples/AdaptiveBlazor.Demo/appsettings.json @@ -0,0 +1,9 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "AllowedHosts": "*" +} diff --git a/examples/AdaptiveBlazor.Demo/wwwroot/app.css b/examples/AdaptiveBlazor.Demo/wwwroot/app.css new file mode 100644 index 0000000..4b6d12e --- /dev/null +++ b/examples/AdaptiveBlazor.Demo/wwwroot/app.css @@ -0,0 +1,29 @@ +h1:focus { + outline: none; +} + +.valid.modified:not([type=checkbox]) { + outline: 1px solid #26b050; +} + +.invalid { + outline: 1px solid #e50000; +} + +.validation-message { + color: #e50000; +} + +.blazor-error-boundary { + background: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTYiIGhlaWdodD0iNDkiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIG92ZXJmbG93PSJoaWRkZW4iPjxkZWZzPjxjbGlwUGF0aCBpZD0iY2xpcDAiPjxyZWN0IHg9IjIzNSIgeT0iNTEiIHdpZHRoPSI1NiIgaGVpZ2h0PSI0OSIvPjwvY2xpcFBhdGg+PC9kZWZzPjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMCkiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0yMzUgLTUxKSI+PHBhdGggZD0iTTI2My41MDYgNTFDMjY0LjcxNyA1MSAyNjUuODEzIDUxLjQ4MzcgMjY2LjYwNiA1Mi4yNjU4TDI2Ny4wNTIgNTIuNzk4NyAyNjcuNTM5IDUzLjYyODMgMjkwLjE4NSA5Mi4xODMxIDI5MC41NDUgOTIuNzk1IDI5MC42NTYgOTIuOTk2QzI5MC44NzcgOTMuNTEzIDI5MSA5NC4wODE1IDI5MSA5NC42NzgyIDI5MSA5Ny4wNjUxIDI4OS4wMzggOTkgMjg2LjYxNyA5OUwyNDAuMzgzIDk5QzIzNy45NjMgOTkgMjM2IDk3LjA2NTEgMjM2IDk0LjY3ODIgMjM2IDk0LjM3OTkgMjM2LjAzMSA5NC4wODg2IDIzNi4wODkgOTMuODA3MkwyMzYuMzM4IDkzLjAxNjIgMjM2Ljg1OCA5Mi4xMzE0IDI1OS40NzMgNTMuNjI5NCAyNTkuOTYxIDUyLjc5ODUgMjYwLjQwNyA1Mi4yNjU4QzI2MS4yIDUxLjQ4MzcgMjYyLjI5NiA1MSAyNjMuNTA2IDUxWk0yNjMuNTg2IDY2LjAxODNDMjYwLjczNyA2Ni4wMTgzIDI1OS4zMTMgNjcuMTI0NSAyNTkuMzEzIDY5LjMzNyAyNTkuMzEzIDY5LjYxMDIgMjU5LjMzMiA2OS44NjA4IDI1OS4zNzEgNzAuMDg4N0wyNjEuNzk1IDg0LjAxNjEgMjY1LjM4IDg0LjAxNjEgMjY3LjgyMSA2OS43NDc1QzI2Ny44NiA2OS43MzA5IDI2Ny44NzkgNjkuNTg3NyAyNjcuODc5IDY5LjMxNzkgMjY3Ljg3OSA2Ny4xMTgyIDI2Ni40NDggNjYuMDE4MyAyNjMuNTg2IDY2LjAxODNaTTI2My41NzYgODYuMDU0N0MyNjEuMDQ5IDg2LjA1NDcgMjU5Ljc4NiA4Ny4zMDA1IDI1OS43ODYgODkuNzkyMSAyNTkuNzg2IDkyLjI4MzcgMjYxLjA0OSA5My41Mjk1IDI2My41NzYgOTMuNTI5NSAyNjYuMTE2IDkzLjUyOTUgMjY3LjM4NyA5Mi4yODM3IDI2Ny4zODcgODkuNzkyMSAyNjcuMzg3IDg3LjMwMDUgMjY2LjExNiA4Ni4wNTQ3IDI2My41NzYgODYuMDU0N1oiIGZpbGw9IiNGRkU1MDAiIGZpbGwtcnVsZT0iZXZlbm9kZCIvPjwvZz48L3N2Zz4=) no-repeat 1rem/1.8rem, #b32121; + padding: 1rem 1rem 1rem 3.7rem; + color: white; +} + + .blazor-error-boundary::after { + content: "An error has occurred." + } + +.darker-border-checkbox.form-check-input { + border-color: #929292; +} diff --git a/src/AdaptiveBlazor.Assets/.gitignore b/src/AdaptiveBlazor.Assets/.gitignore new file mode 100644 index 0000000..3e22129 --- /dev/null +++ b/src/AdaptiveBlazor.Assets/.gitignore @@ -0,0 +1 @@ +/dist \ No newline at end of file diff --git a/src/AdaptiveBlazor.Assets/AdaptiveBlazor.Assets.esproj b/src/AdaptiveBlazor.Assets/AdaptiveBlazor.Assets.esproj new file mode 100644 index 0000000..63de034 --- /dev/null +++ b/src/AdaptiveBlazor.Assets/AdaptiveBlazor.Assets.esproj @@ -0,0 +1,11 @@ + + + FAE04EC0-301F-11D3-BF4B-00C04F79EFBC + dist\ + AdaptiveBlazor + false + + + + + \ No newline at end of file diff --git a/src/AdaptiveBlazor.Assets/esbuild.config.mjs b/src/AdaptiveBlazor.Assets/esbuild.config.mjs new file mode 100644 index 0000000..c9b0ba2 --- /dev/null +++ b/src/AdaptiveBlazor.Assets/esbuild.config.mjs @@ -0,0 +1,14 @@ +import * as esbuild from 'esbuild' +import pkg from './package.json' assert { type: 'json' } + +await esbuild.build({ + entryPoints: [ pkg.source ], + bundle: true, + minify: true, + sourcemap: true, + logLevel: 'info', + target: 'es2022', + format: 'esm', + outfile: pkg.main, + legalComments: 'external', +}); \ No newline at end of file diff --git a/src/AdaptiveBlazor.Assets/package-lock.json b/src/AdaptiveBlazor.Assets/package-lock.json new file mode 100644 index 0000000..7debe3e --- /dev/null +++ b/src/AdaptiveBlazor.Assets/package-lock.json @@ -0,0 +1,1009 @@ +{ + "name": "adaptiveblazor.assets", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "adaptiveblazor.assets", + "license": "MIT", + "dependencies": { + "@adaptive-web/adaptive-web-components": "^0.4.2" + }, + "devDependencies": { + "esbuild": "0.20.0", + "rimraf": "5.0.5" + } + }, + "node_modules/@adaptive-web/adaptive-ui": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/@adaptive-web/adaptive-ui/-/adaptive-ui-0.2.2.tgz", + "integrity": "sha512-xZOiX1dbaYJmtYBm9G1ctydtNsoAgzVEqNU0I/SpRVRHZV3hJv/Mxqwb3qjHPwIlWaYBDZxPZfFm8lQ/RKrZCw==", + "dependencies": { + "@microsoft/fast-element": "2.0.0-beta.26", + "@microsoft/fast-foundation": "3.0.0-alpha.31", + "culori": "^3.2.0" + } + }, + "node_modules/@adaptive-web/adaptive-web-components": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/@adaptive-web/adaptive-web-components/-/adaptive-web-components-0.4.2.tgz", + "integrity": "sha512-tJvcYVT59SLTc+lBByXIMBShxPwNPTxaEPQvSqNro+BlpvDHhsAbqxuzsJY6rutjPdbzhWk2R6W6nSgovDT/JQ==", + "dependencies": { + "@adaptive-web/adaptive-ui": "0.2.2", + "@microsoft/fast-element": "2.0.0-beta.26", + "@microsoft/fast-foundation": "3.0.0-alpha.31", + "@microsoft/fast-web-utilities": "6.0.0", + "tslib": "^2.5.0" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.20.0", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.20.0.tgz", + "integrity": "sha512-fGFDEctNh0CcSwsiRPxiaqX0P5rq+AqE0SRhYGZ4PX46Lg1FNR6oCxJghf8YgY0WQEgQuh3lErUFE4KxLeRmmw==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.20.0", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.20.0.tgz", + "integrity": "sha512-3bMAfInvByLHfJwYPJRlpTeaQA75n8C/QKpEaiS4HrFWFiJlNI0vzq/zCjBrhAYcPyVPG7Eo9dMrcQXuqmNk5g==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.20.0", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.20.0.tgz", + "integrity": "sha512-aVpnM4lURNkp0D3qPoAzSG92VXStYmoVPOgXveAUoQBWRSuQzt51yvSju29J6AHPmwY1BjH49uR29oyfH1ra8Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.20.0", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.20.0.tgz", + "integrity": "sha512-uK7wAnlRvjkCPzh8jJ+QejFyrP8ObKuR5cBIsQZ+qbMunwR8sbd8krmMbxTLSrDhiPZaJYKQAU5Y3iMDcZPhyQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.20.0", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.20.0.tgz", + "integrity": "sha512-AjEcivGAlPs3UAcJedMa9qYg9eSfU6FnGHJjT8s346HSKkrcWlYezGE8VaO2xKfvvlZkgAhyvl06OJOxiMgOYQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.20.0", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.20.0.tgz", + "integrity": "sha512-bsgTPoyYDnPv8ER0HqnJggXK6RyFy4PH4rtsId0V7Efa90u2+EifxytE9pZnsDgExgkARy24WUQGv9irVbTvIw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.20.0", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.20.0.tgz", + "integrity": "sha512-kQ7jYdlKS335mpGbMW5tEe3IrQFIok9r84EM3PXB8qBFJPSc6dpWfrtsC/y1pyrz82xfUIn5ZrnSHQQsd6jebQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.20.0", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.20.0.tgz", + "integrity": "sha512-uG8B0WSepMRsBNVXAQcHf9+Ko/Tr+XqmK7Ptel9HVmnykupXdS4J7ovSQUIi0tQGIndhbqWLaIL/qO/cWhXKyQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.20.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.20.0.tgz", + "integrity": "sha512-2ezuhdiZw8vuHf1HKSf4TIk80naTbP9At7sOqZmdVwvvMyuoDiZB49YZKLsLOfKIr77+I40dWpHVeY5JHpIEIg==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.20.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.20.0.tgz", + "integrity": "sha512-uTtyYAP5veqi2z9b6Gr0NUoNv9F/rOzI8tOD5jKcCvRUn7T60Bb+42NDBCWNhMjkQzI0qqwXkQGo1SY41G52nw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.20.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.20.0.tgz", + "integrity": "sha512-c88wwtfs8tTffPaoJ+SQn3y+lKtgTzyjkD8NgsyCtCmtoIC8RDL7PrJU05an/e9VuAke6eJqGkoMhJK1RY6z4w==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.20.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.20.0.tgz", + "integrity": "sha512-lR2rr/128/6svngnVta6JN4gxSXle/yZEZL3o4XZ6esOqhyR4wsKyfu6qXAL04S4S5CgGfG+GYZnjFd4YiG3Aw==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.20.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.20.0.tgz", + "integrity": "sha512-9Sycc+1uUsDnJCelDf6ZNqgZQoK1mJvFtqf2MUz4ujTxGhvCWw+4chYfDLPepMEvVL9PDwn6HrXad5yOrNzIsQ==", + "cpu": [ + "mips64el" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.20.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.20.0.tgz", + "integrity": "sha512-CoWSaaAXOZd+CjbUTdXIJE/t7Oz+4g90A3VBCHLbfuc5yUQU/nFDLOzQsN0cdxgXd97lYW/psIIBdjzQIwTBGw==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.20.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.20.0.tgz", + "integrity": "sha512-mlb1hg/eYRJUpv8h/x+4ShgoNLL8wgZ64SUr26KwglTYnwAWjkhR2GpoKftDbPOCnodA9t4Y/b68H4J9XmmPzA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.20.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.20.0.tgz", + "integrity": "sha512-fgf9ubb53xSnOBqyvWEY6ukBNRl1mVX1srPNu06B6mNsNK20JfH6xV6jECzrQ69/VMiTLvHMicQR/PgTOgqJUQ==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.20.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.20.0.tgz", + "integrity": "sha512-H9Eu6MGse++204XZcYsse1yFHmRXEWgadk2N58O/xd50P9EvFMLJTQLg+lB4E1cF2xhLZU5luSWtGTb0l9UeSg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.20.0", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.20.0.tgz", + "integrity": "sha512-lCT675rTN1v8Fo+RGrE5KjSnfY0x9Og4RN7t7lVrN3vMSjy34/+3na0q7RIfWDAj0e0rCh0OL+P88lu3Rt21MQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.20.0", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.20.0.tgz", + "integrity": "sha512-HKoUGXz/TOVXKQ+67NhxyHv+aDSZf44QpWLa3I1lLvAwGq8x1k0T+e2HHSRvxWhfJrFxaaqre1+YyzQ99KixoA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.20.0", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.20.0.tgz", + "integrity": "sha512-GDwAqgHQm1mVoPppGsoq4WJwT3vhnz/2N62CzhvApFD1eJyTroob30FPpOZabN+FgCjhG+AgcZyOPIkR8dfD7g==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.20.0", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.20.0.tgz", + "integrity": "sha512-0vYsP8aC4TvMlOQYozoksiaxjlvUcQrac+muDqj1Fxy6jh9l9CZJzj7zmh8JGfiV49cYLTorFLxg7593pGldwQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.20.0", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.20.0.tgz", + "integrity": "sha512-p98u4rIgfh4gdpV00IqknBD5pC84LCub+4a3MO+zjqvU5MVXOc3hqR2UgT2jI2nh3h8s9EQxmOsVI3tyzv1iFg==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.20.0", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.20.0.tgz", + "integrity": "sha512-NgJnesu1RtWihtTtXGFMU5YSE6JyyHPMxCwBZK7a6/8d31GuSo9l0Ss7w1Jw5QnKUawG6UEehs883kcXf5fYwg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@floating-ui/core": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.0.tgz", + "integrity": "sha512-PcF++MykgmTj3CIyOQbKA/hDzOAiqI3mhuoN44WRCopIs1sgoDoU4oty4Jtqaj/y3oDU6fnVSm4QG0a3t5i0+g==", + "dependencies": { + "@floating-ui/utils": "^0.2.1" + } + }, + "node_modules/@floating-ui/dom": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.0.tgz", + "integrity": "sha512-SZ0BEXzsaaS6THZfZJUcAobbZTD+MvfGM42bxgeg0Tnkp4/an/avqwAXiVLsFtIBZtfsx3Ymvwx0+KnnhdA/9g==", + "dependencies": { + "@floating-ui/core": "^1.6.0", + "@floating-ui/utils": "^0.2.1" + } + }, + "node_modules/@floating-ui/utils": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.1.tgz", + "integrity": "sha512-9TANp6GPoMtYzQdt54kfAyMmz1+osLlXdg2ENroU7zzrtflTLrrC/lgrIfaSe+Wu0b89GKccT7vxXA0MoAIO+Q==" + }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@microsoft/fast-element": { + "version": "2.0.0-beta.26", + "resolved": "https://registry.npmjs.org/@microsoft/fast-element/-/fast-element-2.0.0-beta.26.tgz", + "integrity": "sha512-t4x7mlNZdLHg5mTeNAiH9+lpTNFiZTpZZk/YsRGwNBKlw6mEBGT5zYRfQq5X3WhRbXafKmIa4V+etA1kP0ebWw==" + }, + "node_modules/@microsoft/fast-foundation": { + "version": "3.0.0-alpha.31", + "resolved": "https://registry.npmjs.org/@microsoft/fast-foundation/-/fast-foundation-3.0.0-alpha.31.tgz", + "integrity": "sha512-266JfAlmiz1uGQ0cnGIPtahZZ3WVNS8+6vrjsHmEg46sJTzb+9WfhgFan40y+MzgvWzZGr1Y1mh6GVpwVmKFJA==", + "dependencies": { + "@floating-ui/dom": "^1.0.3", + "@microsoft/fast-element": "2.0.0-beta.26", + "@microsoft/fast-web-utilities": "^6.0.0", + "tabbable": "^5.2.0", + "tslib": "^2.4.0" + } + }, + "node_modules/@microsoft/fast-web-utilities": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@microsoft/fast-web-utilities/-/fast-web-utilities-6.0.0.tgz", + "integrity": "sha512-ckCA4Xn91ja1Qz+jhGGL1Q3ZeuRpA5VvYcRA7GzA1NP545sl14bwz3tbHCq8jIk+PL7mkSaIveGMYuJB2L4Izg==", + "dependencies": { + "exenv-es6": "^1.1.1" + } + }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/culori": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/culori/-/culori-3.3.0.tgz", + "integrity": "sha512-pHJg+jbuFsCjz9iclQBqyL3B2HLCBF71BwVNujUYEvCeQMvV97R59MNK3R2+jgJ3a1fcZgI9B3vYgz8lzr/BFQ==", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } + }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true + }, + "node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true + }, + "node_modules/esbuild": { + "version": "0.20.0", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.20.0.tgz", + "integrity": "sha512-6iwE3Y2RVYCME1jLpBqq7LQWK3MW6vjV2bZy6gt/WrqkY+WE74Spyc0ThAOYpMtITvnjX09CrC6ym7A/m9mebA==", + "dev": true, + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.20.0", + "@esbuild/android-arm": "0.20.0", + "@esbuild/android-arm64": "0.20.0", + "@esbuild/android-x64": "0.20.0", + "@esbuild/darwin-arm64": "0.20.0", + "@esbuild/darwin-x64": "0.20.0", + "@esbuild/freebsd-arm64": "0.20.0", + "@esbuild/freebsd-x64": "0.20.0", + "@esbuild/linux-arm": "0.20.0", + "@esbuild/linux-arm64": "0.20.0", + "@esbuild/linux-ia32": "0.20.0", + "@esbuild/linux-loong64": "0.20.0", + "@esbuild/linux-mips64el": "0.20.0", + "@esbuild/linux-ppc64": "0.20.0", + "@esbuild/linux-riscv64": "0.20.0", + "@esbuild/linux-s390x": "0.20.0", + "@esbuild/linux-x64": "0.20.0", + "@esbuild/netbsd-x64": "0.20.0", + "@esbuild/openbsd-x64": "0.20.0", + "@esbuild/sunos-x64": "0.20.0", + "@esbuild/win32-arm64": "0.20.0", + "@esbuild/win32-ia32": "0.20.0", + "@esbuild/win32-x64": "0.20.0" + } + }, + "node_modules/exenv-es6": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/exenv-es6/-/exenv-es6-1.1.1.tgz", + "integrity": "sha512-vlVu3N8d6yEMpMsEm+7sUBAI81aqYYuEvfK0jNqmdb/OPXzzH7QWDDnVjMvDSY47JdHEqx/dfC/q8WkfoTmpGQ==" + }, + "node_modules/foreground-child": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz", + "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob": { + "version": "10.3.10", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.10.tgz", + "integrity": "sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==", + "dev": true, + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^2.3.5", + "minimatch": "^9.0.1", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0", + "path-scurry": "^1.10.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "node_modules/jackspeak": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.6.tgz", + "integrity": "sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==", + "dev": true, + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "node_modules/lru-cache": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.2.0.tgz", + "integrity": "sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q==", + "dev": true, + "engines": { + "node": "14 || >=16.14" + } + }, + "node_modules/minimatch": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/minipass": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", + "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", + "dev": true, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-scurry": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.1.tgz", + "integrity": "sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==", + "dev": true, + "dependencies": { + "lru-cache": "^9.1.1 || ^10.0.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rimraf": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.5.tgz", + "integrity": "sha512-CqDakW+hMe/Bz202FPEymy68P+G50RfMQK+Qo5YUqc9SPipvbGjCGKd0RSKEelbsfQuw3g5NZDSrlZZAJurH1A==", + "dev": true, + "dependencies": { + "glob": "^10.3.7" + }, + "bin": { + "rimraf": "dist/esm/bin.mjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/string-width-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/tabbable": { + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/tabbable/-/tabbable-5.3.3.tgz", + "integrity": "sha512-QD9qKY3StfbZqWOPLp0++pOrAVb/HbUi5xCc8cUo4XjP19808oaMiDzn0leBY5mCespIBM0CIZePzZjgzR83kA==" + }, + "node_modules/tslib": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", + "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/wrap-ansi-cjs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + } + } +} diff --git a/src/AdaptiveBlazor.Assets/package.json b/src/AdaptiveBlazor.Assets/package.json new file mode 100644 index 0000000..36aef0e --- /dev/null +++ b/src/AdaptiveBlazor.Assets/package.json @@ -0,0 +1,19 @@ +{ + "private": true, + "name": "adaptiveblazor.assets", + "source": "src/index.js", + "main": "dist/AdaptiveBlazor.lib.module.js", + "scripts": { + "build": "node ./esbuild.config.mjs", + "clean": "rimraf ./dist" + }, + "type": "module", + "license": "MIT", + "dependencies": { + "@adaptive-web/adaptive-web-components": "^0.4.2" + }, + "devDependencies": { + "esbuild": "0.20.0", + "rimraf": "5.0.5" + } +} diff --git a/src/AdaptiveBlazor.Assets/src/index.js b/src/AdaptiveBlazor.Assets/src/index.js new file mode 100644 index 0000000..a5a04c5 --- /dev/null +++ b/src/AdaptiveBlazor.Assets/src/index.js @@ -0,0 +1,19 @@ +import { AdaptiveDesignSystem } from "@adaptive-web/adaptive-web-components"; +import { AllComponents } from "@adaptive-web/adaptive-web-components/all-components"; +import { DesignToken } from "@microsoft/fast-foundation"; + +// This must be called during initialization for the Design Tokens to be setup so the component styling is applied. +DesignToken.registerDefaultStyleTarget(); +AdaptiveDesignSystem.defineComponents(AllComponents); + + +export function afterWebStarted(blazor) { + blazor.registerCustomEventType('accordionchange', { + browserEventName: 'change', + createEventArgs: event => { + return { + activeId: event.detail + }; + } + }); +} \ No newline at end of file diff --git a/src/AdaptiveBlazor.Storybook/AdaptiveBlazor.Storybook.csproj b/src/AdaptiveBlazor.Storybook/AdaptiveBlazor.Storybook.csproj new file mode 100644 index 0000000..e5552e2 --- /dev/null +++ b/src/AdaptiveBlazor.Storybook/AdaptiveBlazor.Storybook.csproj @@ -0,0 +1,24 @@ + + + + net8.0 + enable + enable + True + false + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/AdaptiveBlazor.Storybook/App.razor b/src/AdaptiveBlazor.Storybook/App.razor new file mode 100644 index 0000000..0576729 --- /dev/null +++ b/src/AdaptiveBlazor.Storybook/App.razor @@ -0,0 +1,6 @@ +@using System.Reflection + +()?.InformationalVersion}")"> + diff --git a/src/AdaptiveBlazor.Storybook/Program.cs b/src/AdaptiveBlazor.Storybook/Program.cs new file mode 100644 index 0000000..5f4a3f4 --- /dev/null +++ b/src/AdaptiveBlazor.Storybook/Program.cs @@ -0,0 +1,11 @@ +using AdaptiveBlazor.Storybook; +using Microsoft.AspNetCore.Components.Web; +using Microsoft.AspNetCore.Components.WebAssembly.Hosting; + +var builder = WebAssemblyHostBuilder.CreateDefault(args); +builder.RootComponents.Add("#app"); +builder.RootComponents.Add("head::after"); + +builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) }); + +await builder.Build().RunAsync(); diff --git a/src/AdaptiveBlazor.Storybook/Properties/launchSettings.json b/src/AdaptiveBlazor.Storybook/Properties/launchSettings.json new file mode 100644 index 0000000..80e3e85 --- /dev/null +++ b/src/AdaptiveBlazor.Storybook/Properties/launchSettings.json @@ -0,0 +1,30 @@ +{ + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:5089/", + "sslPort": 44325 + } + }, + "profiles": { + "AdaptiveBlazor.Storybook": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}", + "applicationUrl": "https://localhost:7292;http://localhost:5257", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, + "inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + } +} \ No newline at end of file diff --git a/src/AdaptiveBlazor.Storybook/Shared/DefaultLayout.razor b/src/AdaptiveBlazor.Storybook/Shared/DefaultLayout.razor new file mode 100644 index 0000000..a3f4a08 --- /dev/null +++ b/src/AdaptiveBlazor.Storybook/Shared/DefaultLayout.razor @@ -0,0 +1,6 @@ +@inherits LayoutComponentBase +@* See also: https://github.com/jsakamoto/BlazingStory#%EF%B8%8F-configure-layouts *@ + +
+ @Body +
diff --git a/src/AdaptiveBlazor.Storybook/Stories/Accordion.stories.razor b/src/AdaptiveBlazor.Storybook/Stories/Accordion.stories.razor new file mode 100644 index 0000000..d9cf690 --- /dev/null +++ b/src/AdaptiveBlazor.Storybook/Stories/Accordion.stories.razor @@ -0,0 +1,78 @@ +@attribute [Stories("Components/Accordion/Accordion")] + + + + + + + + + + + + + + + + + + + +@code +{ + private string lorem = "Lorem ipsum dolor sit amet consectetur adipisicing elit. Repellendus, dicta. Et voluptatum, illo sapiente culpa iste vero animi nesciunt at placeat repellendus earum illum omnis ducimus rem iusto commodi nihil."; +} \ No newline at end of file diff --git a/src/AdaptiveBlazor.Storybook/Stories/AccordionItem.stories.razor b/src/AdaptiveBlazor.Storybook/Stories/AccordionItem.stories.razor new file mode 100644 index 0000000..425887c --- /dev/null +++ b/src/AdaptiveBlazor.Storybook/Stories/AccordionItem.stories.razor @@ -0,0 +1,53 @@ +@attribute [Stories("Components/Accordion/Accordion item")] + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +@code +{ + private RenderFragment headingSlot(int number) => @Heading @number; + private RenderFragment lorem = @Lorem ipsum dolor sit amet consectetur adipisicing elit. Repellendus, dicta. Et voluptatum, illo sapiente culpa iste vero animi nesciunt at placeat repellendus earum illum omnis ducimus rem iusto commodi nihil.; + private RenderFragment startSlot = @Start slot; + private RenderFragment endSlot = @End slot; +} \ No newline at end of file diff --git a/src/AdaptiveBlazor.Storybook/_Imports.razor b/src/AdaptiveBlazor.Storybook/_Imports.razor new file mode 100644 index 0000000..f421103 --- /dev/null +++ b/src/AdaptiveBlazor.Storybook/_Imports.razor @@ -0,0 +1,16 @@ +@using System.Net.Http +@using System.Net.Http.Json +@using Microsoft.AspNetCore.Components.Forms +@using Microsoft.AspNetCore.Components.Routing +@using Microsoft.AspNetCore.Components.Web +@using Microsoft.AspNetCore.Components.Web.Virtualization +@using Microsoft.AspNetCore.Components.WebAssembly.Http +@using Microsoft.JSInterop +@using BlazingStory.Components +@using BlazingStory.Types +@using AdaptiveBlazor.Storybook +@using AdaptiveBlazor.Storybook.Shared +@using AdaptiveBlazor.Storybook.Stories + +@using AdaptiveBlazor.Components + diff --git a/src/AdaptiveBlazor.Storybook/wwwroot/css/blazor-ui.css b/src/AdaptiveBlazor.Storybook/wwwroot/css/blazor-ui.css new file mode 100644 index 0000000..6843bf9 --- /dev/null +++ b/src/AdaptiveBlazor.Storybook/wwwroot/css/blazor-ui.css @@ -0,0 +1,89 @@ +#blazor-error-ui { + background: #ffffe0; + bottom: 0; + box-shadow: 0 -1px 2px rgba(0, 0, 0, .2); + display: none; + left: 0; + padding: .6rem 1.25rem .7rem 1.25rem; + position: fixed; + right: 0; + z-index: 1000 +} + +#blazor-error-ui .dismiss { + cursor: pointer; + position: absolute; + right: .75rem; + top: .5rem +} + +.blazor-error-boundary { + background: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTYiIGhlaWdodD0iNDkiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIG92ZXJmbG93PSJoaWRkZW4iPjxkZWZzPjxjbGlwUGF0aCBpZD0iY2xpcDAiPjxyZWN0IHg9IjIzNSIgeT0iNTEiIHdpZHRoPSI1NiIgaGVpZ2h0PSI0OSIvPjwvY2xpcFBhdGg+PC9kZWZzPjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMCkiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0yMzUgLTUxKSI+PHBhdGggZD0iTTI2My41MDYgNTFDMjY0LjcxNyA1MSAyNjUuODEzIDUxLjQ4MzcgMjY2LjYwNiA1Mi4yNjU4TDI2Ny4wNTIgNTIuNzk4NyAyNjcuNTM5IDUzLjYyODMgMjkwLjE4NSA5Mi4xODMxIDI5MC41NDUgOTIuNzk1IDI5MC42NTYgOTIuOTk2QzI5MC44NzcgOTMuNTEzIDI5MSA5NC4wODE1IDI5MSA5NC42NzgyIDI5MSA5Ny4wNjUxIDI4OS4wMzggOTkgMjg2LjYxNyA5OUwyNDAuMzgzIDk5QzIzNy45NjMgOTkgMjM2IDk3LjA2NTEgMjM2IDk0LjY3ODIgMjM2IDk0LjM3OTkgMjM2LjAzMSA5NC4wODg2IDIzNi4wODkgOTMuODA3MkwyMzYuMzM4IDkzLjAxNjIgMjM2Ljg1OCA5Mi4xMzE0IDI1OS40NzMgNTMuNjI5NCAyNTkuOTYxIDUyLjc5ODUgMjYwLjQwNyA1Mi4yNjU4QzI2MS4yIDUxLjQ4MzcgMjYyLjI5NiA1MSAyNjMuNTA2IDUxWk0yNjMuNTg2IDY2LjAxODNDMjYwLjczNyA2Ni4wMTgzIDI1OS4zMTMgNjcuMTI0NSAyNTkuMzEzIDY5LjMzNyAyNTkuMzEzIDY5LjYxMDIgMjU5LjMzMiA2OS44NjA4IDI1OS4zNzEgNzAuMDg4N0wyNjEuNzk1IDg0LjAxNjEgMjY1LjM4IDg0LjAxNjEgMjY3LjgyMSA2OS43NDc1QzI2Ny44NiA2OS43MzA5IDI2Ny44NzkgNjkuNTg3NyAyNjcuODc5IDY5LjMxNzkgMjY3Ljg3OSA2Ny4xMTgyIDI2Ni40NDggNjYuMDE4MyAyNjMuNTg2IDY2LjAxODNaTTI2My41NzYgODYuMDU0N0MyNjEuMDQ5IDg2LjA1NDcgMjU5Ljc4NiA4Ny4zMDA1IDI1OS43ODYgODkuNzkyMSAyNTkuNzg2IDkyLjI4MzcgMjYxLjA0OSA5My41Mjk1IDI2My41NzYgOTMuNTI5NSAyNjYuMTE2IDkzLjUyOTUgMjY3LjM4NyA5Mi4yODM3IDI2Ny4zODcgODkuNzkyMSAyNjcuMzg3IDg3LjMwMDUgMjY2LjExNiA4Ni4wNTQ3IDI2My41NzYgODYuMDU0N1oiIGZpbGw9IiNGRkU1MDAiIGZpbGwtcnVsZT0iZXZlbm9kZCIvPjwvZz48L3N2Zz4=) no-repeat 1rem/1.8rem, #b32121; + padding: 1rem 1rem 1rem 3.7rem; + color: white; +} + +.blazor-error-boundary::after { + content: "An error has occurred." +} + +.loading-progress { + position: fixed; + inset: 0; + background: #f6f9fc; +} + +.loading-progress svg { + position: relative; + display: block; + width: 8rem; + height: 8rem; + margin: 20vh auto 1rem auto; +} + +.loading-progress svg circle { + fill: none; + stroke: #e0e0e0; + stroke-width: 0.6rem; + transform-origin: 50% 50%; + transform: rotate(-90deg); +} + +.loading-progress svg circle:last-child { + stroke: #542fd4; + stroke-dasharray: calc(3.141 * var(--blazor-load-percentage, 0%) * 0.8), 500%; + transition: stroke-dasharray 0.05s ease-in-out; +} + +.loading-progress img { + position: absolute; + width: 44px; + height: 44px; + margin: auto; + inset: calc(20vh + 3.2rem - 22px) 0 auto 0; +} + +.loading-progress .text { + position: absolute; + text-align: center; + font-weight: bold; + inset: calc(20vh + 4.8rem) 0 auto 0.2rem; +} + +.loading-progress .text:after { + content: var(--blazor-load-percentage-text, "Loading"); +} + +@media (prefers-color-scheme: dark) { + .loading-progress { + background-color: #222425; + } + + .loading-progress svg circle { + stroke: #393a3b; + } + + .loading-progress .text { + color: #c9cdcf; + } +} \ No newline at end of file diff --git a/src/AdaptiveBlazor.Storybook/wwwroot/favicon.ico b/src/AdaptiveBlazor.Storybook/wwwroot/favicon.ico new file mode 100644 index 0000000..b70e74a Binary files /dev/null and b/src/AdaptiveBlazor.Storybook/wwwroot/favicon.ico differ diff --git a/src/AdaptiveBlazor.Storybook/wwwroot/iframe.html b/src/AdaptiveBlazor.Storybook/wwwroot/iframe.html new file mode 100644 index 0000000..195128d --- /dev/null +++ b/src/AdaptiveBlazor.Storybook/wwwroot/iframe.html @@ -0,0 +1,35 @@ + + + + + + + AdaptiveBlazor.Storybook + + + + + + + +
+
+ +
+ An unhandled error has occurred. + Reload + 🗙 +
+ + + + + + \ No newline at end of file diff --git a/src/AdaptiveBlazor.Storybook/wwwroot/index.html b/src/AdaptiveBlazor.Storybook/wwwroot/index.html new file mode 100644 index 0000000..b68b2cc --- /dev/null +++ b/src/AdaptiveBlazor.Storybook/wwwroot/index.html @@ -0,0 +1,42 @@ + + + + + + + + AdaptiveBlazor.Storybook + + + + + +
+
+ + + + +
+ +
+
+ +
+ An unhandled error has occurred. + Reload + 🗙 +
+ + + + + + \ No newline at end of file diff --git a/src/AdaptiveBlazor/AdaptiveBlazor.csproj b/src/AdaptiveBlazor/AdaptiveBlazor.csproj new file mode 100644 index 0000000..d1d5c94 --- /dev/null +++ b/src/AdaptiveBlazor/AdaptiveBlazor.csproj @@ -0,0 +1,34 @@ + + + + net8.0 + enable + enable + True + 1591 + + + + + + $(RepositoryUrl) + Blazor wrapper around Adaptive Web Components. + web-components component-library blazor adaptive-web-components adaptive-ui microsoft-fast adaptive-web-design + MIT + false + + + + + + + + + + + + + + + + diff --git a/src/AdaptiveBlazor/Components/Accordion/AccordionChangeEventArgs.cs b/src/AdaptiveBlazor/Components/Accordion/AccordionChangeEventArgs.cs new file mode 100644 index 0000000..7354dd3 --- /dev/null +++ b/src/AdaptiveBlazor/Components/Accordion/AccordionChangeEventArgs.cs @@ -0,0 +1,12 @@ +using Microsoft.AspNetCore.Components; + +namespace AdaptiveBlazor.Components; + +public class AccordionChangeEventArgs : EventArgs +{ + public string? ActiveId { get; set; } +} + + +[EventHandler("onaccordionchange", typeof(AccordionChangeEventArgs), enableStopPropagation: true, enablePreventDefault: true)] +public static partial class EventHandlers {} \ No newline at end of file diff --git a/src/AdaptiveBlazor/Components/Accordion/AccordionExpandMode.cs b/src/AdaptiveBlazor/Components/Accordion/AccordionExpandMode.cs new file mode 100644 index 0000000..9a13110 --- /dev/null +++ b/src/AdaptiveBlazor/Components/Accordion/AccordionExpandMode.cs @@ -0,0 +1,11 @@ +using System.ComponentModel; + +namespace AdaptiveBlazor.Components; + +public enum AccordionExpandMode +{ + [Description("single")] + Single, + [Description("multi")] + Multi +} diff --git a/src/AdaptiveBlazor/Components/Accordion/AdaptiveAccordion.razor b/src/AdaptiveBlazor/Components/Accordion/AdaptiveAccordion.razor new file mode 100644 index 0000000..63d9610 --- /dev/null +++ b/src/AdaptiveBlazor/Components/Accordion/AdaptiveAccordion.razor @@ -0,0 +1,13 @@ +@namespace AdaptiveBlazor.Components +@inherits AdaptiveComponentBase + + + + @ChildContent + + \ No newline at end of file diff --git a/src/AdaptiveBlazor/Components/Accordion/AdaptiveAccordion.razor.cs b/src/AdaptiveBlazor/Components/Accordion/AdaptiveAccordion.razor.cs new file mode 100644 index 0000000..abcbf2f --- /dev/null +++ b/src/AdaptiveBlazor/Components/Accordion/AdaptiveAccordion.razor.cs @@ -0,0 +1,43 @@ + +using Microsoft.AspNetCore.Components; + +namespace AdaptiveBlazor.Components; + +/// +/// An accordion is a vertically stacked set of interactive headings that each contain a title, +/// content snippet, or thumbnail representing a section of content. The headings function as controls +/// that enable users to reveal or hide their associated sections of content. Accordions are commonly +/// used to reduce the need to scroll when presenting multiple sections of content on a single page. +/// +public partial class AdaptiveAccordion +{ + /// + /// Controls the expand mode of the Accordion, either allowing single or multiple item expansion. + /// + [Parameter] public AccordionExpandMode ExpandMode { get; set; } = AccordionExpandMode.Multi; + + /// + /// The slot for the accordion items + /// + [Parameter] public RenderFragment? ChildContent { get; set; } + + /// + /// Fires a event callback with `AdaptiveAccordionItem` as parameter when the active item changes + /// + [Parameter] public EventCallback OnChange { get; set; } + + private readonly List items = []; + internal void Additem(AdaptiveAccordionItem item) + { + items.Add(item); + } + + private async Task HandleAccordionChange(AccordionChangeEventArgs args) + { + var item = items.FirstOrDefault(x => x.Id == args.ActiveId); + if (item is not null) + { + await OnChange.InvokeAsync(item); + } + } +} diff --git a/src/AdaptiveBlazor/Components/Accordion/AdaptiveAccordionItem.razor b/src/AdaptiveBlazor/Components/Accordion/AdaptiveAccordionItem.razor new file mode 100644 index 0000000..9ea929e --- /dev/null +++ b/src/AdaptiveBlazor/Components/Accordion/AdaptiveAccordionItem.razor @@ -0,0 +1,13 @@ +@namespace AdaptiveBlazor.Components +@inherits AdaptiveComponentBase + + + @Slots + @ChildContent + \ No newline at end of file diff --git a/src/AdaptiveBlazor/Components/Accordion/AdaptiveAccordionItem.razor.cs b/src/AdaptiveBlazor/Components/Accordion/AdaptiveAccordionItem.razor.cs new file mode 100644 index 0000000..cb3005d --- /dev/null +++ b/src/AdaptiveBlazor/Components/Accordion/AdaptiveAccordionItem.razor.cs @@ -0,0 +1,56 @@ +using Microsoft.AspNetCore.Components; + +namespace AdaptiveBlazor.Components; + +/// +/// An individual item in an +/// +public partial class AdaptiveAccordionItem +{ + protected override void OnInitialized() + { + Id ??= Guid.NewGuid().ToString(); + Parent?.Additem(this); + } + + [CascadingParameter] public AdaptiveAccordion? Parent { get; set; } + [Parameter] public RenderFragment? ChildContent { get; set; } + + /// + /// Configures the aria level of the heading element. + /// + [Parameter] public int HeadingLevel { get; set; } = 2; + + /// + /// Expands or collapses the item. + /// + [Parameter] public bool Expanded { get; set; } = false; + + /// + /// Disables an accordion item + /// + [Parameter] public bool Disabled { get; set; } + + /// + /// Content which serves as the accordion item heading and text of the expand button + /// + [Parameter, Slot("heading")] public RenderFragment? HeadingSlot { get; set; } + /// + /// Content which can be provided between the heading and the icon + /// + [Parameter, Slot("start")] public RenderFragment? StartSlot { get; set; } + /// + /// Content which can be provided between the start slot and icon + /// + [Parameter, Slot("end")] public RenderFragment? EndSlot { get; set; } + /// + /// The expanded icon + /// Warning: currently there seems to be bug in awc implementation, as slot is not rendered correctly + /// + [Parameter, Slot("expanded-icon")] public RenderFragment? ExpandedIconSlot { get; set; } + /// + /// The collapsed icon + /// Warning: currently there seems to be bug in awc implementation, as slot is not rendered correctly + /// + [Parameter, Slot("collapsed-icon")] public RenderFragment? CollapsedIconSlot { get; set; } +} diff --git a/src/AdaptiveBlazor/Components/Base/AdaptiveComponentBase.razor b/src/AdaptiveBlazor/Components/Base/AdaptiveComponentBase.razor new file mode 100644 index 0000000..8c55cff --- /dev/null +++ b/src/AdaptiveBlazor/Components/Base/AdaptiveComponentBase.razor @@ -0,0 +1,42 @@ +@using Microsoft.AspNetCore.Components.Rendering +@using System.Reflection; + +@namespace AdaptiveBlazor.Components +@inherits ComponentBase + + +@code +{ + private Dictionary ComponentSlots + { + get { + var slots = new Dictionary(); + + var properties = GetType().GetProperties() + .Where(prop => Attribute.IsDefined(prop, typeof(SlotAttribute))); + + foreach (var prop in properties) + { + var value = prop.GetValue(this); + var attribute = prop.GetCustomAttribute(typeof(SlotAttribute)); + if (value is RenderFragment renderFragment && attribute is SlotAttribute slot) + { + slots.Add(slot.Value, renderFragment); + } + } + + return slots; + } + } + + private void RenderSlots(RenderTreeBuilder __builder) + { + @foreach(var (key, content) in ComponentSlots) + { + if (content is not null) + { +
@content
+ } + } + } +} \ No newline at end of file diff --git a/src/AdaptiveBlazor/Components/Base/AdaptiveComponentBase.razor.cs b/src/AdaptiveBlazor/Components/Base/AdaptiveComponentBase.razor.cs new file mode 100644 index 0000000..2d25b04 --- /dev/null +++ b/src/AdaptiveBlazor/Components/Base/AdaptiveComponentBase.razor.cs @@ -0,0 +1,37 @@ +using Microsoft.AspNetCore.Components; + +namespace AdaptiveBlazor.Components; + +public abstract partial class AdaptiveComponentBase : ComponentBase +{ + protected readonly RenderFragment Slots; + public AdaptiveComponentBase() + { + Slots = RenderSlots; + } + + /// + /// Gets or sets the unique identifier. + /// The value will be used as the HTML global id attribute. + /// + [Parameter] + public virtual string? Id { get; set; } + + /// + /// Optional CSS class names. If given, these will be included in the class attribute of the component. + /// + [Parameter] + public virtual string? Class { get; set; } + + /// + /// Optional in-line styles. If given, these will be included in the style attribute of the component. + /// + [Parameter] + public virtual string? Style { get; set; } + + /// + /// Gets or sets a collection of additional attributes that will be applied to the created element. + /// + [Parameter(CaptureUnmatchedValues = true)] + public virtual IReadOnlyDictionary? AdditionalAttributes { get; set; } +} diff --git a/src/AdaptiveBlazor/Components/Base/SlotAttribute.cs b/src/AdaptiveBlazor/Components/Base/SlotAttribute.cs new file mode 100644 index 0000000..1d68c0f --- /dev/null +++ b/src/AdaptiveBlazor/Components/Base/SlotAttribute.cs @@ -0,0 +1,7 @@ +namespace AdaptiveBlazor.Components; + +[AttributeUsage(AttributeTargets.Property)] +public class SlotAttribute(string slot) : Attribute +{ + public string Value { get; } = slot; +} diff --git a/src/AdaptiveBlazor/Extensions/EnumExtensions.cs b/src/AdaptiveBlazor/Extensions/EnumExtensions.cs new file mode 100644 index 0000000..7e4350f --- /dev/null +++ b/src/AdaptiveBlazor/Extensions/EnumExtensions.cs @@ -0,0 +1,19 @@ +using System.ComponentModel; + +namespace AdaptiveBlazor.Extensions; + +public static class EnumExtensions +{ + public static string ToAttribute(this Enum value) + { + var description = value.ToString(); + var field = value.GetType().GetField(description); + + if (field is not null && Attribute.GetCustomAttribute(field, typeof(DescriptionAttribute)) is DescriptionAttribute attribute) + { + description = attribute.Description; + } + + return description; + } +} diff --git a/src/AdaptiveBlazor/_Imports.razor b/src/AdaptiveBlazor/_Imports.razor new file mode 100644 index 0000000..6a985ff --- /dev/null +++ b/src/AdaptiveBlazor/_Imports.razor @@ -0,0 +1,3 @@ +@using Microsoft.AspNetCore.Components.Web +@using Microsoft.AspNetCore.Components +@using AdaptiveBlazor.Extensions \ No newline at end of file