diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 746a52d675..b92881d6ff 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -3,7 +3,7 @@ "hostRequirements": { "cpus": 4 }, - "onCreateCommand": "wget https://download.visualstudio.microsoft.com/download/pr/86497c4f-3dc8-4ee7-9f6a-9e0464059427/293d074c28bbfd9410f4db8e021fa290/dotnet-sdk-8.0.301-linux-x64.tar.gz -O $HOME/dotnet.tar.gz && export DOTNET_ROOT=$HOME/.dotnet && mkdir -p \"$DOTNET_ROOT\" && tar zxf $HOME/dotnet.tar.gz -C \"$DOTNET_ROOT\" && export PATH=$DOTNET_ROOT:$DOTNET_ROOT/tools:$PATH && sudo dotnet workload install wasm-tools wasm-experimental && dotnet dev-certs https --trust && dotnet build src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Bit.BlazorUI.Demo.Client.Core.csproj -t:InstallNodejsDependencies,BeforeBuildTasks --no-restore && dotnet build src/Websites/Platform/src/Bit.Websites.Platform.Client/Bit.Websites.Platform.Client.csproj -t:InstallNodejsDependencies,BeforeBuildTasks --no-restore && dotnet build src/Websites/Sales/src/Bit.Websites.Sales.Client/Bit.Websites.Sales.Client.csproj -t:InstallNodejsDependencies,BeforeBuildTasks --no-restore && dotnet build src/Templates/Boilerplate/Bit.Boilerplate/src/Client/Boilerplate.Client.Core/Boilerplate.Client.Core.csproj -t:InstallNodejsDependencies,BeforeBuildTasks --no-restore", + "onCreateCommand": "wget https://download.visualstudio.microsoft.com/download/pr/60218cc4-13eb-41d5-aa0b-5fd5a3fb03b8/6c42bee7c3651b1317b709a27a741362/dotnet-sdk-8.0.303-linux-x64.tar.gz -O $HOME/dotnet.tar.gz && export DOTNET_ROOT=$HOME/.dotnet && mkdir -p \"$DOTNET_ROOT\" && tar zxf $HOME/dotnet.tar.gz -C \"$DOTNET_ROOT\" && export PATH=$DOTNET_ROOT:$DOTNET_ROOT/tools:$PATH && dotnet dev-certs https --trust && find . -type f -name '*.csproj' -exec sed -i 's/Microsoft.NET.Sdk.BlazorWebAssembly/Microsoft.NET.Sdk.Web/g' {} \\;", "waitFor": "onCreateCommand", "customizations": { "codespaces": { @@ -13,9 +13,6 @@ }, "vscode": { "extensions": [ - "ms-dotnettools.vscode-dotnet-runtime", - "kevin-chatham.aspnetcorerazor-html-css-class-completion", - "ms-dotnettools.csharp", "glenn2223.live-sass" ] } diff --git a/.github/workflows/admin-sample.cd.yml b/.github/workflows/admin-sample.cd.yml index 351b938a09..9833c2b6a6 100644 --- a/.github/workflows/admin-sample.cd.yml +++ b/.github/workflows/admin-sample.cd.yml @@ -3,7 +3,8 @@ name: Admin Sample CD # Project templates come equipped with CI/CD for both Azure DevOps and GitHub, providing you with a hassle-free way to get started with your new project. It is important to note that you should not depend on the contents of this file. More info at https://bitplatform.dev/templates/dev-ops env: - API_SERVER_ADDRESS: 'https://adminpanel.bitplatform.dev/' + API_SERVER_ADDRESS: 'https://adminpanel-api.bitplatform.dev' + WEB_SERVER_ADDRESS: 'https://adminpanel.bitplatform.dev' APP_SERVICE_NAME: 'bit-adminpanel' on: @@ -35,14 +36,14 @@ jobs: cd src/Templates/Boilerplate && dotnet build -c Release dotnet pack -c Release -o . -p:ReleaseVersion=0.0.0 -p:PackageVersion=0.0.0 dotnet new install Bit.Boilerplate.0.0.0.nupkg - cd ../../../ && dotnet new bit-bp --name AdminPanel --database SqlServer --sample Admin --appInsights --serverUrl adminpanel.bitplatform.dev + cd ../../../ && dotnet new bit-bp --name AdminPanel --database PostgreSQL --sample Admin --appInsights --serverUrl ${{ env.WEB_SERVER_ADDRESS }} --filesStorage AzureBlobStorage --api Standalone - - name: Update appsettings.json api server address + - name: Update core appsettings.json uses: devops-actions/variable-substitution@v1.2 with: - files: 'AdminPanel/src/Client/AdminPanel.Client.Core/appsettings.json' + files: 'AdminPanel/src/Client/AdminPanel.Client.Core/appsettings.json, AdminPanel/src/Shared/appsettings.json' env: - ApiServerAddress: ${{ env.API_SERVER_ADDRESS }} + ServerAddress: ${{ env.API_SERVER_ADDRESS }} ApplicationInsights.ConnectionString: ${{ secrets.APPLICATION_INSIGHTS_CONNECTION_STRING }} - uses: actions/setup-node@v4 @@ -55,17 +56,12 @@ jobs: - name: Configure app render mode run: | sed -i 's/Auto;/BlazorWebAssembly;/g' AdminPanel/src/Client/AdminPanel.Client.Core/Services/AppRenderMode.cs - - - name: Configure bswup - run: | - sed -i 's/self.noPrerenderQuery/\/\/ self.noPrerenderQuery/g' AdminPanel/src/Client/AdminPanel.Client.Web/wwwroot/service-worker.js - sed -i 's/self.isPassive = self.disablePassiveFirstBoot = true;/self.isPassive = self.disablePassiveFirstBoot = false;/g' AdminPanel/src/Client/AdminPanel.Client.Web/wwwroot/service-worker.js - name: Generate CSS/JS files - run: dotnet build AdminPanel/src/Client/AdminPanel.Client.Core/AdminPanel.Client.Core.csproj -t:InstallNodejsDependencies,BeforeBuildTasks -p:Version="${{ vars.APPLICATION_DISPLAY_VERSION}}" --no-restore - + run: dotnet build AdminPanel/src/Client/AdminPanel.Client.Core/AdminPanel.Client.Core.csproj -t:BeforeBuildTasks -p:Version="${{ vars.APPLICATION_DISPLAY_VERSION}}" --no-restore -c Release + - name: Publish - run: dotnet publish AdminPanel/src/AdminPanel.Server/AdminPanel.Server.csproj -c Release -p:PwaEnabled=true --self-contained -r linux-x64 -o ${{env.DOTNET_ROOT}}/server -p:Version="${{ vars.APPLICATION_DISPLAY_VERSION}}" + run: dotnet publish AdminPanel/src/Server/AdminPanel.Server.Api/AdminPanel.Server.Api.csproj -c Release -p:PwaEnabled=true -p:PublishTrimmed=true -p:TrimMode=partial -p:JsonSerializerIsReflectionEnabledByDefault=true --self-contained -r linux-x64 -o ${{env.DOTNET_ROOT}}/server -p:Version="${{ vars.APPLICATION_DISPLAY_VERSION}}" - name: Upload server artifact uses: actions/upload-artifact@v4 @@ -73,6 +69,17 @@ jobs: name: server-bundle path: ${{env.DOTNET_ROOT}}/server + - name: Publish adminpanel blazor wasm standalone + run: | + sed -i 's/adminpanel.bitplatform.dev/adminpanel-api.bitplatform.dev/g' AdminPanel/src/Client/AdminPanel.Client.Web/wwwroot/index.html + dotnet publish AdminPanel/src/Client/AdminPanel.Client.Web/AdminPanel.Client.Web.csproj -c Release -p:BlazorWebAssemblyStandalone=true -o ${{env.DOTNET_ROOT}}/static + + - name: Upload static artifact + uses: actions/upload-artifact@v4 + with: + name: static-bundle + path: ${{env.DOTNET_ROOT}}/static + deploy_api_blazor: name: deploy api + blazor needs: build_api_blazor @@ -88,16 +95,16 @@ jobs: with: name: server-bundle - - name: Delete IdentityCertificate.pfx + - name: Delete DataProtectionCertificate.pfx run: | - rm IdentityCertificate.pfx + rm DataProtectionCertificate.pfx - name: Extract identity certificate from env uses: timheuer/base64-to-file@v1.2 with: fileDir: './' - fileName: 'IdentityCertificate.pfx' - encodedString: ${{ secrets.API_IDENTITY_CERTIFICATE_FILE_BASE64 }} + fileName: 'DataProtectionCertificate.pfx' + encodedString: ${{ secrets.API_DATA_PROTECTION_CERTIFICATE_FILE_BASE64 }} - name: Deploy to Azure Web App id: deploy-to-webapp @@ -109,7 +116,7 @@ jobs: package: . - name: Purge cache - uses: jakejarvis/cloudflare-purge-action@master + uses: jakejarvis/cloudflare-purge-action@v0.3.0 env: CLOUDFLARE_ZONE: ${{ secrets.BITPLATFORM_DEV_CLOUDFLARE_ZONE }} CLOUDFLARE_TOKEN: ${{ secrets.CLOUDFLARE_TOKEN }} @@ -137,19 +144,19 @@ jobs: cd src\Templates\Boilerplate && dotnet build -c Release dotnet pack -c Release -o . -p:ReleaseVersion=0.0.0 -p:PackageVersion=0.0.0 dotnet new install Bit.Boilerplate.0.0.0.nupkg - cd ..\..\..\ && dotnet new bit-bp --name AdminPanel --database SqlServer --sample Admin --windows --appInsights --appCenter --serverUrl adminpanel.bitplatform.dev + cd ..\..\..\ && dotnet new bit-bp --name AdminPanel --database PostgreSQL --sample Admin --windows --appInsights --appCenter --serverUrl ${{ env.WEB_SERVER_ADDRESS }} --filesStorage AzureBlobStorage - - name: Update appsettings.json api server address + - name: Update core appsettings.json uses: devops-actions/variable-substitution@v1.2 with: - files: 'AdminPanel\src\Client\AdminPanel.Client.Core\appsettings.json' + files: 'AdminPanel\src\Client\AdminPanel.Client.Core\appsettings.json, AdminPanel\src\Shared\appsettings.json' env: - ApiServerAddress: ${{ env.API_SERVER_ADDRESS }} + ServerAddress: ${{ env.API_SERVER_ADDRESS }} WindowsUpdateSettings.FilesUrl: https://windows-adminpanel.bitplatform.dev ApplicationInsights.ConnectionString: ${{ secrets.APPLICATION_INSIGHTS_CONNECTION_STRING }} - name: Generate CSS/JS files - run: dotnet build AdminPanel\src\Client\AdminPanel.Client.Core\AdminPanel.Client.Core.csproj -t:InstallNodejsDependencies,BeforeBuildTasks -p:Version="${{ vars.APPLICATION_DISPLAY_VERSION}}" --no-restore + run: dotnet build AdminPanel\src\Client\AdminPanel.Client.Core\AdminPanel.Client.Core.csproj -t:BeforeBuildTasks -p:Version="${{ vars.APPLICATION_DISPLAY_VERSION}}" --no-restore -c Release - name: Set app center secret run: (Get-Content AdminPanel\src\Client\AdminPanel.Client.Windows\Program.cs) -Replace 'appCenterSecret = null;', 'appCenterSecret = "a9ed2257-fb82-496a-ba10-78c2d9ef33a6";' | Out-File -Encoding utf8 AdminPanel\src\Client\AdminPanel.Client.Windows\Program.cs @@ -171,7 +178,7 @@ jobs: echo A | xcopy .\bin\publish-x64 .\publish-result /s /e /h echo A | xcopy .\bin\publish .\publish-result /s /e /h dotnet tool restore - dotnet vpk pack -u AdminPanel.Client.Windows -v "${{ vars.APPLICATION_DISPLAY_VERSION }}" -p .\publish-result -e AdminPanel.Client.Windows-x86.exe -r win-x86 --framework net8.0.6-x86-desktop,net8.0.6-x86-aspnetcore,webview2 --icon .\wwwroot\favicon.ico --packTitle 'AdminPanel' + dotnet vpk pack -u AdminPanel.Client.Windows -v "${{ vars.APPLICATION_DISPLAY_VERSION }}" -p .\publish-result -e AdminPanel.Client.Windows-x86.exe -r win-x86 --framework net8.0.7-x86-desktop,webview2 --icon .\wwwroot\favicon.ico --packTitle 'AdminPanel' - name: Upload artifact uses: actions/upload-artifact@v4 @@ -198,7 +205,7 @@ jobs: cd src/Templates/Boilerplate && dotnet build -c Release dotnet pack -c Release -o . -p:ReleaseVersion=0.0.0 -p:PackageVersion=0.0.0 dotnet new install Bit.Boilerplate.0.0.0.nupkg - cd ../../../ && dotnet new bit-bp --name AdminPanel --database SqlServer --sample Admin --appInsights --appCenter --serverUrl adminpanel.bitplatform.dev + cd ../../../ && dotnet new bit-bp --name AdminPanel --database PostgreSQL --sample Admin --appInsights --appCenter --serverUrl ${{ env.WEB_SERVER_ADDRESS }} --filesStorage AzureBlobStorage - uses: actions/setup-node@v4 with: @@ -211,12 +218,12 @@ jobs: fileName: 'AdminPanel.keystore' encodedString: ${{ secrets.ANDROID_RELEASE_KEYSTORE_FILE_BASE64 }} - - name: Update appsettings.json api server address + - name: Update core appsettings.json uses: devops-actions/variable-substitution@v1.2 with: - files: 'AdminPanel/src/Client/AdminPanel.Client.Core/appsettings.json' + files: 'AdminPanel/src/Client/AdminPanel.Client.Core/appsettings.json, AdminPanel/src/Shared/appsettings.json' env: - ApiServerAddress: ${{ env.API_SERVER_ADDRESS }} + ServerAddress: ${{ env.API_SERVER_ADDRESS }} ApplicationInsights.ConnectionString: ${{ secrets.APPLICATION_INSIGHTS_CONNECTION_STRING }} - name: Set app center secret @@ -231,8 +238,8 @@ jobs: - name: Generate CSS/JS files run: | - dotnet build AdminPanel/src/Client/AdminPanel.Client.Core/AdminPanel.Client.Core.csproj -t:InstallNodejsDependencies,BeforeBuildTasks -p:Version="${{ vars.APPLICATION_DISPLAY_VERSION}}" --no-restore - dotnet build AdminPanel/src/Client/AdminPanel.Client.Maui/AdminPanel.Client.Maui.csproj -t:BeforeBuildTasks -p:Version="${{ vars.APPLICATION_DISPLAY_VERSION}}" --no-restore + dotnet build AdminPanel/src/Client/AdminPanel.Client.Core/AdminPanel.Client.Core.csproj -t:BeforeBuildTasks -p:Version="${{ vars.APPLICATION_DISPLAY_VERSION}}" --no-restore -c Release + dotnet build AdminPanel/src/Client/AdminPanel.Client.Maui/AdminPanel.Client.Maui.csproj -t:BeforeBuildTasks -p:Version="${{ vars.APPLICATION_DISPLAY_VERSION}}" --no-restore -c Release - name: Build aab run: dotnet build AdminPanel/src/Client/AdminPanel.Client.Maui/AdminPanel.Client.Maui.csproj -c Release -p:AndroidPackageFormat=aab -p:AndroidKeyStore=true -p:AndroidSigningKeyStore="AdminPanel.keystore" -p:AndroidSigningKeyAlias=bitplatform -p:AndroidSigningKeyPass="${{ secrets.ANDROID_RELEASE_KEYSTORE_PASSWORD }}" -p:AndroidSigningStorePass="${{ secrets.ANDROID_RELEASE_SIGNING_PASSWORD }}" -p:ApplicationDisplayVersion="${{ vars.APPLICATION_DISPLAY_VERSION }}" -p:ApplicationVersion="${{ vars.APPLICATION_VERSION }}" -p:Version="${{ vars.APPLICATION_DISPLAY_VERSION}}" -p:ApplicationTitle="AdminPanel" -p:ApplicationId="com.bitplatform.AdminPanel.Template" -f net8.0-android @@ -259,7 +266,7 @@ jobs: - uses: maxim-lobanov/setup-xcode@v1.6.0 with: - xcode-version: '15.3' + xcode-version: '15.4' - uses: actions/setup-node@v4 with: @@ -270,14 +277,14 @@ jobs: cd src/Templates/Boilerplate && dotnet build -c Release dotnet pack -c Release -o . -p:ReleaseVersion=0.0.0 -p:PackageVersion=0.0.0 dotnet new install Bit.Boilerplate.0.0.0.nupkg - cd ../../../ && dotnet new bit-bp --name AdminPanel --database SqlServer --sample Admin --appInsights --appCenter --serverUrl adminpanel.bitplatform.dev + cd ../../../ && dotnet new bit-bp --name AdminPanel --database PostgreSQL --sample Admin --appInsights --appCenter --serverUrl ${{ env.WEB_SERVER_ADDRESS }} --filesStorage AzureBlobStorage - - name: Update appsettings.json api server address + - name: Update core appsettings.json uses: devops-actions/variable-substitution@v1.2 with: - files: 'AdminPanel/src/Client/AdminPanel.Client.Core/appsettings.json' + files: 'AdminPanel/src/Client/AdminPanel.Client.Core/appsettings.json, AdminPanel/src/Shared/appsettings.json' env: - ApiServerAddress: ${{ env.API_SERVER_ADDRESS }} + ServerAddress: ${{ env.API_SERVER_ADDRESS }} ApplicationInsights.ConnectionString: ${{ secrets.APPLICATION_INSIGHTS_CONNECTION_STRING }} - name: Set app center secret @@ -303,8 +310,8 @@ jobs: - name: Generate CSS/JS files run: | - dotnet build AdminPanel/src/Client/AdminPanel.Client.Core/AdminPanel.Client.Core.csproj -t:InstallNodejsDependencies,BeforeBuildTasks -p:Version="${{ vars.APPLICATION_DISPLAY_VERSION}}" --no-restore - dotnet build AdminPanel/src/Client/AdminPanel.Client.Maui/AdminPanel.Client.Maui.csproj -t:BeforeBuildTasks -p:Version="${{ vars.APPLICATION_DISPLAY_VERSION}}" --no-restore + dotnet build AdminPanel/src/Client/AdminPanel.Client.Core/AdminPanel.Client.Core.csproj -t:BeforeBuildTasks -p:Version="${{ vars.APPLICATION_DISPLAY_VERSION}}" --no-restore -c Release + dotnet build AdminPanel/src/Client/AdminPanel.Client.Maui/AdminPanel.Client.Maui.csproj -t:BeforeBuildTasks -p:Version="${{ vars.APPLICATION_DISPLAY_VERSION}}" --no-restore -c Release - name: Build ipa run: dotnet publish AdminPanel/src/Client/AdminPanel.Client.Maui/AdminPanel.Client.Maui.csproj -p:RuntimeIdentifier=ios-arm64 -c Release -p:ArchiveOnBuild=true -p:CodesignKey="iPhone Distribution" -p:CodesignProvision="AdminPanel" -p:ApplicationDisplayVersion="${{ vars.APPLICATION_DISPLAY_VERSION }}" -p:ApplicationVersion="${{ vars.APPLICATION_VERSION }}" -p:Version="${{ vars.APPLICATION_DISPLAY_VERSION}}" -p:ApplicationTitle="AdminPanel" -p:ApplicationId="com.bitplatform.AdminPanel.Template" -f net8.0-ios diff --git a/.github/workflows/bit.ci.yml b/.github/workflows/bit.ci.yml index 23ebb99027..cc77bf9103 100644 --- a/.github/workflows/bit.ci.yml +++ b/.github/workflows/bit.ci.yml @@ -27,9 +27,9 @@ jobs: - name: Install wasm and maui run: cd src && dotnet workload install maui-android wasm-tools wasm-experimental - - name: Install Nodejs dependencies - continue-on-error: true # Error MSB4057, not all csproj files have InstallNodejsDependencies target. - run: dotnet build src/Bit-CI-release.sln -t:InstallNodejsDependencies -m:1 + - name: Run BeforeBuildTasks + continue-on-error: true # Error MSB4057, not all csproj files have BeforeBuildTasks target. + run: dotnet build src/Bit-CI-release.sln -t:BeforeBuildTasks -m:1 - name: MSBuild prerelease run: dotnet build src/Bit-CI-release.sln @@ -62,9 +62,9 @@ jobs: - name: Install Android Sdk platform tools run: ${ANDROID_SDK_ROOT}/cmdline-tools/latest/bin/sdkmanager --sdk_root=$ANDROID_SDK_ROOT "platform-tools" - - name: Install Nodejs dependencies - continue-on-error: true # Error MSB4057, not all csproj files have InstallNodejsDependencies target. - run: dotnet build src/Bit-CI.sln -t:InstallNodejsDependencies -m:1 + - name: Run BeforeBuildTasks + continue-on-error: true # Error MSB4057, not all csproj files have BeforeBuildTasks target. + run: dotnet build src/Bit-CI.sln -t:BeforeBuildTasks -m:1 - name: Build run: dotnet build src/Bit-CI.sln -p:WarningLevel=0 -p:RunCodeAnalysis=false diff --git a/.github/workflows/bit.full.ci.yml b/.github/workflows/bit.full.ci.yml index a1a159c7b5..02eb45ee48 100644 --- a/.github/workflows/bit.full.ci.yml +++ b/.github/workflows/bit.full.ci.yml @@ -3,6 +3,9 @@ name: bit platform full CI on: workflow_dispatch: +env: + ConnectionStrings__SqlServerConnectionString: 'Data Source=localhost; Initial Catalog=BoilerplateDb;Application Name=Boilerplate;TrustServerCertificate=True;User Id=sa;Password=P@ssw0rdP@ssw0rd;' + jobs: build: @@ -23,58 +26,110 @@ jobs: with: node-version: 20 - - name: Install Bit.Boilerplate from local source + - name: Prepare environment run: | cd src/Templates/Boilerplate && dotnet build -c Release dotnet pack -c Release -o . -p:ReleaseVersion=0.0.0 -p:PackageVersion=0.0.0 dotnet new install Bit.Boilerplate.0.0.0.nupkg && cd ../../../ - - - name: Release build todo sample + sqlite database - run: | dotnet workload install maui-tizen maui-android wasm-tools wasm-experimental - dotnet new bit-bp --name TodoBPSqlite --database sqlite --sample todo --pipeline none --serverUrl todo.bitplatform.dev ${ANDROID_SDK_ROOT}/cmdline-tools/latest/bin/sdkmanager --sdk_root=$ANDROID_SDK_ROOT "platform-tools" - cd TodoBPSqlite/src/TodoBPSqlite.Server/ + + - name: Install sql server + uses: potatoqualitee/mssqlsuite@v1.7 + with: + install: sqlengine + sa-password: P@ssw0rdP@ssw0rd + show-log: true + + - name: Test Sqlite database option + run: | + dotnet new bit-bp --name TestSqlite --database Sqlite + cd TestSqlite/src/Server/TestSqlite.Server.Api/ dotnet tool restore dotnet ef migrations add InitialMigration dotnet ef database update - cd ../../../ - dotnet build TodoBPSqlite/TodoBPSqlite.sln -c Release -p:RunAOTCompilation=false - dotnet build TodoBPSqlite/src/Client/TodoBPSqlite.Client.Web/TodoBPSqlite.Client.Web.csproj -c Release -p:BlazorWebAssemblyStandalone=true + cd ../../Tests + dotnet test - - name: Release build empty sample + offline db + Win exe + No reCaptcha + - name: Test SqlServer database option run: | - dotnet new bit-bp --name EmptyBP --database other --sample none --pipeline azure --offlineDb --windows --captcha none - dotnet build EmptyBP/EmptyBP.sln -c Release -p:RunAOTCompilation=false + dotnet new bit-bp --name TestSqlServer --database SqlServer + cd TestSqlServer/src/Server/TestSqlServer.Server.Api/ + dotnet tool restore + dotnet ef migrations add InitialMigration + dotnet ef database update + cd ../../Tests + dotnet test - - name: Release build empty sample without api + - name: Test PostgreSQL, Cosmos, MySql, Other database options + run: | + dotnet new bit-bp --name TestPostgreSQL --database PostgreSQL + cd TestPostgreSQL/src/Server/TestPostgreSQL.Server.Api/ + dotnet build + cd ../../../../ + dotnet new bit-bp --name TestCosmos --database Cosmos + cd TestCosmos/src/Server/TestCosmos.Server.Api/ + dotnet build + cd ../../../../ + dotnet new bit-bp --name TestMySql --database MySql + cd TestMySql/src/Server/TestMySql.Server.Api/ + dotnet build + cd ../../../../ + dotnet new bit-bp --name TestOther --database Other + cd TestOther/src/Server/TestOther.Server.Api/ + dotnet build + + - name: Test file storage options + run: | + dotnet new bit-bp --name TestLocal --filesStorage Local + cd TestLocal/src/Server/TestLocal.Server.Api/ + dotnet build + cd ../../../../ + dotnet new bit-bp --name TestAzureBlobStorage --filesStorage AzureBlobStorage + cd TestAzureBlobStorage/src/Server/TestAzureBlobStorage.Server.Api/ + dotnet build + + - name: Test backend setup options + run: | + dotnet new bit-bp --name TestStandalone --api Standalone + cd TestStandalone/src/Server/TestStandalone.Server.Api/ + dotnet build + cd ../ + cd TestStandalone.Server.Web/ + dotnet build + cd ../../../../ + dotnet new bit-bp --name TestIntegrated --api Integrated + cd TestIntegrated/src/Server/TestIntegrated.Server.Web/ + dotnet build + + - name: Test sample configuration 1 run: | - dotnet new bit-bp --name ApiFalse --database other --sample none --pipeline azure --api false - dotnet build ApiFalse/ApiFalse.sln -c Release -p:RunAOTCompilation=false + dotnet new bit-bp --name TestProject --database Cosmos --filesStorage AzureBlobStorage --api Integrated --captcha reCaptcha --pipeline Azure --sample Admin --offlineDb true --windows true --appInsights true --appCenter true --signalr true + dotnet build TestProject/TestProject.sln -p:MultilingualEnabled=true -p:PWA=true -p:BlazorWebAssemblyStandalone=true -p:Environment=Staging - - name: Release build admin panel sample + SqlServer database + - name: Test sample configuration 2 run: | - dotnet new bit-bp --name AdminBPSqlServer --database sqlserver --sample admin --pipeline github --serverUrl adminpanel.bitplatform.dev --appInsights --appCenter - dotnet build AdminBPSqlServer/AdminBPSqlServer.sln -c Release + dotnet new bit-bp --name TestProject2 --database Other --filesStorage Other --api Standalone --captcha None --pipeline None --sample None --offlineDb false --windows false --appInsights false --appCenter false --signalr false + dotnet build TestProject2/TestProject2.sln -p:MultilingualEnabled=false -p:PWA=false -p:BlazorWebAssemblyStandalone=false -p:Environment=Development - - name: Install Nodejs dependencies - continue-on-error: true # Error MSB4057, not all csproj files have InstallNodejsDependencies target. - run: dotnet build src/Bit-CI-release.sln -t:InstallNodejsDependencies -m:1 + - name: Run BeforeBuildTasks + continue-on-error: true # Error MSB4057, not all csproj files have BeforeBuildTasks target. + run: dotnet build src/Bit-CI-release.sln -t:BeforeBuildTasks -m:1 - name: Release build bit blazor ui + butil + bswup + besql + bup + code analyzers + source generators run: dotnet build src/Bit-CI-release.sln -c Release - - name: Release build careers, platform, sales websites + - name: Build careers, platform, sales websites run: | - dotnet build -c Release src/Websites/Platform/Bit.Websites.Platform.sln - dotnet build -c Release src/Websites/Careers/Bit.Websites.Careers.sln - dotnet build -c Release src/Websites/Sales/Bit.Websites.Sales.sln + dotnet build src/Websites/Platform/Bit.Websites.Platform.sln + dotnet build src/Websites/Careers/Bit.Websites.Careers.sln + dotnet build src/Websites/Sales/Bit.Websites.Sales.sln - name: Run bit blazor ui tests - run: dotnet test src/BlazorUI/Bit.BlazorUI.Tests/Bit.BlazorUI.Tests.csproj -c Release + run: dotnet test src/BlazorUI/Bit.BlazorUI.Tests/Bit.BlazorUI.Tests.csproj - - name: Release build bit blazor ui demo - run: dotnet build src/BlazorUI/Bit.BlazorUI.sln -c Release -p:RunAOTCompilation=false + - name: Build bit blazor ui demo + run: dotnet build src/BlazorUI/Bit.BlazorUI.sln - name: Create projects from BlazorEmpty project template with different parameters run: | @@ -84,7 +139,7 @@ jobs: dotnet new bit-empty --name AutoGlobal --interactivity Auto --all-interactive dotnet new bit-empty --name SsrPerPage --interactivity None - - name: Release build blazor empty based projects + - name: Build blazor empty based projects run: | - dotnet build AutoGlobal/AutoGlobal.sln -c Release - dotnet build SsrPerPage/SsrPerPage.csproj -c Release \ No newline at end of file + dotnet build AutoGlobal/AutoGlobal.sln + dotnet build SsrPerPage/SsrPerPage.csproj \ No newline at end of file diff --git a/.github/workflows/blazorui.demo.cd.yml b/.github/workflows/blazorui.demo.cd.yml index 277491ec34..c556e29ee2 100644 --- a/.github/workflows/blazorui.demo.cd.yml +++ b/.github/workflows/blazorui.demo.cd.yml @@ -1,7 +1,7 @@ name: Blazor UI Demo CD env: - API_SERVER_ADDRESS: 'https://blazorui.bitplatform.dev/api/' + SERVER_ADDRESS: 'https://blazorui.bitplatform.dev/api/' APP_SERVICE_NAME: 'bit-components' on: @@ -33,7 +33,7 @@ jobs: with: files: 'src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/appsettings.json' env: - ApiServerAddress: ${{ env.API_SERVER_ADDRESS }} + ApiServerAddress: ${{ env.SERVER_ADDRESS }} - uses: actions/setup-node@v4 with: @@ -82,7 +82,7 @@ jobs: package: . - name: Purge cache - uses: jakejarvis/cloudflare-purge-action@master + uses: jakejarvis/cloudflare-purge-action@v0.3.0 env: CLOUDFLARE_ZONE: ${{ secrets.BITPLATFORM_DEV_CLOUDFLARE_ZONE }} CLOUDFLARE_TOKEN: ${{ secrets.CLOUDFLARE_TOKEN }} @@ -110,7 +110,7 @@ jobs: with: files: 'src\BlazorUI\Demo\Client\Bit.BlazorUI.Demo.Client.Core\appsettings.json' env: - ApiServerAddress: ${{ env.API_SERVER_ADDRESS }} + ApiServerAddress: ${{ env.SERVER_ADDRESS }} WindowsUpdateSettings.FilesUrl: https://windows-components.bitplatform.dev - name: Generate CSS/JS files @@ -132,7 +132,7 @@ jobs: echo A | xcopy .\bin\publish-x64 .\publish-result /s /e /h echo A | xcopy .\bin\publish .\publish-result /s /e /h dotnet tool restore - dotnet vpk pack -u Bit.BlazorUI.Demo.Client.Windows -v "${{ vars.APPLICATION_DISPLAY_VERSION }}" -p .\publish-result -e Bit.BlazorUI.Demo.Client.Windows-x86.exe -r win-x86 --framework net8.0.6-x86-desktop,net8.0.6-x86-aspnetcore,webview2 --icon .\wwwroot\favicon.ico --packTitle 'Bit Blazor UI' + dotnet vpk pack -u Bit.BlazorUI.Demo.Client.Windows -v "${{ vars.APPLICATION_DISPLAY_VERSION }}" -p .\publish-result -e Bit.BlazorUI.Demo.Client.Windows-x86.exe -r win-x86 --framework net8.0.7-x86-desktop,webview2 --icon .\wwwroot\favicon.ico --packTitle 'Bit Blazor UI' - name: Upload artifact uses: actions/upload-artifact@v4 @@ -170,7 +170,7 @@ jobs: with: files: 'src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/appsettings.json' env: - ApiServerAddress: ${{ env.API_SERVER_ADDRESS }} + ApiServerAddress: ${{ env.SERVER_ADDRESS }} - name: Install maui run: cd src && dotnet workload install maui-android @@ -206,7 +206,7 @@ jobs: - uses: maxim-lobanov/setup-xcode@v1.6.0 with: - xcode-version: '15.3' + xcode-version: '15.4' - uses: actions/setup-node@v4 with: @@ -217,7 +217,7 @@ jobs: with: files: 'src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/appsettings.json' env: - ApiServerAddress: ${{ env.API_SERVER_ADDRESS }} + ApiServerAddress: ${{ env.SERVER_ADDRESS }} - name: Install maui run: cd src && dotnet workload install maui diff --git a/.github/workflows/nuget.org.yml b/.github/workflows/nuget.org.yml index d5e1ba5328..764b3baf36 100644 --- a/.github/workflows/nuget.org.yml +++ b/.github/workflows/nuget.org.yml @@ -45,49 +45,49 @@ jobs: encodedString: ${{ secrets.STRONG_SIGN_CERTIFICATE_BASE64 }} - name: Generate CSS/JS files BlazorUI - run: dotnet build src/BlazorUI/Bit.BlazorUI/Bit.BlazorUI.csproj -t:InstallNodejsDependencies,BeforeBuildTasks --no-restore -f:net8.0 + run: dotnet build src/BlazorUI/Bit.BlazorUI/Bit.BlazorUI.csproj -t:BeforeBuildTasks --no-restore -f:net8.0 -c Release - name: dotnet build BlazorUI run: dotnet build src/BlazorUI/Bit.BlazorUI/Bit.BlazorUI.csproj -c Release -p:GeneratePackageOnBuild=false -p:WarningLevel=0 -p:RunCodeAnalysis=false - name: dotnet pack BlazorUI run: dotnet pack src/BlazorUI/Bit.BlazorUI/Bit.BlazorUI.csproj --output . --configuration Release - name: Generate CSS/JS files BlazorUI.Extras - run: dotnet build src/BlazorUI/Bit.BlazorUI.Extras/Bit.BlazorUI.Extras.csproj -t:InstallNodejsDependencies,BeforeBuildTasks --no-restore -f:net8.0 + run: dotnet build src/BlazorUI/Bit.BlazorUI.Extras/Bit.BlazorUI.Extras.csproj -t:BeforeBuildTasks --no-restore -f:net8.0 -c Release - name: dotnet build BlazorUI.Extras run: dotnet build src/BlazorUI/Bit.BlazorUI.Extras/Bit.BlazorUI.Extras.csproj -c Release -p:GeneratePackageOnBuild=false -p:WarningLevel=0 -p:RunCodeAnalysis=false - name: dotnet pack BlazorUI.Extras run: dotnet pack src/BlazorUI/Bit.BlazorUI.Extras/Bit.BlazorUI.Extras.csproj --output . --configuration Release - name: Generate CSS/JS files BlazorUI.Assets - run: dotnet build src/BlazorUI/Bit.BlazorUI.Assets/Bit.BlazorUI.Assets.csproj -t:InstallNodejsDependencies,BeforeBuildTasks --no-restore -f:net8.0 + run: dotnet build src/BlazorUI/Bit.BlazorUI.Assets/Bit.BlazorUI.Assets.csproj -t:BeforeBuildTasks --no-restore -f:net8.0 -c Release - name: dotnet build BlazorUI.Assets run: dotnet build src/BlazorUI/Bit.BlazorUI.Assets/Bit.BlazorUI.Assets.csproj -c Release -p:GeneratePackageOnBuild=false -p:WarningLevel=0 -p:RunCodeAnalysis=false - name: dotnet pack BlazorUI.Assets run: dotnet pack src/BlazorUI/Bit.BlazorUI.Assets/Bit.BlazorUI.Assets.csproj --output . --configuration Release - name: Generate CSS/JS files BlazorUI.Icons - run: dotnet build src/BlazorUI/Bit.BlazorUI.Icons/Bit.BlazorUI.Icons.csproj -t:InstallNodejsDependencies,BeforeBuildTasks --no-restore -f:net8.0 + run: dotnet build src/BlazorUI/Bit.BlazorUI.Icons/Bit.BlazorUI.Icons.csproj -t:BeforeBuildTasks --no-restore -f:net8.0 -c Release - name: dotnet build BlazorUI.Icons run: dotnet build src/BlazorUI/Bit.BlazorUI.Icons/Bit.BlazorUI.Icons.csproj -c Release -p:GeneratePackageOnBuild=false -p:WarningLevel=0 -p:RunCodeAnalysis=false - name: dotnet pack BlazorUI.Icons run: dotnet pack src/BlazorUI/Bit.BlazorUI.Icons/Bit.BlazorUI.Icons.csproj --output . --configuration Release - name: Generate CSS/JS files Bswup - run: dotnet build src/Bswup/Bit.Bswup/Bit.Bswup.csproj -t:InstallNodejsDependencies,BeforeBuildTasks --no-restore -f:net8.0 + run: dotnet build src/Bswup/Bit.Bswup/Bit.Bswup.csproj -t:BeforeBuildTasks --no-restore -f:net8.0 -c Release - name: dotnet build Bswup run: dotnet build src/Bswup/Bit.Bswup/Bit.Bswup.csproj -c Release -p:GeneratePackageOnBuild=false -p:WarningLevel=0 -p:RunCodeAnalysis=false - name: dotnet pack Bswup run: dotnet pack src/Bswup/Bit.Bswup/Bit.Bswup.csproj --output . --configuration Release - name: Generate CSS/JS files Bup - run: dotnet build src/Bup/Bit.Bup/Bit.Bup.csproj -t:InstallNodejsDependencies,BeforeBuildTasks --no-restore -f:net8.0 + run: dotnet build src/Bup/Bit.Bup/Bit.Bup.csproj -t:BeforeBuildTasks --no-restore -f:net8.0 -c Release - name: dotnet build Bup run: dotnet build src/Bup/Bit.Bup/Bit.Bup.csproj -c Release -p:GeneratePackageOnBuild=false -p:WarningLevel=0 -p:RunCodeAnalysis=false - name: dotnet pack Bup run: dotnet pack src/Bup/Bit.Bup/Bit.Bup.csproj --output . --configuration Release - name: Generate CSS/JS files Butil - run: dotnet build src/Butil/Bit.Butil/Bit.Butil.csproj -t:InstallNodejsDependencies,BeforeBuildTasks --no-restore -f:net8.0 + run: dotnet build src/Butil/Bit.Butil/Bit.Butil.csproj -t:BeforeBuildTasks --no-restore -f:net8.0 -c Release - name: dotnet build Butil run: dotnet build src/Butil/Bit.Butil/Bit.Butil.csproj -c Release -p:GeneratePackageOnBuild=false -p:WarningLevel=0 -p:RunCodeAnalysis=false - name: dotnet pack Butil diff --git a/.github/workflows/platform.website.cd.yml b/.github/workflows/platform.website.cd.yml index 32fbff3009..0856e46156 100644 --- a/.github/workflows/platform.website.cd.yml +++ b/.github/workflows/platform.website.cd.yml @@ -31,7 +31,7 @@ jobs: run: cd src && dotnet workload install wasm-tools wasm-experimental - name: Generate CSS/JS files - run: dotnet build src/Websites/Platform/src/Bit.Websites.Platform.Client/Bit.Websites.Platform.Client.csproj -t:InstallNodejsDependencies,BeforeBuildTasks --no-restore + run: dotnet build src/Websites/Platform/src/Bit.Websites.Platform.Client/Bit.Websites.Platform.Client.csproj -t:BeforeBuildTasks --no-restore -c Release - name: Publish run: dotnet publish src/Websites/Platform/src/Bit.Websites.Platform.Server/Bit.Websites.Platform.Server.csproj -c Release --self-contained -r linux-x64 -o server @@ -67,7 +67,7 @@ jobs: package: . - name: Purge cache - uses: jakejarvis/cloudflare-purge-action@master + uses: jakejarvis/cloudflare-purge-action@v0.3.0 env: CLOUDFLARE_ZONE: ${{ secrets.BITPLATFORM_DEV_CLOUDFLARE_ZONE }} CLOUDFLARE_TOKEN: ${{ secrets.CLOUDFLARE_TOKEN }} \ No newline at end of file diff --git a/.github/workflows/prerelease.nuget.org.yml b/.github/workflows/prerelease.nuget.org.yml index 6fc1f51959..b43cdb011b 100644 --- a/.github/workflows/prerelease.nuget.org.yml +++ b/.github/workflows/prerelease.nuget.org.yml @@ -35,49 +35,49 @@ jobs: encodedString: ${{ secrets.STRONG_SIGN_CERTIFICATE_BASE64 }} - name: Generate CSS/JS files BlazorUI - run: dotnet build src/BlazorUI/Bit.BlazorUI/Bit.BlazorUI.csproj -t:InstallNodejsDependencies,BeforeBuildTasks --no-restore -f:net8.0 + run: dotnet build src/BlazorUI/Bit.BlazorUI/Bit.BlazorUI.csproj -t:BeforeBuildTasks --no-restore -f:net8.0 -c Release - name: dotnet build BlazorUI run: dotnet build src/BlazorUI/Bit.BlazorUI/Bit.BlazorUI.csproj -c Release -p:GeneratePackageOnBuild=false -p:WarningLevel=0 -p:RunCodeAnalysis=false - name: dotnet pack BlazorUI run: dotnet pack src/BlazorUI/Bit.BlazorUI/Bit.BlazorUI.csproj --output . --configuration Release - name: Generate CSS/JS files BlazorUI.Extras - run: dotnet build src/BlazorUI/Bit.BlazorUI.Extras/Bit.BlazorUI.Extras.csproj -t:InstallNodejsDependencies,BeforeBuildTasks --no-restore -f:net8.0 + run: dotnet build src/BlazorUI/Bit.BlazorUI.Extras/Bit.BlazorUI.Extras.csproj -t:BeforeBuildTasks --no-restore -f:net8.0 -c Release - name: dotnet build BlazorUI.Extras run: dotnet build src/BlazorUI/Bit.BlazorUI.Extras/Bit.BlazorUI.Extras.csproj -c Release -p:GeneratePackageOnBuild=false -p:WarningLevel=0 -p:RunCodeAnalysis=false - name: dotnet pack BlazorUI.Extras run: dotnet pack src/BlazorUI/Bit.BlazorUI.Extras/Bit.BlazorUI.Extras.csproj --output . --configuration Release - name: Generate CSS/JS files BlazorUI.Assets - run: dotnet build src/BlazorUI/Bit.BlazorUI.Assets/Bit.BlazorUI.Assets.csproj -t:InstallNodejsDependencies,BeforeBuildTasks --no-restore -f:net8.0 + run: dotnet build src/BlazorUI/Bit.BlazorUI.Assets/Bit.BlazorUI.Assets.csproj -t:BeforeBuildTasks --no-restore -f:net8.0 -c Release - name: dotnet build BlazorUI.Assets run: dotnet build src/BlazorUI/Bit.BlazorUI.Assets/Bit.BlazorUI.Assets.csproj -c Release -p:GeneratePackageOnBuild=false -p:WarningLevel=0 -p:RunCodeAnalysis=false - name: dotnet pack BlazorUI.Assets run: dotnet pack src/BlazorUI/Bit.BlazorUI.Assets/Bit.BlazorUI.Assets.csproj --output . --configuration Release - name: Generate CSS/JS files BlazorUI.Icons - run: dotnet build src/BlazorUI/Bit.BlazorUI.Icons/Bit.BlazorUI.Icons.csproj -t:InstallNodejsDependencies,BeforeBuildTasks --no-restore -f:net8.0 + run: dotnet build src/BlazorUI/Bit.BlazorUI.Icons/Bit.BlazorUI.Icons.csproj -t:BeforeBuildTasks --no-restore -f:net8.0 -c Release - name: dotnet build BlazorUI.Icons run: dotnet build src/BlazorUI/Bit.BlazorUI.Icons/Bit.BlazorUI.Icons.csproj -c Release -p:GeneratePackageOnBuild=false -p:WarningLevel=0 -p:RunCodeAnalysis=false - name: dotnet pack BlazorUI.Icons run: dotnet pack src/BlazorUI/Bit.BlazorUI.Icons/Bit.BlazorUI.Icons.csproj --output . --configuration Release - name: Generate CSS/JS files Bswup - run: dotnet build src/Bswup/Bit.Bswup/Bit.Bswup.csproj -t:InstallNodejsDependencies,BeforeBuildTasks --no-restore -f:net8.0 + run: dotnet build src/Bswup/Bit.Bswup/Bit.Bswup.csproj -t:BeforeBuildTasks --no-restore -f:net8.0 -c Release - name: dotnet build Bswup run: dotnet build src/Bswup/Bit.Bswup/Bit.Bswup.csproj -c Release -p:GeneratePackageOnBuild=false -p:WarningLevel=0 -p:RunCodeAnalysis=false - name: dotnet pack Bswup run: dotnet pack src/Bswup/Bit.Bswup/Bit.Bswup.csproj --output . --configuration Release - name: Generate CSS/JS files Bup - run: dotnet build src/Bup/Bit.Bup/Bit.Bup.csproj -t:InstallNodejsDependencies,BeforeBuildTasks --no-restore -f:net8.0 + run: dotnet build src/Bup/Bit.Bup/Bit.Bup.csproj -t:BeforeBuildTasks --no-restore -f:net8.0 -c Release - name: dotnet build Bup run: dotnet build src/Bup/Bit.Bup/Bit.Bup.csproj -c Release -p:GeneratePackageOnBuild=false -p:WarningLevel=0 -p:RunCodeAnalysis=false - name: dotnet pack Bup run: dotnet pack src/Bup/Bit.Bup/Bit.Bup.csproj --output . --configuration Release - name: Generate CSS/JS files Butil - run: dotnet build src/Butil/Bit.Butil/Bit.Butil.csproj -t:InstallNodejsDependencies,BeforeBuildTasks --no-restore -f:net8.0 + run: dotnet build src/Butil/Bit.Butil/Bit.Butil.csproj -t:BeforeBuildTasks --no-restore -f:net8.0 -c Release - name: dotnet build Butil run: dotnet build src/Butil/Bit.Butil/Bit.Butil.csproj -c Release -p:GeneratePackageOnBuild=false -p:WarningLevel=0 -p:RunCodeAnalysis=false - name: dotnet pack Butil diff --git a/.github/workflows/sales.website.cd.yml b/.github/workflows/sales.website.cd.yml index 673693aa82..f000188de7 100644 --- a/.github/workflows/sales.website.cd.yml +++ b/.github/workflows/sales.website.cd.yml @@ -31,7 +31,7 @@ jobs: run: cd src && dotnet workload install wasm-tools wasm-experimental - name: Generate CSS/JS files - run: dotnet build src/Websites/Sales/src/Bit.Websites.Sales.Client/Bit.Websites.Sales.Client.csproj -t:InstallNodejsDependencies,BeforeBuildTasks --no-restore + run: dotnet build src/Websites/Sales/src/Bit.Websites.Sales.Client/Bit.Websites.Sales.Client.csproj -t:BeforeBuildTasks --no-restore -c Release - name: Publish run: dotnet publish src/Websites/Sales/src/Bit.Websites.Sales.Server/Bit.Websites.Sales.Server.csproj -c Release --self-contained -r linux-x64 -o server @@ -67,7 +67,7 @@ jobs: package: . - name: Purge cache - uses: jakejarvis/cloudflare-purge-action@master + uses: jakejarvis/cloudflare-purge-action@v0.3.0 env: CLOUDFLARE_ZONE: ${{ secrets.BITSERVICES_COMPANY_CLOUDFLARE_ZONE }} CLOUDFLARE_TOKEN: ${{ secrets.CLOUDFLARE_TOKEN }} \ No newline at end of file diff --git a/.github/workflows/todo-sample.cd.yml b/.github/workflows/todo-sample.cd.yml index 795b8c385f..ad5682e49c 100644 --- a/.github/workflows/todo-sample.cd.yml +++ b/.github/workflows/todo-sample.cd.yml @@ -3,7 +3,7 @@ name: Todo Sample CD # Project templates come equipped with CI/CD for both Azure DevOps and GitHub, providing you with a hassle-free way to get started with your new project. It is important to note that you should not depend on the contents of this file. More info at https://bitplatform.dev/templates/dev-ops env: - API_SERVER_ADDRESS: 'https://todo.bitplatform.dev/' + SERVER_ADDRESS: 'https://todo.bitplatform.dev' on: workflow_dispatch: @@ -38,14 +38,14 @@ jobs: cd src/Templates/Boilerplate && dotnet build -c Release dotnet pack -c Release -o . -p:ReleaseVersion=0.0.0 -p:PackageVersion=0.0.0 dotnet new install Bit.Boilerplate.0.0.0.nupkg - cd ../../../ && dotnet new bit-bp --name TodoSample --database SqlServer --sample Todo --appInsights --serverUrl todo.bitplatform.dev + cd ../../../ && dotnet new bit-bp --name TodoSample --database PostgreSQL --sample Todo --appInsights --serverUrl ${{ env.SERVER_ADDRESS }} --filesStorage AzureBlobStorage - - name: Update appsettings.json api server address + - name: Update core appsettings.json uses: devops-actions/variable-substitution@v1.2 with: - files: 'TodoSample/src/Client/TodoSample.Client.Core/appsettings.json' + files: 'TodoSample/src/Client/TodoSample.Client.Core/appsettings.json, TodoSample/src/Shared/appsettings.json' env: - ApiServerAddress: ${{ env.API_SERVER_ADDRESS }} + ServerAddress: ${{ env.SERVER_ADDRESS }} ApplicationInsights.ConnectionString: ${{ secrets.APPLICATION_INSIGHTS_CONNECTION_STRING }} - name: Install wasm @@ -57,13 +57,13 @@ jobs: sed -i 's/Auto;/BlazorWebAssembly;/g' TodoSample/src/Client/TodoSample.Client.Core/Services/AppRenderMode.cs - name: Changes for static-todo.bitplatform.dev - Part 1 - run: sed -i 's/http:\/\/localhost:4030/https:\/\/static-todo.bitplatform.dev/g' TodoSample/src/TodoSample.Server/Program.Middlewares.cs + run: sed -i 's/http:\/\/localhost:4030/https:\/\/static-todo.bitplatform.dev/g' TodoSample/src/Server/TodoSample.Server.Web/Program.Middlewares.cs - name: Generate CSS/JS files - run: dotnet build TodoSample/src/Client/TodoSample.Client.Core/TodoSample.Client.Core.csproj -t:InstallNodejsDependencies,BeforeBuildTasks -p:Version="${{ vars.APPLICATION_DISPLAY_VERSION}}" --no-restore + run: dotnet build TodoSample/src/Client/TodoSample.Client.Core/TodoSample.Client.Core.csproj -t:BeforeBuildTasks -p:Version="${{ vars.APPLICATION_DISPLAY_VERSION}}" --no-restore -c Release - name: Publish - run: dotnet publish TodoSample/src/TodoSample.Server/TodoSample.Server.csproj -c Release -p:PwaEnabled=true --self-contained -r linux-x64 -o ${{env.DOTNET_ROOT}}/server -p:Version="${{ vars.APPLICATION_DISPLAY_VERSION}}" + run: dotnet publish TodoSample/src/Server/TodoSample.Server.Web/TodoSample.Server.Web.csproj -c Release -p:PwaEnabled=true -p:PublishTrimmed=true -p:TrimMode=partial -p:JsonSerializerIsReflectionEnabledByDefault=true --self-contained -r linux-x64 -o ${{env.DOTNET_ROOT}}/server -p:Version="${{ vars.APPLICATION_DISPLAY_VERSION}}" - name: Upload server artifact uses: actions/upload-artifact@v4 @@ -71,23 +71,6 @@ jobs: name: server-bundle path: ${{env.DOTNET_ROOT}}/server - - name: Changes for static-todo.bitplatform.dev - Part 2 - run: sed -i 's/public static readonly bool PrerenderEnabled = true;/public static readonly bool PrerenderEnabled = false;/g' TodoSample/src/Client/TodoSample.Client.Core/Services/AppRenderMode.cs - - - name: Configure bswup - run: | - sed -i 's/self.noPrerenderQuery/\/\/ self.noPrerenderQuery/g' TodoSample/src/Client/TodoSample.Client.Web/wwwroot/service-worker.js - sed -i 's/self.isPassive = self.disablePassiveFirstBoot = true;/self.isPassive = self.disablePassiveFirstBoot = false;/g' TodoSample/src/Client/TodoSample.Client.Web/wwwroot/service-worker.js - - - name: Publish static todo - run: dotnet publish TodoSample/src/Client/TodoSample.Client.Web/TodoSample.Client.Web.csproj -c Release -p:BlazorWebAssemblyStandalone=true -o ${{env.DOTNET_ROOT}}/static - - - name: Upload static artifact - uses: actions/upload-artifact@v4 - with: - name: static-bundle - path: ${{env.DOTNET_ROOT}}/static - deploy_api_blazor: name: deploy api + blazor needs: build_api_blazor @@ -103,16 +86,16 @@ jobs: with: name: server-bundle - - name: Delete IdentityCertificate.pfx + - name: Delete DataProtectionCertificate.pfx run: | - rm IdentityCertificate.pfx + rm DataProtectionCertificate.pfx - name: Extract identity certificate from env uses: timheuer/base64-to-file@v1.2 with: fileDir: './' - fileName: 'IdentityCertificate.pfx' - encodedString: ${{ secrets.API_IDENTITY_CERTIFICATE_FILE_BASE64 }} + fileName: 'DataProtectionCertificate.pfx' + encodedString: ${{ secrets.API_DATA_PROTECTION_CERTIFICATE_FILE_BASE64 }} - name: Deploy to Azure Web App id: deploy-to-webapp @@ -124,7 +107,7 @@ jobs: package: . - name: Purge cache - uses: jakejarvis/cloudflare-purge-action@master + uses: jakejarvis/cloudflare-purge-action@v0.3.0 env: CLOUDFLARE_ZONE: ${{ secrets.BITPLATFORM_DEV_CLOUDFLARE_ZONE }} CLOUDFLARE_TOKEN: ${{ secrets.CLOUDFLARE_TOKEN }} @@ -152,14 +135,14 @@ jobs: cd src\Templates\Boilerplate && dotnet build -c Release dotnet pack -c Release -o . -p:ReleaseVersion=0.0.0 -p:PackageVersion=0.0.0 dotnet new install Bit.Boilerplate.0.0.0.nupkg - cd ..\..\..\ && dotnet new bit-bp --name TodoSample --database SqlServer --sample Todo --windows --appInsights --appCenter --serverUrl todo.bitplatform.dev + cd ..\..\..\ && dotnet new bit-bp --name TodoSample --database PostgreSQL --sample Todo --windows --appInsights --appCenter --serverUrl ${{ env.SERVER_ADDRESS }} --filesStorage AzureBlobStorage - - name: Update appsettings.json api server address + - name: Update core appsettings.json uses: devops-actions/variable-substitution@v1.2 with: - files: 'TodoSample\src\Client\TodoSample.Client.Core\appsettings.json' + files: 'TodoSample\src\Client\TodoSample.Client.Core\appsettings.json, TodoSample\src\Shared\appsettings.json' env: - ApiServerAddress: ${{ env.API_SERVER_ADDRESS }} + ServerAddress: ${{ env.SERVER_ADDRESS }} WindowsUpdateSettings.FilesUrl: https://windows-todo.bitplatform.dev ApplicationInsights.ConnectionString: ${{ secrets.APPLICATION_INSIGHTS_CONNECTION_STRING }} @@ -168,7 +151,7 @@ jobs: shell: pwsh - name: Generate CSS/JS files - run: dotnet build TodoSample\src\Client\TodoSample.Client.Core\TodoSample.Client.Core.csproj -t:InstallNodejsDependencies,BeforeBuildTasks -p:Version="${{ vars.APPLICATION_DISPLAY_VERSION}}" --no-restore + run: dotnet build TodoSample\src\Client\TodoSample.Client.Core\TodoSample.Client.Core.csproj -t:BeforeBuildTasks -p:Version="${{ vars.APPLICATION_DISPLAY_VERSION}}" --no-restore -c Release - name: Publish run: | @@ -186,7 +169,7 @@ jobs: echo A | xcopy .\bin\publish-x64 .\publish-result /s /e /h echo A | xcopy .\bin\publish .\publish-result /s /e /h dotnet tool restore - dotnet vpk pack -u TodoSample.Client.Windows -v "${{ vars.APPLICATION_DISPLAY_VERSION }}" -p .\publish-result -e TodoSample.Client.Windows-x86.exe -r win-x86 --framework net8.0.6-x86-desktop,net8.0.6-x86-aspnetcore,webview2 --icon .\wwwroot\favicon.ico --packTitle TodoSample + dotnet vpk pack -u TodoSample.Client.Windows -v "${{ vars.APPLICATION_DISPLAY_VERSION }}" -p .\publish-result -e TodoSample.Client.Windows-x86.exe -r win-x86 --framework net8.0.7-x86-desktop,webview2 --icon .\wwwroot\favicon.ico --packTitle TodoSample - name: Upload artifact uses: actions/upload-artifact@v4 @@ -217,7 +200,7 @@ jobs: cd src/Templates/Boilerplate && dotnet build -c Release dotnet pack -c Release -o . -p:ReleaseVersion=0.0.0 -p:PackageVersion=0.0.0 dotnet new install Bit.Boilerplate.0.0.0.nupkg - cd ../../../ && dotnet new bit-bp --name TodoSample --database SqlServer --sample Todo --appInsights --appCenter --serverUrl todo.bitplatform.dev + cd ../../../ && dotnet new bit-bp --name TodoSample --database PostgreSQL --sample Todo --appInsights --appCenter --serverUrl ${{ env.SERVER_ADDRESS }} --filesStorage AzureBlobStorage - name: Extract Android signing key from env uses: timheuer/base64-to-file@v1.2 @@ -226,12 +209,12 @@ jobs: fileName: 'TodoSample.keystore' encodedString: ${{ secrets.ANDROID_RELEASE_KEYSTORE_FILE_BASE64 }} - - name: Update appsettings.json api server address + - name: Update core appsettings.json uses: devops-actions/variable-substitution@v1.2 with: - files: 'TodoSample/src/Client/TodoSample.Client.Core/appsettings.json' + files: 'TodoSample/src/Client/TodoSample.Client.Core/appsettings.json, TodoSample/src/Shared/appsettings.json' env: - ApiServerAddress: ${{ env.API_SERVER_ADDRESS }} + ServerAddress: ${{ env.SERVER_ADDRESS }} ApplicationInsights.ConnectionString: ${{ secrets.APPLICATION_INSIGHTS_CONNECTION_STRING }} - name: Set app center secret @@ -266,8 +249,8 @@ jobs: - name: Generate CSS/JS files run: | - dotnet build TodoSample/src/Client/TodoSample.Client.Core/TodoSample.Client.Core.csproj -t:InstallNodejsDependencies,BeforeBuildTasks -p:Version="${{ vars.APPLICATION_DISPLAY_VERSION}}" --no-restore - dotnet build TodoSample/src/Client/TodoSample.Client.Maui/TodoSample.Client.Maui.csproj -t:BeforeBuildTasks -p:Version="${{ vars.APPLICATION_DISPLAY_VERSION}}" --no-restore + dotnet build TodoSample/src/Client/TodoSample.Client.Core/TodoSample.Client.Core.csproj -t:BeforeBuildTasks -p:Version="${{ vars.APPLICATION_DISPLAY_VERSION}}" --no-restore -c Release + dotnet build TodoSample/src/Client/TodoSample.Client.Maui/TodoSample.Client.Maui.csproj -t:BeforeBuildTasks -p:Version="${{ vars.APPLICATION_DISPLAY_VERSION}}" --no-restore -c Release - name: Build aab run: dotnet build TodoSample/src/Client/TodoSample.Client.Maui/TodoSample.Client.Maui.csproj -c Release -p:AndroidPackageFormat=aab -p:AndroidKeyStore=true -p:AndroidSigningKeyStore="TodoSample.keystore" -p:AndroidSigningKeyAlias=bitplatform -p:AndroidSigningKeyPass="${{ secrets.ANDROID_RELEASE_KEYSTORE_PASSWORD }}" -p:AndroidSigningStorePass="${{ secrets.ANDROID_RELEASE_SIGNING_PASSWORD }}" -p:ApplicationDisplayVersion="${{ vars.APPLICATION_DISPLAY_VERSION }}" -p:ApplicationVersion="${{ vars.APPLICATION_VERSION }}" -p:Version="${{ vars.APPLICATION_DISPLAY_VERSION}}" -p:ApplicationTitle="TodoSample" -p:ApplicationId="com.bitplatform.Todo.Template" -f net8.0-android @@ -298,21 +281,21 @@ jobs: - uses: maxim-lobanov/setup-xcode@v1.6.0 with: - xcode-version: '15.3' + xcode-version: '15.4' - name: Create project from Boilerplate run: | cd src/Templates/Boilerplate && dotnet build -c Release dotnet pack -c Release -o . -p:ReleaseVersion=0.0.0 -p:PackageVersion=0.0.0 dotnet new install Bit.Boilerplate.0.0.0.nupkg - cd ../../../ && dotnet new bit-bp --name TodoSample --database SqlServer --sample Todo --appInsights --appCenter --serverUrl todo.bitplatform.dev + cd ../../../ && dotnet new bit-bp --name TodoSample --database PostgreSQL --sample Todo --appInsights --appCenter --serverUrl ${{ env.SERVER_ADDRESS }} --filesStorage AzureBlobStorage - - name: Update appsettings.json api server address + - name: Update core appsettings.json uses: devops-actions/variable-substitution@v1.2 with: - files: 'TodoSample/src/Client/TodoSample.Client.Core/appsettings.json' + files: 'TodoSample/src/Client/TodoSample.Client.Core/appsettings.json, TodoSample/src/Shared/appsettings.json' env: - ApiServerAddress: ${{ env.API_SERVER_ADDRESS }} + ServerAddress: ${{ env.SERVER_ADDRESS }} ApplicationInsights.ConnectionString: ${{ secrets.APPLICATION_INSIGHTS_CONNECTION_STRING }} - name: Set app center secret @@ -358,8 +341,8 @@ jobs: - name: Generate CSS/JS files run: | - dotnet build TodoSample/src/Client/TodoSample.Client.Core/TodoSample.Client.Core.csproj -t:InstallNodejsDependencies,BeforeBuildTasks -p:Version="${{ vars.APPLICATION_DISPLAY_VERSION}}" --no-restore - dotnet build TodoSample/src/Client/TodoSample.Client.Maui/TodoSample.Client.Maui.csproj -t:BeforeBuildTasks -p:Version="${{ vars.APPLICATION_DISPLAY_VERSION}}" --no-restore + dotnet build TodoSample/src/Client/TodoSample.Client.Core/TodoSample.Client.Core.csproj -t:BeforeBuildTasks -p:Version="${{ vars.APPLICATION_DISPLAY_VERSION}}" --no-restore -c Release + dotnet build TodoSample/src/Client/TodoSample.Client.Maui/TodoSample.Client.Maui.csproj -t:BeforeBuildTasks -p:Version="${{ vars.APPLICATION_DISPLAY_VERSION}}" --no-restore -c Release - name: Build ipa run: dotnet publish TodoSample/src/Client/TodoSample.Client.Maui/TodoSample.Client.Maui.csproj -p:RuntimeIdentifier=ios-arm64 -c Release -p:ArchiveOnBuild=true -p:CodesignKey="iPhone Distribution" -p:CodesignProvision="TodoTemplate" -p:ApplicationDisplayVersion="${{ vars.APPLICATION_DISPLAY_VERSION }}" -p:ApplicationVersion="${{ vars.APPLICATION_VERSION }}" -p:Version="${{ vars.APPLICATION_DISPLAY_VERSION}}" -p:ApplicationTitle="Todo" -p:ApplicationId="com.bitplatform.Todo.Template" -f net8.0-ios diff --git a/README.md b/README.md index fe04ab0f1d..2693cae43a 100644 --- a/README.md +++ b/README.md @@ -3,11 +3,11 @@
![License](https://img.shields.io/github/license/bitfoundation/bitplatform.svg) -![Code size](https://img.shields.io/github/languages/code-size/bitfoundation/bitplatform.svg?logo=github) ![CI Status](https://github.com/bitfoundation/bitplatform/actions/workflows/bit.ci.yml/badge.svg) ![NuGet version](https://img.shields.io/nuget/v/bit.blazorui.svg?logo=nuget) [![Nuget downloads](https://img.shields.io/badge/packages_download-4.9M-blue.svg?logo=nuget)](https://www.nuget.org/profiles/bit-foundation) -[![](https://dcbadge.vercel.app/api/server/7bNMRNYshd?style=flat-square&compact=true&v=2)](https://discord.gg/7bNMRNYshd) +[![Average time to resolve an issue](http://isitmaintained.com/badge/resolution/bitfoundation/bitplatform.svg)](http://isitmaintained.com/project/bitfoundation/bitplatform "Average time to resolve an issue") +[![Percentage of issues still open](http://isitmaintained.com/badge/open/bitfoundation/bitplatform.svg)](http://isitmaintained.com/project/bitfoundation/bitplatform "Percentage of issues still open")
@@ -47,8 +47,7 @@ The following apps are our open-source projects powered by the bit platform show 1. [bitplatform.dev](https://bitplatform.dev): Pre-rendered SPA with Blazor WebAssembly 2. [blazorui.bitplatform.dev](https://blazorui.bitplatform.dev): Pre-rendered PWA with Blazor Auto 3. [todo.bitplatform.dev](https://todo.bitplatform.dev): Pre-rendered PWA with Blazor WebAssembly -4. [static-todo.bitplatform.dev](https://static-todo.bitplatform.dev): PWA with Blazor WebAssembly Standalone (Hosted on Cloudflare Pages) -5. [adminpanel.bitplatform.dev](https://adminpanel.bitplatform.dev): PWA with Blazor WebAssembly +5. [adminpanel.bitplatform.dev](https://adminpanel.bitplatform.dev): PWA with Blazor WebAssembly Standalone (Hosted on Cloudflare Pages) [Todo](https://todo.bitplatform.dev) & [Adminpanel](https://adminpanel.bitplatform.dev) web apps will launch their respective Android and iOS applications if you have already installed them, mirroring the behavior of apps like YouTube and Instagram. diff --git a/docs/how-to-build.md b/docs/how-to-build.md index 52eb04dea1..c405f3e2f2 100644 --- a/docs/how-to-build.md +++ b/docs/how-to-build.md @@ -22,7 +22,7 @@ building each one of them requires some specific steps that are explained below. Building each of the bit platform projects needs the following basic requirements other than the specific requirements that are explained later: -- [.NET 8 SDK (8.0.301)](https://dotnet.microsoft.com/en-us/download/dotnet/8.0) +- [.NET 8 SDK (8.0.303)](https://dotnet.microsoft.com/en-us/download/dotnet/8.0) - [Node.js](https://nodejs.org)
diff --git a/src/Besql/Bit.Besql/wwwroot/bit-besql.js b/src/Besql/Bit.Besql/wwwroot/bit-besql.js index 9c725c2abb..210e8a3cda 100644 --- a/src/Besql/Bit.Besql/wwwroot/bit-besql.js +++ b/src/Besql/Bit.Besql/wwwroot/bit-besql.js @@ -1,3 +1,6 @@ +var BitBesql = BitBesql || {}; +BitBesql.version = window['bit-besql version'] = '8.10.0'; + async function synchronizeDbWithCache(file) { window.sqlitedb = window.sqlitedb || { diff --git a/src/Besql/Demo/Bit.Besql.Demo.Client/Bit.Besql.Demo.Client.csproj b/src/Besql/Demo/Bit.Besql.Demo.Client/Bit.Besql.Demo.Client.csproj index 5b178a9274..aa8daccb14 100644 --- a/src/Besql/Demo/Bit.Besql.Demo.Client/Bit.Besql.Demo.Client.csproj +++ b/src/Besql/Demo/Bit.Besql.Demo.Client/Bit.Besql.Demo.Client.csproj @@ -10,7 +10,7 @@ - + diff --git a/src/Besql/Demo/Bit.Besql.Demo/Bit.Besql.Demo.csproj b/src/Besql/Demo/Bit.Besql.Demo/Bit.Besql.Demo.csproj index 6d5899b9e1..0132859de1 100644 --- a/src/Besql/Demo/Bit.Besql.Demo/Bit.Besql.Demo.csproj +++ b/src/Besql/Demo/Bit.Besql.Demo/Bit.Besql.Demo.csproj @@ -8,7 +8,7 @@ - + @@ -19,11 +19,11 @@ and open Nuget Package Manager Console, and select `Bit.Besql.Demo` project as default project Then run either Add-Migration MigrationName -OutputDir Data\Migrations or Optimize-DbContext -OutputDir Data/CompiledModel commands. --> - + all runtime; build; native; contentfiles; analyzers; buildtransitive - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/src/Besql/Demo/Bit.Besql.Demo/Properties/launchSettings.json b/src/Besql/Demo/Bit.Besql.Demo/Properties/launchSettings.json index 7c567208af..7f09e1b580 100644 --- a/src/Besql/Demo/Bit.Besql.Demo/Properties/launchSettings.json +++ b/src/Besql/Demo/Bit.Besql.Demo/Properties/launchSettings.json @@ -1,41 +1,15 @@ { - "$schema": "http://json.schemastore.org/launchsettings.json", - "iisSettings": { - "windowsAuthentication": false, - "anonymousAuthentication": true, - "iisExpress": { - "applicationUrl": "http://localhost:1558", - "sslPort": 44374 - } - }, + "$schema": "http://json.schemastore.org/launchsettings.json", "profiles": { - "http": { - "commandName": "Project", - "dotnetRunMessages": true, - "launchBrowser": true, - "inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}", - "applicationUrl": "http://localhost:5222", - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" + "Bit.Besql.Demo": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}", + "applicationUrl": "https://localhost:5050;http://localhost:5051", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } } - }, - "https": { - "commandName": "Project", - "dotnetRunMessages": true, - "launchBrowser": true, - "inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}", - "applicationUrl": "https://localhost:7046;http://localhost:5222", - "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/Bit-CI.sln b/src/Bit-CI.sln index 252a40f537..c333ad2606 100644 --- a/src/Bit-CI.sln +++ b/src/Bit-CI.sln @@ -1,4 +1,3 @@ - Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 17 VisualStudioVersion = 17.0.31808.319 @@ -143,7 +142,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Boilerplate", "Boilerplate" Templates\Boilerplate\Bit.Boilerplate\Clean.bat = Templates\Boilerplate\Bit.Boilerplate\Clean.bat Templates\Boilerplate\Bit.Boilerplate\src\Directory.Build.props = Templates\Boilerplate\Bit.Boilerplate\src\Directory.Build.props Templates\Boilerplate\Bit.Boilerplate\global.json = Templates\Boilerplate\Bit.Boilerplate\global.json - Templates\Boilerplate\Readme.md = Templates\Boilerplate\Readme.md + Templates\Boilerplate\README.md = Templates\Boilerplate\README.md EndProjectSection EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".azure-devops", ".azure-devops", "{D08A374C-FB7C-4C29-86B8-3C16344BCBD2}" @@ -166,7 +165,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Bit.Boilerplate.ProjectTemp EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Client", "Client", "{EEAF80AE-EC5F-4E55-BD4D-CE7075D67C90}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Boilerplate.Shared", "Templates\Boilerplate\Bit.Boilerplate\src\Boilerplate.Shared\Boilerplate.Shared.csproj", "{91D0FEF4-872C-4DEF-AC93-E7D088B1A145}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Boilerplate.Shared", "Templates\Boilerplate\Bit.Boilerplate\src\Shared\Boilerplate.Shared.csproj", "{91D0FEF4-872C-4DEF-AC93-E7D088B1A145}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Boilerplate.Client.Maui", "Templates\Boilerplate\Bit.Boilerplate\src\Client\Boilerplate.Client.Maui\Boilerplate.Client.Maui.csproj", "{CA4A30E2-F844-4026-9CC2-6839FD28BF44}" EndProject @@ -174,14 +173,12 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Boilerplate.Client.Core", " EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Boilerplate.Client.Web", "Templates\Boilerplate\Bit.Boilerplate\src\Client\Boilerplate.Client.Web\Boilerplate.Client.Web.csproj", "{0749CBB8-8694-470C-B5F3-7428963A2F7D}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Boilerplate.Server", "Templates\Boilerplate\Bit.Boilerplate\src\Boilerplate.Server\Boilerplate.Server.csproj", "{8654B9AF-3598-49E6-A8FE-159F8F537733}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Boilerplate.Server.Web", "Templates\Boilerplate\Bit.Boilerplate\src\Server\Boilerplate.Server.Web\Boilerplate.Server.Web.csproj", "{8654B9AF-3598-49E6-A8FE-159F8F537733}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Bit.Websites.Platform.Client", "Websites\Platform\src\Bit.Websites.Platform.Client\Bit.Websites.Platform.Client.csproj", "{69FC9651-E55F-4DC3-AFFA-104B4FACCB0F}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Bit.Websites.Platform.Server", "Websites\Platform\src\Bit.Websites.Platform.Server\Bit.Websites.Platform.Server.csproj", "{FB1E2F03-F064-4B14-9B51-A5F39AB47E9F}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Boilerplate.Iac", "Templates\Boilerplate\Bit.Boilerplate\src\Boilerplate.Iac\Boilerplate.Iac.csproj", "{8DD94797-A476-4E69-85B5-6B2069EBDAF5}" -EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{62253EDF-1D35-4184-8E2B-3CC1C419F2C0}" ProjectSection(SolutionItems) = preProject ..\.github\workflows\admin-sample.cd.yml = ..\.github\workflows\admin-sample.cd.yml @@ -236,6 +233,12 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Bit.BlazorUI.Demo.Client.Wi EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Boilerplate.Client.Windows", "Templates\Boilerplate\Bit.Boilerplate\src\Client\Boilerplate.Client.Windows\Boilerplate.Client.Windows.csproj", "{5021C89A-8AB8-4345-B8C4-E1B4F1F20BE7}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Boilerplate.Server.Api", "Templates\Boilerplate\Bit.Boilerplate\src\Server\Boilerplate.Server.Api\Boilerplate.Server.Api.csproj", "{44BE8600-E77F-487C-830B-DF3CC8B77E6D}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Server", "Server", "{5FF50FF2-B1F8-4CBE-B063-F02E0936B7F5}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Shared", "Shared", "{26C5360A-67A4-423E-9E9F-06442776E096}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -900,26 +903,6 @@ Global {FB1E2F03-F064-4B14-9B51-A5F39AB47E9F}.Release|x64.Build.0 = Release|Any CPU {FB1E2F03-F064-4B14-9B51-A5F39AB47E9F}.Release|x86.ActiveCfg = Release|Any CPU {FB1E2F03-F064-4B14-9B51-A5F39AB47E9F}.Release|x86.Build.0 = Release|Any CPU - {8DD94797-A476-4E69-85B5-6B2069EBDAF5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {8DD94797-A476-4E69-85B5-6B2069EBDAF5}.Debug|Any CPU.Build.0 = Debug|Any CPU - {8DD94797-A476-4E69-85B5-6B2069EBDAF5}.Debug|iPhone.ActiveCfg = Debug|Any CPU - {8DD94797-A476-4E69-85B5-6B2069EBDAF5}.Debug|iPhone.Build.0 = Debug|Any CPU - {8DD94797-A476-4E69-85B5-6B2069EBDAF5}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {8DD94797-A476-4E69-85B5-6B2069EBDAF5}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU - {8DD94797-A476-4E69-85B5-6B2069EBDAF5}.Debug|x64.ActiveCfg = Debug|Any CPU - {8DD94797-A476-4E69-85B5-6B2069EBDAF5}.Debug|x64.Build.0 = Debug|Any CPU - {8DD94797-A476-4E69-85B5-6B2069EBDAF5}.Debug|x86.ActiveCfg = Debug|Any CPU - {8DD94797-A476-4E69-85B5-6B2069EBDAF5}.Debug|x86.Build.0 = Debug|Any CPU - {8DD94797-A476-4E69-85B5-6B2069EBDAF5}.Release|Any CPU.ActiveCfg = Release|Any CPU - {8DD94797-A476-4E69-85B5-6B2069EBDAF5}.Release|Any CPU.Build.0 = Release|Any CPU - {8DD94797-A476-4E69-85B5-6B2069EBDAF5}.Release|iPhone.ActiveCfg = Release|Any CPU - {8DD94797-A476-4E69-85B5-6B2069EBDAF5}.Release|iPhone.Build.0 = Release|Any CPU - {8DD94797-A476-4E69-85B5-6B2069EBDAF5}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU - {8DD94797-A476-4E69-85B5-6B2069EBDAF5}.Release|iPhoneSimulator.Build.0 = Release|Any CPU - {8DD94797-A476-4E69-85B5-6B2069EBDAF5}.Release|x64.ActiveCfg = Release|Any CPU - {8DD94797-A476-4E69-85B5-6B2069EBDAF5}.Release|x64.Build.0 = Release|Any CPU - {8DD94797-A476-4E69-85B5-6B2069EBDAF5}.Release|x86.ActiveCfg = Release|Any CPU - {8DD94797-A476-4E69-85B5-6B2069EBDAF5}.Release|x86.Build.0 = Release|Any CPU {1D46B4BC-95B0-4706-AB64-69F4F66D09AA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {1D46B4BC-95B0-4706-AB64-69F4F66D09AA}.Debug|Any CPU.Build.0 = Debug|Any CPU {1D46B4BC-95B0-4706-AB64-69F4F66D09AA}.Debug|iPhone.ActiveCfg = Debug|Any CPU @@ -1231,13 +1214,35 @@ Global {5021C89A-8AB8-4345-B8C4-E1B4F1F20BE7}.Release|x64.Build.0 = Release|Any CPU {5021C89A-8AB8-4345-B8C4-E1B4F1F20BE7}.Release|x86.ActiveCfg = Release|Any CPU {5021C89A-8AB8-4345-B8C4-E1B4F1F20BE7}.Release|x86.Build.0 = Release|Any CPU + {44BE8600-E77F-487C-830B-DF3CC8B77E6D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {44BE8600-E77F-487C-830B-DF3CC8B77E6D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {44BE8600-E77F-487C-830B-DF3CC8B77E6D}.Debug|iPhone.ActiveCfg = Debug|Any CPU + {44BE8600-E77F-487C-830B-DF3CC8B77E6D}.Debug|iPhone.Build.0 = Debug|Any CPU + {44BE8600-E77F-487C-830B-DF3CC8B77E6D}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {44BE8600-E77F-487C-830B-DF3CC8B77E6D}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU + {44BE8600-E77F-487C-830B-DF3CC8B77E6D}.Debug|x64.ActiveCfg = Debug|Any CPU + {44BE8600-E77F-487C-830B-DF3CC8B77E6D}.Debug|x64.Build.0 = Debug|Any CPU + {44BE8600-E77F-487C-830B-DF3CC8B77E6D}.Debug|x86.ActiveCfg = Debug|Any CPU + {44BE8600-E77F-487C-830B-DF3CC8B77E6D}.Debug|x86.Build.0 = Debug|Any CPU + {44BE8600-E77F-487C-830B-DF3CC8B77E6D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {44BE8600-E77F-487C-830B-DF3CC8B77E6D}.Release|Any CPU.Build.0 = Release|Any CPU + {44BE8600-E77F-487C-830B-DF3CC8B77E6D}.Release|iPhone.ActiveCfg = Release|Any CPU + {44BE8600-E77F-487C-830B-DF3CC8B77E6D}.Release|iPhone.Build.0 = Release|Any CPU + {44BE8600-E77F-487C-830B-DF3CC8B77E6D}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU + {44BE8600-E77F-487C-830B-DF3CC8B77E6D}.Release|iPhoneSimulator.Build.0 = Release|Any CPU + {44BE8600-E77F-487C-830B-DF3CC8B77E6D}.Release|x64.ActiveCfg = Release|Any CPU + {44BE8600-E77F-487C-830B-DF3CC8B77E6D}.Release|x64.Build.0 = Release|Any CPU + {44BE8600-E77F-487C-830B-DF3CC8B77E6D}.Release|x86.ActiveCfg = Release|Any CPU + {44BE8600-E77F-487C-830B-DF3CC8B77E6D}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection GlobalSection(NestedProjects) = preSolution {23426B1A-CC46-4D11-B233-208A57B2BCA2} = {DC165533-038F-4D71-9BA1-44CF254E116F} + {26C5360A-67A4-423E-9E9F-06442776E096} = {B07A45DA-F7B7-4AF0-BE64-54DAE906FC01} {48C1BB77-8B36-4EAD-B52F-CDC8A875D120} = {DC165533-038F-4D71-9BA1-44CF254E116F} + {5FF50FF2-B1F8-4CBE-B063-F02E0936B7F5} = {B07A45DA-F7B7-4AF0-BE64-54DAE906FC01} {FA10EFB6-6DA4-48BA-8969-8C605581B33F} = {DC165533-038F-4D71-9BA1-44CF254E116F} {F169FDFD-F1FC-43D4-9C80-D1D956A006C6} = {C6EBC527-A489-44B4-A951-D023107A577F} {B49D51B5-E173-4BBF-B645-6B876EB3A23F} = {C6EBC527-A489-44B4-A951-D023107A577F} @@ -1273,14 +1278,13 @@ Global {F96FD99F-E0C5-40C9-B4B9-C4AF03DCFAF7} = {D08A374C-FB7C-4C29-86B8-3C16344BCBD2} {52345787-7B00-41AA-A366-88392073C4DD} = {B07A45DA-F7B7-4AF0-BE64-54DAE906FC01} {EEAF80AE-EC5F-4E55-BD4D-CE7075D67C90} = {B07A45DA-F7B7-4AF0-BE64-54DAE906FC01} - {91D0FEF4-872C-4DEF-AC93-E7D088B1A145} = {B07A45DA-F7B7-4AF0-BE64-54DAE906FC01} + {91D0FEF4-872C-4DEF-AC93-E7D088B1A145} = {26C5360A-67A4-423E-9E9F-06442776E096} {CA4A30E2-F844-4026-9CC2-6839FD28BF44} = {EEAF80AE-EC5F-4E55-BD4D-CE7075D67C90} {EA92A298-A595-4405-BB55-B0844237DFFF} = {EEAF80AE-EC5F-4E55-BD4D-CE7075D67C90} {0749CBB8-8694-470C-B5F3-7428963A2F7D} = {EEAF80AE-EC5F-4E55-BD4D-CE7075D67C90} - {8654B9AF-3598-49E6-A8FE-159F8F537733} = {B07A45DA-F7B7-4AF0-BE64-54DAE906FC01} + {8654B9AF-3598-49E6-A8FE-159F8F537733} = {5FF50FF2-B1F8-4CBE-B063-F02E0936B7F5} {69FC9651-E55F-4DC3-AFFA-104B4FACCB0F} = {0691024C-D19B-41C0-AA76-7CBC1A875831} {FB1E2F03-F064-4B14-9B51-A5F39AB47E9F} = {0691024C-D19B-41C0-AA76-7CBC1A875831} - {8DD94797-A476-4E69-85B5-6B2069EBDAF5} = {B07A45DA-F7B7-4AF0-BE64-54DAE906FC01} {62253EDF-1D35-4184-8E2B-3CC1C419F2C0} = {EF6EF35E-9612-4B2A-8BFE-41234BFCAD78} {D7242830-A91D-4729-BF2D-B1E7E141953E} = {23426B1A-CC46-4D11-B233-208A57B2BCA2} {1D46B4BC-95B0-4706-AB64-69F4F66D09AA} = {D7242830-A91D-4729-BF2D-B1E7E141953E} @@ -1300,6 +1304,7 @@ Global {610E87D1-63A1-4D78-BA84-6E90DDDCF138} = {C6EBC527-A489-44B4-A951-D023107A577F} {62F75EFA-BF6D-4B61-8CA9-6E071806827B} = {D7242830-A91D-4729-BF2D-B1E7E141953E} {5021C89A-8AB8-4345-B8C4-E1B4F1F20BE7} = {EEAF80AE-EC5F-4E55-BD4D-CE7075D67C90} + {44BE8600-E77F-487C-830B-DF3CC8B77E6D} = {5FF50FF2-B1F8-4CBE-B063-F02E0936B7F5} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {DA107107-478F-477A-872B-787CEA7DD9B8} diff --git a/src/Bit.Build.props b/src/Bit.Build.props index f42ec5d2bb..973824c4c0 100644 --- a/src/Bit.Build.props +++ b/src/Bit.Build.props @@ -25,7 +25,7 @@ https://github.com/bitfoundation/bitplatform https://avatars.githubusercontent.com/u/22663390 - 8.9.0 + 8.10.0 https://github.com/bitfoundation/bitplatform/releases/tag/v-$(ReleaseVersion) $(ReleaseVersion) diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/Bit.BlazorUI.Assets.csproj b/src/BlazorUI/Bit.BlazorUI.Assets/Bit.BlazorUI.Assets.csproj index d73dfc6231..55c1b88153 100644 --- a/src/BlazorUI/Bit.BlazorUI.Assets/Bit.BlazorUI.Assets.csproj +++ b/src/BlazorUI/Bit.BlazorUI.Assets/Bit.BlazorUI.Assets.csproj @@ -7,7 +7,6 @@ Bit.BlazorUI 0 - InstallNodejsDependencies; BeforeBuildTasks; $(ResolveStaticWebAssetsInputsDependsOn) @@ -21,14 +20,20 @@ + - + + + + + + - - + + diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/package-lock.json b/src/BlazorUI/Bit.BlazorUI.Assets/package-lock.json index 9e43f4f795..d8e763d495 100644 --- a/src/BlazorUI/Bit.BlazorUI.Assets/package-lock.json +++ b/src/BlazorUI/Bit.BlazorUI.Assets/package-lock.json @@ -5,7 +5,7 @@ "packages": { "": { "devDependencies": { - "sass": "1.77.2" + "sass": "1.77.8" } }, "node_modules/anymatch": { @@ -189,9 +189,9 @@ } }, "node_modules/sass": { - "version": "1.77.2", - "resolved": "https://registry.npmjs.org/sass/-/sass-1.77.2.tgz", - "integrity": "sha512-eb4GZt1C3avsX3heBNlrc7I09nyT00IUuo4eFhAbeXWU2fvA7oXI53SxODVAA+zgZCk9aunAZgO+losjR3fAwA==", + "version": "1.77.8", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.77.8.tgz", + "integrity": "sha512-4UHg6prsrycW20fqLGPShtEvo/WyHRVRHwOP4DzkUrObWoWI05QBSfzU71TVB7PFaL104TwNaHpjlWXAZbQiNQ==", "dev": true, "dependencies": { "chokidar": ">=3.0.0 <4.0.0", diff --git a/src/BlazorUI/Bit.BlazorUI.Assets/package.json b/src/BlazorUI/Bit.BlazorUI.Assets/package.json index 4dc91e335b..ea5cb1f7da 100644 --- a/src/BlazorUI/Bit.BlazorUI.Assets/package.json +++ b/src/BlazorUI/Bit.BlazorUI.Assets/package.json @@ -1,5 +1,5 @@ { "devDependencies": { - "sass": "1.77.2" + "sass": "1.77.8" } } diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/Bit.BlazorUI.Extras.csproj b/src/BlazorUI/Bit.BlazorUI.Extras/Bit.BlazorUI.Extras.csproj index 65d85e8f93..efe43245e2 100644 --- a/src/BlazorUI/Bit.BlazorUI.Extras/Bit.BlazorUI.Extras.csproj +++ b/src/BlazorUI/Bit.BlazorUI.Extras/Bit.BlazorUI.Extras.csproj @@ -9,7 +9,6 @@ false 0 - InstallNodejsDependencies; BeforeBuildTasks; $(ResolveStaticWebAssetsInputsDependsOn) @@ -51,16 +50,30 @@ - + + + + + + + + + + + + - - + + + + + True diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/Components/DataGrid/BitDataGrid.scss b/src/BlazorUI/Bit.BlazorUI.Extras/Components/DataGrid/BitDataGrid.scss index 2e6429a5a2..ca30743ff1 100644 --- a/src/BlazorUI/Bit.BlazorUI.Extras/Components/DataGrid/BitDataGrid.scss +++ b/src/BlazorUI/Bit.BlazorUI.Extras/Components/DataGrid/BitDataGrid.scss @@ -5,6 +5,10 @@ */ .bitdatagrid { + /*========================================================*/ + /*default theme*/ + /*========================================================*/ + --col-gap: 1rem; th { position: relative; /* So that col-options appears next to it */ @@ -58,8 +62,8 @@ border: 1px solid; position: absolute; inset-inline-start: 0; - border-color: var(--bit-clr-brd-primary); - background-color: var(--bit-clr-bg-secondary); + border-color: var(--bit-clr-brd-pri); + background-color: var(--bit-clr-bg-sec); } .col-justify-end .col-options { @@ -134,10 +138,6 @@ white-space: nowrap; text-overflow: ellipsis; } - /*========================================================*/ - /*default theme*/ - /*========================================================*/ - --col-gap: 1rem; .col-header-content { padding-right: var(--col-gap); @@ -183,7 +183,7 @@ inset-block-end: 5px; inset-block-start: 5px; inset-inline-start: 0.5rem; - border-color: var(--bit-clr-brd-primary); + border-color: var(--bit-clr-brd-pri); } > tbody > tr > td.grid-cell-placeholder:after { diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/Components/DataGrid/Pagination/BitDataGridPaginator.scss b/src/BlazorUI/Bit.BlazorUI.Extras/Components/DataGrid/Pagination/BitDataGridPaginator.scss index 894564a535..a5c88d6333 100644 --- a/src/BlazorUI/Bit.BlazorUI.Extras/Components/DataGrid/Pagination/BitDataGridPaginator.scss +++ b/src/BlazorUI/Bit.BlazorUI.Extras/Components/DataGrid/Pagination/BitDataGridPaginator.scss @@ -28,11 +28,11 @@ } nav button:not([disabled]):hover { - background-color: var(--bit-clr-act-hover-bg-pri); + background-color: var(--bit-clr-bg-pri-hover); } nav button:not([disabled]):active { - background-color: var(--bit-clr-act-active-bg-pri); + background-color: var(--bit-clr-bg-pri-active); } .go-first:before, diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/package-lock.json b/src/BlazorUI/Bit.BlazorUI.Extras/package-lock.json index 5558a8afbc..8e4d81141d 100644 --- a/src/BlazorUI/Bit.BlazorUI.Extras/package-lock.json +++ b/src/BlazorUI/Bit.BlazorUI.Extras/package-lock.json @@ -5,15 +5,15 @@ "packages": { "": { "devDependencies": { - "esbuild": "0.21.4", - "sass": "1.77.2", - "typescript": "5.4.5" + "esbuild": "0.23.0", + "sass": "1.77.8", + "typescript": "5.5.4" } }, "node_modules/@esbuild/aix-ppc64": { - "version": "0.21.4", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.4.tgz", - "integrity": "sha512-Zrm+B33R4LWPLjDEVnEqt2+SLTATlru1q/xYKVn8oVTbiRBGmK2VIMoIYGJDGyftnGaC788IuzGFAlb7IQ0Y8A==", + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.23.0.tgz", + "integrity": "sha512-3sG8Zwa5fMcA9bgqB8AfWPQ+HFke6uD3h1s3RIwUNK8EG7a4buxvuFTs3j1IMs2NXAk9F30C/FF4vxRgQCcmoQ==", "cpu": [ "ppc64" ], @@ -23,13 +23,13 @@ "aix" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/android-arm": { - "version": "0.21.4", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.4.tgz", - "integrity": "sha512-E7H/yTd8kGQfY4z9t3nRPk/hrhaCajfA3YSQSBrst8B+3uTcgsi8N+ZWYCaeIDsiVs6m65JPCaQN/DxBRclF3A==", + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.23.0.tgz", + "integrity": "sha512-+KuOHTKKyIKgEEqKbGTK8W7mPp+hKinbMBeEnNzjJGyFcWsfrXjSTNluJHCY1RqhxFurdD8uNXQDei7qDlR6+g==", "cpu": [ "arm" ], @@ -39,13 +39,13 @@ "android" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/android-arm64": { - "version": "0.21.4", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.4.tgz", - "integrity": "sha512-fYFnz+ObClJ3dNiITySBUx+oNalYUT18/AryMxfovLkYWbutXsct3Wz2ZWAcGGppp+RVVX5FiXeLYGi97umisA==", + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.23.0.tgz", + "integrity": "sha512-EuHFUYkAVfU4qBdyivULuu03FhJO4IJN9PGuABGrFy4vUuzk91P2d+npxHcFdpUnfYKy0PuV+n6bKIpHOB3prQ==", "cpu": [ "arm64" ], @@ -55,13 +55,13 @@ "android" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/android-x64": { - "version": "0.21.4", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.4.tgz", - "integrity": "sha512-mDqmlge3hFbEPbCWxp4fM6hqq7aZfLEHZAKGP9viq9wMUBVQx202aDIfc3l+d2cKhUJM741VrCXEzRFhPDKH3Q==", + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.23.0.tgz", + "integrity": "sha512-WRrmKidLoKDl56LsbBMhzTTBxrsVwTKdNbKDalbEZr0tcsBgCLbEtoNthOW6PX942YiYq8HzEnb4yWQMLQuipQ==", "cpu": [ "x64" ], @@ -71,13 +71,13 @@ "android" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/darwin-arm64": { - "version": "0.21.4", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.4.tgz", - "integrity": "sha512-72eaIrDZDSiWqpmCzVaBD58c8ea8cw/U0fq/PPOTqE3c53D0xVMRt2ooIABZ6/wj99Y+h4ksT/+I+srCDLU9TA==", + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.23.0.tgz", + "integrity": "sha512-YLntie/IdS31H54Ogdn+v50NuoWF5BDkEUFpiOChVa9UnKpftgwzZRrI4J132ETIi+D8n6xh9IviFV3eXdxfow==", "cpu": [ "arm64" ], @@ -87,13 +87,13 @@ "darwin" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/darwin-x64": { - "version": "0.21.4", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.4.tgz", - "integrity": "sha512-uBsuwRMehGmw1JC7Vecu/upOjTsMhgahmDkWhGLWxIgUn2x/Y4tIwUZngsmVb6XyPSTXJYS4YiASKPcm9Zitag==", + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.23.0.tgz", + "integrity": "sha512-IMQ6eme4AfznElesHUPDZ+teuGwoRmVuuixu7sv92ZkdQcPbsNHzutd+rAfaBKo8YK3IrBEi9SLLKWJdEvJniQ==", "cpu": [ "x64" ], @@ -103,13 +103,13 @@ "darwin" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/freebsd-arm64": { - "version": "0.21.4", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.4.tgz", - "integrity": "sha512-8JfuSC6YMSAEIZIWNL3GtdUT5NhUA/CMUCpZdDRolUXNAXEE/Vbpe6qlGLpfThtY5NwXq8Hi4nJy4YfPh+TwAg==", + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.23.0.tgz", + "integrity": "sha512-0muYWCng5vqaxobq6LB3YNtevDFSAZGlgtLoAc81PjUfiFz36n4KMpwhtAd4he8ToSI3TGyuhyx5xmiWNYZFyw==", "cpu": [ "arm64" ], @@ -119,13 +119,13 @@ "freebsd" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/freebsd-x64": { - "version": "0.21.4", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.4.tgz", - "integrity": "sha512-8d9y9eQhxv4ef7JmXny7591P/PYsDFc4+STaxC1GBv0tMyCdyWfXu2jBuqRsyhY8uL2HU8uPyscgE2KxCY9imQ==", + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.23.0.tgz", + "integrity": "sha512-XKDVu8IsD0/q3foBzsXGt/KjD/yTKBCIwOHE1XwiXmrRwrX6Hbnd5Eqn/WvDekddK21tfszBSrE/WMaZh+1buQ==", "cpu": [ "x64" ], @@ -135,13 +135,13 @@ "freebsd" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-arm": { - "version": "0.21.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.4.tgz", - "integrity": "sha512-2rqFFefpYmpMs+FWjkzSgXg5vViocqpq5a1PSRgT0AvSgxoXmGF17qfGAzKedg6wAwyM7UltrKVo9kxaJLMF/g==", + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.23.0.tgz", + "integrity": "sha512-SEELSTEtOFu5LPykzA395Mc+54RMg1EUgXP+iw2SJ72+ooMwVsgfuwXo5Fn0wXNgWZsTVHwY2cg4Vi/bOD88qw==", "cpu": [ "arm" ], @@ -151,13 +151,13 @@ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-arm64": { - "version": "0.21.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.4.tgz", - "integrity": "sha512-/GLD2orjNU50v9PcxNpYZi+y8dJ7e7/LhQukN3S4jNDXCKkyyiyAz9zDw3siZ7Eh1tRcnCHAo/WcqKMzmi4eMQ==", + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.23.0.tgz", + "integrity": "sha512-j1t5iG8jE7BhonbsEg5d9qOYcVZv/Rv6tghaXM/Ug9xahM0nX/H2gfu6X6z11QRTMT6+aywOMA8TDkhPo8aCGw==", "cpu": [ "arm64" ], @@ -167,13 +167,13 @@ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-ia32": { - "version": "0.21.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.4.tgz", - "integrity": "sha512-pNftBl7m/tFG3t2m/tSjuYeWIffzwAZT9m08+9DPLizxVOsUl8DdFzn9HvJrTQwe3wvJnwTdl92AonY36w/25g==", + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.23.0.tgz", + "integrity": "sha512-P7O5Tkh2NbgIm2R6x1zGJJsnacDzTFcRWZyTTMgFdVit6E98LTxO+v8LCCLWRvPrjdzXHx9FEOA8oAZPyApWUA==", "cpu": [ "ia32" ], @@ -183,13 +183,13 @@ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-loong64": { - "version": "0.21.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.4.tgz", - "integrity": "sha512-cSD2gzCK5LuVX+hszzXQzlWya6c7hilO71L9h4KHwqI4qeqZ57bAtkgcC2YioXjsbfAv4lPn3qe3b00Zt+jIfQ==", + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.23.0.tgz", + "integrity": "sha512-InQwepswq6urikQiIC/kkx412fqUZudBO4SYKu0N+tGhXRWUqAx+Q+341tFV6QdBifpjYgUndV1hhMq3WeJi7A==", "cpu": [ "loong64" ], @@ -199,13 +199,13 @@ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-mips64el": { - "version": "0.21.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.4.tgz", - "integrity": "sha512-qtzAd3BJh7UdbiXCrg6npWLYU0YpufsV9XlufKhMhYMJGJCdfX/G6+PNd0+v877X1JG5VmjBLUiFB0o8EUSicA==", + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.23.0.tgz", + "integrity": "sha512-J9rflLtqdYrxHv2FqXE2i1ELgNjT+JFURt/uDMoPQLcjWQA5wDKgQA4t/dTqGa88ZVECKaD0TctwsUfHbVoi4w==", "cpu": [ "mips64el" ], @@ -215,13 +215,13 @@ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-ppc64": { - "version": "0.21.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.4.tgz", - "integrity": "sha512-yB8AYzOTaL0D5+2a4xEy7OVvbcypvDR05MsB/VVPVA7nL4hc5w5Dyd/ddnayStDgJE59fAgNEOdLhBxjfx5+dg==", + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.23.0.tgz", + "integrity": "sha512-cShCXtEOVc5GxU0fM+dsFD10qZ5UpcQ8AM22bYj0u/yaAykWnqXJDpd77ublcX6vdDsWLuweeuSNZk4yUxZwtw==", "cpu": [ "ppc64" ], @@ -231,13 +231,13 @@ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-riscv64": { - "version": "0.21.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.4.tgz", - "integrity": "sha512-Y5AgOuVzPjQdgU59ramLoqSSiXddu7F3F+LI5hYy/d1UHN7K5oLzYBDZe23QmQJ9PIVUXwOdKJ/jZahPdxzm9w==", + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.23.0.tgz", + "integrity": "sha512-HEtaN7Y5UB4tZPeQmgz/UhzoEyYftbMXrBCUjINGjh3uil+rB/QzzpMshz3cNUxqXN7Vr93zzVtpIDL99t9aRw==", "cpu": [ "riscv64" ], @@ -247,13 +247,13 @@ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-s390x": { - "version": "0.21.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.4.tgz", - "integrity": "sha512-Iqc/l/FFwtt8FoTK9riYv9zQNms7B8u+vAI/rxKuN10HgQIXaPzKZc479lZ0x6+vKVQbu55GdpYpeNWzjOhgbA==", + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.23.0.tgz", + "integrity": "sha512-WDi3+NVAuyjg/Wxi+o5KPqRbZY0QhI9TjrEEm+8dmpY9Xir8+HE/HNx2JoLckhKbFopW0RdO2D72w8trZOV+Wg==", "cpu": [ "s390x" ], @@ -263,13 +263,13 @@ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-x64": { - "version": "0.21.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.4.tgz", - "integrity": "sha512-Td9jv782UMAFsuLZINfUpoF5mZIbAj+jv1YVtE58rFtfvoKRiKSkRGQfHTgKamLVT/fO7203bHa3wU122V/Bdg==", + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.23.0.tgz", + "integrity": "sha512-a3pMQhUEJkITgAw6e0bWA+F+vFtCciMjW/LPtoj99MhVt+Mfb6bbL9hu2wmTZgNd994qTAEw+U/r6k3qHWWaOQ==", "cpu": [ "x64" ], @@ -279,13 +279,13 @@ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/netbsd-x64": { - "version": "0.21.4", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.4.tgz", - "integrity": "sha512-Awn38oSXxsPMQxaV0Ipb7W/gxZtk5Tx3+W+rAPdZkyEhQ6968r9NvtkjhnhbEgWXYbgV+JEONJ6PcdBS+nlcpA==", + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.23.0.tgz", + "integrity": "sha512-cRK+YDem7lFTs2Q5nEv/HHc4LnrfBCbH5+JHu6wm2eP+d8OZNoSMYgPZJq78vqQ9g+9+nMuIsAO7skzphRXHyw==", "cpu": [ "x64" ], @@ -295,13 +295,29 @@ "netbsd" ], "engines": { - "node": ">=12" + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.23.0.tgz", + "integrity": "sha512-suXjq53gERueVWu0OKxzWqk7NxiUWSUlrxoZK7usiF50C6ipColGR5qie2496iKGYNLhDZkPxBI3erbnYkU0rQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" } }, "node_modules/@esbuild/openbsd-x64": { - "version": "0.21.4", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.4.tgz", - "integrity": "sha512-IsUmQeCY0aU374R82fxIPu6vkOybWIMc3hVGZ3ChRwL9hA1TwY+tS0lgFWV5+F1+1ssuvvXt3HFqe8roCip8Hg==", + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.23.0.tgz", + "integrity": "sha512-6p3nHpby0DM/v15IFKMjAaayFhqnXV52aEmv1whZHX56pdkK+MEaLoQWj+H42ssFarP1PcomVhbsR4pkz09qBg==", "cpu": [ "x64" ], @@ -311,13 +327,13 @@ "openbsd" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/sunos-x64": { - "version": "0.21.4", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.4.tgz", - "integrity": "sha512-hsKhgZ4teLUaDA6FG/QIu2q0rI6I36tZVfM4DBZv3BG0mkMIdEnMbhc4xwLvLJSS22uWmaVkFkqWgIS0gPIm+A==", + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.23.0.tgz", + "integrity": "sha512-BFelBGfrBwk6LVrmFzCq1u1dZbG4zy/Kp93w2+y83Q5UGYF1d8sCzeLI9NXjKyujjBBniQa8R8PzLFAUrSM9OA==", "cpu": [ "x64" ], @@ -327,13 +343,13 @@ "sunos" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/win32-arm64": { - "version": "0.21.4", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.4.tgz", - "integrity": "sha512-UUfMgMoXPoA/bvGUNfUBFLCh0gt9dxZYIx9W4rfJr7+hKe5jxxHmfOK8YSH4qsHLLN4Ck8JZ+v7Q5fIm1huErg==", + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.23.0.tgz", + "integrity": "sha512-lY6AC8p4Cnb7xYHuIxQ6iYPe6MfO2CC43XXKo9nBXDb35krYt7KGhQnOkRGar5psxYkircpCqfbNDB4uJbS2jQ==", "cpu": [ "arm64" ], @@ -343,13 +359,13 @@ "win32" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/win32-ia32": { - "version": "0.21.4", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.4.tgz", - "integrity": "sha512-yIxbspZb5kGCAHWm8dexALQ9en1IYDfErzjSEq1KzXFniHv019VT3mNtTK7t8qdy4TwT6QYHI9sEZabONHg+aw==", + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.23.0.tgz", + "integrity": "sha512-7L1bHlOTcO4ByvI7OXVI5pNN6HSu6pUQq9yodga8izeuB1KcT2UkHaH6118QJwopExPn0rMHIseCTx1CRo/uNA==", "cpu": [ "ia32" ], @@ -359,13 +375,13 @@ "win32" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/win32-x64": { - "version": "0.21.4", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.4.tgz", - "integrity": "sha512-sywLRD3UK/qRJt0oBwdpYLBibk7KiRfbswmWRDabuncQYSlf8aLEEUor/oP6KRz8KEG+HoiVLBhPRD5JWjS8Sg==", + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.23.0.tgz", + "integrity": "sha512-Arm+WgUFLUATuoxCJcahGuk6Yj9Pzxd6l11Zb/2aAuv5kWWvvfhLFo2fni4uSK5vzlUdCGZ/BdV5tH8klj8p8g==", "cpu": [ "x64" ], @@ -375,7 +391,7 @@ "win32" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/anymatch": { @@ -440,41 +456,42 @@ } }, "node_modules/esbuild": { - "version": "0.21.4", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.4.tgz", - "integrity": "sha512-sFMcNNrj+Q0ZDolrp5pDhH0nRPN9hLIM3fRPwgbLYJeSHHgnXSnbV3xYgSVuOeLWH9c73VwmEverVzupIv5xuA==", + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.23.0.tgz", + "integrity": "sha512-1lvV17H2bMYda/WaFb2jLPeHU3zml2k4/yagNMG8Q/YtfMjCwEUZa2eXXMgZTVSL5q1n4H7sQ0X6CdJDqqeCFA==", "dev": true, "hasInstallScript": true, "bin": { "esbuild": "bin/esbuild" }, "engines": { - "node": ">=12" + "node": ">=18" }, "optionalDependencies": { - "@esbuild/aix-ppc64": "0.21.4", - "@esbuild/android-arm": "0.21.4", - "@esbuild/android-arm64": "0.21.4", - "@esbuild/android-x64": "0.21.4", - "@esbuild/darwin-arm64": "0.21.4", - "@esbuild/darwin-x64": "0.21.4", - "@esbuild/freebsd-arm64": "0.21.4", - "@esbuild/freebsd-x64": "0.21.4", - "@esbuild/linux-arm": "0.21.4", - "@esbuild/linux-arm64": "0.21.4", - "@esbuild/linux-ia32": "0.21.4", - "@esbuild/linux-loong64": "0.21.4", - "@esbuild/linux-mips64el": "0.21.4", - "@esbuild/linux-ppc64": "0.21.4", - "@esbuild/linux-riscv64": "0.21.4", - "@esbuild/linux-s390x": "0.21.4", - "@esbuild/linux-x64": "0.21.4", - "@esbuild/netbsd-x64": "0.21.4", - "@esbuild/openbsd-x64": "0.21.4", - "@esbuild/sunos-x64": "0.21.4", - "@esbuild/win32-arm64": "0.21.4", - "@esbuild/win32-ia32": "0.21.4", - "@esbuild/win32-x64": "0.21.4" + "@esbuild/aix-ppc64": "0.23.0", + "@esbuild/android-arm": "0.23.0", + "@esbuild/android-arm64": "0.23.0", + "@esbuild/android-x64": "0.23.0", + "@esbuild/darwin-arm64": "0.23.0", + "@esbuild/darwin-x64": "0.23.0", + "@esbuild/freebsd-arm64": "0.23.0", + "@esbuild/freebsd-x64": "0.23.0", + "@esbuild/linux-arm": "0.23.0", + "@esbuild/linux-arm64": "0.23.0", + "@esbuild/linux-ia32": "0.23.0", + "@esbuild/linux-loong64": "0.23.0", + "@esbuild/linux-mips64el": "0.23.0", + "@esbuild/linux-ppc64": "0.23.0", + "@esbuild/linux-riscv64": "0.23.0", + "@esbuild/linux-s390x": "0.23.0", + "@esbuild/linux-x64": "0.23.0", + "@esbuild/netbsd-x64": "0.23.0", + "@esbuild/openbsd-arm64": "0.23.0", + "@esbuild/openbsd-x64": "0.23.0", + "@esbuild/sunos-x64": "0.23.0", + "@esbuild/win32-arm64": "0.23.0", + "@esbuild/win32-ia32": "0.23.0", + "@esbuild/win32-x64": "0.23.0" } }, "node_modules/fill-range": { @@ -597,9 +614,9 @@ } }, "node_modules/sass": { - "version": "1.77.2", - "resolved": "https://registry.npmjs.org/sass/-/sass-1.77.2.tgz", - "integrity": "sha512-eb4GZt1C3avsX3heBNlrc7I09nyT00IUuo4eFhAbeXWU2fvA7oXI53SxODVAA+zgZCk9aunAZgO+losjR3fAwA==", + "version": "1.77.8", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.77.8.tgz", + "integrity": "sha512-4UHg6prsrycW20fqLGPShtEvo/WyHRVRHwOP4DzkUrObWoWI05QBSfzU71TVB7PFaL104TwNaHpjlWXAZbQiNQ==", "dev": true, "dependencies": { "chokidar": ">=3.0.0 <4.0.0", @@ -635,10 +652,11 @@ } }, "node_modules/typescript": { - "version": "5.4.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz", - "integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==", + "version": "5.5.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.4.tgz", + "integrity": "sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==", "dev": true, + "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" diff --git a/src/BlazorUI/Bit.BlazorUI.Extras/package.json b/src/BlazorUI/Bit.BlazorUI.Extras/package.json index 6a96365976..7a62a6a112 100644 --- a/src/BlazorUI/Bit.BlazorUI.Extras/package.json +++ b/src/BlazorUI/Bit.BlazorUI.Extras/package.json @@ -1,7 +1,7 @@ { "devDependencies": { - "esbuild": "0.21.4", - "sass": "1.77.2", - "typescript": "5.4.5" + "esbuild": "0.23.0", + "sass": "1.77.8", + "typescript": "5.5.4" } } diff --git a/src/BlazorUI/Bit.BlazorUI.Icons/Bit.BlazorUI.Icons.csproj b/src/BlazorUI/Bit.BlazorUI.Icons/Bit.BlazorUI.Icons.csproj index 8dff850c83..32b08f24d7 100644 --- a/src/BlazorUI/Bit.BlazorUI.Icons/Bit.BlazorUI.Icons.csproj +++ b/src/BlazorUI/Bit.BlazorUI.Icons/Bit.BlazorUI.Icons.csproj @@ -7,7 +7,6 @@ Bit.BlazorUI 0 - InstallNodejsDependencies; BeforeBuildTasks; $(ResolveStaticWebAssetsInputsDependsOn) @@ -23,12 +22,21 @@ - + + + + + + + + + + - - + + diff --git a/src/BlazorUI/Bit.BlazorUI.Icons/package-lock.json b/src/BlazorUI/Bit.BlazorUI.Icons/package-lock.json index d60344ad33..41826ee258 100644 --- a/src/BlazorUI/Bit.BlazorUI.Icons/package-lock.json +++ b/src/BlazorUI/Bit.BlazorUI.Icons/package-lock.json @@ -5,7 +5,7 @@ "packages": { "": { "devDependencies": { - "sass": "1.77.2" + "sass": "1.77.8" } }, "node_modules/anymatch": { @@ -189,9 +189,9 @@ } }, "node_modules/sass": { - "version": "1.77.2", - "resolved": "https://registry.npmjs.org/sass/-/sass-1.77.2.tgz", - "integrity": "sha512-eb4GZt1C3avsX3heBNlrc7I09nyT00IUuo4eFhAbeXWU2fvA7oXI53SxODVAA+zgZCk9aunAZgO+losjR3fAwA==", + "version": "1.77.8", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.77.8.tgz", + "integrity": "sha512-4UHg6prsrycW20fqLGPShtEvo/WyHRVRHwOP4DzkUrObWoWI05QBSfzU71TVB7PFaL104TwNaHpjlWXAZbQiNQ==", "dev": true, "dependencies": { "chokidar": ">=3.0.0 <4.0.0", diff --git a/src/BlazorUI/Bit.BlazorUI.Icons/package.json b/src/BlazorUI/Bit.BlazorUI.Icons/package.json index 4dc91e335b..ea5cb1f7da 100644 --- a/src/BlazorUI/Bit.BlazorUI.Icons/package.json +++ b/src/BlazorUI/Bit.BlazorUI.Icons/package.json @@ -1,5 +1,5 @@ { "devDependencies": { - "sass": "1.77.2" + "sass": "1.77.8" } } diff --git a/src/BlazorUI/Bit.BlazorUI.SourceGenerators/Bit.BlazorUI.SourceGenerators.csproj b/src/BlazorUI/Bit.BlazorUI.SourceGenerators/Bit.BlazorUI.SourceGenerators.csproj index 97ee9a8ef5..ad1f0f2270 100644 --- a/src/BlazorUI/Bit.BlazorUI.SourceGenerators/Bit.BlazorUI.SourceGenerators.csproj +++ b/src/BlazorUI/Bit.BlazorUI.SourceGenerators/Bit.BlazorUI.SourceGenerators.csproj @@ -1,7 +1,7 @@  netstandard2.0 - 11.0 + 12.0 enable true diff --git a/src/BlazorUI/Bit.BlazorUI.SourceGenerators/Blazor/BitProperty.cs b/src/BlazorUI/Bit.BlazorUI.SourceGenerators/Blazor/BitProperty.cs deleted file mode 100644 index 96956ff88f..0000000000 --- a/src/BlazorUI/Bit.BlazorUI.SourceGenerators/Blazor/BitProperty.cs +++ /dev/null @@ -1,15 +0,0 @@ -using Microsoft.CodeAnalysis; - -namespace Bit.BlazorUI.SourceGenerators.Blazor; - -public class BitProperty -{ - public BitProperty(IPropertySymbol propertySymbol, bool isTwoWayBoundProperty) - { - PropertySymbol = propertySymbol; - IsTwoWayBoundProperty = isTwoWayBoundProperty; - } - - public IPropertySymbol PropertySymbol { get; set; } - public bool IsTwoWayBoundProperty { get; set; } -} diff --git a/src/BlazorUI/Bit.BlazorUI.SourceGenerators/Blazor/BlazorParameterPropertySyntaxReceiver.cs b/src/BlazorUI/Bit.BlazorUI.SourceGenerators/Blazor/BlazorParameterPropertySyntaxReceiver.cs deleted file mode 100644 index 66173cbc6c..0000000000 --- a/src/BlazorUI/Bit.BlazorUI.SourceGenerators/Blazor/BlazorParameterPropertySyntaxReceiver.cs +++ /dev/null @@ -1,42 +0,0 @@ -using System.Collections.Generic; -using System.Linq; -using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.CSharp; -using Microsoft.CodeAnalysis.CSharp.Syntax; - -namespace Bit.BlazorUI.SourceGenerators.Blazor; - -public class BlazorParameterPropertySyntaxReceiver : ISyntaxContextReceiver -{ - public IList Properties { get; } = new List(); - - public void OnVisitSyntaxNode(GeneratorSyntaxContext context) - { - if (context.Node is not PropertyDeclarationSyntax propertyDeclarationSyntax || !propertyDeclarationSyntax.AttributeLists.Any()) return; - - var parent = propertyDeclarationSyntax.Parent; - - if (parent is null || parent.IsKind(SyntaxKind.ClassDeclaration) is false) return; - - var classDeclarationSyntax = (ClassDeclarationSyntax?)parent; - - if (classDeclarationSyntax?.Modifiers.Any(k => k.IsKind(SyntaxKind.PartialKeyword)) is false) return; - - var propertySymbol = context.SemanticModel.GetDeclaredSymbol(propertyDeclarationSyntax); - - if (propertySymbol is null) return; - - var type = propertySymbol.ContainingType; - - if (type == null) return; - - if (type.GetMembers().Any(m => m.Name == "SetParametersAsync")) return; - - - if (propertySymbol.GetAttributes().Any(ad => ad.AttributeClass?.ToDisplayString() == "Microsoft.AspNetCore.Components.ParameterAttribute" - || ad.AttributeClass?.ToDisplayString() == "Microsoft.AspNetCore.Components.CascadingParameterAttribute")) - { - Properties.Add(propertySymbol); - } - } -} diff --git a/src/BlazorUI/Bit.BlazorUI.SourceGenerators/Blazor/BlazorSetParametersSourceGenerator.cs b/src/BlazorUI/Bit.BlazorUI.SourceGenerators/Blazor/BlazorSetParametersSourceGenerator.cs deleted file mode 100644 index 0757a20910..0000000000 --- a/src/BlazorUI/Bit.BlazorUI.SourceGenerators/Blazor/BlazorSetParametersSourceGenerator.cs +++ /dev/null @@ -1,118 +0,0 @@ -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.Text; - -namespace Bit.BlazorUI.SourceGenerators.Blazor; - -[Generator] -public class BlazorSetParametersSourceGenerator : ISourceGenerator -{ - public void Execute(GeneratorExecutionContext context) - { - if (context.SyntaxContextReceiver is not BlazorParameterPropertySyntaxReceiver receiver) return; - - foreach (var group in receiver.Properties.GroupBy(symbol => symbol.ContainingType, SymbolEqualityComparer.Default)) - { - var properties = group.Select(p => new BitProperty(p, false)).ToList(); - CheckTwoWayBoundParameter(properties); - - if (group.Key == null) continue; - - string classSource = GeneratePartialClassToOverrideSetParameters((INamedTypeSymbol)group.Key, properties); - context.AddSource($"{group.Key.Name}_SetParametersAsync.AutoGenerated.cs", SourceText.From(classSource, Encoding.UTF8)); - } - } - - public void Initialize(GeneratorInitializationContext context) - { - context.RegisterForSyntaxNotifications(() => new BlazorParameterPropertySyntaxReceiver()); - } - - private static string GeneratePartialClassToOverrideSetParameters(INamedTypeSymbol classSymbol, List properties) - { - string namespaceName = classSymbol.ContainingNamespace.ToDisplayString(); - bool isBase = classSymbol.BaseType?.ToDisplayString() == "Microsoft.AspNetCore.Components.ComponentBase"; - - StringBuilder source = new StringBuilder($@"using System; -using System.Threading.Tasks; -using System.Collections.Generic; -using Microsoft.AspNetCore.Components; -using Microsoft.AspNetCore.Components.Web; - -namespace {namespaceName} -{{ - public partial class {GetClassName(classSymbol)} - {{ - [global::System.Diagnostics.DebuggerNonUserCode] - [global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] - public override Task SetParametersAsync(ParameterView parameters) - {{ -"); - foreach (var property in properties.Where(p => p.IsTwoWayBoundProperty)) - { - source.AppendLine($" {property.PropertySymbol.Name}HasBeenSet = false;"); - } - source.AppendLine(" var parametersDictionary = parameters.ToDictionary() as Dictionary;"); - source.AppendLine(" foreach (var parameter in parametersDictionary!)"); - source.AppendLine(" {"); - source.AppendLine(" switch (parameter.Key)"); - source.AppendLine(" {"); - - // create cases for each property - foreach (var bitProperty in properties) - { - source.AppendLine($" case nameof({bitProperty.PropertySymbol.Name}):"); - if (bitProperty.IsTwoWayBoundProperty) - { - source.AppendLine($" {bitProperty.PropertySymbol.Name}HasBeenSet = true;"); - } - source.AppendLine($" {bitProperty.PropertySymbol.Name} = parameter.Value is null ? default! : ({bitProperty.PropertySymbol.Type.ToDisplayString()})parameter.Value;"); - source.AppendLine(" parametersDictionary.Remove(parameter.Key);"); - source.AppendLine(" break;"); - } - - source.AppendLine(" }"); - source.AppendLine(" }"); - - if (isBase) - { - source.AppendLine(" return base.SetParametersAsync(ParameterView.Empty);"); - } - else - { - source.AppendLine(" return base.SetParametersAsync(ParameterView.FromDictionary(parametersDictionary as IDictionary));"); - } - - source.AppendLine(" }"); - source.AppendLine(" }"); - source.AppendLine("}"); - - return source.ToString(); - } - - private static string GetClassName(INamedTypeSymbol classSymbol) - { - StringBuilder sbName = new StringBuilder(classSymbol.Name); - - if (classSymbol.IsGenericType) - { - sbName.Append('<'); - sbName.Append(string.Join(", ", classSymbol.TypeArguments.Select(s => s.Name))); - sbName.Append('>'); - } - - return sbName.ToString(); - } - - private static void CheckTwoWayBoundParameter(List properties) - { - foreach (var item in properties) - { - var propName = $"{item.PropertySymbol.Name}Changed"; - var propType = $"Microsoft.AspNetCore.Components.EventCallback<{item.PropertySymbol.Type.ToDisplayString()}>"; - item.IsTwoWayBoundProperty = properties.Any(p => p.PropertySymbol.Name == propName && p.PropertySymbol.Type.ToDisplayString() == propType); - } - } -} diff --git a/src/BlazorUI/Bit.BlazorUI.SourceGenerators/Component/BlazorParameter.cs b/src/BlazorUI/Bit.BlazorUI.SourceGenerators/Component/BlazorParameter.cs new file mode 100644 index 0000000000..23f2433ebf --- /dev/null +++ b/src/BlazorUI/Bit.BlazorUI.SourceGenerators/Component/BlazorParameter.cs @@ -0,0 +1,15 @@ +using Microsoft.CodeAnalysis; + +namespace Bit.BlazorUI.SourceGenerators.Component; + +public class BlazorParameter(IPropertySymbol propertySymbol, bool resetClassBuilder, bool resetStyleBuilder, bool isTwoWayBound) +{ + public IPropertySymbol PropertySymbol { get; set; } = propertySymbol; + + public bool IsTwoWayBound { get; set; } = isTwoWayBound; + + public bool ResetClassBuilder { get; set; } = resetClassBuilder; + public bool ResetStyleBuilder { get; set; } = resetStyleBuilder; + + public string? CallOnSetMethodName { get; set; } +} diff --git a/src/BlazorUI/Bit.BlazorUI.SourceGenerators/Component/ComponentSourceGenerator.cs b/src/BlazorUI/Bit.BlazorUI.SourceGenerators/Component/ComponentSourceGenerator.cs new file mode 100644 index 0000000000..7a67744444 --- /dev/null +++ b/src/BlazorUI/Bit.BlazorUI.SourceGenerators/Component/ComponentSourceGenerator.cs @@ -0,0 +1,174 @@ +using System.Linq; +using System.Text; +using System.Collections.Generic; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.Text; + +namespace Bit.BlazorUI.SourceGenerators.Component; + +[Generator] +public class ComponentSourceGenerator : ISourceGenerator +{ + public void Initialize(GeneratorInitializationContext context) + { + context.RegisterForSyntaxNotifications(() => new ComponentSyntaxContextReceiver()); + } + + public void Execute(GeneratorExecutionContext context) + { + if (context.SyntaxContextReceiver is not ComponentSyntaxContextReceiver receiver) return; + + foreach (var parametersGroup in receiver.Parameters.GroupBy(p => p.PropertySymbol.ContainingType, SymbolEqualityComparer.Default)) + { + var parameters = parametersGroup.ToList(); + + if (parametersGroup.Key == null) continue; + + string classSource = GeneratePartialClass((INamedTypeSymbol)parametersGroup.Key, parameters); + context.AddSource($"{parametersGroup.Key.Name}_SetParametersAsync.AutoGenerated.cs", SourceText.From(classSource, Encoding.UTF8)); + } + } + + private static string GeneratePartialClass(INamedTypeSymbol classSymbol, List parameters) + { + var namespaceName = classSymbol.ContainingNamespace.ToDisplayString(); + var className = GetClassName(classSymbol); + var twoWayParameters = parameters.Where(p => p.IsTwoWayBound).ToArray(); + var isBaseTypeComponentBase = classSymbol.BaseType?.ToDisplayString() == "Microsoft.AspNetCore.Components.ComponentBase"; + + StringBuilder builder = new StringBuilder($@"using System; +using System.Threading.Tasks; +using System.Collections.Generic; +using Microsoft.AspNetCore.Components; +using Microsoft.AspNetCore.Components.Web; + +namespace {namespaceName} +{{ + public partial class {className} + {{ +"); + foreach (var par in twoWayParameters) + { + var sym = par.PropertySymbol; + builder.AppendLine($" private bool {sym.Name}HasBeenSet;"); + builder.AppendLine($" [Parameter] public EventCallback<{sym.Type.ToDisplayString()}> {sym.Name}Changed {{ get; set; }}"); + } + if (twoWayParameters.Length > 0) builder.AppendLine(""); + builder.AppendLine($@" [global::System.Diagnostics.DebuggerNonUserCode] + [global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] + public override Task SetParametersAsync(ParameterView parameters) + {{"); + foreach (var par in twoWayParameters) + { + builder.AppendLine($" {par.PropertySymbol.Name}HasBeenSet = false;"); + } + builder.AppendLine(" var parametersDictionary = parameters.ToDictionary() as Dictionary;"); + builder.AppendLine(" foreach (var parameter in parametersDictionary!)"); + builder.AppendLine(" {"); + builder.AppendLine(" switch (parameter.Key)"); + builder.AppendLine(" {"); + foreach (var par in parameters) + { + var sym = par.PropertySymbol; + var paramName = sym.Name; + var varName = $"@{paramName.ToLower()}"; + var paramType = sym.Type.ToDisplayString(); + builder.AppendLine($" case nameof({paramName}):"); + if (par.IsTwoWayBound) + { + builder.AppendLine($" {paramName}HasBeenSet = true;"); + } + builder.AppendLine($" var {varName} = parameter.Value is null ? default! : ({paramType})parameter.Value;"); + if (par.ResetClassBuilder || par.ResetStyleBuilder || string.IsNullOrWhiteSpace(par.CallOnSetMethodName) is false) + { + builder.AppendLine($" var notEquals{paramName} = EqualityComparer<{paramType}>.Default.Equals({paramName}, {varName}) is false;"); + } + builder.AppendLine($" {paramName} = {varName};"); + if (par.ResetClassBuilder) + { + builder.AppendLine($" if (notEquals{paramName}) ClassBuilder.Reset();"); + } + if (par.ResetStyleBuilder) + { + builder.AppendLine($" if (notEquals{paramName}) StyleBuilder.Reset();"); + } + if (string.IsNullOrWhiteSpace(par.CallOnSetMethodName) is false) + { + builder.AppendLine($" if (notEquals{paramName}) {par.CallOnSetMethodName}();"); + } + builder.AppendLine(" parametersDictionary.Remove(parameter.Key);"); + builder.AppendLine(" break;"); + if (par.IsTwoWayBound) + { + paramName = $"{paramName}Changed"; + varName = $"@{paramName.ToLower()}"; + builder.AppendLine($" case nameof({paramName}):"); + builder.AppendLine($" var {varName} = parameter.Value is null ? default! : (EventCallback<{sym.Type.ToDisplayString()}>)parameter.Value;"); + builder.AppendLine($" {paramName} = {varName};"); + builder.AppendLine(" parametersDictionary.Remove(parameter.Key);"); + builder.AppendLine(" break;"); + } + } + builder.AppendLine(" }"); + builder.AppendLine(" }"); + if (isBaseTypeComponentBase) + { + builder.AppendLine(" return base.SetParametersAsync(ParameterView.Empty);"); + } + else + { + builder.AppendLine(" return base.SetParametersAsync(ParameterView.FromDictionary(parametersDictionary as IDictionary));"); + } + builder.AppendLine(@" }"); + + if (twoWayParameters.Length > 0) builder.AppendLine(""); + foreach (var par in twoWayParameters) + { + var paramName = par.PropertySymbol.Name; + var paramType = par.PropertySymbol.Type.ToDisplayString(); + builder.AppendLine($@" [global::System.Diagnostics.DebuggerNonUserCode] + [global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] + public async Task Assign{paramName}({paramType} value) + {{"); + builder.AppendLine($" if ({paramName}HasBeenSet && {paramName}Changed.HasDelegate is false) return false;"); + builder.AppendLine($" if (EqualityComparer<{paramType}>.Default.Equals({paramName}, value) is false)"); + builder.AppendLine(" {"); + builder.AppendLine($" {paramName} = value;"); + builder.AppendLine($" await {paramName}Changed.InvokeAsync(value);"); + if (par.ResetClassBuilder) + { + builder.AppendLine($" ClassBuilder.Reset();"); + } + if (par.ResetStyleBuilder) + { + builder.AppendLine($" StyleBuilder.Reset();"); + } + if (string.IsNullOrWhiteSpace(par.CallOnSetMethodName) is false) + { + builder.AppendLine($" {par.CallOnSetMethodName}();"); + } + builder.AppendLine(" }"); + builder.AppendLine($" return true;"); + builder.AppendLine(" }"); + } + + builder.AppendLine(" }"); + builder.AppendLine("}"); + + return builder.ToString(); + } + + private static string GetClassName(INamedTypeSymbol classSymbol) + { + StringBuilder sbName = new StringBuilder(classSymbol.Name); + + if (classSymbol.IsGenericType) + { + sbName.Append('<'); + sbName.Append(string.Join(", ", classSymbol.TypeArguments.Select(s => s.Name))); + sbName.Append('>'); + } + + return sbName.ToString(); + } +} diff --git a/src/BlazorUI/Bit.BlazorUI.SourceGenerators/Component/ComponentSyntaxContextReceiver.cs b/src/BlazorUI/Bit.BlazorUI.SourceGenerators/Component/ComponentSyntaxContextReceiver.cs new file mode 100644 index 0000000000..fba159951d --- /dev/null +++ b/src/BlazorUI/Bit.BlazorUI.SourceGenerators/Component/ComponentSyntaxContextReceiver.cs @@ -0,0 +1,54 @@ +using System.Linq; +using System.Collections.Generic; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp; +using Microsoft.CodeAnalysis.CSharp.Syntax; + +namespace Bit.BlazorUI.SourceGenerators.Component; + +public class ComponentSyntaxContextReceiver : ISyntaxContextReceiver +{ + public IList Parameters { get; } = []; + + public void OnVisitSyntaxNode(GeneratorSyntaxContext context) + { + if (context.Node is not PropertyDeclarationSyntax propertyDeclarationSyntax || !propertyDeclarationSyntax.AttributeLists.Any()) return; + + var parent = propertyDeclarationSyntax.Parent; + + if (parent is null || parent.IsKind(SyntaxKind.ClassDeclaration) is false) return; + + var classDeclarationSyntax = (ClassDeclarationSyntax?)parent; + + if (classDeclarationSyntax?.Modifiers.Any(k => k.IsKind(SyntaxKind.PartialKeyword)) is false) return; + + var propertySymbol = context.SemanticModel.GetDeclaredSymbol(propertyDeclarationSyntax); + + if (propertySymbol is null) return; + + var type = propertySymbol.ContainingType; + + if (type == null) return; + + if (type.GetMembers().Any(m => m.Name == "SetParametersAsync")) return; + + var attributes = propertySymbol.GetAttributes(); + + if (attributes.Any(ad => ad.AttributeClass?.ToDisplayString() == "Microsoft.AspNetCore.Components.ParameterAttribute" || + ad.AttributeClass?.ToDisplayString() == "Microsoft.AspNetCore.Components.CascadingParameterAttribute")) + { + var resetClassBuilder = attributes.Any(a => a.AttributeClass?.ToDisplayString() == "Bit.BlazorUI.ResetClassBuilderAttribute"); + var resetStyleBuilder = attributes.Any(a => a.AttributeClass?.ToDisplayString() == "Bit.BlazorUI.ResetStyleBuilderAttribute"); + var isTwoWayBound = attributes.Any(a => a.AttributeClass?.ToDisplayString() == "Bit.BlazorUI.TwoWayBoundAttribute"); + + var parameter = new BlazorParameter(propertySymbol, resetClassBuilder, resetStyleBuilder, isTwoWayBound); + + var callOnSetAttribute = attributes.SingleOrDefault(a => a.AttributeClass?.ToDisplayString() == "Bit.BlazorUI.CallOnSetAttribute"); + var name = callOnSetAttribute?.ConstructorArguments.FirstOrDefault().Value as string; + + parameter.CallOnSetMethodName = name; + + Parameters.Add(parameter); + } + } +} diff --git a/src/BlazorUI/Bit.BlazorUI.SourceGenerators/Properties/launchSettings.json b/src/BlazorUI/Bit.BlazorUI.SourceGenerators/Properties/launchSettings.json new file mode 100644 index 0000000000..b60f815dfb --- /dev/null +++ b/src/BlazorUI/Bit.BlazorUI.SourceGenerators/Properties/launchSettings.json @@ -0,0 +1,8 @@ +{ + "profiles": { + "Debug with BlazorUI": { + "commandName": "DebugRoslynComponent", + "targetProject": "..\\Bit.BlazorUI\\Bit.BlazorUI.csproj" + } + } +} \ No newline at end of file diff --git a/src/BlazorUI/Bit.BlazorUI.Tests/Bit.BlazorUI.Tests.csproj b/src/BlazorUI/Bit.BlazorUI.Tests/Bit.BlazorUI.Tests.csproj index 2af9b98896..5e8760215a 100644 --- a/src/BlazorUI/Bit.BlazorUI.Tests/Bit.BlazorUI.Tests.csproj +++ b/src/BlazorUI/Bit.BlazorUI.Tests/Bit.BlazorUI.Tests.csproj @@ -7,16 +7,16 @@ - + - + - - + + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/src/BlazorUI/Bit.BlazorUI.Tests/Buttons/BitCompoundButtonTests.cs b/src/BlazorUI/Bit.BlazorUI.Tests/Buttons/BitCompoundButtonTests.cs deleted file mode 100644 index a86c6128ed..0000000000 --- a/src/BlazorUI/Bit.BlazorUI.Tests/Buttons/BitCompoundButtonTests.cs +++ /dev/null @@ -1,180 +0,0 @@ -using System; -using Bunit; -using Microsoft.VisualStudio.TestTools.UnitTesting; - -namespace Bit.BlazorUI.Tests.Buttons; - -[TestClass] -public class BitCompoundButtonTests : BunitTestContext -{ - [DataTestMethod, - DataRow(true, BitButtonStyle.Primary), - DataRow(true, BitButtonStyle.Standard), - DataRow(false, BitButtonStyle.Primary), - DataRow(false, BitButtonStyle.Standard) - ] - public void BitCompoundButtonTest(bool isEnabled, BitButtonStyle style) - { - var clicked = false; - var com = RenderComponent(parameters => - { - parameters.Add(p => p.IsEnabled, isEnabled); - parameters.Add(p => p.ButtonStyle, style); - parameters.Add(p => p.OnClick, () => clicked = true); - }); - - var bitButton = com.Find(".bit-cmb"); - - if (isEnabled) - { - Assert.IsFalse(bitButton.ClassList.Contains("bit-dis")); - } - else - { - Assert.IsTrue(bitButton.ClassList.Contains("bit-dis")); - } - - bitButton.Click(); - - Assert.AreEqual(isEnabled, clicked); - } - - [DataTestMethod, - DataRow(true, BitButtonStyle.Primary, false, false), - DataRow(true, BitButtonStyle.Standard, true, false), - DataRow(false, BitButtonStyle.Primary, false, true), - DataRow(false, BitButtonStyle.Standard, true, false), - ] - public void BitCompoundButtonDisabledFocusTest(bool isEnabled, BitButtonStyle style, bool allowDisabledFocus, bool expectedResult) - { - var com = RenderComponent(parameters => - { - parameters.Add(p => p.IsEnabled, isEnabled); - parameters.Add(p => p.ButtonStyle, style); - parameters.Add(p => p.AllowDisabledFocus, allowDisabledFocus); - }); - - var bitButton = com.Find(".bit-cmb"); - - var hasTabindexAttr = bitButton.HasAttribute("tabindex"); - - Assert.AreEqual(hasTabindexAttr, expectedResult); - - if (hasTabindexAttr) - { - Assert.IsTrue(bitButton.GetAttribute("tabindex").Equals("-1")); - } - } - - [DataTestMethod, DataRow("Detailed description")] - public void BitCompoundButtonAriaDescriptionTest(string ariaDescription) - { - var com = RenderComponent(parameters => - { - parameters.Add(p => p.AriaDescription, ariaDescription); - }); - - var bitCompoundButton = com.Find(".bit-cmb"); - - Assert.IsTrue(bitCompoundButton.GetAttribute("aria-describedby").Contains(ariaDescription)); - } - - [DataTestMethod, DataRow("Detailed label")] - public void BitCompoundButtonAriaLabelTest(string ariaLabel) - { - var com = RenderComponent(parameters => - { - parameters.Add(p => p.AriaLabel, ariaLabel); - }); - - var bitCompoundButton = com.Find(".bit-cmb"); - - Assert.IsTrue(bitCompoundButton.GetAttribute("aria-label").Contains(ariaLabel)); - } - - [DataTestMethod, DataRow(true, true), DataRow(false, false), DataRow(null, false)] - public void BitCompoundButtonAriaHiddenTest(bool ariaHidden, bool expectedResult) - { - var com = RenderComponent(parameters => - { - parameters.Add(p => p.AriaHidden, ariaHidden); - }); - - var bitCompoundButton = com.Find(".bit-cmb"); - - Assert.AreEqual(bitCompoundButton.HasAttribute("aria-hidden"), expectedResult); - } - - [DataTestMethod, - DataRow("", true), - DataRow("bing.com", true), - DataRow("bing.com", false) - ] - public void BitCompoundButtonShouldRenderExpectedElementBasedOnHref(string href, bool isEnabled) - { - var component = RenderComponent(parameters => - { - parameters.Add(p => p.Href, href); - parameters.Add(p => p.IsEnabled, isEnabled); - }); - - var bitCompoundButton = component.Find(".bit-cmb"); - var tagName = bitCompoundButton.TagName; - var expectedElement = href.HasValue() && isEnabled ? "a" : "button"; - - Assert.AreEqual(expectedElement, tagName, ignoreCase: true); - } - - [DataTestMethod, - DataRow(BitButtonStyle.Primary), - DataRow(BitButtonStyle.Standard), - DataRow(null), - ] - public void BitCompoundButtonTypeOfButtonStyleTest(BitButtonStyle? buttonStyle) - { - var component = RenderComponent(parameters => - { - if (buttonStyle.HasValue) - { - parameters.Add(p => p.ButtonStyle, buttonStyle.Value); - } - }); - - var bitCompoundButton = component.Find(".bit-cmb"); - - if (buttonStyle == BitButtonStyle.Standard) - { - Assert.IsFalse(bitCompoundButton.ClassList.Contains("bit-cmb-pri")); - Assert.IsTrue(bitCompoundButton.ClassList.Contains("bit-cmb-std")); - } - else - { - Assert.IsTrue(bitCompoundButton.ClassList.Contains("bit-cmb-pri")); - Assert.IsFalse(bitCompoundButton.ClassList.Contains("bit-cmb-std")); - } - } - - [DataTestMethod, - DataRow(BitButtonType.Button), - DataRow(BitButtonType.Submit), - DataRow(BitButtonType.Reset) - ] - public void BitCompoundButtonTypeOfButtonTest(BitButtonType buttonType) - { - var component = RenderComponent(parameters => - { - parameters.Add(p => p.ButtonType, buttonType); - }); - - var bitCompoundButton = component.Find(".bit-cmb"); - - var buttonTypeName = buttonType switch - { - BitButtonType.Button => "button", - BitButtonType.Submit => "submit", - BitButtonType.Reset => "reset", - _ => throw new NotSupportedException(), - }; - Assert.AreEqual(bitCompoundButton.GetAttribute("type"), buttonTypeName); - } -} diff --git a/src/BlazorUI/Bit.BlazorUI.Tests/Buttons/BitIconButtonTests.cs b/src/BlazorUI/Bit.BlazorUI.Tests/Buttons/BitIconButtonTests.cs deleted file mode 100644 index 459ceb02ad..0000000000 --- a/src/BlazorUI/Bit.BlazorUI.Tests/Buttons/BitIconButtonTests.cs +++ /dev/null @@ -1,193 +0,0 @@ -using System; -using Bunit; -using Microsoft.AspNetCore.Components.Forms; -using Microsoft.VisualStudio.TestTools.UnitTesting; - -namespace Bit.BlazorUI.Tests.Buttons; - -[TestClass] -public class BitIconButtonTests : BunitTestContext -{ - [DataTestMethod, - DataRow(true, "Emoji2", null), - DataRow(false, "Emoji2", null), - DataRow(true, "Emoji2", "I'm Happy"), - DataRow(false, "Emoji2", "I'm Happy") - ] - public void BitIconButtonTest(bool isEnabled, string iconName, string title) - { - var clicked = false; - var com = RenderComponent(parameters => - { - parameters.Add(p => p.IsEnabled, isEnabled); - parameters.Add(p => p.IconName, iconName); - parameters.Add(p => p.Title, title); - parameters.Add(p => p.OnClick, () => clicked = true); - }); - - var bitIconButton = com.Find(".bit-icb"); - - if (isEnabled) - { - Assert.IsFalse(bitIconButton.ClassList.Contains("bit-dis")); - } - else - { - Assert.IsTrue(bitIconButton.ClassList.Contains("bit-dis")); - } - - var bitIconITag = com.Find(".bit-icb > span.bit-icb-ict > i.bit-icon"); - Assert.IsTrue(bitIconITag.ClassList.Contains($"bit-icon--{iconName}")); - - if (title.HasValue()) - { - Assert.IsTrue(bitIconButton.GetAttribute("title").Contains(title)); - } - - bitIconButton.Click(); - - Assert.AreEqual(isEnabled, clicked); - } - - [DataTestMethod, - DataRow(true, false), - DataRow(true, true), - DataRow(false, false), - DataRow(false, true) - ] - public void BitIconButtonDisabledFocusTest(bool isEnabled, bool allowDisabledFocus) - { - var com = RenderComponent(parameters => - { - parameters.Add(p => p.IsEnabled, isEnabled); - parameters.Add(p => p.AllowDisabledFocus, allowDisabledFocus); - }); - - var bitButton = com.Find(".bit-icb"); - - var hasTabindexAttr = bitButton.HasAttribute("tabindex"); - - var expectedResult = isEnabled ? false : allowDisabledFocus ? false : true; - - Assert.AreEqual(hasTabindexAttr, expectedResult); - - if (hasTabindexAttr) - { - Assert.IsTrue(bitButton.GetAttribute("tabindex").Equals("-1")); - } - } - - [DataTestMethod, DataRow("Detailed description")] - public void BitIconButtonAriaDescriptionTest(string ariaDescription) - { - var com = RenderComponent(parameters => - { - parameters.Add(p => p.AriaDescription, ariaDescription); - }); - - var bitIconButton = com.Find(".bit-icb"); - - Assert.IsTrue(bitIconButton.GetAttribute("aria-describedby").Contains(ariaDescription)); - } - - [DataTestMethod, DataRow("Detailed label")] - public void BitIconButtonAriaLabelTest(string ariaLabel) - { - var com = RenderComponent(parameters => - { - parameters.Add(p => p.AriaLabel, ariaLabel); - }); - - var bitIconButton = com.Find(".bit-icb"); - - Assert.IsTrue(bitIconButton.GetAttribute("aria-label").Contains(ariaLabel)); - } - - [DataTestMethod, - DataRow(true), - DataRow(false), - DataRow(null) - ] - public void BitIconButtonAriaHiddenTest(bool expectedAriaHidden) - { - var com = RenderComponent(parameters => - { - parameters.Add(p => p.AriaHidden, expectedAriaHidden); - }); - - var bitIconButton = com.Find(".bit-icb"); - - Assert.AreEqual(expectedAriaHidden, bitIconButton.HasAttribute("aria-hidden")); - } - - [DataTestMethod, - DataRow("", true), - DataRow("bing.com", true), - DataRow("bing.com", false) - ] - public void BitIconButtonShouldRenderExpectedElementBasedOnHref(string href, bool isEnabled) - { - var component = RenderComponent(parameters => - { - parameters.Add(p => p.Href, href); - parameters.Add(p => p.IsEnabled, isEnabled); - }); - - var bitIconButton = component.Find(".bit-icb"); - var tagName = bitIconButton.TagName; - var expectedElement = href.HasValue() && isEnabled ? "a" : "button"; - - Assert.AreEqual(expectedElement, tagName, ignoreCase: true); - } - - [DataTestMethod, - DataRow(BitButtonType.Button), - DataRow(BitButtonType.Submit), - DataRow(BitButtonType.Reset) - ] - public void BitIconButtonTypeOfButtonTest(BitButtonType buttonType) - { - var component = RenderComponent(parameters => - { - parameters.Add(p => p.ButtonType, buttonType); - }); - - var bitIconButton = component.Find(".bit-icb"); - - var buttonTypeName = buttonType switch - { - BitButtonType.Button => "button", - BitButtonType.Submit => "submit", - BitButtonType.Reset => "reset", - _ => throw new NotSupportedException(), - }; - Assert.AreEqual(bitIconButton.GetAttribute("type"), buttonTypeName); - } - - [TestMethod] - public void BitIconButtonSubmitStateInEditContextTest() - { - var com = RenderComponent(parameters => - { - parameters.Add(p => p.EditContext, new EditContext(this)); - }); - - var bitButton = com.Find(".bit-icb"); - - Assert.AreEqual("submit", bitButton.GetAttribute("type")); - } - - [TestMethod] - public void BitIconButtonButtonStateNotOverridenInEditContextTest() - { - var com = RenderComponent(parameters => - { - parameters.Add(p => p.EditContext, new EditContext(this)); - parameters.Add(p => p.ButtonType, BitButtonType.Button); - }); - - var bitButton = com.Find(".bit-icb"); - - Assert.AreEqual("button", bitButton.GetAttribute("type")); - } -} diff --git a/src/BlazorUI/Bit.BlazorUI.Tests/Buttons/BitActionButtonTests.cs b/src/BlazorUI/Bit.BlazorUI.Tests/Components/Buttons/BitActionButtonTests.cs similarity index 97% rename from src/BlazorUI/Bit.BlazorUI.Tests/Buttons/BitActionButtonTests.cs rename to src/BlazorUI/Bit.BlazorUI.Tests/Components/Buttons/BitActionButtonTests.cs index 0047a9917b..105e340f4e 100644 --- a/src/BlazorUI/Bit.BlazorUI.Tests/Buttons/BitActionButtonTests.cs +++ b/src/BlazorUI/Bit.BlazorUI.Tests/Components/Buttons/BitActionButtonTests.cs @@ -1,9 +1,9 @@ using System; -using Bunit; using Microsoft.AspNetCore.Components.Forms; using Microsoft.VisualStudio.TestTools.UnitTesting; +using Bunit; -namespace Bit.BlazorUI.Tests.Buttons; +namespace Bit.BlazorUI.Tests.Components.Buttons; [TestClass] public class BitActionButtonTests : BunitTestContext @@ -125,7 +125,7 @@ public void BitActionButtonShouldRenderExpectedElementBasedOnHref(string href, b var bitActionButton = component.Find(".bit-acb"); var tagName = bitActionButton.TagName; - var expectedElement = href.HasValue() && isEnabled ? "a" : "button"; + var expectedElement = href.HasValue() ? "a" : "button"; Assert.AreEqual(expectedElement, tagName, ignoreCase: true); } diff --git a/src/BlazorUI/Bit.BlazorUI.Tests/Buttons/BitButtonTests.cs b/src/BlazorUI/Bit.BlazorUI.Tests/Components/Buttons/BitButtonTests.cs similarity index 81% rename from src/BlazorUI/Bit.BlazorUI.Tests/Buttons/BitButtonTests.cs rename to src/BlazorUI/Bit.BlazorUI.Tests/Components/Buttons/BitButtonTests.cs index 6b156cb89e..088aaf4938 100644 --- a/src/BlazorUI/Bit.BlazorUI.Tests/Buttons/BitButtonTests.cs +++ b/src/BlazorUI/Bit.BlazorUI.Tests/Components/Buttons/BitButtonTests.cs @@ -1,26 +1,26 @@ using System; -using Bunit; using Microsoft.AspNetCore.Components.Forms; using Microsoft.VisualStudio.TestTools.UnitTesting; +using Bunit; -namespace Bit.BlazorUI.Tests.Buttons; +namespace Bit.BlazorUI.Tests.Components.Buttons; [TestClass] public class BitButtonTests : BunitTestContext { [DataTestMethod, - DataRow(true, BitButtonStyle.Primary, "title"), - DataRow(true, BitButtonStyle.Standard, "title"), - DataRow(false, BitButtonStyle.Primary, "title"), - DataRow(false, BitButtonStyle.Standard, "title") + DataRow(true, BitVariant.Fill, "title"), + DataRow(true, BitVariant.Outline, "title"), + DataRow(false, BitVariant.Fill, "title"), + DataRow(false, BitVariant.Outline, "title") ] - public void BitButtonTest(bool isEnabled, BitButtonStyle buttonStyle, string title) + public void BitButtonTest(bool isEnabled, BitVariant variant, string title) { var clicked = false; var com = RenderComponent(parameters => { parameters.Add(p => p.IsEnabled, isEnabled); - parameters.Add(p => p.ButtonStyle, buttonStyle); + parameters.Add(p => p.Variant, variant); parameters.Add(p => p.Title, title); parameters.Add(p => p.OnClick, () => clicked = true); }); @@ -36,15 +36,16 @@ public void BitButtonTest(bool isEnabled, BitButtonStyle buttonStyle, string tit Assert.IsTrue(bitButton.ClassList.Contains("bit-dis")); } - if (buttonStyle == BitButtonStyle.Standard) + if (variant == BitVariant.Fill) { - Assert.IsFalse(bitButton.ClassList.Contains("bit-btn-pri")); - Assert.IsTrue(bitButton.ClassList.Contains("bit-btn-std")); + Assert.IsTrue(bitButton.ClassList.Contains("bit-btn-fil")); + Assert.IsFalse(bitButton.ClassList.Contains("bit-btn-otl")); } - else + + if (variant == BitVariant.Outline) { - Assert.IsTrue(bitButton.ClassList.Contains("bit-btn-pri")); - Assert.IsFalse(bitButton.ClassList.Contains("bit-btn-std")); + Assert.IsFalse(bitButton.ClassList.Contains("bit-btn-fil")); + Assert.IsTrue(bitButton.ClassList.Contains("bit-btn-otl")); } Assert.AreEqual(bitButton.GetAttribute("title"), title); @@ -55,17 +56,17 @@ public void BitButtonTest(bool isEnabled, BitButtonStyle buttonStyle, string tit } [DataTestMethod, - DataRow(true, BitButtonStyle.Primary, false, false), - DataRow(true, BitButtonStyle.Standard, true, false), - DataRow(false, BitButtonStyle.Primary, false, true), - DataRow(false, BitButtonStyle.Standard, true, false), + DataRow(true, BitVariant.Fill, false, false), + DataRow(true, BitVariant.Outline, true, false), + DataRow(false, BitVariant.Fill, false, true), + DataRow(false, BitVariant.Outline, true, false), ] - public void BitButtonDisabledFocusTest(bool isEnabled, BitButtonStyle style, bool allowDisabledFocus, bool expectedResult) + public void BitButtonDisabledFocusTest(bool isEnabled, BitVariant variant, bool allowDisabledFocus, bool expectedResult) { var com = RenderComponent(parameters => { parameters.Add(p => p.IsEnabled, isEnabled); - parameters.Add(p => p.ButtonStyle, style); + parameters.Add(p => p.Variant, variant); parameters.Add(p => p.AllowDisabledFocus, allowDisabledFocus); }); @@ -82,17 +83,17 @@ public void BitButtonDisabledFocusTest(bool isEnabled, BitButtonStyle style, boo } [DataTestMethod, - DataRow(true, BitButtonStyle.Primary, "https://github.com/bitfoundation", "bit", "_blank"), - DataRow(true, BitButtonStyle.Standard, "https://github.com/bitfoundation", "bit", "_blank"), - DataRow(false, BitButtonStyle.Primary, "https://github.com/bitfoundation", "bit", "_blank"), - DataRow(false, BitButtonStyle.Standard, "https://github.com/bitfoundation", "bit", "_blank") + DataRow(true, BitVariant.Fill, "https://github.com/bitfoundation", "bit", "_blank"), + DataRow(true, BitVariant.Outline, "https://github.com/bitfoundation", "bit", "_blank"), + DataRow(false, BitVariant.Fill, "https://github.com/bitfoundation", "bit", "_blank"), + DataRow(false, BitVariant.Outline, "https://github.com/bitfoundation", "bit", "_blank") ] - public void BitAnchorButtonTest(bool isEnabled, BitButtonStyle style, string href, string title, string target) + public void BitAnchorButtonTest(bool isEnabled, BitVariant variant, string href, string title, string target) { var com = RenderComponent(parameters => { parameters.Add(p => p.IsEnabled, isEnabled); - parameters.Add(p => p.ButtonStyle, style); + parameters.Add(p => p.Variant, variant); parameters.Add(p => p.Href, href); parameters.Add(p => p.Title, title); parameters.Add(p => p.Target, target); @@ -204,7 +205,7 @@ public void BitButtonButtonStateNotOverriddenInEditContextTest() Assert.AreEqual("button", bitButton.GetAttribute("type")); } - + [DataTestMethod, DataRow(BitColor.Info), DataRow(BitColor.Success), @@ -233,7 +234,7 @@ public void BitColorOfButtonTest(BitColor? color) BitColor.Warning => "bit-btn-wrn", BitColor.SevereWarning => "bit-btn-swr", BitColor.Error => "bit-btn-err", - _ => String.Empty + _ => "bit-btn-pri" }; if (color.HasValue) @@ -242,18 +243,18 @@ public void BitColorOfButtonTest(BitColor? color) } else { - Assert.AreEqual(3, bitButton.ClassList.Length); + Assert.AreEqual(5, bitButton.ClassList.Length); } } - + [DataTestMethod, - DataRow(BitButtonSize.Small), - DataRow(BitButtonSize.Medium), - DataRow(BitButtonSize.Large), + DataRow(BitSize.Small), + DataRow(BitSize.Medium), + DataRow(BitSize.Large), DataRow(null) ] [TestMethod] - public void BitButtonSizeOfButtonTest(BitButtonSize? size) + public void BitSizeOfButtonTest(BitSize? size) { var com = RenderComponent(parameters => { @@ -267,10 +268,10 @@ public void BitButtonSizeOfButtonTest(BitButtonSize? size) var sizeClassName = size switch { - BitButtonSize.Small => "bit-btn-sm", - BitButtonSize.Medium => "bit-btn-md", - BitButtonSize.Large => "bit-btn-lg", - _ => String.Empty + BitSize.Small => "bit-btn-sm", + BitSize.Medium => "bit-btn-md", + BitSize.Large => "bit-btn-lg", + _ => "bit-btn-md" }; if (size.HasValue) @@ -279,7 +280,7 @@ public void BitButtonSizeOfButtonTest(BitButtonSize? size) } else { - Assert.AreEqual(3, bitButton.ClassList.Length); + Assert.AreEqual(5, bitButton.ClassList.Length); } } @@ -293,7 +294,7 @@ public void BitButtonLoadingContentTest(bool isLoading) var com = RenderComponent(parameters => { - parameters.Add(p => p.Content, textContent); + parameters.Add(p => p.PrimaryTemplate, textContent); parameters.Add(p => p.IsLoading, isLoading); }); diff --git a/src/BlazorUI/Bit.BlazorUI.Tests/Buttons/BitMenuButtonTests.cs b/src/BlazorUI/Bit.BlazorUI.Tests/Components/Buttons/BitMenuButtonTests.cs similarity index 90% rename from src/BlazorUI/Bit.BlazorUI.Tests/Buttons/BitMenuButtonTests.cs rename to src/BlazorUI/Bit.BlazorUI.Tests/Components/Buttons/BitMenuButtonTests.cs index 6d3994d014..7d5684b69f 100644 --- a/src/BlazorUI/Bit.BlazorUI.Tests/Buttons/BitMenuButtonTests.cs +++ b/src/BlazorUI/Bit.BlazorUI.Tests/Components/Buttons/BitMenuButtonTests.cs @@ -1,9 +1,9 @@ -using System.Collections.Generic; -using System.Linq; -using Bunit; +using System.Linq; +using System.Collections.Generic; using Microsoft.VisualStudio.TestTools.UnitTesting; +using Bunit; -namespace Bit.BlazorUI.Tests.Buttons; +namespace Bit.BlazorUI.Tests.Components.Buttons; [TestClass] public class BitMenuButtonTests : BunitTestContext @@ -23,17 +23,17 @@ public class BitMenuButtonTests : BunitTestContext }; [DataTestMethod, - DataRow(true, BitButtonStyle.Primary), - DataRow(true, BitButtonStyle.Standard), - DataRow(false, BitButtonStyle.Primary), - DataRow(false, BitButtonStyle.Standard) + DataRow(true, BitVariant.Fill), + DataRow(true, BitVariant.Outline), + DataRow(false, BitVariant.Fill), + DataRow(false, BitVariant.Outline) ] - public void BitMenuButtonTest(bool isEnabled, BitButtonStyle buttonStyle) + public void BitMenuButtonTest(bool isEnabled, BitVariant variant) { var com = RenderComponent>(parameters => { parameters.Add(p => p.IsEnabled, isEnabled); - parameters.Add(p => p.ButtonStyle, buttonStyle); + parameters.Add(p => p.Variant, variant); parameters.Add(p => p.Items, items); }); @@ -48,15 +48,16 @@ public void BitMenuButtonTest(bool isEnabled, BitButtonStyle buttonStyle) Assert.IsTrue(bitMenuButton.ClassList.Contains("bit-dis")); } - if (buttonStyle == BitButtonStyle.Standard) + + if (variant == BitVariant.Fill) { - Assert.IsFalse(bitMenuButton.ClassList.Contains("bit-mnb-pri")); - Assert.IsTrue(bitMenuButton.ClassList.Contains("bit-mnb-std")); + Assert.IsTrue(bitMenuButton.ClassList.Contains("bit-mnb-fil")); + Assert.IsFalse(bitMenuButton.ClassList.Contains("bit-mnb-otl")); } - else + if (variant == BitVariant.Outline) { - Assert.IsTrue(bitMenuButton.ClassList.Contains("bit-mnb-pri")); - Assert.IsFalse(bitMenuButton.ClassList.Contains("bit-mnb-std")); + Assert.IsFalse(bitMenuButton.ClassList.Contains("bit-mnb-fil")); + Assert.IsTrue(bitMenuButton.ClassList.Contains("bit-mnb-otl")); } } @@ -129,7 +130,7 @@ public void BitMenuButtonShouldBeItemClickIfEnabled(bool itemIsEnabled) var lastItem = com.Find("li:last-child .bit-mnb-itm"); lastItem.Click(); - Assert.AreEqual(itemIsEnabled, lastItem.ClassList.Contains("bit-dis") is false); + Assert.AreEqual(itemIsEnabled, lastItem.HasAttribute("disabled") is false); if (itemIsEnabled) { diff --git a/src/BlazorUI/Bit.BlazorUI.Tests/Buttons/BitToggleButtonTests.cs b/src/BlazorUI/Bit.BlazorUI.Tests/Components/Buttons/BitToggleButtonTests.cs similarity index 96% rename from src/BlazorUI/Bit.BlazorUI.Tests/Buttons/BitToggleButtonTests.cs rename to src/BlazorUI/Bit.BlazorUI.Tests/Components/Buttons/BitToggleButtonTests.cs index a4a8b0907c..b1d6552390 100644 --- a/src/BlazorUI/Bit.BlazorUI.Tests/Buttons/BitToggleButtonTests.cs +++ b/src/BlazorUI/Bit.BlazorUI.Tests/Components/Buttons/BitToggleButtonTests.cs @@ -1,7 +1,7 @@ -using Bunit; -using Microsoft.VisualStudio.TestTools.UnitTesting; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Bunit; -namespace Bit.BlazorUI.Tests.Buttons; +namespace Bit.BlazorUI.Tests.Components.Buttons; [TestClass] public class BitToggleButtonTests : BunitTestContext @@ -24,8 +24,8 @@ public void BitToggleButtonShouldHaveCorrectLabelAndIconAndTitle(bool isChecked, }); var bitToggleButton = component.Find(".bit-tgb"); - var bitIconTag = component.Find(".bit-tgb > span > i"); - var bitLabelTag = component.Find(".bit-tgb > span > span"); + var bitIconTag = component.Find(".bit-tgb > i"); + var bitLabelTag = component.Find(".bit-tgb > span"); if (isEnabled) { diff --git a/src/BlazorUI/Bit.BlazorUI.Tests/Checkboxes/BitCheckboxTestModel.cs b/src/BlazorUI/Bit.BlazorUI.Tests/Components/Inputs/Checkbox/BitCheckboxTestModel.cs similarity index 76% rename from src/BlazorUI/Bit.BlazorUI.Tests/Checkboxes/BitCheckboxTestModel.cs rename to src/BlazorUI/Bit.BlazorUI.Tests/Components/Inputs/Checkbox/BitCheckboxTestModel.cs index d76b71911b..f3f585b378 100644 --- a/src/BlazorUI/Bit.BlazorUI.Tests/Checkboxes/BitCheckboxTestModel.cs +++ b/src/BlazorUI/Bit.BlazorUI.Tests/Components/Inputs/Checkbox/BitCheckboxTestModel.cs @@ -1,7 +1,7 @@ using System; using System.ComponentModel.DataAnnotations; -namespace Bit.BlazorUI.Tests.Checkboxes; +namespace Bit.BlazorUI.Tests.Components.Inputs.Checkbox; public class BitCheckboxTestModel { diff --git a/src/BlazorUI/Bit.BlazorUI.Tests/Checkboxes/BitCheckboxTests.cs b/src/BlazorUI/Bit.BlazorUI.Tests/Components/Inputs/Checkbox/BitCheckboxTests.cs similarity index 93% rename from src/BlazorUI/Bit.BlazorUI.Tests/Checkboxes/BitCheckboxTests.cs rename to src/BlazorUI/Bit.BlazorUI.Tests/Components/Inputs/Checkbox/BitCheckboxTests.cs index a4c63dc5e8..b56892f92b 100644 --- a/src/BlazorUI/Bit.BlazorUI.Tests/Checkboxes/BitCheckboxTests.cs +++ b/src/BlazorUI/Bit.BlazorUI.Tests/Components/Inputs/Checkbox/BitCheckboxTests.cs @@ -1,7 +1,7 @@ -using Bunit; -using Microsoft.VisualStudio.TestTools.UnitTesting; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Bunit; -namespace Bit.BlazorUI.Tests.Checkboxes; +namespace Bit.BlazorUI.Tests.Components.Inputs.Checkbox; [TestClass] public class BitCheckboxTests : BunitTestContext @@ -48,25 +48,25 @@ public void BitCheckboxOnClickShouldWorkIfIsEnabled(bool defaultValue, bool isEn } [DataTestMethod, - DataRow(BitCheckboxSide.Start), - DataRow(BitCheckboxSide.End), + DataRow(false), + DataRow(true), ] - public void BitCheckboxBoxSideTest(BitCheckboxSide boxSide) + public void BitCheckboxReversedTest(bool reversed) { var component = RenderComponent(parameters => { - parameters.Add(p => p.BoxSide, boxSide); + parameters.Add(p => p.Reversed, reversed); }); var checkBox = component.Find(".bit-chb"); - if (boxSide is BitCheckboxSide.End) + if (reversed) { - Assert.IsTrue(checkBox.ClassList.Contains("bit-chb-end")); + Assert.IsTrue(checkBox.ClassList.Contains("bit-chb-rvs")); } else { - Assert.IsFalse(checkBox.ClassList.Contains("bit-chb-end")); + Assert.IsFalse(checkBox.ClassList.Contains("bit-chb-rvs")); } } @@ -80,7 +80,7 @@ public void IndeterminateBitCheckboxShouldHaveCorrectClassNameIfIsEnabled(bool i var component = RenderComponent(parameters => { - parameters.Add(p => p.DefaultIsIndeterminate, true); + parameters.Add(p => p.DefaultIndeterminate, true); parameters.Add(p => p.IsEnabled, isEnabled); }); @@ -263,7 +263,7 @@ public void BitCheckboxCustomCheckmarkIconTest(string checkmarkIconName) { var component = RenderComponent(parameters => { - parameters.Add(p => p.CheckmarkIconName, checkmarkIconName); + parameters.Add(p => p.CheckIconName, checkmarkIconName); }); var icon = component.Find(".bit-chb-box i.bit-icon"); @@ -279,7 +279,7 @@ public void BitCheckboxCheckmarkIconAriaLabelTest(string ariaLabel) { var component = RenderComponent(parameters => { - parameters.Add(p => p.CheckmarkIconAriaLabel, ariaLabel); + parameters.Add(p => p.CheckIconAriaLabel, ariaLabel); }); var icon = component.Find(".bit-chb-box i.bit-icon"); @@ -336,8 +336,8 @@ public void BitCheckBoxIsIndeterminateTwoWayBoundWithCustomHandlerTest() { var component = RenderComponent(parameters => { - parameters.Add(p => p.IsIndeterminate, true); - parameters.Add(p => p.IsIndeterminateChanged, HandleIsIndeterminateChanged); + parameters.Add(p => p.Indeterminate, true); + parameters.Add(p => p.IndeterminateChanged, HandleIsIndeterminateChanged); }); var chb = component.Find("input"); diff --git a/src/BlazorUI/Bit.BlazorUI.Tests/Checkboxes/BitCheckboxValidationTest.razor b/src/BlazorUI/Bit.BlazorUI.Tests/Components/Inputs/Checkbox/BitCheckboxValidationTest.razor similarity index 85% rename from src/BlazorUI/Bit.BlazorUI.Tests/Checkboxes/BitCheckboxValidationTest.razor rename to src/BlazorUI/Bit.BlazorUI.Tests/Components/Inputs/Checkbox/BitCheckboxValidationTest.razor index 899af47eb8..8048cf4809 100644 --- a/src/BlazorUI/Bit.BlazorUI.Tests/Checkboxes/BitCheckboxValidationTest.razor +++ b/src/BlazorUI/Bit.BlazorUI.Tests/Components/Inputs/Checkbox/BitCheckboxValidationTest.razor @@ -12,9 +12,9 @@ Title="@Title" DefaultValue="@DefaultValue" @bind-Value="@TestModel.Value" - CheckmarkIconAriaLabel="@CheckmarkIconAriaLabel" - BoxSide="@BoxSide" - DefaultIsIndeterminate="@DefaultIsIndeterminate" + CheckIconAriaLabel="@CheckIconAriaLabel" + Reversed="@Reversed" + DefaultIndeterminate="@DefaultIndeterminate" OnClick="HandleOnClick" OnChange="HandleOnChange"> @@ -29,16 +29,16 @@ [Parameter] public bool IsIndeterminate { get; set; } [Parameter] public string AriaLabel { get; set; } [Parameter] public string CheckmarkIconName { get; set; } - [Parameter] public string CheckmarkIconAriaLabel { get; set; } + [Parameter] public string CheckIconAriaLabel { get; set; } [Parameter] public string AriaDescription { get; set; } [Parameter] public string AriaLabelledby { get; set; } [Parameter] public int? AriaPositionInSet { get; set; } [Parameter] public int? AriaSetSize { get; set; } [Parameter] public string Name { get; set; } [Parameter] public string Title { get; set; } - [Parameter] public BitCheckboxSide BoxSide { get; set; } + [Parameter] public bool Reversed { get; set; } [Parameter] public bool? DefaultValue { get; set; } - [Parameter] public bool? DefaultIsIndeterminate { get; set; } + [Parameter] public bool? DefaultIndeterminate { get; set; } [Parameter] public RenderFragment ChildContent { get; set; } [Parameter] public BitCheckboxTestModel TestModel { get; set; } diff --git a/src/BlazorUI/Bit.BlazorUI.Tests/ChoiceGroup/BitChoiceGroupTests.cs b/src/BlazorUI/Bit.BlazorUI.Tests/Components/Inputs/ChoiceGroup/BitChoiceGroupTests.cs similarity index 98% rename from src/BlazorUI/Bit.BlazorUI.Tests/ChoiceGroup/BitChoiceGroupTests.cs rename to src/BlazorUI/Bit.BlazorUI.Tests/Components/Inputs/ChoiceGroup/BitChoiceGroupTests.cs index 719abffb6a..1f58b2f3d1 100644 --- a/src/BlazorUI/Bit.BlazorUI.Tests/ChoiceGroup/BitChoiceGroupTests.cs +++ b/src/BlazorUI/Bit.BlazorUI.Tests/Components/Inputs/ChoiceGroup/BitChoiceGroupTests.cs @@ -1,10 +1,10 @@ using System.Linq; using System.Collections.Generic; using Microsoft.VisualStudio.TestTools.UnitTesting; -using Bunit; using AngleSharp.Dom; +using Bunit; -namespace Bit.BlazorUI.Tests.ChoiceGroup; +namespace Bit.BlazorUI.Tests.Components.Inputs.ChoiceGroup; [TestClass] public class BitChoiceGroupTests : BunitTestContext @@ -223,7 +223,7 @@ public void BitChoiceGroupShouldTakeCustomVisibility(BitVisibility visibility) switch (visibility) { case BitVisibility.Visible: - Assert.IsTrue(bitChoiceGroup.GetAttribute("style").Contains("")); + Assert.IsFalse(bitChoiceGroup.HasAttribute("style")); break; case BitVisibility.Hidden: Assert.IsTrue(bitChoiceGroup.GetAttribute("style").Contains("visibility:hidden")); diff --git a/src/BlazorUI/Bit.BlazorUI.Tests/ColorPicker/BitColorPickerTests.cs b/src/BlazorUI/Bit.BlazorUI.Tests/Components/Inputs/ColorPicker/BitColorPickerTests.cs similarity index 93% rename from src/BlazorUI/Bit.BlazorUI.Tests/ColorPicker/BitColorPickerTests.cs rename to src/BlazorUI/Bit.BlazorUI.Tests/Components/Inputs/ColorPicker/BitColorPickerTests.cs index 37e9e50b99..6f7819701d 100644 --- a/src/BlazorUI/Bit.BlazorUI.Tests/ColorPicker/BitColorPickerTests.cs +++ b/src/BlazorUI/Bit.BlazorUI.Tests/Components/Inputs/ColorPicker/BitColorPickerTests.cs @@ -1,8 +1,8 @@ -using Bunit; -using Microsoft.VisualStudio.TestTools.UnitTesting; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Bunit; -namespace Bit.BlazorUI.Tests.ColorPicker; +namespace Bit.BlazorUI.Tests.Components.Inputs.ColorPicker; [TestClass] public class BitColorPickerTests : BunitTestContext diff --git a/src/BlazorUI/Bit.BlazorUI.Tests/ColorPicker/BitColorTests.cs b/src/BlazorUI/Bit.BlazorUI.Tests/Components/Inputs/ColorPicker/BitColorTests.cs similarity index 97% rename from src/BlazorUI/Bit.BlazorUI.Tests/ColorPicker/BitColorTests.cs rename to src/BlazorUI/Bit.BlazorUI.Tests/Components/Inputs/ColorPicker/BitColorTests.cs index 1495267eb1..1302286829 100644 --- a/src/BlazorUI/Bit.BlazorUI.Tests/ColorPicker/BitColorTests.cs +++ b/src/BlazorUI/Bit.BlazorUI.Tests/Components/Inputs/ColorPicker/BitColorTests.cs @@ -1,7 +1,7 @@ using System; using Microsoft.VisualStudio.TestTools.UnitTesting; -namespace Bit.BlazorUI.Tests.ColorPicker; +namespace Bit.BlazorUI.Tests.Components.Inputs.ColorPicker; [TestClass] public class BitColorTests diff --git a/src/BlazorUI/Bit.BlazorUI.Tests/DatePicker/BitDatePickerTestModel.cs b/src/BlazorUI/Bit.BlazorUI.Tests/Components/Inputs/DatePicker/BitDatePickerTestModel.cs similarity index 73% rename from src/BlazorUI/Bit.BlazorUI.Tests/DatePicker/BitDatePickerTestModel.cs rename to src/BlazorUI/Bit.BlazorUI.Tests/Components/Inputs/DatePicker/BitDatePickerTestModel.cs index 1e7b117f4c..006dd7ac01 100644 --- a/src/BlazorUI/Bit.BlazorUI.Tests/DatePicker/BitDatePickerTestModel.cs +++ b/src/BlazorUI/Bit.BlazorUI.Tests/Components/Inputs/DatePicker/BitDatePickerTestModel.cs @@ -1,7 +1,7 @@ using System; using System.ComponentModel.DataAnnotations; -namespace Bit.BlazorUI.Tests.DatePicker; +namespace Bit.BlazorUI.Tests.Components.Inputs.DatePicker; public class BitDatePickerTestModel { diff --git a/src/BlazorUI/Bit.BlazorUI.Tests/DatePicker/BitDatePickerTests.cs b/src/BlazorUI/Bit.BlazorUI.Tests/Components/Inputs/DatePicker/BitDatePickerTests.cs similarity index 99% rename from src/BlazorUI/Bit.BlazorUI.Tests/DatePicker/BitDatePickerTests.cs rename to src/BlazorUI/Bit.BlazorUI.Tests/Components/Inputs/DatePicker/BitDatePickerTests.cs index bf67edbaab..4ce4148eed 100644 --- a/src/BlazorUI/Bit.BlazorUI.Tests/DatePicker/BitDatePickerTests.cs +++ b/src/BlazorUI/Bit.BlazorUI.Tests/Components/Inputs/DatePicker/BitDatePickerTests.cs @@ -1,9 +1,9 @@ using System; using System.Collections.Generic; -using Bunit; using Microsoft.VisualStudio.TestTools.UnitTesting; +using Bunit; -namespace Bit.BlazorUI.Tests.DatePicker; +namespace Bit.BlazorUI.Tests.Components.Inputs.DatePicker; [TestClass] public class BitDatePickerTests : BunitTestContext diff --git a/src/BlazorUI/Bit.BlazorUI.Tests/DatePicker/BitDatePickerValidationTest.razor b/src/BlazorUI/Bit.BlazorUI.Tests/Components/Inputs/DatePicker/BitDatePickerValidationTest.razor similarity index 100% rename from src/BlazorUI/Bit.BlazorUI.Tests/DatePicker/BitDatePickerValidationTest.razor rename to src/BlazorUI/Bit.BlazorUI.Tests/Components/Inputs/DatePicker/BitDatePickerValidationTest.razor diff --git a/src/BlazorUI/Bit.BlazorUI.Tests/DateRangePicker/BitDateRangePickerTests.cs b/src/BlazorUI/Bit.BlazorUI.Tests/Components/Inputs/DateRangePicker/BitDateRangePickerTests.cs similarity index 99% rename from src/BlazorUI/Bit.BlazorUI.Tests/DateRangePicker/BitDateRangePickerTests.cs rename to src/BlazorUI/Bit.BlazorUI.Tests/Components/Inputs/DateRangePicker/BitDateRangePickerTests.cs index 1977553610..669b48c7df 100644 --- a/src/BlazorUI/Bit.BlazorUI.Tests/DateRangePicker/BitDateRangePickerTests.cs +++ b/src/BlazorUI/Bit.BlazorUI.Tests/Components/Inputs/DateRangePicker/BitDateRangePickerTests.cs @@ -1,9 +1,9 @@ using System; using System.Collections.Generic; -using Bunit; using Microsoft.VisualStudio.TestTools.UnitTesting; +using Bunit; -namespace Bit.BlazorUI.Tests.DateRangePicker; +namespace Bit.BlazorUI.Tests.Components.Inputs.DateRangePicker; [TestClass] public class BitDateRangePickerTests : BunitTestContext diff --git a/src/BlazorUI/Bit.BlazorUI.Tests/Dropdown/BitDropdownMultiSelectTestModel.cs b/src/BlazorUI/Bit.BlazorUI.Tests/Components/Inputs/Dropdown/BitDropdownMultiSelectTestModel.cs similarity index 80% rename from src/BlazorUI/Bit.BlazorUI.Tests/Dropdown/BitDropdownMultiSelectTestModel.cs rename to src/BlazorUI/Bit.BlazorUI.Tests/Components/Inputs/Dropdown/BitDropdownMultiSelectTestModel.cs index 5505274bf0..15ebfe078d 100644 --- a/src/BlazorUI/Bit.BlazorUI.Tests/Dropdown/BitDropdownMultiSelectTestModel.cs +++ b/src/BlazorUI/Bit.BlazorUI.Tests/Components/Inputs/Dropdown/BitDropdownMultiSelectTestModel.cs @@ -1,7 +1,7 @@ using System.Collections.Generic; using System.ComponentModel.DataAnnotations; -namespace Bit.BlazorUI.Tests.Dropdown; +namespace Bit.BlazorUI.Tests.Components.Inputs.Dropdown; public class BitDropdownMultiSelectTestModel { diff --git a/src/BlazorUI/Bit.BlazorUI.Tests/Dropdown/BitDropdownMultiSelectValidationTest.razor b/src/BlazorUI/Bit.BlazorUI.Tests/Components/Inputs/Dropdown/BitDropdownMultiSelectValidationTest.razor similarity index 96% rename from src/BlazorUI/Bit.BlazorUI.Tests/Dropdown/BitDropdownMultiSelectValidationTest.razor rename to src/BlazorUI/Bit.BlazorUI.Tests/Components/Inputs/Dropdown/BitDropdownMultiSelectValidationTest.razor index a8a77a06a7..16f4778dd4 100644 --- a/src/BlazorUI/Bit.BlazorUI.Tests/Dropdown/BitDropdownMultiSelectValidationTest.razor +++ b/src/BlazorUI/Bit.BlazorUI.Tests/Components/Inputs/Dropdown/BitDropdownMultiSelectValidationTest.razor @@ -15,7 +15,7 @@ Title="@Title" IsReselectable="IsReselectable" OnSelectItem="HandleSelectItem" - IsRequired="IsRequired" + Required="Required" TItem="BitDropdownItem" TValue="string"> @@ -28,7 +28,7 @@ @code { [Parameter] public bool IsMultiSelect { get; set; } [Parameter] public bool IsEnabled { get; set; } - [Parameter] public bool IsRequired { get; set; } + [Parameter] public bool Required { get; set; } [Parameter] public bool IsOpen { get; set; } [Parameter] public List> Items { get; set; } = new(); [Parameter] public BitDropdownMultiSelectTestModel TestModel { get; set; } diff --git a/src/BlazorUI/Bit.BlazorUI.Tests/Dropdown/BitDropdownTestModel.cs b/src/BlazorUI/Bit.BlazorUI.Tests/Components/Inputs/Dropdown/BitDropdownTestModel.cs similarity index 71% rename from src/BlazorUI/Bit.BlazorUI.Tests/Dropdown/BitDropdownTestModel.cs rename to src/BlazorUI/Bit.BlazorUI.Tests/Components/Inputs/Dropdown/BitDropdownTestModel.cs index 9d9c21c90c..cdc1f97f0a 100644 --- a/src/BlazorUI/Bit.BlazorUI.Tests/Dropdown/BitDropdownTestModel.cs +++ b/src/BlazorUI/Bit.BlazorUI.Tests/Components/Inputs/Dropdown/BitDropdownTestModel.cs @@ -1,6 +1,6 @@ using System.ComponentModel.DataAnnotations; -namespace Bit.BlazorUI.Tests.Dropdown; +namespace Bit.BlazorUI.Tests.Components.Inputs.Dropdown; public class BitDropdownTestModel { diff --git a/src/BlazorUI/Bit.BlazorUI.Tests/Dropdown/BitDropdownTests.cs b/src/BlazorUI/Bit.BlazorUI.Tests/Components/Inputs/Dropdown/BitDropdownTests.cs similarity index 99% rename from src/BlazorUI/Bit.BlazorUI.Tests/Dropdown/BitDropdownTests.cs rename to src/BlazorUI/Bit.BlazorUI.Tests/Components/Inputs/Dropdown/BitDropdownTests.cs index 3df7d9b18d..c2d9e49ee7 100644 --- a/src/BlazorUI/Bit.BlazorUI.Tests/Dropdown/BitDropdownTests.cs +++ b/src/BlazorUI/Bit.BlazorUI.Tests/Components/Inputs/Dropdown/BitDropdownTests.cs @@ -1,11 +1,11 @@ using System; -using System.Collections.Generic; using System.Linq; using System.Text; -using Bunit; +using System.Collections.Generic; using Microsoft.VisualStudio.TestTools.UnitTesting; +using Bunit; -namespace Bit.BlazorUI.Tests.Dropdown; +namespace Bit.BlazorUI.Tests.Components.Inputs.Dropdown; [TestClass] public class BitDropdownTests : BunitTestContext @@ -446,7 +446,7 @@ public void BitDropdownNotifyOnReselectShouldWorkCorrect(bool notifyOnReselect, parameters.Add(p => p.IsEnabled, true); parameters.Add(p => p.IsReselectable, notifyOnReselect); parameters.Add(p => p.DefaultValue, defaultValue); - parameters.Add(p => p.OnChange, () => itemSelected = true); + parameters.Add(p => p.OnSelectItem, () => itemSelected = true); }); var selectedItem = component.Find(".bit-drp-sel"); @@ -480,7 +480,7 @@ public void BitDropdownEnableItemSelectionShouldWorkCorrect(bool itemIsEnabled, parameters.Add(p => p.IsOpenChanged, v => isOpen = v); parameters.Add(p => p.IsEnabled, true); parameters.Add(p => p.IsMultiSelect, isMultiSelect); - parameters.Add(p => p.OnChange, () => itemsSelected++); + parameters.Add(p => p.OnValuesChange, () => itemsSelected++); }); if (isMultiSelect) diff --git a/src/BlazorUI/Bit.BlazorUI.Tests/Dropdown/BitDropdownValidationTest.razor b/src/BlazorUI/Bit.BlazorUI.Tests/Components/Inputs/Dropdown/BitDropdownValidationTest.razor similarity index 96% rename from src/BlazorUI/Bit.BlazorUI.Tests/Dropdown/BitDropdownValidationTest.razor rename to src/BlazorUI/Bit.BlazorUI.Tests/Components/Inputs/Dropdown/BitDropdownValidationTest.razor index da2b66eccb..47f81de98c 100644 --- a/src/BlazorUI/Bit.BlazorUI.Tests/Dropdown/BitDropdownValidationTest.razor +++ b/src/BlazorUI/Bit.BlazorUI.Tests/Components/Inputs/Dropdown/BitDropdownValidationTest.razor @@ -14,7 +14,7 @@ Title="@Title" IsReselectable="IsReselectable" OnSelectItem="HandleSelectItem" - IsRequired="IsRequired" + Required="Required" TItem="BitDropdownItem" TValue="string"> @@ -27,7 +27,7 @@ @code { [Parameter] public bool IsMultiSelect { get; set; } [Parameter] public bool IsEnabled { get; set; } - [Parameter] public bool IsRequired { get; set; } + [Parameter] public bool Required { get; set; } [Parameter] public bool IsOpen { get; set; } [Parameter] public List> Items { get; set; } = new(); [Parameter] public BitDropdownTestModel TestModel { get; set; } diff --git a/src/BlazorUI/Bit.BlazorUI.Tests/FileUpload/BitFileUploadTests.cs b/src/BlazorUI/Bit.BlazorUI.Tests/Components/Inputs/FileUpload/BitFileUploadTests.cs similarity index 97% rename from src/BlazorUI/Bit.BlazorUI.Tests/FileUpload/BitFileUploadTests.cs rename to src/BlazorUI/Bit.BlazorUI.Tests/Components/Inputs/FileUpload/BitFileUploadTests.cs index b465730456..5c16f55e96 100644 --- a/src/BlazorUI/Bit.BlazorUI.Tests/FileUpload/BitFileUploadTests.cs +++ b/src/BlazorUI/Bit.BlazorUI.Tests/Components/Inputs/FileUpload/BitFileUploadTests.cs @@ -1,8 +1,8 @@ using System.Collections.Generic; -using Bunit; using Microsoft.VisualStudio.TestTools.UnitTesting; +using Bunit; -namespace Bit.BlazorUI.Tests.FileUpload; +namespace Bit.BlazorUI.Tests.Components.Inputs.FileUpload; [TestClass] public class BitFileUploadTests : BunitTestContext diff --git a/src/BlazorUI/Bit.BlazorUI.Tests/NumberField/BitNumberFieldTestModel.cs b/src/BlazorUI/Bit.BlazorUI.Tests/Components/Inputs/NumberField/BitNumberFieldTestModel.cs similarity index 70% rename from src/BlazorUI/Bit.BlazorUI.Tests/NumberField/BitNumberFieldTestModel.cs rename to src/BlazorUI/Bit.BlazorUI.Tests/Components/Inputs/NumberField/BitNumberFieldTestModel.cs index 89cb1a4572..abcd2a68e7 100644 --- a/src/BlazorUI/Bit.BlazorUI.Tests/NumberField/BitNumberFieldTestModel.cs +++ b/src/BlazorUI/Bit.BlazorUI.Tests/Components/Inputs/NumberField/BitNumberFieldTestModel.cs @@ -1,6 +1,6 @@ using System.ComponentModel.DataAnnotations; -namespace Bit.BlazorUI.Tests.NumberField; +namespace Bit.BlazorUI.Tests.Components.Inputs.NumberField; public class BitNumberFieldTestModel { diff --git a/src/BlazorUI/Bit.BlazorUI.Tests/NumberField/BitNumberFieldTests.cs b/src/BlazorUI/Bit.BlazorUI.Tests/Components/Inputs/NumberField/BitNumberFieldTests.cs similarity index 81% rename from src/BlazorUI/Bit.BlazorUI.Tests/NumberField/BitNumberFieldTests.cs rename to src/BlazorUI/Bit.BlazorUI.Tests/Components/Inputs/NumberField/BitNumberFieldTests.cs index 8a011ede36..93cfba9f38 100644 --- a/src/BlazorUI/Bit.BlazorUI.Tests/NumberField/BitNumberFieldTests.cs +++ b/src/BlazorUI/Bit.BlazorUI.Tests/Components/Inputs/NumberField/BitNumberFieldTests.cs @@ -1,13 +1,12 @@ using System; -using System.Collections.Generic; -using System.Text.RegularExpressions; using System.Threading.Tasks; -using Bunit; +using System.Collections.Generic; using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components.Web; using Microsoft.VisualStudio.TestTools.UnitTesting; +using Bunit; -namespace Bit.BlazorUI.Tests.NumberField; +namespace Bit.BlazorUI.Tests.Components.Inputs.NumberField; [TestClass] public class BitNumberFieldTests : BunitTestContext @@ -200,10 +199,9 @@ public void BitNumberFieldShouldRenderCorrectDecrementButton(string iconName, st } [DataTestMethod, - DataRow("{0} cm", 0), - DataRow("{0} Inch", 24), - DataRow("{0} foot", 100), - DataRow("{0:0} foot", 1000) + DataRow("0", 11), + DataRow("C2", 100), + DataRow("0:00000", 1363) ] public void BitNumberFieldShouldHaveNumberFormaWhenItsPropertySet(string numberFormat, int defaultValue) { @@ -215,7 +213,7 @@ public void BitNumberFieldShouldHaveNumberFormaWhenItsPropertySet(string numberF var input = component.Find("input"); var inputValue = input.GetAttribute("value"); - var expectedValue = string.Format(numberFormat, defaultValue); + var expectedValue = defaultValue.ToString(numberFormat); Assert.AreEqual(expectedValue, inputValue); } @@ -224,18 +222,18 @@ public void BitNumberFieldShouldHaveNumberFormaWhenItsPropertySet(string numberF DataRow(true), DataRow(false) ] - public void BitNumberFieldShouldHaveLabelPositionClassName(bool leftLabel) + public void BitNumberFieldShouldHaveLabelPositionClassName(bool inlineLabel) { var component = RenderComponent>(parameters => { - parameters.Add(p => p.LeftLabel, leftLabel); + parameters.Add(p => p.InlineLabel, inlineLabel); }); - var labelPositionClass = leftLabel ? "lf" : "tp"; + var lblClass = inlineLabel ? "ilb" : "tlb"; var numberFieldButton = component.Find(".bit-nfl"); - Assert.IsTrue(numberFieldButton.ClassList.Contains($"bit-nfl-l{labelPositionClass}")); + Assert.IsTrue(numberFieldButton.ClassList.Contains($"bit-nfl-{lblClass}")); } [DataTestMethod, @@ -291,12 +289,16 @@ public void BitNumberFieldWrapperShouldHaveCorrectAttributes(string title, strin [DataTestMethod, DataRow(null, null), - DataRow(5, null), - DataRow(null, 100), - DataRow(0, 100), - DataRow(50, 1) + DataRow("0", null), + DataRow("10", null), + DataRow(null, "0"), + DataRow(null, "10"), + DataRow("0", "10"), + DataRow("-10", "0"), + DataRow("10", "0"), + DataRow("0", "-10"), ] - public void BitNumberFieldShouldHaveCorrectMaxMin(int? min, int? max) + public void BitNumberFieldShouldHaveCorrectMaxMin(string min, string max) { var component = RenderComponent>(parameters => { @@ -305,17 +307,17 @@ public void BitNumberFieldShouldHaveCorrectMaxMin(int? min, int? max) }); var input = component.Find("input"); - int? expectedMinValue = null; - int? expectedMaxValue = null; + int? expectedMinValue = int.MinValue; + int? expectedMaxValue = int.MaxValue; - if (max.HasValue) + if (max is not null) { - expectedMaxValue = max.Value; + expectedMaxValue = int.Parse(max); } - if (min.HasValue) + if (min is not null) { - expectedMinValue = min.Value; + expectedMinValue = int.Parse(min); } Assert.AreEqual(expectedMinValue.HasValue ? expectedMinValue.ToString() : null, input.GetAttribute("aria-valuemin")); @@ -328,7 +330,7 @@ public void BitNumberFieldShouldHaveCorrectMaxMin(int? min, int? max) ] public async Task BitNumberFieldOnIncrementTest(int countOfClicks) { - int onIncrementEventCounter = 0; + var onIncrementEventCounter = 0; var component = RenderComponent>(parameters => { parameters.Add(p => p.ShowButtons, true); @@ -336,7 +338,7 @@ public async Task BitNumberFieldOnIncrementTest(int countOfClicks) }); var increaseButton = component.Find("button.bit-nfl-aup"); - for (int i = 0; i < countOfClicks; i++) + for (var i = 0; i < countOfClicks; i++) { increaseButton.PointerDown(); await Task.Delay(1); @@ -352,7 +354,7 @@ public async Task BitNumberFieldOnIncrementTest(int countOfClicks) ] public async Task BitNumberFieldOnDecrementTest(int countOfClicks) { - int onDecrementEventCounter = 20; + var onDecrementEventCounter = 20; var component = RenderComponent>(parameters => { parameters.Add(p => p.ShowButtons, true); @@ -360,7 +362,7 @@ public async Task BitNumberFieldOnDecrementTest(int countOfClicks) }); var decreaseButton = component.Find("button.bit-nfl-adn"); - for (int i = 0; i < countOfClicks; i++) + for (var i = 0; i < countOfClicks; i++) { decreaseButton.PointerDown(); await Task.Delay(1); @@ -376,14 +378,14 @@ public async Task BitNumberFieldOnDecrementTest(int countOfClicks) ] public void BitNumberFieldInputOnBlurEventCallbackTest(int countOfBlur) { - int onBlurEventCounter = 0; + var onBlurEventCounter = 0; var component = RenderComponent>(parameters => { parameters.Add(p => p.OnBlur, () => onBlurEventCounter++); }); var input = component.Find("input"); - for (int i = 0; i < countOfBlur; i++) + for (var i = 0; i < countOfBlur; i++) { input.Blur(); } @@ -397,14 +399,14 @@ public void BitNumberFieldInputOnBlurEventCallbackTest(int countOfBlur) ] public void BitNumberFieldInputOnFocusTest(int countOfFocus) { - int onFocusEventCounter = 0; + var onFocusEventCounter = 0; var component = RenderComponent>(parameters => { parameters.Add(p => p.OnFocus, () => onFocusEventCounter++); }); var input = component.Find("input"); - for (int i = 0; i < countOfFocus; i++) + for (var i = 0; i < countOfFocus; i++) { input.Focus(); } @@ -418,14 +420,14 @@ public void BitNumberFieldInputOnFocusTest(int countOfFocus) ] public void BitNumberFieldOnChangeTest(int inputValue) { - int onChangeEventValue = 0; + var onChangeEventValue = 0; var component = RenderComponent>(parameters => { parameters.Add(p => p.OnChange, (int value) => onChangeEventValue = value); }); var input = component.Find("input"); - input.Input(inputValue); + input.Change(inputValue); Assert.AreEqual(onChangeEventValue, inputValue); } @@ -477,16 +479,15 @@ public void BitNumberFieldInputShouldHaveCorrectAriaValueNow(int? ariaValueNow, } [DataTestMethod, - DataRow("3", null, 0), - DataRow(null, "{0} cm", 0), - DataRow(null, null, 0) + DataRow("3", null), + DataRow(null, "00"), + DataRow(null, null) ] - public void BitNumberFieldInputShouldHaveCorrectAriaValueText(string ariaValueText, string numberFormat, int precision) + public void BitNumberFieldInputShouldHaveCorrectAriaValueText(string ariaValueText, string numberFormat) { var component = RenderComponent>(parameters => { parameters.Add(p => p.AriaValueText, ariaValueText); - parameters.Add(p => p.Precision, precision); if (numberFormat.HasValue()) { parameters.Add(p => p.NumberFormat, numberFormat); @@ -494,18 +495,22 @@ public void BitNumberFieldInputShouldHaveCorrectAriaValueText(string ariaValueTe }); var input = component.Find("input"); - var expectedResult = ariaValueText.HasValue() ? ariaValueText : numberFormat.HasValue() ? string.Format(numberFormat, Normalize(component.Instance.Value, precision)) : component.Instance.Value.ToString(); + var expectedResult = ariaValueText.HasValue() + ? ariaValueText + : numberFormat.HasValue() + ? component.Instance.Value.ToString(numberFormat) + : component.Instance.Value.ToString(); Assert.AreEqual(expectedResult, input.GetAttribute("aria-valuetext")); } [DataTestMethod, - DataRow(3, 1, 12), - DataRow(8, 2, 10), - DataRow(8, 1, 8), - DataRow(8, 2, 9), - DataRow(8, 5, 9) + DataRow(3, "1", "12"), + DataRow(8, "2", "10"), + DataRow(8, "1", "8"), + DataRow(8, "2", "9"), + DataRow(8, "5", "9") ] - public void BitNumberFieldIncrementButtonClickTest(int defaultValue, int step, int max) + public void BitNumberFieldIncrementButtonClickTest(int defaultValue, string step, string max) { var component = RenderComponent>(parameters => { @@ -519,21 +524,21 @@ public void BitNumberFieldIncrementButtonClickTest(int defaultValue, int step, i var incrementButton = component.Find("button.bit-nfl-aup"); incrementButton.PointerDown(); var inputValue = input.GetAttribute("value"); - var expectedResult = defaultValue + step <= max - ? defaultValue + step - : defaultValue; + var expectedResult = defaultValue + int.Parse(step) <= int.Parse(max) + ? defaultValue + int.Parse(step) + : int.Parse(max); Assert.AreEqual(inputValue, expectedResult.ToString()); } [DataTestMethod, - DataRow(3, 1, 12), - DataRow(8, 2, 10), - DataRow(8, 1, 8), - DataRow(8, 2, 9), - DataRow(8, 5, 9) + DataRow(3, "1", "12"), + DataRow(8, "2", "10"), + DataRow(8, "1", "8"), + DataRow(8, "2", "9"), + DataRow(8, "5", "9") ] - public void BitNumberFieldArrowUpKeyDownTest(int defaultValue, int step, int max) + public void BitNumberFieldArrowUpKeyDownTest(int defaultValue, string step, string max) { var component = RenderComponent>(parameters => { @@ -549,20 +554,20 @@ public void BitNumberFieldArrowUpKeyDownTest(int defaultValue, int step, int max }; input.KeyDown(args); var inputValue = input.GetAttribute("value"); - var expectedResult = defaultValue + step <= max - ? defaultValue + step - : defaultValue; + var expectedResult = defaultValue + int.Parse(step) <= int.Parse(max) + ? defaultValue + int.Parse(step) + : int.Parse(max); Assert.AreEqual(expectedResult.ToString(), inputValue); } [DataTestMethod, - DataRow(3, 1, 0), - DataRow(2, 2, 0), - DataRow(3, 4, 0), - DataRow(0, 1, 0) + DataRow(3, "1", "0"), + DataRow(2, "2", "0"), + DataRow(3, "4", "0"), + DataRow(0, "1", "0") ] - public void BitNumberFieldDecrementButtonClickTest(int defaultValue, int step, int min) + public void BitNumberFieldDecrementButtonClickTest(int defaultValue, string step, string min) { var component = RenderComponent>(parameters => { @@ -576,20 +581,20 @@ public void BitNumberFieldDecrementButtonClickTest(int defaultValue, int step, i var decrementButton = component.Find("button.bit-nfl-adn"); decrementButton.PointerDown(); var inputValue = input.GetAttribute("value"); - var expectedResult = defaultValue - step >= min - ? defaultValue - step - : defaultValue; + var expectedResult = defaultValue - int.Parse(step) >= int.Parse(min) + ? defaultValue - int.Parse(step) + : int.Parse(min); Assert.AreEqual(inputValue, expectedResult.ToString()); } [DataTestMethod, - DataRow(3, 1, 0), - DataRow(2, 2, 0), - DataRow(3, 4, 0), - DataRow(0, 1, 0) + DataRow(3, "1", "0"), + DataRow(2, "2", "0"), + DataRow(3, "4", "0"), + DataRow(0, "1", "0") ] - public void BitNumberFieldArrowDownKeyDownTest(int defaultValue, int step, int min) + public void BitNumberFieldArrowDownKeyDownTest(int defaultValue, string step, string min) { var component = RenderComponent>(parameters => { @@ -605,21 +610,21 @@ public void BitNumberFieldArrowDownKeyDownTest(int defaultValue, int step, int m }; input.KeyDown(args); var inputValue = input.GetAttribute("value"); - var expectedResult = defaultValue - step >= min - ? defaultValue - step - : defaultValue; + var expectedResult = defaultValue - int.Parse(step) >= int.Parse(min) + ? defaultValue - int.Parse(step) + : int.Parse(min); Assert.AreEqual(expectedResult.ToString(), inputValue); } [DataTestMethod, - DataRow(50.02, 0, 100, "25"), - DataRow(50.02, 0, 100, "112.2"), - DataRow(50.02, 0, 100, "62.72"), - DataRow(50.02, 0, 100, "-5"), - DataRow(50.02, 0, 100, "text123") + DataRow(50.02, "0", "100", "25"), + DataRow(50.02, "0", "100", "112.2"), + DataRow(50.02, "0", "100", "62.72"), + DataRow(50.02, "0", "100", "-5"), + DataRow(50.02, "0", "100", "text123") ] - public void BitNumberFieldEnterKeyDownTest(double defaultValue, int min, int max, string userInput) + public void BitNumberFieldEnterKeyDownTest(double defaultValue, string min, string max, string userInput) { var component = RenderComponent>(parameters => { @@ -633,7 +638,7 @@ public void BitNumberFieldEnterKeyDownTest(double defaultValue, int min, int max { Value = userInput }; - input.Input(changeArgs); + input.Change(changeArgs); var keyboardArgs = new KeyboardEventArgs { Key = "Enter" @@ -644,25 +649,28 @@ public void BitNumberFieldEnterKeyDownTest(double defaultValue, int min, int max var isNumber = double.TryParse(userInput, out var numericValue); if (isNumber) { - expectedResult = Normalize(numericValue, 0); - if (expectedResult > max) expectedResult = max; - if (expectedResult < min) expectedResult = min; + expectedResult = numericValue; + if (expectedResult > int.Parse(max)) expectedResult = int.Parse(max); + if (expectedResult < int.Parse(min)) expectedResult = int.Parse(min); } else { - expectedResult = Normalize(defaultValue, 0); + expectedResult = defaultValue; } Assert.AreEqual(expectedResult, inputValue); } [DataTestMethod, - DataRow(5, 0, 100, "25"), - DataRow(5, 0, 100, "112"), - DataRow(5, 0, 100, "-5"), - DataRow(5, 0, 100, "text123") + DataRow(5, "0", "100", "25"), + DataRow(5, "0", "100", "112"), + DataRow(5, "0", "100", "-5"), + DataRow(5, "-100", "0", "-25"), + DataRow(5, "-100", "0", "-112"), + DataRow(5, "-100", "0", "5"), + DataRow(5, "10", "20", "text123") ] - public void BitNumberFieldOnBlurTest(double defaultValue, int min, int max, string userInput) + public void BitNumberFieldOnBlurTest(double defaultValue, string min, string max, string userInput) { var component = RenderComponent>(parameters => { @@ -676,15 +684,15 @@ public void BitNumberFieldOnBlurTest(double defaultValue, int min, int max, stri { Value = userInput }; - input.Input(changeArgs); + input.Change(changeArgs); var inputValue = component.Instance.Value; double? expectedResult = 0; var isNumber = double.TryParse(userInput, out var numericValue); if (isNumber) { - expectedResult = Normalize(numericValue, 1); - if (expectedResult > max) expectedResult = max; - if (expectedResult < min) expectedResult = min; + expectedResult = numericValue; + if (expectedResult > int.Parse(max)) expectedResult = int.Parse(max); + if (expectedResult < int.Parse(min)) expectedResult = int.Parse(min); } else { @@ -695,13 +703,13 @@ public void BitNumberFieldOnBlurTest(double defaultValue, int min, int max, stri } [DataTestMethod, - DataRow(0, 100, 1, "25"), - DataRow(0, 100, 2, "25"), - DataRow(0, 100, 25, "12"), - DataRow(0, 10, 52, "12"), - DataRow(13, 100, 523, "12") + DataRow("0", "100", "1", "25"), + DataRow("0", "100", "2", "25"), + DataRow("0", "100", "25", "12"), + DataRow("0", "10", "52", "12"), + DataRow("13", "100", "523", "12") ] - public void BitNumberFieldPrecisionTest(int min, int max, int step, string userInput) + public void BitNumberFieldPrecisionTest(string min, string max, string step, string userInput) { var component = RenderComponent>(parameters => { @@ -715,21 +723,20 @@ public void BitNumberFieldPrecisionTest(int min, int max, int step, string userI { Value = userInput }; - input.Input(changeArgs); + input.Change(changeArgs); var inputValue = component.Instance.Value; - var precision = CalculatePrecision(step); - var expectedResult = Normalize(int.Parse(userInput), precision); - if (expectedResult > max) expectedResult = max; - if (expectedResult < min) expectedResult = min; + var expectedResult = int.Parse(userInput); + if (expectedResult > int.Parse(max)) expectedResult = int.Parse(max); + if (expectedResult < int.Parse(min)) expectedResult = int.Parse(min); Assert.AreEqual(expectedResult, inputValue); } [DataTestMethod, - DataRow(5, 2, 4), - DataRow(1, 15, 1) + DataRow(5, 2, "4"), + DataRow(1, 15, "1") ] - public async Task BitNumberFieldTwoWayBoundWithCustomHandlerShouldWorkCorrect(int value, int countOfIncrements, int step) + public async Task BitNumberFieldTwoWayBoundWithCustomHandlerShouldWorkCorrect(int value, int countOfIncrements, string step) { BitNumberFieldTwoWayBoundValue = value; @@ -749,7 +756,7 @@ public async Task BitNumberFieldTwoWayBoundWithCustomHandlerShouldWorkCorrect(in await Task.Delay(1); } - var expectedValue = value + (step * countOfIncrements); + var expectedValue = value + int.Parse(step) * countOfIncrements; Assert.AreEqual(expectedValue, BitNumberFieldTwoWayBoundValue); } @@ -768,10 +775,10 @@ public void BitNumberFieldLabelFragmentTest(string labelFragment) [Ignore] [DataTestMethod, - DataRow(3, 1, 100, 475), - DataRow(3, 1, 100, 550) + DataRow(3, "1", "100", 475), + DataRow(3, "1", "100", 550) ] - public void BitNumberFieldContinuousIncrementOnPointerDownTest(int defaultValue, int step, int max, int timeout) + public void BitNumberFieldContinuousIncrementOnPointerDownTest(int defaultValue, string step, string max, int timeout) { var component = RenderComponent>(parameters => { @@ -785,7 +792,7 @@ public void BitNumberFieldContinuousIncrementOnPointerDownTest(int defaultValue, var incrementButton = component.Find("button.bit-nfl-aup"); var initialIncrementCount = timeout / 400; var continuousIncrementCount = timeout >= 400 ? (timeout - 400) / 75 : 0; - var expectedResult = defaultValue + step * (initialIncrementCount + continuousIncrementCount); + var expectedResult = defaultValue + int.Parse(step) * (initialIncrementCount + continuousIncrementCount); incrementButton.PointerDown(); component.WaitForAssertion(() => Assert.AreEqual(expectedResult.ToString(), input.GetAttribute("value")), @@ -794,10 +801,10 @@ public void BitNumberFieldContinuousIncrementOnPointerDownTest(int defaultValue, [Ignore] [DataTestMethod, - DataRow(50, 1, 0, 475), - DataRow(50, 1, 0, 550) + DataRow(50, "1", "0", 475), + DataRow(50, "1", "0", 550) ] - public void BitNumberFieldContinuousDecrementOnPointerDownTest(int defaultValue, int step, int min, int timeout) + public void BitNumberFieldContinuousDecrementOnPointerDownTest(int defaultValue, string step, string min, int timeout) { var component = RenderComponent>(parameters => { @@ -811,7 +818,7 @@ public void BitNumberFieldContinuousDecrementOnPointerDownTest(int defaultValue, var incrementButton = component.Find("button.bit-nfl-aup"); var initialDecrementCount = timeout / 400; var continuousDecrementCount = timeout >= 400 ? (timeout - 400) / 75 : 0; - var expectedResult = defaultValue - step * (initialDecrementCount + continuousDecrementCount); + var expectedResult = defaultValue - int.Parse(step) * (initialDecrementCount + continuousDecrementCount); incrementButton.PointerDown(); component.WaitForAssertion(() => Assert.AreEqual(expectedResult.ToString(), input.GetAttribute("value")), @@ -845,11 +852,11 @@ public void BitNumberFieldValidationFormTest(int value) var input = component.Find("input"); if (isValid) { - input.Input(2); + input.Change(2); } else { - input.Input(8); + input.Change(8); } form.Submit(); @@ -891,12 +898,12 @@ public void BitNumberFieldValidationInvalidHtmlAttributeTest(int value) if (isInvalid) { - input.Input(10); + input.Change(10); Assert.IsFalse(input.HasAttribute("aria-invalid")); } else { - input.Input(4); + input.Change(4); Assert.IsTrue(input.HasAttribute("aria-invalid")); } } @@ -928,41 +935,16 @@ public void BitNumberFieldValidationInvalidCssClassTest(int value) if (isInvalid) { - input.Input(10); + input.Change(10); } else { - input.Input(3); + input.Change(3); } Assert.AreEqual(!isInvalid, numberField.ClassList.Contains("bit-inv")); } - private double? Normalize(double? value, int precision) => - value.HasValue ? (double?)Math.Round(value.Value, precision) : null; - - private int CalculatePrecision(int value) - { - var regex = new Regex(@"[1-9]([0]+$)|\.([0-9]*)"); - if (regex.IsMatch(value.ToString()) is false) return 0; - - var matches = regex.Matches(value.ToString()); - if (matches.Count == 0) return 0; - - var groups = matches[0].Groups; - if (groups[1] != null && groups[1].Length != 0) - { - return -groups[1].Length; - } - - if (groups[2] != null && groups[2].Length != 0) - { - return groups[2].Length; - } - - return 0; - } - private void HandleValueChanged(int value) => BitNumberFieldTwoWayBoundValue = value; } diff --git a/src/BlazorUI/Bit.BlazorUI.Tests/NumberField/BitNumberFieldValidationTest.razor b/src/BlazorUI/Bit.BlazorUI.Tests/Components/Inputs/NumberField/BitNumberFieldValidationTest.razor similarity index 93% rename from src/BlazorUI/Bit.BlazorUI.Tests/NumberField/BitNumberFieldValidationTest.razor rename to src/BlazorUI/Bit.BlazorUI.Tests/Components/Inputs/NumberField/BitNumberFieldValidationTest.razor index f84276ba90..27b318b284 100644 --- a/src/BlazorUI/Bit.BlazorUI.Tests/NumberField/BitNumberFieldValidationTest.razor +++ b/src/BlazorUI/Bit.BlazorUI.Tests/Components/Inputs/NumberField/BitNumberFieldValidationTest.razor @@ -13,7 +13,7 @@ AriaValueText="@AriaValueText" AriaLabel="@AriaLabel" Suffix="@Suffix" - LeftLabel="@LeftLabel" + InlineLabel="@InlineLabel" IconName="@IconName" IconAriaLabel="@IconAriaLabel" DecrementIconName="@DecrementIconName" @@ -37,16 +37,16 @@ @code { - [Parameter] public bool LeftLabel { get; set; } + [Parameter] public bool InlineLabel { get; set; } [Parameter] public string AriaDescription { get; set; } [Parameter] public int? AriaPositionInSet { get; set; } [Parameter] public int? AriaSetSize { get; set; } [Parameter] public int? AriaValueNow { get; set; } [Parameter] public string AriaValueText { get; set; } [Parameter] public string AriaLabel { get; set; } - [Parameter] public int? Step { get; set; } = 1; - [Parameter] public int? Min { get; set; } - [Parameter] public int? Max { get; set; } + [Parameter] public string Min { get; set; } + [Parameter] public string Max { get; set; } + [Parameter] public string Step { get; set; } = "1"; [Parameter] public BitNumberFieldTestModel TestModel { get; set; } [Parameter] public EventCallback ValueChanged { get; set; } [Parameter] public string Suffix { get; set; } = string.Empty; diff --git a/src/BlazorUI/Bit.BlazorUI.Tests/OtpInput/BitOtpInputTests.cs b/src/BlazorUI/Bit.BlazorUI.Tests/Components/Inputs/OtpInput/BitOtpInputTests.cs similarity index 96% rename from src/BlazorUI/Bit.BlazorUI.Tests/OtpInput/BitOtpInputTests.cs rename to src/BlazorUI/Bit.BlazorUI.Tests/Components/Inputs/OtpInput/BitOtpInputTests.cs index 91656ada37..76c3c1ba07 100644 --- a/src/BlazorUI/Bit.BlazorUI.Tests/OtpInput/BitOtpInputTests.cs +++ b/src/BlazorUI/Bit.BlazorUI.Tests/Components/Inputs/OtpInput/BitOtpInputTests.cs @@ -1,7 +1,7 @@ -using Bunit; -using Microsoft.VisualStudio.TestTools.UnitTesting; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Bunit; -namespace Bit.BlazorUI.Tests.OtpInput; +namespace Bit.BlazorUI.Tests.Components.Inputs.OtpInput; [TestClass] public class BitOtpInputTests : BunitTestContext diff --git a/src/BlazorUI/Bit.BlazorUI.Tests/Rating/BitRatingTests.cs b/src/BlazorUI/Bit.BlazorUI.Tests/Components/Inputs/Rating/BitRatingTests.cs similarity index 82% rename from src/BlazorUI/Bit.BlazorUI.Tests/Rating/BitRatingTests.cs rename to src/BlazorUI/Bit.BlazorUI.Tests/Components/Inputs/Rating/BitRatingTests.cs index 3815d19414..2e46af9d15 100644 --- a/src/BlazorUI/Bit.BlazorUI.Tests/Rating/BitRatingTests.cs +++ b/src/BlazorUI/Bit.BlazorUI.Tests/Components/Inputs/Rating/BitRatingTests.cs @@ -1,8 +1,8 @@ using System.Linq; -using Bunit; using Microsoft.VisualStudio.TestTools.UnitTesting; +using Bunit; -namespace Bit.BlazorUI.Tests.Rating; +namespace Bit.BlazorUI.Tests.Components.Inputs.Rating; [TestClass] public class BitRatingTests : BunitTestContext @@ -37,11 +37,11 @@ public void BitRatingShouldTakeCorrectVisualAndEnabledStyle(bool isEnabled) } [TestMethod] - public void BitRatingShouldRespectIsReadonly() + public void BitRatingShouldRespectReadOnly() { var component = RenderComponent(parameters => { - parameters.Add(p => p.IsReadOnly, true); + parameters.Add(p => p.ReadOnly, true); parameters.Add(p => p.AllowZeroStars, true); }); @@ -90,10 +90,10 @@ public void BitRatingShouldTakeCorrectAriaLabelFormat(string ariaLabelFormat) [DataTestMethod, DataRow(null), - DataRow(BitRatingSize.Small), - DataRow(BitRatingSize.Large) + DataRow(BitSize.Small), + DataRow(BitSize.Large) ] - public void BitRatingShouldRespectSize(BitRatingSize size) + public void BitRatingShouldRespectSize(BitSize size) { var component = RenderComponent(parameters => { @@ -101,7 +101,7 @@ public void BitRatingShouldRespectSize(BitRatingSize size) }); var bitRating = component.Find(".bit-rtg"); - var sizeClass = size == BitRatingSize.Large ? "bit-rtg-lg" : "bit-rtg-sm"; + var sizeClass = size == BitSize.Large ? "bit-rtg-lg" : "bit-rtg-sm"; Assert.IsTrue(bitRating.ClassList.Contains(sizeClass)); } @@ -124,24 +124,29 @@ public void BitRatingShouldRespectAllowZeroStars(bool allowZeroStars) Assert.AreEqual(allowZeroStars is false, bool.Parse(firstButton.GetAttribute("aria-checked"))); } - [DataTestMethod, - DataRow("HeartFill", "Heart"), - DataRow("HeartFill", "Heart"), - ] - public void BitRatingShouldTakeCustomIcon(string icon, string unselectedIcon) + [TestMethod] + public void BitRatingShouldTakeCustomIcon() { + var icon = "HeartFill"; + var unselectedIcon = "Heart"; var component = RenderComponent(parameters => { + parameters.Add(p => p.DefaultValue, 2); parameters.Add(p => p.SelectedIconName, icon); parameters.Add(p => p.UnselectedIconName, unselectedIcon); }); - var ratingIcon = component.Find(".bit-rtg-btn i"); - var ratingUnselectedIcon = component.Find(".bit-rtg-btn:nth-child(2) i"); - - //TODO: bypassed - BUnit 2-way bound parameters issue - Assert.IsTrue(ratingIcon.ClassList.Contains($"bit-icon--{icon}")); - Assert.IsTrue(ratingUnselectedIcon.ClassList.Contains($"bit-icon--{unselectedIcon}")); + var ratingIcon1 = component.Find(".bit-rtg-btn:nth-child(1) i"); + var ratingIcon2 = component.Find(".bit-rtg-btn:nth-child(2) i"); + var ratingUnselectedIcon3 = component.Find(".bit-rtg-btn:nth-child(3) i"); + var ratingUnselectedIcon4 = component.Find(".bit-rtg-btn:nth-child(4) i"); + var ratingUnselectedIcon5 = component.Find(".bit-rtg-btn:nth-child(5) i"); + + Assert.IsTrue(ratingIcon1.ClassList.Contains($"bit-icon--{icon}")); + Assert.IsTrue(ratingIcon2.ClassList.Contains($"bit-icon--{icon}")); + Assert.IsTrue(ratingUnselectedIcon3.ClassList.Contains($"bit-icon--{unselectedIcon}")); + Assert.IsTrue(ratingUnselectedIcon4.ClassList.Contains($"bit-icon--{unselectedIcon}")); + Assert.IsTrue(ratingUnselectedIcon5.ClassList.Contains($"bit-icon--{unselectedIcon}")); } [Ignore("bypassed - BUnit 2-way bound parameters issue")] @@ -152,13 +157,13 @@ public void BitRatingShouldTakeCustomIcon(string icon, string unselectedIcon) DataRow(10, 4, false, true, 1), DataRow(10, 0, true, false, 1) ] - public void BitRatingShouldRespectClickIndex(int max, int clickedIndex, bool isEnabled, bool isReadonly, int expectedResult) + public void BitRatingShouldRespectClickIndex(int max, int clickedIndex, bool isEnabled, bool readOnly, int expectedResult) { var component = RenderComponent(parameters => { parameters.Add(p => p.Max, max); parameters.Add(p => p.IsEnabled, isEnabled); - parameters.Add(p => p.IsReadOnly, isReadonly); + parameters.Add(p => p.ReadOnly, readOnly); }); var bitRatingButtons = component.FindAll(".bit-rtg-btn"); @@ -178,8 +183,8 @@ public void BitRatingShouldRespectClickIndex(int max, int clickedIndex, bool isE Assert.AreEqual(bitRatingButtons.Count(), max); //TODO: bypassed - BUnit 2-way bound parameters issue - Assert.AreEqual((!isEnabled || isReadonly) ? 1 : clickedIndex, filledBitRatingIconCount); - Assert.AreEqual((!isEnabled || isReadonly) ? max - 1 : max - clickedIndex, unselectedBitRatingIconCount); + Assert.AreEqual((!isEnabled || readOnly) ? 1 : clickedIndex, filledBitRatingIconCount); + Assert.AreEqual((!isEnabled || readOnly) ? max - 1 : max - clickedIndex, unselectedBitRatingIconCount); } [DataTestMethod, DataRow("Detailed label")] diff --git a/src/BlazorUI/Bit.BlazorUI.Tests/SearchBoxes/BitSearchBoxTestModel.cs b/src/BlazorUI/Bit.BlazorUI.Tests/Components/Inputs/SearchBox/BitSearchBoxTestModel.cs similarity index 73% rename from src/BlazorUI/Bit.BlazorUI.Tests/SearchBoxes/BitSearchBoxTestModel.cs rename to src/BlazorUI/Bit.BlazorUI.Tests/Components/Inputs/SearchBox/BitSearchBoxTestModel.cs index ea4aaf9e80..5ee42ad952 100644 --- a/src/BlazorUI/Bit.BlazorUI.Tests/SearchBoxes/BitSearchBoxTestModel.cs +++ b/src/BlazorUI/Bit.BlazorUI.Tests/Components/Inputs/SearchBox/BitSearchBoxTestModel.cs @@ -1,6 +1,6 @@ using System.ComponentModel.DataAnnotations; -namespace Bit.BlazorUI.Tests.SearchBoxes; +namespace Bit.BlazorUI.Tests.Components.Inputs.SearchBox; public class BitSearchBoxTestModel { diff --git a/src/BlazorUI/Bit.BlazorUI.Tests/SearchBoxes/BitSearchBoxTests.cs b/src/BlazorUI/Bit.BlazorUI.Tests/Components/Inputs/SearchBox/BitSearchBoxTests.cs similarity index 98% rename from src/BlazorUI/Bit.BlazorUI.Tests/SearchBoxes/BitSearchBoxTests.cs rename to src/BlazorUI/Bit.BlazorUI.Tests/Components/Inputs/SearchBox/BitSearchBoxTests.cs index b1c9b501da..a397114f75 100644 --- a/src/BlazorUI/Bit.BlazorUI.Tests/SearchBoxes/BitSearchBoxTests.cs +++ b/src/BlazorUI/Bit.BlazorUI.Tests/Components/Inputs/SearchBox/BitSearchBoxTests.cs @@ -1,8 +1,7 @@ -using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; using Bunit; -using Microsoft.VisualStudio.TestTools.UnitTesting; -namespace Bit.BlazorUI.Tests.SearchBoxes; +namespace Bit.BlazorUI.Tests.Components.Inputs.SearchBox; [TestClass] public class BitSearchBoxTests : BunitTestContext diff --git a/src/BlazorUI/Bit.BlazorUI.Tests/SearchBoxes/BitSearchBoxValidationTest.razor b/src/BlazorUI/Bit.BlazorUI.Tests/Components/Inputs/SearchBox/BitSearchBoxValidationTest.razor similarity index 100% rename from src/BlazorUI/Bit.BlazorUI.Tests/SearchBoxes/BitSearchBoxValidationTest.razor rename to src/BlazorUI/Bit.BlazorUI.Tests/Components/Inputs/SearchBox/BitSearchBoxValidationTest.razor diff --git a/src/BlazorUI/Bit.BlazorUI.Tests/Sliders/BitSliderTests.cs b/src/BlazorUI/Bit.BlazorUI.Tests/Components/Inputs/Slider/BitSliderTests.cs similarity index 99% rename from src/BlazorUI/Bit.BlazorUI.Tests/Sliders/BitSliderTests.cs rename to src/BlazorUI/Bit.BlazorUI.Tests/Components/Inputs/Slider/BitSliderTests.cs index bfa13c0a9f..de94114400 100644 --- a/src/BlazorUI/Bit.BlazorUI.Tests/Sliders/BitSliderTests.cs +++ b/src/BlazorUI/Bit.BlazorUI.Tests/Components/Inputs/Slider/BitSliderTests.cs @@ -1,9 +1,8 @@ -using System; -using System.Linq; -using Bunit; +using System.Linq; using Microsoft.VisualStudio.TestTools.UnitTesting; +using Bunit; -namespace Bit.BlazorUI.Tests.Sliders; +namespace Bit.BlazorUI.Tests.Components.Inputs.Slider; [TestClass] public class BitSliderTests : BunitTestContext diff --git a/src/BlazorUI/Bit.BlazorUI.Tests/SpinButtons/BitSpinButtonTestModel.cs b/src/BlazorUI/Bit.BlazorUI.Tests/Components/Inputs/SpinButton/BitSpinButtonTestModel.cs similarity index 71% rename from src/BlazorUI/Bit.BlazorUI.Tests/SpinButtons/BitSpinButtonTestModel.cs rename to src/BlazorUI/Bit.BlazorUI.Tests/Components/Inputs/SpinButton/BitSpinButtonTestModel.cs index c519a1af24..ccdcede5c1 100644 --- a/src/BlazorUI/Bit.BlazorUI.Tests/SpinButtons/BitSpinButtonTestModel.cs +++ b/src/BlazorUI/Bit.BlazorUI.Tests/Components/Inputs/SpinButton/BitSpinButtonTestModel.cs @@ -1,6 +1,6 @@ using System.ComponentModel.DataAnnotations; -namespace Bit.BlazorUI.Tests.SpinButtons; +namespace Bit.BlazorUI.Tests.Components.Inputs.SpinButton; public class BitSpinButtonTestModel { diff --git a/src/BlazorUI/Bit.BlazorUI.Tests/SpinButtons/BitSpinButtonTests.cs b/src/BlazorUI/Bit.BlazorUI.Tests/Components/Inputs/SpinButton/BitSpinButtonTests.cs similarity index 99% rename from src/BlazorUI/Bit.BlazorUI.Tests/SpinButtons/BitSpinButtonTests.cs rename to src/BlazorUI/Bit.BlazorUI.Tests/Components/Inputs/SpinButton/BitSpinButtonTests.cs index 1438983356..2a812220cb 100644 --- a/src/BlazorUI/Bit.BlazorUI.Tests/SpinButtons/BitSpinButtonTests.cs +++ b/src/BlazorUI/Bit.BlazorUI.Tests/Components/Inputs/SpinButton/BitSpinButtonTests.cs @@ -1,13 +1,13 @@ using System; +using System.Threading.Tasks; using System.Collections.Generic; using System.Text.RegularExpressions; -using System.Threading.Tasks; -using Bunit; using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components.Web; using Microsoft.VisualStudio.TestTools.UnitTesting; +using Bunit; -namespace Bit.BlazorUI.Tests.SpinButtons; +namespace Bit.BlazorUI.Tests.Components.Inputs.SpinButton; [TestClass] public class BitSpinButtonTests : BunitTestContext diff --git a/src/BlazorUI/Bit.BlazorUI.Tests/SpinButtons/BitSpinButtonValidationTest.razor b/src/BlazorUI/Bit.BlazorUI.Tests/Components/Inputs/SpinButton/BitSpinButtonValidationTest.razor similarity index 100% rename from src/BlazorUI/Bit.BlazorUI.Tests/SpinButtons/BitSpinButtonValidationTest.razor rename to src/BlazorUI/Bit.BlazorUI.Tests/Components/Inputs/SpinButton/BitSpinButtonValidationTest.razor diff --git a/src/BlazorUI/Bit.BlazorUI.Tests/TextField/BitTextFieldTestModel.cs b/src/BlazorUI/Bit.BlazorUI.Tests/Components/Inputs/TextField/BitTextFieldTestModel.cs similarity index 76% rename from src/BlazorUI/Bit.BlazorUI.Tests/TextField/BitTextFieldTestModel.cs rename to src/BlazorUI/Bit.BlazorUI.Tests/Components/Inputs/TextField/BitTextFieldTestModel.cs index 97c77de031..c09b3c7a85 100644 --- a/src/BlazorUI/Bit.BlazorUI.Tests/TextField/BitTextFieldTestModel.cs +++ b/src/BlazorUI/Bit.BlazorUI.Tests/Components/Inputs/TextField/BitTextFieldTestModel.cs @@ -1,6 +1,6 @@ using System.ComponentModel.DataAnnotations; -namespace Bit.BlazorUI.Tests.TextField; +namespace Bit.BlazorUI.Tests.Components.Inputs.TextField; public class BitTextFieldTestModel { diff --git a/src/BlazorUI/Bit.BlazorUI.Tests/TextField/BitTextFieldTests.cs b/src/BlazorUI/Bit.BlazorUI.Tests/Components/Inputs/TextField/BitTextFieldTests.cs similarity index 95% rename from src/BlazorUI/Bit.BlazorUI.Tests/TextField/BitTextFieldTests.cs rename to src/BlazorUI/Bit.BlazorUI.Tests/Components/Inputs/TextField/BitTextFieldTests.cs index e5cea4f1c7..086eb334af 100644 --- a/src/BlazorUI/Bit.BlazorUI.Tests/TextField/BitTextFieldTests.cs +++ b/src/BlazorUI/Bit.BlazorUI.Tests/Components/Inputs/TextField/BitTextFieldTests.cs @@ -1,9 +1,8 @@ -using System; -using Bunit; -using Microsoft.AspNetCore.Components.Web; +using Microsoft.AspNetCore.Components.Web; using Microsoft.VisualStudio.TestTools.UnitTesting; +using Bunit; -namespace Bit.BlazorUI.Tests.TextField; +namespace Bit.BlazorUI.Tests.Components.Inputs.TextField; [TestClass] public class BitTextFieldTests : BunitTestContext @@ -14,13 +13,13 @@ public class BitTextFieldTests : BunitTestContext DataRow(true, false, true), DataRow(false, false, false) ] - public void BitTextFieldShouldTakeCorrectTypeAndVisual(bool isEnabled, bool isMultiline, bool isRequired) + public void BitTextFieldShouldTakeCorrectTypeAndVisual(bool isEnabled, bool isMultiline, bool required) { var component = RenderComponent(parameters => { parameters.Add(p => p.IsEnabled, isEnabled); parameters.Add(p => p.IsMultiline, isMultiline); - parameters.Add(p => p.IsRequired, isRequired); + parameters.Add(p => p.Required, required); }); var bitTextField = component.Find(".bit-txt"); @@ -37,8 +36,8 @@ public void BitTextFieldShouldTakeCorrectTypeAndVisual(bool isEnabled, bool isMu Assert.AreEqual(isMultiline ? "TEXTAREA" : "INPUT", textField.TagName); - Assert.AreEqual(isRequired, textField.HasAttribute("required")); - Assert.AreEqual(isRequired, bitTextField.ClassList.Contains("bit-txt-req")); + Assert.AreEqual(required, textField.HasAttribute("required")); + Assert.AreEqual(required, bitTextField.ClassList.Contains("bit-txt-req")); } [DataTestMethod, @@ -77,14 +76,14 @@ public void BitTextFieldLabel(string label) DataRow(15, false, "this is placeholder", true), DataRow(15, false, "this is placeholder", false), ] - public void BitTextFieldShouldTakeBaseParameters(int maxLength, bool isMultiline, string placeholder, bool isReadOnly) + public void BitTextFieldShouldTakeBaseParameters(int maxLength, bool isMultiline, string placeholder, bool readOnly) { var component = RenderComponent(parameters => { parameters.Add(p => p.MaxLength, maxLength); parameters.Add(p => p.IsMultiline, isMultiline); parameters.Add(p => p.Placeholder, placeholder); - parameters.Add(p => p.IsReadOnly, isReadOnly); + parameters.Add(p => p.ReadOnly, readOnly); }); var bitTextField = component.Find(".bit-txt-inp"); @@ -95,7 +94,7 @@ public void BitTextFieldShouldTakeBaseParameters(int maxLength, bool isMultiline Assert.IsTrue(bitTextField.HasAttribute("placeholder")); Assert.AreEqual(bitTextField.GetAttribute("placeholder"), placeholder); - Assert.AreEqual(isReadOnly, bitTextField.HasAttribute("readonly")); + Assert.AreEqual(readOnly, bitTextField.HasAttribute("readonly")); } [DataTestMethod, DataRow("Emoji2")] @@ -254,7 +253,7 @@ public void BitTextFieldMustRespondToTheChangeEvent(bool isEnabled, bool isMulti var bitTextField = component.Find(".bit-txt-inp"); - bitTextField.Input("a"); + bitTextField.Change("a"); Assert.AreEqual(isEnabled ? 1 : 0, currentCount); } @@ -284,25 +283,20 @@ public void BitTextFieldShowSuffix(string suffix) } [DataTestMethod, - DataRow(true, null, "hello world"), - DataRow(false, null, "hello world"), - DataRow(true, "hello bit", "hello world"), - DataRow(false, "hello bit", "hello world"), + DataRow(true, "hello world"), + DataRow(false, "hello world"), ] - public void BitTextFieldShouldTakeDefaultValue(bool isMultiline, string value, string defaultValue) + public void BitTextFieldShouldTakeDefaultValue(bool isMultiline, string defaultValue) { var component = RenderComponent(parameters => { - parameters.Bind(p => p.Value, value, v => value = v); parameters.Add(p => p.DefaultValue, defaultValue); parameters.Add(p => p.IsMultiline, isMultiline); }); var bitTextField = component.Find(".bit-txt-inp"); - var actualValue = string.IsNullOrEmpty(value) ? defaultValue : value; - - Assert.AreEqual(bitTextField.GetAttribute("value"), actualValue); + Assert.AreEqual(defaultValue, bitTextField.GetAttribute("value")); } [DataTestMethod, DataRow("test description")] @@ -623,6 +617,7 @@ public void BitTextFieldValidationInvalidCssClassTest(string value) Assert.AreEqual(isInvalid, bitTextField.ClassList.Contains("bit-inv")); var input = component.Find("input"); + if (isInvalid) { input.Change("test@bit.com"); diff --git a/src/BlazorUI/Bit.BlazorUI.Tests/TextField/BitTextFieldValidationTest.razor b/src/BlazorUI/Bit.BlazorUI.Tests/Components/Inputs/TextField/BitTextFieldValidationTest.razor similarity index 95% rename from src/BlazorUI/Bit.BlazorUI.Tests/TextField/BitTextFieldValidationTest.razor rename to src/BlazorUI/Bit.BlazorUI.Tests/Components/Inputs/TextField/BitTextFieldValidationTest.razor index 3f7114be17..2988b0acb4 100644 --- a/src/BlazorUI/Bit.BlazorUI.Tests/TextField/BitTextFieldValidationTest.razor +++ b/src/BlazorUI/Bit.BlazorUI.Tests/Components/Inputs/TextField/BitTextFieldValidationTest.razor @@ -5,8 +5,8 @@ IsMultiline="IsMultiline" Type="Type" Placeholder="@Placeholder" - IsReadOnly="IsReadOnly" - IsRequired="IsRequired" + ReadOnly="ReadOnly" + Required="Required" IsEnabled="IsEnabled" IconName="@IconName" @bind-Value="@TestModel.Value" @@ -39,8 +39,8 @@ [Parameter] public string IconName { get; set; } [Parameter] public bool IsMultiline { get; set; } [Parameter] public bool IsEnabled { get; set; } = true; - [Parameter] public bool IsReadOnly { get; set; } - [Parameter] public bool IsRequired { get; set; } + [Parameter] public bool ReadOnly { get; set; } + [Parameter] public bool Required { get; set; } [Parameter] public string Placeholder { get; set; } [Parameter] public bool CanRevealPassword { get; set; } [Parameter] public string RevealPasswordAriaLabel { get; set; } diff --git a/src/BlazorUI/Bit.BlazorUI.Tests/Toggles/BitToggleTestModel.cs b/src/BlazorUI/Bit.BlazorUI.Tests/Components/Inputs/Toggle/BitToggleTestModel.cs similarity index 75% rename from src/BlazorUI/Bit.BlazorUI.Tests/Toggles/BitToggleTestModel.cs rename to src/BlazorUI/Bit.BlazorUI.Tests/Components/Inputs/Toggle/BitToggleTestModel.cs index 002d0cd76d..43f9d5f918 100644 --- a/src/BlazorUI/Bit.BlazorUI.Tests/Toggles/BitToggleTestModel.cs +++ b/src/BlazorUI/Bit.BlazorUI.Tests/Components/Inputs/Toggle/BitToggleTestModel.cs @@ -1,6 +1,6 @@ using System.ComponentModel.DataAnnotations; -namespace Bit.BlazorUI.Tests.Toggles; +namespace Bit.BlazorUI.Tests.Components.Inputs.Toggle; public class BitToggleTestModel { diff --git a/src/BlazorUI/Bit.BlazorUI.Tests/Toggles/BitToggleTests.cs b/src/BlazorUI/Bit.BlazorUI.Tests/Components/Inputs/Toggle/BitToggleTests.cs similarity index 98% rename from src/BlazorUI/Bit.BlazorUI.Tests/Toggles/BitToggleTests.cs rename to src/BlazorUI/Bit.BlazorUI.Tests/Components/Inputs/Toggle/BitToggleTests.cs index 6938838a49..8782b466c9 100644 --- a/src/BlazorUI/Bit.BlazorUI.Tests/Toggles/BitToggleTests.cs +++ b/src/BlazorUI/Bit.BlazorUI.Tests/Components/Inputs/Toggle/BitToggleTests.cs @@ -1,8 +1,7 @@ -using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; using Bunit; -using Microsoft.VisualStudio.TestTools.UnitTesting; -namespace Bit.BlazorUI.Tests.Toggles; +namespace Bit.BlazorUI.Tests.Components.Inputs.Toggle; [TestClass] public class BitToggleTests : BunitTestContext diff --git a/src/BlazorUI/Bit.BlazorUI.Tests/Toggles/BitToggleValidationTest.razor b/src/BlazorUI/Bit.BlazorUI.Tests/Components/Inputs/Toggle/BitToggleValidationTest.razor similarity index 100% rename from src/BlazorUI/Bit.BlazorUI.Tests/Toggles/BitToggleValidationTest.razor rename to src/BlazorUI/Bit.BlazorUI.Tests/Components/Inputs/Toggle/BitToggleValidationTest.razor diff --git a/src/BlazorUI/Bit.BlazorUI.Tests/Lists/BitBasicList/BitBasicListTest.razor b/src/BlazorUI/Bit.BlazorUI.Tests/Components/Lists/BasicList/BitBasicListTest.razor similarity index 100% rename from src/BlazorUI/Bit.BlazorUI.Tests/Lists/BitBasicList/BitBasicListTest.razor rename to src/BlazorUI/Bit.BlazorUI.Tests/Components/Lists/BasicList/BitBasicListTest.razor diff --git a/src/BlazorUI/Bit.BlazorUI.Tests/Lists/BitBasicList/BitBasicListTests.cs b/src/BlazorUI/Bit.BlazorUI.Tests/Components/Lists/BasicList/BitBasicListTests.cs similarity index 98% rename from src/BlazorUI/Bit.BlazorUI.Tests/Lists/BitBasicList/BitBasicListTests.cs rename to src/BlazorUI/Bit.BlazorUI.Tests/Components/Lists/BasicList/BitBasicListTests.cs index 082472841c..36b72a53c3 100644 --- a/src/BlazorUI/Bit.BlazorUI.Tests/Lists/BitBasicList/BitBasicListTests.cs +++ b/src/BlazorUI/Bit.BlazorUI.Tests/Components/Lists/BasicList/BitBasicListTests.cs @@ -1,9 +1,9 @@ using System; using System.Collections.Generic; -using Bunit; using Microsoft.VisualStudio.TestTools.UnitTesting; +using Bunit; -namespace Bit.BlazorUI.Tests.Lists.BitBasicList; +namespace Bit.BlazorUI.Tests.Components.Lists.BasicList; [TestClass] public class BitBasicListTests : BunitTestContext diff --git a/src/BlazorUI/Bit.BlazorUI.Tests/Lists/BitBasicList/PersonTestModel.cs b/src/BlazorUI/Bit.BlazorUI.Tests/Components/Lists/BasicList/PersonTestModel.cs similarity index 74% rename from src/BlazorUI/Bit.BlazorUI.Tests/Lists/BitBasicList/PersonTestModel.cs rename to src/BlazorUI/Bit.BlazorUI.Tests/Components/Lists/BasicList/PersonTestModel.cs index ac7dbc2021..8b279df224 100644 --- a/src/BlazorUI/Bit.BlazorUI.Tests/Lists/BitBasicList/PersonTestModel.cs +++ b/src/BlazorUI/Bit.BlazorUI.Tests/Components/Lists/BasicList/PersonTestModel.cs @@ -1,4 +1,5 @@ -namespace Bit.BlazorUI.Tests.Lists.BitBasicList; +namespace Bit.BlazorUI.Tests.Components.Lists.BasicList; + public class Person { public int Id { get; set; } diff --git a/src/BlazorUI/Bit.BlazorUI.Tests/Breadcrumb/BitBreadcrumbTests.cs b/src/BlazorUI/Bit.BlazorUI.Tests/Components/Navs/Breadcrumb/BitBreadcrumbTests.cs similarity index 88% rename from src/BlazorUI/Bit.BlazorUI.Tests/Breadcrumb/BitBreadcrumbTests.cs rename to src/BlazorUI/Bit.BlazorUI.Tests/Components/Navs/Breadcrumb/BitBreadcrumbTests.cs index a10ddc38e1..029d6c0b55 100644 --- a/src/BlazorUI/Bit.BlazorUI.Tests/Breadcrumb/BitBreadcrumbTests.cs +++ b/src/BlazorUI/Bit.BlazorUI.Tests/Components/Navs/Breadcrumb/BitBreadcrumbTests.cs @@ -1,8 +1,8 @@ using System.Collections.Generic; -using Bunit; using Microsoft.VisualStudio.TestTools.UnitTesting; +using Bunit; -namespace Bit.BlazorUI.Tests.Breadcrumb; +namespace Bit.BlazorUI.Tests.Components.Navs.Breadcrumb; [TestClass] public class BitBreadcrumbTests : BunitTestContext @@ -14,7 +14,7 @@ public void BitBreadcrumbShouldTakeDividerIcon(string icon) { var component = RenderComponent>(parameters => { - parameters.Add(p => p.Items, BitBreadcrumbTests.GetBreadcrumbItems()); + parameters.Add(p => p.Items, GetBreadcrumbItems()); parameters.Add(p => p.DividerIconName, icon); }); @@ -29,7 +29,7 @@ public void BitBreadcrumbShouldTakeDividerIcon(string icon) ] public void BitBreadcrumbShouldRespectMaxDisplayItems(uint maxDisplayedItems) { - var breadcrumbItems = BitBreadcrumbTests.GetBreadcrumbItems(); + var breadcrumbItems = GetBreadcrumbItems(); var component = RenderComponent>(parameters => { @@ -57,7 +57,7 @@ public void BitBreadcrumbShouldRespectOverflowChanges(string icon, uint maxDispl { var component = RenderComponent>(parameters => { - parameters.Add(p => p.Items, BitBreadcrumbTests.GetBreadcrumbItems()); + parameters.Add(p => p.Items, GetBreadcrumbItems()); parameters.Add(p => p.OverflowIndex, overflowIndex); parameters.Add(p => p.OverflowIconName, icon); parameters.Add(p => p.MaxDisplayedItems, maxDisplayedItems); @@ -77,7 +77,7 @@ public void BitBreadcrumbShouldRespectOverflowChanges(string icon, uint maxDispl [DataTestMethod] public void BitBreadcrumbShouldTakeCorrectAriaCurrent() { - var breadcrumbItems = BitBreadcrumbTests.GetBreadcrumbItems(); + var breadcrumbItems = GetBreadcrumbItems(); var component = RenderComponent>(parameters => { @@ -96,7 +96,7 @@ public void BitBreadcrumbShouldTakeCorrectAriaCurrent() ] public void BitBreadcrumbShouldTakeOverflowAriaLabel(string overflowAriaLabel, uint maxDisplayedItems) { - var breadcrumbItems = BitBreadcrumbTests.GetBreadcrumbItems(); + var breadcrumbItems = GetBreadcrumbItems(); var component = RenderComponent>(parameters => { @@ -117,7 +117,7 @@ public void BitBreadcrumbShouldTakeCustomStyle(string customStyle) { var component = RenderComponent>(parameters => { - parameters.Add(p => p.Items, BitBreadcrumbTests.GetBreadcrumbItems()); + parameters.Add(p => p.Items, GetBreadcrumbItems()); parameters.Add(p => p.Style, customStyle); }); @@ -133,7 +133,7 @@ public void BitBreadcrumbShouldTakeCustomClass(string customClass) { var component = RenderComponent>(parameters => { - parameters.Add(p => p.Items, BitBreadcrumbTests.GetBreadcrumbItems()); + parameters.Add(p => p.Items, GetBreadcrumbItems()); parameters.Add(p => p.Class, customClass); }); @@ -151,7 +151,7 @@ public void BitBreadcrumbShouldTakeCustomVisibility(BitVisibility visibility) { var component = RenderComponent>(parameters => { - parameters.Add(p => p.Items, BitBreadcrumbTests.GetBreadcrumbItems()); + parameters.Add(p => p.Items, GetBreadcrumbItems()); parameters.Add(p => p.Visibility, visibility); }); @@ -160,7 +160,7 @@ public void BitBreadcrumbShouldTakeCustomVisibility(BitVisibility visibility) switch (visibility) { case BitVisibility.Visible: - Assert.IsTrue(breadcrumb.GetAttribute("style").Contains("")); + Assert.IsFalse(breadcrumb.HasAttribute("style")); break; case BitVisibility.Hidden: Assert.IsTrue(breadcrumb.GetAttribute("style").Contains("visibility:hidden")); diff --git a/src/BlazorUI/Bit.BlazorUI.Tests/Nav/BitNavTest.razor b/src/BlazorUI/Bit.BlazorUI.Tests/Components/Navs/Nav/BitNavTest.razor similarity index 100% rename from src/BlazorUI/Bit.BlazorUI.Tests/Nav/BitNavTest.razor rename to src/BlazorUI/Bit.BlazorUI.Tests/Components/Navs/Nav/BitNavTest.razor diff --git a/src/BlazorUI/Bit.BlazorUI.Tests/Nav/BitNavTests.cs b/src/BlazorUI/Bit.BlazorUI.Tests/Components/Navs/Nav/BitNavTests.cs similarity index 98% rename from src/BlazorUI/Bit.BlazorUI.Tests/Nav/BitNavTests.cs rename to src/BlazorUI/Bit.BlazorUI.Tests/Components/Navs/Nav/BitNavTests.cs index 55f2a05867..446f150195 100644 --- a/src/BlazorUI/Bit.BlazorUI.Tests/Nav/BitNavTests.cs +++ b/src/BlazorUI/Bit.BlazorUI.Tests/Components/Navs/Nav/BitNavTests.cs @@ -1,8 +1,8 @@ using System.Collections.Generic; -using Bunit; using Microsoft.VisualStudio.TestTools.UnitTesting; +using Bunit; -namespace Bit.BlazorUI.Tests.Nav; +namespace Bit.BlazorUI.Tests.Components.Navs.Nav; [TestClass] public class BitNavTests : BunitTestContext @@ -15,7 +15,7 @@ public class BitNavTests : BunitTestContext ] public void BitNavLinkItemMainClassTest(bool isEnabled, bool hasUrl) { - string url = hasUrl ? "https://www.google.com/" : null; + var url = hasUrl ? "https://www.google.com/" : null; var navLinkItems = new List { new BitNavItem { Text = "test", IsEnabled = isEnabled, Url = url } }; var component = RenderComponent(parameters => diff --git a/src/BlazorUI/Bit.BlazorUI.Tests/Pivot/BitPivotTests.cs b/src/BlazorUI/Bit.BlazorUI.Tests/Components/Navs/Pivot/BitPivotTests.cs similarity index 83% rename from src/BlazorUI/Bit.BlazorUI.Tests/Pivot/BitPivotTests.cs rename to src/BlazorUI/Bit.BlazorUI.Tests/Components/Navs/Pivot/BitPivotTests.cs index 6b9a1e0826..5aabe78aa0 100644 --- a/src/BlazorUI/Bit.BlazorUI.Tests/Pivot/BitPivotTests.cs +++ b/src/BlazorUI/Bit.BlazorUI.Tests/Components/Navs/Pivot/BitPivotTests.cs @@ -1,17 +1,17 @@ -using Bunit; -using Microsoft.VisualStudio.TestTools.UnitTesting; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Bunit; -namespace Bit.BlazorUI.Tests.Pivot; +namespace Bit.BlazorUI.Tests.Components.Navs.Pivot; [TestClass] public class BitPivotTests : BunitTestContext { [DataTestMethod, - DataRow(BitPivotLinkFormat.Links, BitPivotLinkSize.Large, BitPivotOverflowBehavior.None), - DataRow(BitPivotLinkFormat.Tabs, BitPivotLinkSize.Normal, BitPivotOverflowBehavior.Scroll), - DataRow(BitPivotLinkFormat.Tabs, BitPivotLinkSize.Normal, BitPivotOverflowBehavior.Menu) + DataRow(BitPivotLinkFormat.Links, BitSize.Large, BitPivotOverflowBehavior.None), + DataRow(BitPivotLinkFormat.Tabs, BitSize.Medium, BitPivotOverflowBehavior.Scroll), + DataRow(BitPivotLinkFormat.Tabs, BitSize.Small, BitPivotOverflowBehavior.Menu) ] - public void BitPivotShouldRespectLinkFormatClasses(BitPivotLinkFormat linkFormat, BitPivotLinkSize linkSize, BitPivotOverflowBehavior overflowBehavior) + public void BitPivotShouldRespectLinkFormatClasses(BitPivotLinkFormat linkFormat, BitSize linkSize, BitPivotOverflowBehavior overflowBehavior) { var component = RenderComponent(parameters => { @@ -20,8 +20,8 @@ public void BitPivotShouldRespectLinkFormatClasses(BitPivotLinkFormat linkFormat parameters.Add(p => p.OverflowBehavior, overflowBehavior); }); + var linkSizeClass = $"bit-pvt-{linkSize switch { BitSize.Small => "sm", BitSize.Medium => "md", BitSize.Large => "lg", _ => "md" }}"; var linkFormatClass = $"bit-pvt-{linkFormat.ToString().ToLower()}"; - var linkSizeClass = $"bit-pvt-{linkSize.ToString().ToLower()}"; var overflowBehaviorClass = $"bit-pvt-{overflowBehavior.ToString().ToLower()}"; var bitPivot = component.Find(".bit-pvt"); diff --git a/src/BlazorUI/Bit.BlazorUI.Tests/Message/BitMessageTests.cs b/src/BlazorUI/Bit.BlazorUI.Tests/Components/Notifications/Message/BitMessageTests.cs similarity index 62% rename from src/BlazorUI/Bit.BlazorUI.Tests/Message/BitMessageTests.cs rename to src/BlazorUI/Bit.BlazorUI.Tests/Components/Notifications/Message/BitMessageTests.cs index df1f4d99bc..e6e005b762 100644 --- a/src/BlazorUI/Bit.BlazorUI.Tests/Message/BitMessageTests.cs +++ b/src/BlazorUI/Bit.BlazorUI.Tests/Components/Notifications/Message/BitMessageTests.cs @@ -1,49 +1,49 @@ using System.Collections.Generic; -using Bunit; using Microsoft.VisualStudio.TestTools.UnitTesting; +using Bunit; -namespace Bit.BlazorUI.Tests.Message; +namespace Bit.BlazorUI.Tests.Components.Notifications.Message; [TestClass] public class BitMessageTests : BunitTestContext { [DataTestMethod, - DataRow(BitSeverity.Info), - DataRow(BitSeverity.Error), - DataRow(BitSeverity.SevereWarning), - DataRow(BitSeverity.Success), - DataRow(BitSeverity.Warning) + DataRow(BitColor.Info), + DataRow(BitColor.Error), + DataRow(BitColor.SevereWarning), + DataRow(BitColor.Success), + DataRow(BitColor.Warning) ] - public void BitMessageShouldTakeCorrectType(BitSeverity type) + public void BitMessageShouldTakeCorrectType(BitColor type) { var component = RenderComponent(parameters => { - parameters.Add(p => p.Severity, type); + parameters.Add(p => p.Color, type); }); var bitMessage = component.Find(".bit-msg"); var typeClass = type switch { - BitSeverity.Info => "bit-msg-info", - BitSeverity.Success => "bit-msg-success", - BitSeverity.Warning => "bit-msg-warning", - BitSeverity.SevereWarning => "bit-msg-severe-warning", - BitSeverity.Error => "bit-msg-error", - _ => "bit-msg-info" + BitColor.Info => "bit-msg-inf", + BitColor.Success => "bit-msg-suc", + BitColor.Warning => "bit-msg-wrn", + BitColor.SevereWarning => "bit-msg-swr", + BitColor.Error => "bit-msg-err", + _ => "bit-msg-inf" }; Assert.IsTrue(bitMessage.ClassList.Contains(typeClass)); var icon = component.Find(".bit-msg-ict > i"); - Dictionary iconMap = new() + Dictionary iconMap = new() { - [BitSeverity.Info] = "Info", - [BitSeverity.Warning] = "Info", - [BitSeverity.Error] = "ErrorBadge", - [BitSeverity.SevereWarning] = "Warning", - [BitSeverity.Success] = "Completed" + [BitColor.Info] = "Info", + [BitColor.Warning] = "Info", + [BitColor.Error] = "ErrorBadge", + [BitColor.SevereWarning] = "Warning", + [BitColor.Success] = "Completed" }; Assert.IsTrue(icon.ClassList.Contains($"bit-icon--{iconMap[type]}")); @@ -67,7 +67,7 @@ public void BitMessageShouldRespectCustomIcon(string iconName) [DataTestMethod] public void BitMessageDismissButtonShouldWorkCorrect() { - int currentCount = 0; + var currentCount = 0; var component = RenderComponent(parameters => { parameters.Add(p => p.OnDismiss, () => currentCount++); @@ -112,24 +112,24 @@ public void BitMessageShouldRespectAction(string actions) } [DataTestMethod, - DataRow("alert", BitSeverity.Info), - DataRow("alert", BitSeverity.Success), - DataRow("alert", BitSeverity.Warning), - DataRow("alert", BitSeverity.SevereWarning), - DataRow("alert", BitSeverity.Error), - - DataRow(null, BitSeverity.Info), - DataRow(null, BitSeverity.Success), - DataRow(null, BitSeverity.Warning), - DataRow(null, BitSeverity.SevereWarning), - DataRow(null, BitSeverity.Error), + DataRow("alert", BitColor.Info), + DataRow("alert", BitColor.Success), + DataRow("alert", BitColor.Warning), + DataRow("alert", BitColor.SevereWarning), + DataRow("alert", BitColor.Error), + + DataRow(null, BitColor.Info), + DataRow(null, BitColor.Success), + DataRow(null, BitColor.Warning), + DataRow(null, BitColor.SevereWarning), + DataRow(null, BitColor.Error), ] - public void BitMessageRoleTest(string role, BitSeverity type) + public void BitMessageRoleTest(string role, BitColor type) { var component = RenderComponent(parameter => { parameter.Add(p => p.Role, role); - parameter.Add(p => p.Severity, type); + parameter.Add(p => p.Color, type); }); var textEl = component.Find(".bit-msg-cnc"); @@ -138,10 +138,10 @@ public void BitMessageRoleTest(string role, BitSeverity type) Assert.AreEqual(expectedRole, textEl.GetAttribute("role")); } - private static string GetRole(BitSeverity type) + private static string GetRole(BitColor type) => type switch { - BitSeverity.Error or BitSeverity.SevereWarning or BitSeverity.Warning => "alert", + BitColor.Error or BitColor.SevereWarning or BitColor.Warning => "alert", _ => "status", }; } diff --git a/src/BlazorUI/Bit.BlazorUI.Tests/Persona/BitPersonaTests.cs b/src/BlazorUI/Bit.BlazorUI.Tests/Components/Notifications/Persona/BitPersonaTests.cs similarity index 97% rename from src/BlazorUI/Bit.BlazorUI.Tests/Persona/BitPersonaTests.cs rename to src/BlazorUI/Bit.BlazorUI.Tests/Components/Notifications/Persona/BitPersonaTests.cs index 3d3a02c9b5..ec333f26be 100644 --- a/src/BlazorUI/Bit.BlazorUI.Tests/Persona/BitPersonaTests.cs +++ b/src/BlazorUI/Bit.BlazorUI.Tests/Components/Notifications/Persona/BitPersonaTests.cs @@ -1,8 +1,7 @@ -using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; using Bunit; -using Microsoft.VisualStudio.TestTools.UnitTesting; -namespace Bit.BlazorUI.Tests.Persona; +namespace Bit.BlazorUI.Tests.Components.Notifications.Persona; [TestClass] public class BitPersonaTests : BunitTestContext diff --git a/src/BlazorUI/Bit.BlazorUI.Tests/SnackBar/BitSnackBarTests.cs b/src/BlazorUI/Bit.BlazorUI.Tests/Components/Notifications/SnackBar/BitSnackBarTests.cs similarity index 96% rename from src/BlazorUI/Bit.BlazorUI.Tests/SnackBar/BitSnackBarTests.cs rename to src/BlazorUI/Bit.BlazorUI.Tests/Components/Notifications/SnackBar/BitSnackBarTests.cs index fbce056d5e..5d8c866ce5 100644 --- a/src/BlazorUI/Bit.BlazorUI.Tests/SnackBar/BitSnackBarTests.cs +++ b/src/BlazorUI/Bit.BlazorUI.Tests/Components/Notifications/SnackBar/BitSnackBarTests.cs @@ -1,11 +1,11 @@ -using System; +using System; using System.Threading.Tasks; -using Bunit; -using Bunit.Extensions; using Microsoft.AspNetCore.Components; using Microsoft.VisualStudio.TestTools.UnitTesting; +using Bunit; +using Bunit.Extensions; -namespace Bit.BlazorUI.Tests.SnackBar; +namespace Bit.BlazorUI.Tests.Components.Notifications.SnackBar; [TestClass] public class BitSnackBarTests : BunitTestContext @@ -124,7 +124,7 @@ public async Task BitSnackBarTypeTest(string title, BitSnackBarType? type) BitSnackBarType.Success => $"bit-snb-success", BitSnackBarType.Error => $"bit-snb-error", BitSnackBarType.SevereWarning => $"bit-snb-severe-warning", - _ => String.Empty + _ => string.Empty }; if (typeClass.IsNullOrEmpty()) @@ -185,7 +185,7 @@ public async Task BitSnackBarDismissIconNameTest(string title, string iconName) [TestMethod] public async Task BitSnackBarTitleTemplateTest(string title) { - RenderFragment titleTemplate = (string text) => (builder) => + RenderFragment titleTemplate = (text) => (builder) => { builder.AddMarkupContent(0, $"{text}"); }; @@ -209,7 +209,7 @@ public async Task BitSnackBarTitleTemplateTest(string title) [TestMethod] public async Task BitSnackBarBodyTemplateTest(string title, string body) { - RenderFragment bodyTemplate = (string text) => (builder) => + RenderFragment bodyTemplate = (text) => (builder) => { builder.AddMarkupContent(0, $"

{text}

"); }; diff --git a/src/BlazorUI/Bit.BlazorUI.Tests/ProgressBar/BitProgressBarTests.cs b/src/BlazorUI/Bit.BlazorUI.Tests/Components/Progress/ProgressBar/BitProgressTests.cs similarity index 72% rename from src/BlazorUI/Bit.BlazorUI.Tests/ProgressBar/BitProgressBarTests.cs rename to src/BlazorUI/Bit.BlazorUI.Tests/Components/Progress/ProgressBar/BitProgressTests.cs index e1d072d966..53170f5baf 100644 --- a/src/BlazorUI/Bit.BlazorUI.Tests/ProgressBar/BitProgressBarTests.cs +++ b/src/BlazorUI/Bit.BlazorUI.Tests/Components/Progress/ProgressBar/BitProgressTests.cs @@ -1,25 +1,25 @@ -using Bunit; -using Microsoft.VisualStudio.TestTools.UnitTesting; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Bunit; -namespace Bit.BlazorUI.Tests.ProgressBar; +namespace Bit.BlazorUI.Tests.Components.Progress.Progress; [TestClass] -public class BitProgressBarTests : BunitTestContext +public class BitProgressTests : BunitTestContext { [DataTestMethod, DataRow(3), DataRow(12) ] - public void BitProgressBarHeightTest(int height) + public void BitProgressThicknessTest(int thickness) { - var component = RenderComponent(parameters => + var component = RenderComponent(parameters => { - parameters.Add(p => p.Height, height); + parameters.Add(p => p.Thickness, thickness); }); var piWrapper = component.Find(".bit-prb-bcn"); var piWrapperStyle = piWrapper.GetAttribute("style"); - var expectedValue = $"height: {height}px"; + var expectedValue = $"height: {thickness}px"; Assert.IsTrue(piWrapperStyle.Contains(expectedValue)); } @@ -27,9 +27,9 @@ public void BitProgressBarHeightTest(int height) DataRow(52), DataRow(43) ] - public void BitProgressBarBarWidthShouldBeEqualPercent(double percent) + public void BitProgressWidthShouldBeEqualPercent(double percent) { - var component = RenderComponent(parameters => + var component = RenderComponent(parameters => { parameters.Add(p => p.Percent, percent); }); @@ -44,9 +44,9 @@ public void BitProgressBarBarWidthShouldBeEqualPercent(double percent) DataRow(520), DataRow(430) ] - public void BitProgressBarBarWidthCanNotBeBiggerThan100(double percent) + public void BitProgressWidthCanNotBeBiggerThan100(double percent) { - var component = RenderComponent(parameters => + var component = RenderComponent(parameters => { parameters.Add(p => p.Percent, percent); }); @@ -61,9 +61,9 @@ public void BitProgressBarBarWidthCanNotBeBiggerThan100(double percent) DataRow(-5), DataRow(-265) ] - public void BitProgressBarBarWidthCanNotBeSmallerThan0(double percent) + public void BitProgressWidthCanNotBeSmallerThan0(double percent) { - var component = RenderComponent(parameters => + var component = RenderComponent(parameters => { parameters.Add(p => p.Percent, percent); }); @@ -74,14 +74,14 @@ public void BitProgressBarBarWidthCanNotBeSmallerThan0(double percent) Assert.IsTrue(piBarStyle.Contains(expectedValue)); } - + [DataTestMethod, DataRow(true), DataRow(false) ] - public void BitProgressBarIndeterminateClassTest(bool indeterminate) + public void BitProgressIndeterminateClassTest(bool indeterminate) { - var component = RenderComponent(parameters => + var component = RenderComponent(parameters => { parameters.Add(p => p.Indeterminate, indeterminate); }); @@ -94,9 +94,9 @@ public void BitProgressBarIndeterminateClassTest(bool indeterminate) DataRow("Label"), DataRow(null), ] - public void BitProgressBarLabelTest(string label) + public void BitProgressLabelTest(string label) { - var component = RenderComponent(parameters => + var component = RenderComponent(parameters => { parameters.Add(p => p.Label, label); }); @@ -119,9 +119,9 @@ public void BitProgressBarLabelTest(string label) DataRow("Description"), DataRow(null), ] - public void BitProgressBarDescriptionTest(string description) + public void BitProgressDescriptionTest(string description) { - var component = RenderComponent(parameters => + var component = RenderComponent(parameters => { parameters.Add(p => p.Description, description); }); @@ -144,9 +144,9 @@ public void BitProgressBarDescriptionTest(string description) DataRow("Aria Value Text"), DataRow(null), ] - public void BitProgressBarAriaValueTextTest(string txt) + public void BitProgressAriaValueTextTest(string txt) { - var component = RenderComponent(parameters => + var component = RenderComponent(parameters => { parameters.Add(p => p.AriaValueText, txt); }); @@ -165,9 +165,9 @@ public void BitProgressBarAriaValueTextTest(string txt) [DataTestMethod, DataRow(true), DataRow(false)] - public void BitProgressBarShowPercentNumberTest(bool showPercentNumber) + public void BitProgressShowPercentNumberTest(bool showPercentNumber) { - var component = RenderComponent(parameters => + var component = RenderComponent(parameters => { parameters.Add(p => p.ShowPercentNumber, showPercentNumber); }); @@ -187,9 +187,9 @@ public void BitProgressBarShowPercentNumberTest(bool showPercentNumber) [DataTestMethod, DataRow("

this is a custom label

") ] - public void BitProgressBarLabelTemplateTest(string labelTemplate) + public void BitProgressLabelTemplateTest(string labelTemplate) { - var component = RenderComponent(parameters => + var component = RenderComponent(parameters => { parameters.Add(p => p.LabelTemplate, labelTemplate); }); @@ -201,9 +201,9 @@ public void BitProgressBarLabelTemplateTest(string labelTemplate) [DataTestMethod, DataRow("

this is a custom description

"), ] - public void BitProgressBarDescriptionTemplateTest(string descriptionTemplate) + public void BitProgressDescriptionTemplateTest(string descriptionTemplate) { - var component = RenderComponent(parameters => + var component = RenderComponent(parameters => { parameters.Add(p => p.DescriptionTemplate, descriptionTemplate); }); diff --git a/src/BlazorUI/Bit.BlazorUI.Tests/Accordion/BitAccordionTests.cs b/src/BlazorUI/Bit.BlazorUI.Tests/Components/Surfaces/Accordion/BitAccordionTests.cs similarity index 89% rename from src/BlazorUI/Bit.BlazorUI.Tests/Accordion/BitAccordionTests.cs rename to src/BlazorUI/Bit.BlazorUI.Tests/Components/Surfaces/Accordion/BitAccordionTests.cs index c3dee02275..24ee9f78b4 100644 --- a/src/BlazorUI/Bit.BlazorUI.Tests/Accordion/BitAccordionTests.cs +++ b/src/BlazorUI/Bit.BlazorUI.Tests/Components/Surfaces/Accordion/BitAccordionTests.cs @@ -1,7 +1,7 @@ -using Bunit; -using Microsoft.VisualStudio.TestTools.UnitTesting; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Bunit; -namespace Bit.BlazorUI.Tests.Accordion; +namespace Bit.BlazorUI.Tests.Components.Surfaces.Accordion; [TestClass] public class BitAccordionTests : BunitTestContext @@ -32,9 +32,9 @@ public void BitAccordionIsEnabledTest(bool isEnabled) [DataTestMethod] public void BitAccordionShouldBeSetTitleAndDescriptionAndText() { - string title = "title-value"; - string description = "description-value"; - string text = "text-value"; + var title = "title-value"; + var description = "description-value"; + var text = "text-value"; var com = RenderComponent(parameters => { @@ -93,8 +93,8 @@ public void BitAccordionShouldBeSetDefaultIsExpanded(bool defaultIsExpanded) ] public void BitAccordionShouldBeOnClickAndOnChange(bool isClick) { - bool isClicked = !isClick; - bool isChanged = !isClick; + var isClicked = !isClick; + var isChanged = !isClick; var com = RenderComponent(parameters => { @@ -115,8 +115,8 @@ public void BitAccordionShouldBeOnClickAndOnChange(bool isClick) ] public void BitAccordionShouldBeSetHeaderTemplate(bool defaultIsExpanded) { - string expandedHeaderHtml = "

Expanded

"; - string collapsedHeaderHtml = "

Collapsed

"; + var expandedHeaderHtml = "

Expanded

"; + var collapsedHeaderHtml = "

Collapsed

"; var com = RenderComponent(parameters => { @@ -133,7 +133,7 @@ public void BitAccordionShouldBeSetHeaderTemplate(bool defaultIsExpanded) [DataTestMethod] public void BitAccordionShouldBeSetContentTemplate() { - string contentHtml = "

ContentTemplate

"; + var contentHtml = "

ContentTemplate

"; var com = RenderComponent(parameters => { diff --git a/src/BlazorUI/Bit.BlazorUI.Tests/Modal/BitModalTests.cs b/src/BlazorUI/Bit.BlazorUI.Tests/Components/Surfaces/Modal/BitModalTests.cs similarity index 97% rename from src/BlazorUI/Bit.BlazorUI.Tests/Modal/BitModalTests.cs rename to src/BlazorUI/Bit.BlazorUI.Tests/Components/Surfaces/Modal/BitModalTests.cs index 08599d0107..3841ea0d2c 100644 --- a/src/BlazorUI/Bit.BlazorUI.Tests/Modal/BitModalTests.cs +++ b/src/BlazorUI/Bit.BlazorUI.Tests/Components/Surfaces/Modal/BitModalTests.cs @@ -1,7 +1,7 @@ -using Bunit; -using Microsoft.VisualStudio.TestTools.UnitTesting; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Bunit; -namespace Bit.BlazorUI.Tests.Modal; +namespace Bit.BlazorUI.Tests.Components.Surfaces.Modal; [TestClass] public class BitModalTests : BunitTestContext @@ -176,8 +176,8 @@ public void BitModalCloseWhenClickOutOfModalTest() [TestMethod] public void BitModalOnDismissShouldWorkCorrect() { - bool isOpen = true; - int currentCount = 0; + var isOpen = true; + var currentCount = 0; var com = RenderComponent(parameters => { parameters.Bind(p => p.IsOpen, isOpen, newValue => isOpen = newValue); diff --git a/src/BlazorUI/Bit.BlazorUI.Tests/Panel/BitPanelTests.cs b/src/BlazorUI/Bit.BlazorUI.Tests/Components/Surfaces/Panel/BitPanelTests.cs similarity index 97% rename from src/BlazorUI/Bit.BlazorUI.Tests/Panel/BitPanelTests.cs rename to src/BlazorUI/Bit.BlazorUI.Tests/Components/Surfaces/Panel/BitPanelTests.cs index 390674d771..c2ef4de625 100644 --- a/src/BlazorUI/Bit.BlazorUI.Tests/Panel/BitPanelTests.cs +++ b/src/BlazorUI/Bit.BlazorUI.Tests/Components/Surfaces/Panel/BitPanelTests.cs @@ -1,7 +1,7 @@ -using Bunit; -using Microsoft.VisualStudio.TestTools.UnitTesting; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Bunit; -namespace Bit.BlazorUI.Tests.Panel; +namespace Bit.BlazorUI.Tests.Components.Surfaces.Panel; [TestClass] public class BitPanelTests : BunitTestContext @@ -191,8 +191,8 @@ public void BitPanelCloseWhenClickOutOfPanelTest() [TestMethod] public void BitPanelOnDismissShouldWorkCorrect() { - bool isOpen = true; - int currentCount = 0; + var isOpen = true; + var currentCount = 0; var com = RenderComponent(parameters => { parameters.Bind(p => p.IsOpen, isOpen, newValue => isOpen = newValue); diff --git a/src/BlazorUI/Bit.BlazorUI.Tests/Components/Utilities/Element/BitElementHtmlAttributesTest.razor b/src/BlazorUI/Bit.BlazorUI.Tests/Components/Utilities/Element/BitElementHtmlAttributesTest.razor new file mode 100644 index 0000000000..e6d98c529e --- /dev/null +++ b/src/BlazorUI/Bit.BlazorUI.Tests/Components/Utilities/Element/BitElementHtmlAttributesTest.razor @@ -0,0 +1 @@ +I'm a element \ No newline at end of file diff --git a/src/BlazorUI/Bit.BlazorUI.Tests/Components/Utilities/Element/BitElementTests.cs b/src/BlazorUI/Bit.BlazorUI.Tests/Components/Utilities/Element/BitElementTests.cs new file mode 100644 index 0000000000..921641485a --- /dev/null +++ b/src/BlazorUI/Bit.BlazorUI.Tests/Components/Utilities/Element/BitElementTests.cs @@ -0,0 +1,274 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Bunit; + +namespace Bit.BlazorUI.Tests.Components.Utilities.Element; + +[TestClass] +public class BitElementTests : BunitTestContext +{ + [DataTestMethod] + public void BitElementShouldRenderExpectedElement() + { + var component = RenderComponent(); + + component.MarkupMatches(@"
"); + } + + [DataTestMethod, + DataRow("div"), + DataRow("button"), + DataRow("input"), + DataRow("a"), + DataRow(null) + ] + public void BitElementShouldRespectElement(string element) + { + var component = RenderComponent(parameters => + { + parameters.Add(p => p.Element, element); + }); + + var el = element ?? "div"; + + component.MarkupMatches(@$"<{el} class=""bit-elm"" id:ignore>"); + } + + [DataTestMethod, + DataRow(true), + DataRow(false) + ] + public void BitElementShouldRespectIsEnabled(bool isEnabled) + { + var component = RenderComponent(parameters => + { + parameters.Add(p => p.IsEnabled, isEnabled); + }); + + var cssClass = isEnabled ? null : " bit-dis"; + + component.MarkupMatches(@$"
"); + } + + [DataTestMethod] + public void BitElementShouldRespectIsEnabledChangingAfterRender() + { + var component = RenderComponent(); + + component.MarkupMatches(@"
"); + + component.SetParametersAndRender(parameters => + { + parameters.Add(p => p.IsEnabled, false); + }); + + component.MarkupMatches(@"
"); + } + + [DataTestMethod, + DataRow("font-size: 14px; color: red;"), + DataRow("padding: 1rem;"), + DataRow(null) + ] + public void BitElementShouldRespectStyle(string style) + { + var component = RenderComponent(parameters => + { + parameters.Add(p => p.Style, style); + }); + + if (style.HasValue()) + { + component.MarkupMatches(@$"
"); + } + else + { + component.MarkupMatches(@"
"); + } + } + + [DataTestMethod] + public void BitElementShouldRespectStyleChangingAfterRender() + { + var component = RenderComponent(); + + component.MarkupMatches(@"
"); + + component.SetParametersAndRender(parameters => + { + parameters.Add(p => p.Style, "padding: 1rem;"); + }); + + component.MarkupMatches(@"
"); + } + + [DataTestMethod, + DataRow("test-class"), + DataRow(null) + ] + public void BitElementShouldRespectClass(string @class) + { + var component = RenderComponent(parameters => + { + parameters.Add(p => p.Class, @class); + }); + + var cssClass = @class.HasValue() ? $" {@class}" : null; + + component.MarkupMatches(@$"
"); + } + + [DataTestMethod] + public void BitElementShouldRespectClassChangingAfterRender() + { + var component = RenderComponent(); + + component.MarkupMatches(@"
"); + + component.SetParametersAndRender(parameters => + { + parameters.Add(p => p.Class, "test-class"); + }); + + component.MarkupMatches(@"
"); + } + + [DataTestMethod, + DataRow("test-id"), + DataRow(null) + ] + public void BitElementShouldRespectId(string id) + { + var component = RenderComponent(parameters => + { + parameters.Add(p => p.Id, id); + }); + + var expectedId = id.HasValue() ? id : component.Instance.UniqueId.ToString(); + + component.MarkupMatches(@$"
"); + } + + [DataTestMethod, + DataRow(BitDir.Rtl), + DataRow(BitDir.Ltr), + DataRow(BitDir.Auto), + DataRow(null) + ] + public void BitElementShouldRespectDir(BitDir? dir) + { + var component = RenderComponent(parameters => + { + parameters.Add(p => p.Dir, dir); + }); + + if (dir.HasValue) + { + var cssClass = dir is BitDir.Rtl ? " bit-rtl" : null; + component.MarkupMatches(@$"
"); + } + else + { + component.MarkupMatches(@"
"); + } + } + + [DataTestMethod] + public void BitElementShouldRespectDirChangingAfterRender() + { + var component = RenderComponent(); + + component.MarkupMatches(@"
"); + + component.SetParametersAndRender(parameters => + { + parameters.Add(p => p.Dir, BitDir.Ltr); + }); + + component.MarkupMatches(@"
"); + } + + [DataTestMethod, + DataRow(BitVisibility.Visible), + DataRow(BitVisibility.Collapsed), + DataRow(BitVisibility.Hidden) + ] + public void BitElementShouldRespectVisibility(BitVisibility visibility) + { + var component = RenderComponent(parameters => + { + parameters.Add(p => p.Visibility, visibility); + }); + + switch (visibility) + { + case BitVisibility.Visible: + component.MarkupMatches(@"
"); + break; + case BitVisibility.Hidden: + component.MarkupMatches(@"
"); + break; + case BitVisibility.Collapsed: + component.MarkupMatches(@"
"); + break; + } + } + + [DataTestMethod] + public void BitElementShouldRespectVisibilityChangingAfterRender() + { + var component = RenderComponent(); + + component.MarkupMatches(@"
"); + + component.SetParametersAndRender(parameters => + { + parameters.Add(p => p.Visibility, BitVisibility.Collapsed); + }); + + component.MarkupMatches(@"
"); + } + + [DataTestMethod, + DataRow("Bit Blazor UI"), + DataRow(null) + ] + public void BitElementShouldRespectAriaLabel(string ariaLabel) + { + var component = RenderComponent(parameters => + { + parameters.Add(p => p.AriaLabel, ariaLabel); + }); + + if (ariaLabel.HasValue()) + { + component.MarkupMatches(@$"
"); + } + else + { + component.MarkupMatches(@"
"); + } + } + + [DataTestMethod, + DataRow("Bit Blazor UI"), + DataRow("Bit Blazor UI"), + DataRow(null) + ] + public void BitElementShouldRespectChildContent(string childContent) + { + var component = RenderComponent(parameters => + { + parameters.AddChildContent(childContent); + }); + + component.MarkupMatches(@$"
{childContent}"); + } + + [DataTestMethod] + public void BitElementShouldRespectHtmlAttributes() + { + var component = RenderComponent(); + + component.MarkupMatches(@"
I'm a element
"); + } +} diff --git a/src/BlazorUI/Bit.BlazorUI.Tests/Components/Utilities/Icon/BitIconHtmlAttributesTest.razor b/src/BlazorUI/Bit.BlazorUI.Tests/Components/Utilities/Icon/BitIconHtmlAttributesTest.razor new file mode 100644 index 0000000000..034aa6be16 --- /dev/null +++ b/src/BlazorUI/Bit.BlazorUI.Tests/Components/Utilities/Icon/BitIconHtmlAttributesTest.razor @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/BlazorUI/Bit.BlazorUI.Tests/Components/Utilities/Icon/BitIconTests.cs b/src/BlazorUI/Bit.BlazorUI.Tests/Components/Utilities/Icon/BitIconTests.cs new file mode 100644 index 0000000000..00b9520c7b --- /dev/null +++ b/src/BlazorUI/Bit.BlazorUI.Tests/Components/Utilities/Icon/BitIconTests.cs @@ -0,0 +1,363 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Bunit; + +namespace Bit.BlazorUI.Tests.Components.Utilities.Icon; + +[TestClass] +public class BitIconTests : BunitTestContext +{ + private const string CLASS = "bit-ico bit-ico-pri bit-ico-md"; + + [DataTestMethod] + public void BitIconShouldRenderExpectedElement() + { + var component = RenderComponent(); + + component.MarkupMatches(@$""); + } + + [DataTestMethod, + DataRow(true), + DataRow(false) + ] + public void BitIconShouldRespectIsEnabled(bool isEnabled) + { + var component = RenderComponent(parameters => + { + parameters.Add(p => p.IsEnabled, isEnabled); + }); + + var cssClass = isEnabled ? null : " bit-dis"; + + component.MarkupMatches(@$""); + } + + [DataTestMethod] + public void BitIconShouldRespectIsEnabledChangingAfterRender() + { + var component = RenderComponent(); + + component.MarkupMatches(@$""); + + component.SetParametersAndRender(parameters => + { + parameters.Add(p => p.IsEnabled, false); + }); + + component.MarkupMatches(@$""); + } + + [DataTestMethod, + DataRow("VisualStudioForWindows"), + DataRow("AzureIcon"), + DataRow(""), + DataRow(null) + ] + public void BitIconShouldRespectIconName(string iconName) + { + var component = RenderComponent(parameters => + { + parameters.Add(p => p.IconName, iconName); + }); + + var icoClass = iconName.HasValue() ? $" bit-icon bit-icon--{iconName}" : null; + + component.MarkupMatches(@$""); + } + + [DataTestMethod] + public void BitIconShouldRespectIconNameChangingAfterRender() + { + var component = RenderComponent(); + + component.MarkupMatches(@$""); + + component.SetParametersAndRender(parameters => + { + parameters.Add(p => p.IconName, "AzureIcon"); + }); + + component.MarkupMatches(@$""); + } + + [DataTestMethod, + DataRow("font-size: 14px; color: red;"), + DataRow("padding: 1rem;"), + DataRow(null) + ] + public void BitIconShouldRespectStyle(string style) + { + var component = RenderComponent(parameters => + { + parameters.Add(p => p.Style, style); + }); + + if (style.HasValue()) + { + component.MarkupMatches(@$""); + } + else + { + component.MarkupMatches(@$""); + } + } + + [DataTestMethod] + public void BitIconShouldRespectStyleChangingAfterRender() + { + var component = RenderComponent(); + + component.MarkupMatches(@$""); + + component.SetParametersAndRender(parameters => + { + parameters.Add(p => p.Style, "padding: 1rem;"); + }); + + component.MarkupMatches(@$""); + } + + [DataTestMethod, + DataRow("test-class"), + DataRow(null) + ] + public void BitIconShouldRespectClass(string @class) + { + var component = RenderComponent(parameters => + { + parameters.Add(p => p.Class, @class); + }); + + var cssClass = @class.HasValue() ? $" {@class}" : null; + + component.MarkupMatches(@$""); + } + + [DataTestMethod] + public void BitIconShouldRespectClassChangingAfterRender() + { + var component = RenderComponent(); + + component.MarkupMatches(@$""); + + component.SetParametersAndRender(parameters => + { + parameters.Add(p => p.Class, "test-class"); + }); + + component.MarkupMatches(@$""); + } + + [DataTestMethod, + DataRow("test-id"), + DataRow(null) + ] + public void BitIconShouldRespectId(string id) + { + var component = RenderComponent(parameters => + { + parameters.Add(p => p.Id, id); + }); + + var expectedId = id.HasValue() ? id : component.Instance.UniqueId.ToString(); + + component.MarkupMatches(@$""); + } + + [DataTestMethod, + DataRow(BitDir.Rtl), + DataRow(BitDir.Ltr), + DataRow(BitDir.Auto), + DataRow(null) + ] + public void BitIconShouldRespectDir(BitDir? dir) + { + var component = RenderComponent(parameters => + { + parameters.Add(p => p.Dir, dir); + }); + + if (dir.HasValue) + { + var cssClass = dir is BitDir.Rtl ? " bit-rtl" : null; + component.MarkupMatches(@$""); + } + else + { + component.MarkupMatches(@$""); + } + } + + [DataTestMethod] + public void BitIconShouldRespectDirChangingAfterRender() + { + var component = RenderComponent(); + + component.MarkupMatches(@$""); + + component.SetParametersAndRender(parameters => + { + parameters.Add(p => p.Dir, BitDir.Ltr); + }); + + component.MarkupMatches(@$""); + } + + [DataTestMethod, + DataRow(BitVisibility.Visible), + DataRow(BitVisibility.Collapsed), + DataRow(BitVisibility.Hidden) + ] + public void BitIconShouldRespectVisibility(BitVisibility visibility) + { + var component = RenderComponent(parameters => + { + parameters.Add(p => p.Visibility, visibility); + }); + + switch (visibility) + { + case BitVisibility.Visible: + component.MarkupMatches(@$""); + break; + case BitVisibility.Hidden: + component.MarkupMatches(@$""); + break; + case BitVisibility.Collapsed: + component.MarkupMatches(@$""); + break; + } + } + + [DataTestMethod] + public void BitIconShouldRespectVisibilityChangingAfterRender() + { + var component = RenderComponent(); + + component.MarkupMatches(@$""); + + component.SetParametersAndRender(parameters => + { + parameters.Add(p => p.Visibility, BitVisibility.Collapsed); + }); + + component.MarkupMatches(@$""); + } + + [DataTestMethod, + DataRow("Bit Blazor UI"), + DataRow(null) + ] + public void BitIconShouldRespectAriaLabel(string ariaLabel) + { + var component = RenderComponent(parameters => + { + parameters.Add(p => p.AriaLabel, ariaLabel); + }); + + if (ariaLabel.HasValue()) + { + component.MarkupMatches(@$""); + } + else + { + component.MarkupMatches(@$""); + } + } + + [DataTestMethod, + DataRow(BitSize.Small), + DataRow(BitSize.Medium), + DataRow(BitSize.Large), + DataRow(null) + ] + public void BitIconShouldRespectSize(BitSize? size) + { + var component = RenderComponent(parameters => + { + parameters.Add(p => p.Size, size); + }); + + var sizeClass = size switch + { + BitSize.Small => " bit-ico-sm", + BitSize.Medium => " bit-ico-md", + BitSize.Large => " bit-ico-lg", + _ => " bit-ico-md" + }; + + component.MarkupMatches(@$""); + } + + [DataTestMethod] + public void BitIconShouldRespectSizeChangingAfterRender() + { + var component = RenderComponent(); + + component.MarkupMatches(@$""); + + component.SetParametersAndRender(parameters => + { + parameters.Add(p => p.Size, BitSize.Large); + }); + + component.MarkupMatches(@""); + } + + [DataTestMethod, + DataRow(BitColor.Primary), + DataRow(BitColor.Secondary), + DataRow(BitColor.Tertiary), + DataRow(BitColor.Info), + DataRow(BitColor.Success), + DataRow(BitColor.Warning), + DataRow(BitColor.SevereWarning), + DataRow(BitColor.Error), + DataRow(null) + ] + public void BitIconShouldRespectColor(BitColor? color) + { + var component = RenderComponent(parameters => + { + parameters.Add(p => p.Color, color); + }); + + var colorClass = color switch + { + BitColor.Primary => " bit-ico-pri", + BitColor.Secondary => " bit-ico-sec", + BitColor.Tertiary => " bit-ico-ter", + BitColor.Info => " bit-ico-inf", + BitColor.Success => " bit-ico-suc", + BitColor.Warning => " bit-ico-wrn", + BitColor.SevereWarning => " bit-ico-swr", + BitColor.Error => " bit-ico-err", + _ => " bit-ico-pri" + }; + + component.MarkupMatches(@$""); + } + + [DataTestMethod] + public void BitIconShouldRespectColorChangingAfterRender() + { + var component = RenderComponent(); + + component.MarkupMatches(@$""); + + component.SetParametersAndRender(parameters => + { + parameters.Add(p => p.Color, BitColor.Error); + }); + + component.MarkupMatches(@""); + } + + [DataTestMethod] + public void BitIconShouldRespectHtmlAttributes() + { + var component = RenderComponent(); + + component.MarkupMatches(@$""); + } +} diff --git a/src/BlazorUI/Bit.BlazorUI.Tests/Components/Utilities/Labels/BitLabelHtmlAttributesTest.razor b/src/BlazorUI/Bit.BlazorUI.Tests/Components/Utilities/Labels/BitLabelHtmlAttributesTest.razor new file mode 100644 index 0000000000..a57d12eaf0 --- /dev/null +++ b/src/BlazorUI/Bit.BlazorUI.Tests/Components/Utilities/Labels/BitLabelHtmlAttributesTest.razor @@ -0,0 +1 @@ +I'm a label \ No newline at end of file diff --git a/src/BlazorUI/Bit.BlazorUI.Tests/Components/Utilities/Labels/BitLabelTests.cs b/src/BlazorUI/Bit.BlazorUI.Tests/Components/Utilities/Labels/BitLabelTests.cs new file mode 100644 index 0000000000..61665dab29 --- /dev/null +++ b/src/BlazorUI/Bit.BlazorUI.Tests/Components/Utilities/Labels/BitLabelTests.cs @@ -0,0 +1,307 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Bunit; + +namespace Bit.BlazorUI.Tests.Components.Utilities.Labels; + +[TestClass] +public class BitLabelTests : BunitTestContext +{ + [DataTestMethod] + public void BitLabelShouldRenderExpectedElement() + { + var component = RenderComponent(); + + component.MarkupMatches(@""); + } + + [DataTestMethod, + DataRow(true), + DataRow(false) + ] + public void BitLabelShouldRespectIsEnabled(bool isEnabled) + { + var component = RenderComponent(parameters => + { + parameters.Add(p => p.IsEnabled, isEnabled); + }); + + var cssClass = isEnabled ? "bit-lbl" : "bit-lbl bit-dis"; + + component.MarkupMatches(@$""); + } + + [DataTestMethod] + public void BitLabelShouldRespectIsEnabledChangingAfterRender() + { + var component = RenderComponent(); + + component.MarkupMatches(@""); + + component.SetParametersAndRender(parameters => + { + parameters.Add(p => p.IsEnabled, false); + }); + + component.MarkupMatches(@""); + } + + [DataTestMethod, + DataRow(true), + DataRow(false) + ] + public void BitLabelShouldRespectRequired(bool required) + { + var component = RenderComponent(parameters => + { + parameters.Add(p => p.Required, required); + }); + + var cssClass = required ? "bit-lbl bit-lbl-req" : "bit-lbl"; + + component.MarkupMatches(@$""); + } + + [DataTestMethod] + public void BitLabelShouldRespectRequiredChangingAfterRender() + { + var component = RenderComponent(); + + component.MarkupMatches(@""); + + component.SetParametersAndRender(parameters => + { + parameters.Add(p => p.Required, true); + }); + + component.MarkupMatches(@""); + } + + [DataTestMethod, + DataRow("font-size: 14px; color: red;"), + DataRow("padding: 1rem;"), + DataRow(null) + ] + public void BitLabelShouldRespectStyle(string style) + { + var component = RenderComponent(parameters => + { + parameters.Add(p => p.Style, style); + }); + + if (style.HasValue()) + { + component.MarkupMatches(@$""); + } + else + { + component.MarkupMatches(@""); + } + } + + [DataTestMethod] + public void BitLabelShouldRespectStyleChangingAfterRender() + { + var component = RenderComponent(); + + component.MarkupMatches(@""); + + component.SetParametersAndRender(parameters => + { + parameters.Add(p => p.Style, "padding: 1rem;"); + }); + + component.MarkupMatches(@""); + } + + [DataTestMethod, + DataRow("test-class"), + DataRow(null) + ] + public void BitLabelShouldRespectClass(string @class) + { + var component = RenderComponent(parameters => + { + parameters.Add(p => p.Class, @class); + }); + + var cssClass = @class.HasValue() ? $"bit-lbl {@class}" : "bit-lbl"; + + component.MarkupMatches(@$""); + } + + [DataTestMethod] + public void BitLabelShouldRespectClassChangingAfterRender() + { + var component = RenderComponent(); + + component.MarkupMatches(@""); + + component.SetParametersAndRender(parameters => + { + parameters.Add(p => p.Class, "test-class"); + }); + + component.MarkupMatches(@""); + } + + [DataTestMethod, + DataRow("test-id"), + DataRow(null) + ] + public void BitLabelShouldRespectId(string id) + { + var component = RenderComponent(parameters => + { + parameters.Add(p => p.Id, id); + }); + + var expectedId = id.HasValue() ? id : component.Instance.UniqueId; + + component.MarkupMatches(@$""); + } + + [DataTestMethod, + DataRow("test-for"), + DataRow(null) + ] + public void BitLabelShouldRespectFor(string @for) + { + var component = RenderComponent(parameters => + { + parameters.Add(p => p.For, @for); + }); + + if (@for.HasValue()) + { + component.MarkupMatches(@$""); + } + else + { + component.MarkupMatches(@""); + } + } + + [DataTestMethod, + DataRow(BitDir.Rtl), + DataRow(BitDir.Ltr), + DataRow(BitDir.Auto), + DataRow(null) + ] + public void BitLabelShouldRespectDir(BitDir? dir) + { + var component = RenderComponent(parameters => + { + parameters.Add(p => p.Dir, dir); + }); + + if (dir.HasValue) + { + var cssClass = dir is BitDir.Rtl ? "bit-lbl bit-rtl" : "bit-lbl"; + component.MarkupMatches(@$""); + } + else + { + component.MarkupMatches(@""); + } + } + + [DataTestMethod] + public void BitLabelShouldRespectDirChangingAfterRender() + { + var component = RenderComponent(); + + component.MarkupMatches(@""); + + component.SetParametersAndRender(parameters => + { + parameters.Add(p => p.Dir, BitDir.Ltr); + }); + + component.MarkupMatches(@""); + } + + [DataTestMethod, + DataRow(BitVisibility.Visible), + DataRow(BitVisibility.Collapsed), + DataRow(BitVisibility.Hidden) + ] + public void BitLabelShouldRespectVisibility(BitVisibility visibility) + { + var component = RenderComponent(parameters => + { + parameters.Add(p => p.Visibility, visibility); + }); + + switch (visibility) + { + case BitVisibility.Visible: + component.MarkupMatches(@""); + break; + case BitVisibility.Hidden: + component.MarkupMatches(@""); + break; + case BitVisibility.Collapsed: + component.MarkupMatches(@""); + break; + } + } + + [DataTestMethod] + public void BitLabelShouldRespectVisibilityChangingAfterRender() + { + var component = RenderComponent(); + + component.MarkupMatches(@""); + + component.SetParametersAndRender(parameters => + { + parameters.Add(p => p.Visibility, BitVisibility.Collapsed); + }); + + component.MarkupMatches(@""); + } + + [DataTestMethod, + DataRow("Bit Blazor UI"), + DataRow("Bit Blazor UI"), + DataRow(null) + ] + public void BitLabelShouldRespectChildContent(string childContent) + { + var component = RenderComponent(parameters => + { + parameters.AddChildContent(childContent); + }); + + component.MarkupMatches(@$""); + } + + [DataTestMethod, + DataRow("Bit Blazor UI"), + DataRow(null) + ] + public void BitLabelShouldRespectAriaLabel(string ariaLabel) + { + var component = RenderComponent(parameters => + { + parameters.Add(p => p.AriaLabel, ariaLabel); + }); + + if (ariaLabel.HasValue()) + { + component.MarkupMatches(@$""); + } + else + { + component.MarkupMatches(@""); + } + } + + [DataTestMethod] + public void BitLabelShouldRespectHtmlAttributes() + { + var component = RenderComponent(); + + component.MarkupMatches(@""); + } +} diff --git a/src/BlazorUI/Bit.BlazorUI.Tests/Components/Utilities/Link/BitLinkHtmlAttributesTest.razor b/src/BlazorUI/Bit.BlazorUI.Tests/Components/Utilities/Link/BitLinkHtmlAttributesTest.razor new file mode 100644 index 0000000000..cf0d7468c6 --- /dev/null +++ b/src/BlazorUI/Bit.BlazorUI.Tests/Components/Utilities/Link/BitLinkHtmlAttributesTest.razor @@ -0,0 +1,5 @@ +I'm a link + +@code { + [Parameter] public string? Href { get; set; } +} \ No newline at end of file diff --git a/src/BlazorUI/Bit.BlazorUI.Tests/Components/Utilities/Link/BitLinkTests.cs b/src/BlazorUI/Bit.BlazorUI.Tests/Components/Utilities/Link/BitLinkTests.cs new file mode 100644 index 0000000000..10f18e65c6 --- /dev/null +++ b/src/BlazorUI/Bit.BlazorUI.Tests/Components/Utilities/Link/BitLinkTests.cs @@ -0,0 +1,615 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Bunit; + +namespace Bit.BlazorUI.Tests.Components.Utilities.Link; + +[TestClass] +public class BitLinkTests : BunitTestContext +{ + [DataTestMethod] + public void BitLinkShouldRenderExpectedElement() + { + var component = RenderComponent(); + + component.MarkupMatches(@""); + } + + [DataTestMethod, + DataRow("https://bitplatform.dev"), + DataRow("#go-to-section"), + DataRow(""), + DataRow(null) + ] + public void BitLinkShouldRenderHref(string href) + { + var component = RenderComponent(parameters => + { + parameters.Add(p => p.Href, href); + }); + + if (href.HasNoValue()) + { + component.MarkupMatches(@""); + + //check clickable element + component.Find(".bit-lnk").Click(); + } + else if (href.StartsWith('#')) + { + component.MarkupMatches(@""); + + //check clickable element + component.Find(".bit-lnk").Click(); + } + else + { + component.MarkupMatches(@$""); + + Assert.ThrowsException(() => component.Find(".bit-lnk").Click()); + } + } + + [DataTestMethod, + DataRow(null, "_blank"), + DataRow(null, null), + DataRow(null, ""), + DataRow("https://bitplatform.dev", "_blank"), + DataRow("https://bitplatform.dev", null), + DataRow("https://bitplatform.dev", ""), + DataRow("#go-to-section", "_blank"), + DataRow("#go-to-section", null), + DataRow("#go-to-section", "") + ] + public void BitLinkShouldRespectTarget(string href, string target) + { + var component = RenderComponent(parameters => + { + parameters.Add(p => p.Href, href); + parameters.Add(p => p.Target, target); + }); + + if (href.HasValue()) + { + if (href.StartsWith('#')) + { + component.MarkupMatches(@""); + } + else + { + if (target.HasValue()) + { + component.MarkupMatches(@$""); + } + else + { + component.MarkupMatches(@$""); + } + } + } + else + { + component.MarkupMatches(@""); + } + } + + [DataTestMethod, + DataRow(null), + DataRow("https://bitplatform.dev"), + DataRow("#go-to-section") + ] + public void BitLinkShouldRespectIsEnabled(string href) + { + var component = RenderComponent(parameters => + { + parameters.Add(p => p.Href, href); + parameters.Add(p => p.IsEnabled, false); + }); + + // This test specifically checks the disabled state of the component. + // Since the enabled state is the default state and is checked in all tests, we focus on verifying the disabled behavior here. + if (href.HasValue()) + { + component.MarkupMatches(@""); + } + else + { + component.MarkupMatches(@""); + } + } + + [DataTestMethod, + DataRow(null), + DataRow("https://bitplatform.dev"), + DataRow("#go-to-section") + ] + public void BitLinkShouldRespectIsEnabledChangingAfterRender(string href) + { + var component = RenderComponent(parameters => + { + parameters.Add(p => p.Href, href); + }); + + MatchSimpleMarkup(component, href); + + component.SetParametersAndRender(parameters => + { + parameters.Add(p => p.IsEnabled, false); + }); + + if (href.HasValue()) + { + component.MarkupMatches(@""); + } + else + { + component.MarkupMatches(@""); + } + } + + [DataTestMethod, + DataRow(null, "font-size: 14px; color: red;"), + DataRow(null, null), + DataRow("https://bitplatform.dev", "font-size: 14px; color: red;"), + DataRow("https://bitplatform.dev", null), + DataRow("#go-to-section", "font-size: 14px; color: red;"), + DataRow("#go-to-section", null) + ] + public void BitLinkShouldRespectStyle(string href, string style) + { + var component = RenderComponent(parameters => + { + parameters.Add(p => p.Href, href); + parameters.Add(p => p.Style, style); + }); + + var styleAttribute = style.HasValue() ? @$"style=""{style}""" : null; + + if (href.HasValue()) + { + component.MarkupMatches(@$""); + } + else + { + component.MarkupMatches(@$""); + } + } + + [DataTestMethod, + DataRow(null), + DataRow("https://bitplatform.dev"), + DataRow("#go-to-section"), + ] + public void BitLinkShouldRespectStyleChangingAfterRender(string href) + { + var component = RenderComponent(parameters => + { + parameters.Add(p => p.Href, href); + }); + + MatchSimpleMarkup(component, href); + + component.SetParametersAndRender(parameters => + { + parameters.Add(p => p.Style, "padding: 1rem;"); + }); + + if (href.HasValue()) + { + component.MarkupMatches(@$""); + } + else + { + component.MarkupMatches(@""); + } + } + + [DataTestMethod, + DataRow(null, "test-class"), + DataRow(null, null), + DataRow("https://bitplatform.dev", "test-class"), + DataRow("https://bitplatform.dev", null), + DataRow("#go-to-section", "test-class"), + DataRow("#go-to-section", null) + ] + public void BitLinkShouldRespectClass(string href, string @class) + { + var component = RenderComponent(parameters => + { + parameters.Add(p => p.Href, href); + parameters.Add(p => p.Class, @class); + }); + + var cssClass = @class.HasValue() ? $" {@class}" : null; + + if (href.HasValue()) + { + component.MarkupMatches(@$""); + } + else + { + component.MarkupMatches(@$""); + } + } + + [DataTestMethod, + DataRow(null), + DataRow("https://bitplatform.dev"), + DataRow("#go-to-section") + ] + public void BitLinkShouldRespectClassChangingAfterRender(string href) + { + var component = RenderComponent(parameters => + { + parameters.Add(p => p.Href, href); + }); + + MatchSimpleMarkup(component, href); + + component.SetParametersAndRender(parameters => + { + parameters.Add(p => p.Class, "test-class"); + }); + + if (href.HasValue()) + { + component.MarkupMatches(@$""); + } + else + { + component.MarkupMatches(@""); + } + } + + [DataTestMethod, + DataRow(null, "test-id"), + DataRow(null, null), + DataRow("https://bitplatform.dev", "test-id"), + DataRow("https://bitplatform.dev", null), + DataRow("#go-to-section", "test-id"), + DataRow("#go-to-section", null) + ] + public void BitLinkShouldRespectId(string href, string id) + { + var component = RenderComponent(parameters => + { + parameters.Add(p => p.Id, id); + parameters.Add(p => p.Href, href); + }); + + var expectedId = id.HasValue() ? id : component.Instance.UniqueId.ToString(); + + if (href.HasValue()) + { + component.MarkupMatches(@$""); + } + else + { + component.MarkupMatches(@$""); + } + } + + [DataTestMethod, + DataRow(null, BitDir.Rtl), + DataRow(null, BitDir.Ltr), + DataRow(null, BitDir.Auto), + DataRow(null, null), + DataRow("https://bitplatform.dev", BitDir.Rtl), + DataRow("https://bitplatform.dev", BitDir.Ltr), + DataRow("https://bitplatform.dev", BitDir.Auto), + DataRow("https://bitplatform.dev", null), + DataRow("#go-to-section", BitDir.Rtl), + DataRow("#go-to-section", BitDir.Ltr), + DataRow("#go-to-section", BitDir.Auto), + DataRow("#go-to-section", null) + ] + public void BitLinkShouldRespectDir(string href, BitDir? dir) + { + var component = RenderComponent(parameters => + { + parameters.Add(p => p.Dir, dir); + parameters.Add(p => p.Href, href); + }); + + var cssClass = dir is BitDir.Rtl ? " bit-rtl" : null; + var dirAttribute = dir.HasValue ? @$"dir=""{dir.Value.ToString().ToLower()}""" : null; + + if (href.HasValue()) + { + component.MarkupMatches(@$""); + } + else + { + component.MarkupMatches(@$""); + } + } + + [DataTestMethod, + DataRow(null), + DataRow("https://bitplatform.dev"), + DataRow("#go-to-section") + ] + public void BitLinkShouldRespectDirChangingAfterRender(string href) + { + var component = RenderComponent(parameters => + { + parameters.Add(p => p.Href, href); + }); + + MatchSimpleMarkup(component, href); + + component.SetParametersAndRender(parameters => + { + parameters.Add(p => p.Dir, BitDir.Ltr); + }); + + if (href.HasValue()) + { + component.MarkupMatches(@$""); + } + else + { + component.MarkupMatches(@""); + } + } + + [DataTestMethod, + DataRow(null, BitVisibility.Visible), + DataRow(null, BitVisibility.Collapsed), + DataRow(null, BitVisibility.Hidden), + DataRow("https://bitplatform.dev", BitVisibility.Visible), + DataRow("https://bitplatform.dev", BitVisibility.Collapsed), + DataRow("https://bitplatform.dev", BitVisibility.Hidden), + DataRow("#go-to-section", BitVisibility.Visible), + DataRow("#go-to-section", BitVisibility.Collapsed), + DataRow("#go-to-section", BitVisibility.Hidden) + ] + public void BitLinkShouldRespectVisibility(string href, BitVisibility visibility) + { + var component = RenderComponent(parameters => + { + parameters.Add(p => p.Href, href); + parameters.Add(p => p.Visibility, visibility); + }); + + var visibilityAttribute = visibility switch + { + BitVisibility.Visible => null, + BitVisibility.Hidden => @"style=""visibility: hidden;""", + BitVisibility.Collapsed => @"style=""display: none;""" + }; + + if (href.HasValue()) + { + component.MarkupMatches(@$""); + } + else + { + component.MarkupMatches(@$""); + } + } + + [DataTestMethod, + DataRow(null), + DataRow("https://bitplatform.dev"), + DataRow("#go-to-section") + ] + public void BitLinkShouldRespectVisibilityChangingAfterRender(string href) + { + var component = RenderComponent(parameters => + { + parameters.Add(p => p.Href, href); + }); + + MatchSimpleMarkup(component, href); + + component.SetParametersAndRender(parameters => + { + parameters.Add(p => p.Visibility, BitVisibility.Collapsed); + }); + + if (href.HasValue()) + { + component.MarkupMatches(@$""); + } + else + { + component.MarkupMatches(@$""); + } + } + + [DataTestMethod, + DataRow(null, "Bit Blazor UI"), + DataRow(null, "Bit Blazor UI"), + DataRow(null, null), + DataRow("https://bitplatform.dev", "Bit Blazor UI"), + DataRow("https://bitplatform.dev", "Bit Blazor UI"), + DataRow("https://bitplatform.dev", null), + DataRow("#go-to-section", "Bit Blazor UI"), + DataRow("#go-to-section", "Bit Blazor UI"), + DataRow("#go-to-section", null) + ] + public void BitLinkShouldRespectChildContent(string href, string childContent) + { + var component = RenderComponent(parameters => + { + parameters.Add(p => p.Href, href); + parameters.AddChildContent(childContent); + }); + + if (href.HasValue()) + { + component.MarkupMatches(@$"{childContent}"); + } + else + { + component.MarkupMatches(@$""); + } + } + + [DataTestMethod, + DataRow(null, "Bit Blazor UI"), + DataRow(null, null), + DataRow("https://bitplatform.dev", "Bit Blazor UI"), + DataRow("https://bitplatform.dev", null), + DataRow("#go-to-section", "Bit Blazor UI"), + DataRow("#go-to-section", null) + ] + public void BitLinkShouldRespectAriaLabel(string href, string ariaLabel) + { + var component = RenderComponent(parameters => + { + parameters.Add(p => p.Href, href); + parameters.Add(p => p.AriaLabel, ariaLabel); + }); + + var ariaLabelAttribute = ariaLabel.HasValue() ? @$"aria-label=""{ariaLabel}""" : null; + + if (href.HasValue()) + { + component.MarkupMatches(@$""); + } + else + { + component.MarkupMatches(@$""); + } + } + + [DataTestMethod, + DataRow(null, true), + DataRow(null, false), + DataRow("https://bitplatform.dev", true), + DataRow("https://bitplatform.dev", false), + DataRow("#go-to-section", true), + DataRow("#go-to-section", false) + ] + public void BitLinkShouldRespectUnderlined(string href, bool underlined) + { + var component = RenderComponent(parameters => + { + parameters.Add(p => p.Href, href); + parameters.Add(p => p.Underlined, underlined); + }); + + var cssClass = underlined ? " bit-lnk-und" : null; + + if (href.HasValue()) + { + component.MarkupMatches(@$""); + } + else + { + component.MarkupMatches(@$""); + } + } + + [DataTestMethod, + DataRow(null), + DataRow("https://bitplatform.dev"), + DataRow("#go-to-section") + ] + public void BitLinkShouldRespectUnderlinedChangingAfterRender(string href) + { + var component = RenderComponent(parameters => + { + parameters.Add(p => p.Href, href); + }); + + MatchSimpleMarkup(component, href); + + component.SetParametersAndRender(parameters => + { + parameters.Add(p => p.Underlined, true); + }); + + if (href.HasValue()) + { + component.MarkupMatches(@$""); + } + else + { + component.MarkupMatches(@""); + } + } + + [TestMethod, + DataRow(true), + DataRow(false) + ] + public void BitLinkButtonOnClickTest(bool isEnabled) + { + var currentCount = 0; + var component = RenderComponent(parameters => + { + parameters.Add(p => p.IsEnabled, isEnabled); + parameters.Add(p => p.OnClick, () => currentCount++); + }); + + var bitLinkButton = component.Find(".bit-lnk"); + + bitLinkButton.Click(); + + Assert.AreEqual(isEnabled ? 1 : 0, currentCount); + } + + [TestMethod, + DataRow(true), + DataRow(false) + ] + public void BitLinkScrollIntoViewTest(bool isEnabled) + { + var component = RenderComponent(parameters => + { + parameters.Add(p => p.IsEnabled, isEnabled); + parameters.Add(p => p.Href, "#go-to-section"); + }); + + var bitLinkButton = component.Find(".bit-lnk"); + + bitLinkButton.Click(); + + if (isEnabled) + { + Context.JSInterop.VerifyInvoke("BitBlazorUI.Utils.scrollElementIntoView"); + } + else + { + Context.JSInterop.VerifyNotInvoke("BitBlazorUI.Utils.scrollElementIntoView"); + } + } + + [DataTestMethod, + DataRow("https://bitplatform.dev"), + DataRow("#go-to-section"), + DataRow(""), + DataRow(null)] + public void BitLinkShouldRespectHtmlAttributes(string href) + { + var component = RenderComponent(parameters => + { + parameters.Add(p => p.Href, href); + }); + + if (href.HasValue()) + { + component.MarkupMatches(@$"I'm a link"); + } + else + { + component.MarkupMatches(@""); + } + } + + private void MatchSimpleMarkup(IRenderedComponent component, string href) + { + if (href.HasValue()) + { + component.MarkupMatches(@$""); + } + else + { + component.MarkupMatches(@""); + } + } + + private string GetHrefAttribute(string href) => href.StartsWith('#') ? null : @$"href=""{href}"""; +} diff --git a/src/BlazorUI/Bit.BlazorUI.Tests/Overlay/BitOverlayTests.cs b/src/BlazorUI/Bit.BlazorUI.Tests/Components/Utilities/Overlay/BitOverlayTests.cs similarity index 95% rename from src/BlazorUI/Bit.BlazorUI.Tests/Overlay/BitOverlayTests.cs rename to src/BlazorUI/Bit.BlazorUI.Tests/Components/Utilities/Overlay/BitOverlayTests.cs index dc409bf25e..442bdd9993 100644 --- a/src/BlazorUI/Bit.BlazorUI.Tests/Overlay/BitOverlayTests.cs +++ b/src/BlazorUI/Bit.BlazorUI.Tests/Components/Utilities/Overlay/BitOverlayTests.cs @@ -1,6 +1,7 @@ -using Bunit; -using Microsoft.VisualStudio.TestTools.UnitTesting; -namespace Bit.BlazorUI.Tests.Overlay; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Bunit; + +namespace Bit.BlazorUI.Tests.Components.Utilities.Overlay; [TestClass] public class BitOverlayTests : BunitTestContext diff --git a/src/BlazorUI/Bit.BlazorUI.Tests/Components/Utilities/Separator/BitSeparatorHtmlAttributesTest.razor b/src/BlazorUI/Bit.BlazorUI.Tests/Components/Utilities/Separator/BitSeparatorHtmlAttributesTest.razor new file mode 100644 index 0000000000..717eb555d6 --- /dev/null +++ b/src/BlazorUI/Bit.BlazorUI.Tests/Components/Utilities/Separator/BitSeparatorHtmlAttributesTest.razor @@ -0,0 +1 @@ +I'm a separator \ No newline at end of file diff --git a/src/BlazorUI/Bit.BlazorUI.Tests/Components/Utilities/Separator/BitSeparatorTests.cs b/src/BlazorUI/Bit.BlazorUI.Tests/Components/Utilities/Separator/BitSeparatorTests.cs new file mode 100644 index 0000000000..ea0df33f90 --- /dev/null +++ b/src/BlazorUI/Bit.BlazorUI.Tests/Components/Utilities/Separator/BitSeparatorTests.cs @@ -0,0 +1,320 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Bunit; + +namespace Bit.BlazorUI.Tests.Components.Utilities.Separator; + +[TestClass] +public class BitSeparatorTests : BunitTestContext +{ + [DataTestMethod] + public void BitSeparatorShouldRenderExpectedElement() + { + var component = RenderComponent(); + + component.MarkupMatches(@"
"); + } + + [DataTestMethod, + DataRow(true), + DataRow(false) + ] + public void BitSeparatorShouldRespectIsEnabled(bool isEnabled) + { + var component = RenderComponent(parameters => + { + parameters.Add(p => p.IsEnabled, isEnabled); + }); + + var cssClass = isEnabled ? null : " bit-dis"; + + component.MarkupMatches(@$"
"); + } + + [DataTestMethod] + public void BitSeparatorShouldRespectIsEnabledChangingAfterRender() + { + var component = RenderComponent(); + + component.MarkupMatches(@"
"); + + component.SetParametersAndRender(parameters => + { + parameters.Add(p => p.IsEnabled, false); + }); + + component.MarkupMatches(@"
"); + } + + [DataTestMethod, + DataRow("font-size: 14px; color: red;"), + DataRow("padding: 1rem;"), + DataRow(null) + ] + public void BitSeparatorShouldRespectStyle(string style) + { + var component = RenderComponent(parameters => + { + parameters.Add(p => p.Style, style); + }); + + if (style.HasValue()) + { + component.MarkupMatches(@$"
"); + } + else + { + component.MarkupMatches(@"
"); + } + } + + [DataTestMethod] + public void BitSeparatorShouldRespectStyleChangingAfterRender() + { + var component = RenderComponent(); + + component.MarkupMatches(@"
"); + + var style = "padding: 1rem;"; + component.SetParametersAndRender(parameters => + { + parameters.Add(p => p.Style, style); + }); + + component.MarkupMatches(@$"
"); + } + + [DataTestMethod, + DataRow("test-class"), + DataRow(null) + ] + public void BitSeparatorShouldRespectClass(string @class) + { + var component = RenderComponent(parameters => + { + parameters.Add(p => p.Class, @class); + }); + + var cssClass = @class.HasValue() ? $" {@class}" : null; + + component.MarkupMatches(@$"
"); + } + + [DataTestMethod] + public void BitSeparatorShouldRespectClassChangingAfterRender() + { + var component = RenderComponent(); + + component.MarkupMatches(@"
"); + + var cssClass = "test-class"; + + component.SetParametersAndRender(parameters => + { + parameters.Add(p => p.Class, cssClass); + }); + + component.MarkupMatches(@$"
"); + } + + [DataTestMethod, + DataRow("test-id"), + DataRow(null) + ] + public void BitSeparatorShouldRespectId(string id) + { + var component = RenderComponent(parameters => + { + parameters.Add(p => p.Id, id); + }); + + var expectedId = id.HasValue() ? id : component.Instance.UniqueId.ToString(); + + component.MarkupMatches(@$"
"); + } + + [DataTestMethod, + DataRow(BitDir.Rtl), + DataRow(BitDir.Ltr), + DataRow(BitDir.Auto), + DataRow(null) + ] + public void BitSeparatorShouldRespectDir(BitDir? dir) + { + var component = RenderComponent(parameters => + { + parameters.Add(p => p.Dir, dir); + }); + + if (dir.HasValue) + { + var cssClass = dir is BitDir.Rtl ? " bit-rtl" : null; + component.MarkupMatches(@$"
"); + } + else + { + component.MarkupMatches(@"
"); + } + } + + [DataTestMethod] + public void BitSeparatorShouldRespectDirChangingAfterRender() + { + var component = RenderComponent(); + + component.MarkupMatches(@"
"); + + component.SetParametersAndRender(parameters => + { + parameters.Add(p => p.Dir, BitDir.Ltr); + }); + + component.MarkupMatches(@"
"); + } + + [DataTestMethod, + DataRow(BitVisibility.Visible), + DataRow(BitVisibility.Collapsed), + DataRow(BitVisibility.Hidden) + ] + public void BitSeparatorShouldRespectVisibility(BitVisibility visibility) + { + var component = RenderComponent(parameters => + { + parameters.Add(p => p.Visibility, visibility); + }); + + switch (visibility) + { + case BitVisibility.Visible: + component.MarkupMatches(@"
"); + break; + case BitVisibility.Hidden: + component.MarkupMatches(@"
"); + break; + case BitVisibility.Collapsed: + component.MarkupMatches(@"
"); + break; + } + } + + [DataTestMethod] + public void BitSeparatorShouldRespectVisibilityChangingAfterRender() + { + var component = RenderComponent(); + + component.MarkupMatches(@"
"); + + component.SetParametersAndRender(parameters => + { + parameters.Add(p => p.Visibility, BitVisibility.Collapsed); + }); + + component.MarkupMatches(@"
"); + } + + [DataTestMethod, + DataRow("Bit Blazor UI"), + DataRow(null) + ] + public void BitSeparatorShouldRespectAriaLabel(string ariaLabel) + { + var component = RenderComponent(parameters => + { + parameters.Add(p => p.AriaLabel, ariaLabel); + }); + + if (ariaLabel.HasValue()) + { + component.MarkupMatches(@$"
"); + } + else + { + component.MarkupMatches(@"
"); + } + } + + [DataTestMethod, + DataRow("Bit Blazor UI"), + DataRow("Bit Blazor UI"), + DataRow(null) + ] + public void BitSeparatorShouldRespectChildContent(string childContent) + { + var component = RenderComponent(parameters => + { + if (childContent is not null) + { + parameters.AddChildContent(childContent); + } + }); + + if (childContent is not null) + { + component.MarkupMatches(@$"
+
+ {childContent} +
+
"); + } + else + { + component.MarkupMatches(@"
"); + } + } + + [DataTestMethod] + public void BitSeparatorShouldRespectHtmlAttributes() + { + var component = RenderComponent(); + + component.MarkupMatches(@"
+
+ I'm a separator +
+
"); + } + + [DataTestMethod, + DataRow(true), + DataRow(false) + ] + public void BitSeparatorShouldRespectVertical(bool vertical) + { + var component = RenderComponent(parameters => + { + parameters.Add(p => p.Vertical, vertical); + parameters.AddChildContent("Bit Blazor UI"); + }); + + var cssClass = vertical ? "bit-spr-vrt" : "bit-spr-hrz"; + var ariaOrientation = vertical ? "vertical" : "horizontal"; + + component.MarkupMatches(@$"
+
+ Bit Blazor UI +
+
"); + } + + [DataTestMethod, + DataRow(BitSeparatorAlignContent.Start), + DataRow(BitSeparatorAlignContent.Center), + DataRow(BitSeparatorAlignContent.End) + ] + public void BitSeparatorShouldRespectAlignContent(BitSeparatorAlignContent alignContent) + { + var component = RenderComponent(parameters => + { + parameters.Add(p => p.AlignContent, alignContent); + }); + + var cssClass = alignContent switch + { + BitSeparatorAlignContent.Start => "bit-spr-srt", + BitSeparatorAlignContent.End => "bit-spr-end", + _ => "bit-spr-ctr" + }; + + component.MarkupMatches(@$"
"); + } +} diff --git a/src/BlazorUI/Bit.BlazorUI.Tests/Components/Utilities/Stack/BitStackHtmlAttributesTest.razor b/src/BlazorUI/Bit.BlazorUI.Tests/Components/Utilities/Stack/BitStackHtmlAttributesTest.razor new file mode 100644 index 0000000000..2ea7ef1234 --- /dev/null +++ b/src/BlazorUI/Bit.BlazorUI.Tests/Components/Utilities/Stack/BitStackHtmlAttributesTest.razor @@ -0,0 +1 @@ +I'm a stack \ No newline at end of file diff --git a/src/BlazorUI/Bit.BlazorUI.Tests/Components/Utilities/Stack/BitStackTests.cs b/src/BlazorUI/Bit.BlazorUI.Tests/Components/Utilities/Stack/BitStackTests.cs new file mode 100644 index 0000000000..765d0200b0 --- /dev/null +++ b/src/BlazorUI/Bit.BlazorUI.Tests/Components/Utilities/Stack/BitStackTests.cs @@ -0,0 +1,592 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Collections.Generic; +using System; +using Bunit; + +namespace Bit.BlazorUI.Tests.Components.Utilities.Stack; + +[TestClass] +public class BitStackTests : BunitTestContext +{ + private const string STYLE = "flex-direction:column;align-items:flex-start;justify-content:flex-start;"; + + private static readonly Dictionary _AlignmentMap = new() + { + { BitStackAlignment.Start, "flex-start" }, + { BitStackAlignment.End, "flex-end" }, + { BitStackAlignment.Center, "center" }, + { BitStackAlignment.SpaceBetween, "space-between" }, + { BitStackAlignment.SpaceAround, "space-around" }, + { BitStackAlignment.SpaceEvenly, "space-evenly" }, + { BitStackAlignment.Baseline, "baseline" }, + { BitStackAlignment.Stretch, "stretch" }, + }; + + [DataTestMethod] + public void BitStackShouldRenderExpectedElement() + { + var component = RenderComponent(); + + component.MarkupMatches(@$"
"); + } + + [DataTestMethod, + DataRow(true), + DataRow(false) + ] + public void BitStackShouldRespectIsEnabled(bool isEnabled) + { + var component = RenderComponent(parameters => + { + parameters.Add(p => p.IsEnabled, isEnabled); + }); + + var cssClass = isEnabled ? null : " bit-dis"; + + component.MarkupMatches(@$"
"); + } + + [DataTestMethod] + public void BitStackShouldRespectIsEnabledChangingAfterRender() + { + var component = RenderComponent(); + + component.MarkupMatches(@$"
"); + + component.SetParametersAndRender(parameters => + { + parameters.Add(p => p.IsEnabled, false); + }); + + component.MarkupMatches(@$"
"); + } + + [DataTestMethod, + DataRow("font-size: 14px; color: red;"), + DataRow("padding: 1rem;"), + DataRow(null) + ] + public void BitStackShouldRespectStyle(string style) + { + var component = RenderComponent(parameters => + { + parameters.Add(p => p.Style, style); + }); + + component.MarkupMatches(@$"
"); + } + + [DataTestMethod] + public void BitStackShouldRespectStyleChangingAfterRender() + { + var component = RenderComponent(); + + component.MarkupMatches(@$"
"); + + var style = "padding: 1rem;"; + component.SetParametersAndRender(parameters => + { + parameters.Add(p => p.Style, style); + }); + + component.MarkupMatches(@$"
"); + } + + [DataTestMethod, + DataRow("test-class"), + DataRow(null) + ] + public void BitStackShouldRespectClass(string @class) + { + var component = RenderComponent(parameters => + { + parameters.Add(p => p.Class, @class); + }); + + var cssClass = @class.HasValue() ? $" {@class}" : null; + + component.MarkupMatches(@$"
"); + } + + [DataTestMethod] + public void BitStackShouldRespectClassChangingAfterRender() + { + var component = RenderComponent(); + + component.MarkupMatches(@$"
"); + + var cssClass = "test-class"; + + component.SetParametersAndRender(parameters => + { + parameters.Add(p => p.Class, cssClass); + }); + + component.MarkupMatches(@$"
"); + } + + [DataTestMethod, + DataRow("test-id"), + DataRow(null) + ] + public void BitStackShouldRespectId(string id) + { + var component = RenderComponent(parameters => + { + parameters.Add(p => p.Id, id); + }); + + var expectedId = id.HasValue() ? id : component.Instance.UniqueId.ToString(); + + component.MarkupMatches(@$"
"); + } + + [DataTestMethod, + DataRow(BitDir.Rtl), + DataRow(BitDir.Ltr), + DataRow(BitDir.Auto), + DataRow(null) + ] + public void BitStackShouldRespectDir(BitDir? dir) + { + var component = RenderComponent(parameters => + { + parameters.Add(p => p.Dir, dir); + }); + + if (dir.HasValue) + { + var cssClass = dir is BitDir.Rtl ? " bit-rtl" : null; + component.MarkupMatches(@$"
"); + } + else + { + component.MarkupMatches(@$"
"); + } + } + + [DataTestMethod] + public void BitStackShouldRespectDirChangingAfterRender() + { + var component = RenderComponent(); + + component.MarkupMatches(@$"
"); + + component.SetParametersAndRender(parameters => + { + parameters.Add(p => p.Dir, BitDir.Ltr); + }); + + component.MarkupMatches(@$"
"); + } + + [DataTestMethod, + DataRow(BitVisibility.Visible), + DataRow(BitVisibility.Collapsed), + DataRow(BitVisibility.Hidden) + ] + public void BitStackShouldRespectVisibility(BitVisibility visibility) + { + var component = RenderComponent(parameters => + { + parameters.Add(p => p.Visibility, visibility); + }); + + var style = visibility switch + { + BitVisibility.Hidden => "visibility: hidden;", + BitVisibility.Collapsed => "display: none;", + _ => null + }; + + component.MarkupMatches(@$"
"); + } + + [DataTestMethod] + public void BitStackShouldRespectVisibilityChangingAfterRender() + { + var component = RenderComponent(); + + component.MarkupMatches(@$"
"); + + component.SetParametersAndRender(parameters => + { + parameters.Add(p => p.Visibility, BitVisibility.Collapsed); + }); + + component.MarkupMatches(@$"
"); + } + + [DataTestMethod, + DataRow("Bit Blazor UI"), + DataRow("Bit Blazor UI"), + DataRow(null) + ] + public void BitStackShouldRespectChildContent(string childContent) + { + var component = RenderComponent(parameters => + { + if (childContent is not null) + { + parameters.AddChildContent(childContent); + } + }); + + component.MarkupMatches(@$"
{childContent}
"); + } + + [DataTestMethod] + public void BitStackShouldRespectHtmlAttributes() + { + var component = RenderComponent(); + + component.MarkupMatches(@$"
I'm a stack
"); + } + + [DataTestMethod, + DataRow("p"), + DataRow("span"), + DataRow(null) + ] + public void BitStackShouldRespectElement(string element) + { + var component = RenderComponent(parameters => + { + parameters.Add(p => p.Element, element); + }); + + var el = element.HasValue() ? element : "div"; + component.MarkupMatches(@$"<{el} class=""bit-stc"" style=""{STYLE}"" id:ignore>"); + } + + [DataTestMethod, + DataRow("10px"), + DataRow("1rem"), + DataRow(null) + ] + public void BitStackShouldRespectGap(string gap) + { + var component = RenderComponent(parameters => + { + parameters.Add(p => p.Gap, gap); + }); + + var style = gap.HasValue() ? $"gap:{gap}" : null; + + component.MarkupMatches(@$"
"); + } + + [DataTestMethod] + public void BitStackShouldRespectGapChangingAfterRender() + { + var component = RenderComponent(); + + component.MarkupMatches(@$"
"); + + var gap = "1rem"; + component.SetParametersAndRender(parameters => + { + parameters.Add(p => p.Gap, gap); + }); + + component.MarkupMatches(@$"
"); + } + + [DataTestMethod, + DataRow("3"), + DataRow("initial"), + DataRow("inherit"), + DataRow(null) + ] + public void BitStackShouldRespectGrow(string grow) + { + var component = RenderComponent(parameters => + { + parameters.Add(p => p.Grow, grow); + }); + + var style = grow.HasValue() ? $"flex-grow:{grow}" : null; + + component.MarkupMatches(@$"
"); + } + + [DataTestMethod] + public void BitStackShouldRespectGrowChangingAfterRender() + { + var component = RenderComponent(); + + component.MarkupMatches(@$"
"); + + var grow = "2"; + component.SetParametersAndRender(parameters => + { + parameters.Add(p => p.Grow, grow); + }); + + component.MarkupMatches(@$"
"); + } + + [DataTestMethod, + DataRow(true), + DataRow(false) + ] + public void BitStackShouldRespectGrows(bool grows) + { + var component = RenderComponent(parameters => + { + parameters.Add(p => p.Grows, grows); + }); + + var style = grows ? "flex-grow:1" : null; + + component.MarkupMatches(@$"
"); + } + + [DataTestMethod] + public void BitStackShouldRespectGrowsChangingAfterRender() + { + var component = RenderComponent(); + + component.MarkupMatches(@$"
"); + + component.SetParametersAndRender(parameters => + { + parameters.Add(p => p.Grows, true); + }); + + component.MarkupMatches(@$"
"); + } + + [DataTestMethod, + DataRow(true), + DataRow(false) + ] + public void BitStackShouldRespectHorizontal(bool horizontal) + { + var component = RenderComponent(parameters => + { + parameters.Add(p => p.Horizontal, horizontal); + }); + + var fd = horizontal ? "row" : "column"; + + component.MarkupMatches(@$"
"); + } + + [DataTestMethod] + public void BitStackShouldRespectHorizontalChangingAfterRender() + { + var component = RenderComponent(); + + component.MarkupMatches(@$"
"); + + component.SetParametersAndRender(parameters => + { + parameters.Add(p => p.Horizontal, true); + }); + + component.MarkupMatches(@$"
"); + } + + [DataTestMethod, + DataRow(BitStackAlignment.Start), + DataRow(BitStackAlignment.End), + DataRow(BitStackAlignment.Center), + DataRow(BitStackAlignment.SpaceBetween), + DataRow(BitStackAlignment.SpaceAround), + DataRow(BitStackAlignment.SpaceEvenly), + DataRow(BitStackAlignment.Baseline), + DataRow(BitStackAlignment.Stretch) + ] + public void BitStackShouldRespectHorizontalAlign(BitStackAlignment horizontalAlign) + { + var component = RenderComponent(parameters => + { + parameters.Add(p => p.HorizontalAlign, horizontalAlign); + }); + + var ai = _AlignmentMap[horizontalAlign]; + + component.MarkupMatches(@$"
"); + } + + [DataTestMethod] + public void BitStackShouldRespectHorizontalAlignChangingAfterRender() + { + var component = RenderComponent(); + + component.MarkupMatches(@$"
"); + + component.SetParametersAndRender(parameters => + { + parameters.Add(p => p.HorizontalAlign, BitStackAlignment.SpaceBetween); + }); + + component.MarkupMatches(@$"
"); + } + + [DataTestMethod, + DataRow(true), + DataRow(false) + ] + public void BitStackShouldRespectReversed(bool reversed) + { + var component = RenderComponent(parameters => + { + parameters.Add(p => p.Reversed, reversed); + }); + + var fd = reversed ? "column-reverse" : "column"; + + component.MarkupMatches(@$"
"); + } + + [DataTestMethod] + public void BitStackShouldRespectReversedChangingAfterRender() + { + var component = RenderComponent(); + + component.MarkupMatches(@$"
"); + + component.SetParametersAndRender(parameters => + { + parameters.Add(p => p.Reversed, true); + }); + + component.MarkupMatches(@$"
"); + } + + [DataTestMethod, + DataRow(BitStackAlignment.Start), + DataRow(BitStackAlignment.End), + DataRow(BitStackAlignment.Center), + DataRow(BitStackAlignment.SpaceBetween), + DataRow(BitStackAlignment.SpaceAround), + DataRow(BitStackAlignment.SpaceEvenly), + DataRow(BitStackAlignment.Baseline), + DataRow(BitStackAlignment.Stretch) + ] + public void BitStackShouldRespectBitStackAlignment(BitStackAlignment verticalAlign) + { + var component = RenderComponent(parameters => + { + parameters.Add(p => p.VerticalAlign, verticalAlign); + }); + + var jc = _AlignmentMap[verticalAlign]; + + component.MarkupMatches(@$"
"); + } + + [DataTestMethod] + public void BitStackShouldRespectVerticalAlignChangingAfterRender() + { + var component = RenderComponent(); + + component.MarkupMatches(@$"
"); + + component.SetParametersAndRender(parameters => + { + parameters.Add(p => p.VerticalAlign, BitStackAlignment.SpaceBetween); + }); + + component.MarkupMatches(@$"
"); + } + + [DataTestMethod, + DataRow(true), + DataRow(false) + ] + public void BitStackShouldRespectWrap(bool wrap) + { + var component = RenderComponent(parameters => + { + parameters.Add(p => p.Wrap, wrap); + }); + + var style = wrap ? "flex-wrap:wrap" : null; + + component.MarkupMatches(@$"
"); + } + + [DataTestMethod] + public void BitStackShouldRespectWrapChangingAfterRender() + { + var component = RenderComponent(); + + component.MarkupMatches(@$"
"); + + component.SetParametersAndRender(parameters => + { + parameters.Add(p => p.Wrap, true); + }); + + component.MarkupMatches(@$"
"); + } + + [DataTestMethod, + DataRow(true, null), + DataRow(true, "2"), + DataRow(false, null), + DataRow(false, "2") + ] + public void BitStackShouldRespectGrowsAndGrow(bool grows, string grow) + { + var component = RenderComponent(parameters => + { + parameters.Add(p => p.Grow, grow); + parameters.Add(p => p.Grows, grows); + }); + + var style = (grow.HasValue() || grows) ? $"flex-grow:{(grow.HasValue() ? grow : "1")}" : null; + + component.MarkupMatches(@$"
"); + } + + [DataTestMethod, + DataRow(true, true), + DataRow(true, false), + DataRow(false, true), + DataRow(false, false) + ] + public void BitStackShouldRespectHorizontalAndReversed(bool horizontal, bool reversed) + { + var component = RenderComponent(parameters => + { + parameters.Add(p => p.Horizontal, horizontal); + parameters.Add(p => p.Reversed, reversed); + }); + + var fd = $"{(horizontal ? "row" : "column")}{(reversed ? "-reverse" : null)}"; + + component.MarkupMatches(@$"
"); + } + + [DataTestMethod, + DataRow(true), + DataRow(false) + ] + public void BitStackShouldRespectHorizontalAndReversedAndHorizontalAlignAndVerticalAlign(bool horizontal) + { + var aligns = Enum.GetValues(typeof(BitStackAlignment)); + + foreach (BitStackAlignment horizontalAlign in aligns) + { + foreach (BitStackAlignment verticalAlign in aligns) + { + var component = RenderComponent(parameters => + { + parameters.Add(p => p.Horizontal, horizontal); + parameters.Add(p => p.VerticalAlign, verticalAlign); + parameters.Add(p => p.HorizontalAlign, horizontalAlign); + }); + + var fd = horizontal ? "row" : "column"; + var ai = _AlignmentMap[horizontal ? verticalAlign : horizontalAlign]; + var jc = _AlignmentMap[horizontal ? horizontalAlign : verticalAlign]; + + component.MarkupMatches(@$"
"); + } + } + } +} diff --git a/src/BlazorUI/Bit.BlazorUI.Tests/Components/Utilities/Sticky/BitStickyHtmlAttributesTest.razor b/src/BlazorUI/Bit.BlazorUI.Tests/Components/Utilities/Sticky/BitStickyHtmlAttributesTest.razor new file mode 100644 index 0000000000..b21ae5e193 --- /dev/null +++ b/src/BlazorUI/Bit.BlazorUI.Tests/Components/Utilities/Sticky/BitStickyHtmlAttributesTest.razor @@ -0,0 +1 @@ +I'm a sticky \ No newline at end of file diff --git a/src/BlazorUI/Bit.BlazorUI.Tests/Components/Utilities/Sticky/BitStickyTests.cs b/src/BlazorUI/Bit.BlazorUI.Tests/Components/Utilities/Sticky/BitStickyTests.cs new file mode 100644 index 0000000000..aa3bf07139 --- /dev/null +++ b/src/BlazorUI/Bit.BlazorUI.Tests/Components/Utilities/Sticky/BitStickyTests.cs @@ -0,0 +1,487 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Bunit; + +namespace Bit.BlazorUI.Tests.Components.Utilities.Sticky; + +[TestClass] +public class BitStickyTests : BunitTestContext +{ + [DataTestMethod] + public void BitStickyShouldRenderExpectedElement() + { + var component = RenderComponent(); + + component.MarkupMatches(@"
"); + } + + [DataTestMethod, + DataRow(true), + DataRow(false) + ] + public void BitStickyShouldRespectIsEnabled(bool isEnabled) + { + var component = RenderComponent(parameters => + { + parameters.Add(p => p.IsEnabled, isEnabled); + }); + + var cssClass = isEnabled ? null : " bit-dis"; + + component.MarkupMatches(@$"
"); + } + + [DataTestMethod] + public void BitStickyShouldRespectIsEnabledChangingAfterRender() + { + var component = RenderComponent(); + + component.MarkupMatches(@"
"); + + component.SetParametersAndRender(parameters => + { + parameters.Add(p => p.IsEnabled, false); + }); + + component.MarkupMatches(@"
"); + } + + [DataTestMethod, + DataRow("font-size: 14px; color: red;"), + DataRow("padding: 1rem;"), + DataRow(null) + ] + public void BitStickyShouldRespectStyle(string style) + { + var component = RenderComponent(parameters => + { + parameters.Add(p => p.Style, style); + }); + + if (style.HasValue()) + { + component.MarkupMatches(@$"
"); + } + else + { + component.MarkupMatches(@"
"); + } + } + + [DataTestMethod] + public void BitStickyShouldRespectStyleChangingAfterRender() + { + var component = RenderComponent(); + + component.MarkupMatches(@"
"); + + var style = "padding: 1rem;"; + component.SetParametersAndRender(parameters => + { + parameters.Add(p => p.Style, style); + }); + + component.MarkupMatches(@$"
"); + } + + [DataTestMethod, + DataRow("test-class"), + DataRow(null) + ] + public void BitStickyShouldRespectClass(string @class) + { + var component = RenderComponent(parameters => + { + parameters.Add(p => p.Class, @class); + }); + + var cssClass = @class.HasValue() ? $" {@class}" : null; + + component.MarkupMatches(@$"
"); + } + + [DataTestMethod] + public void BitStickyShouldRespectClassChangingAfterRender() + { + var component = RenderComponent(); + + component.MarkupMatches(@"
"); + + var cssClass = "test-class"; + + component.SetParametersAndRender(parameters => + { + parameters.Add(p => p.Class, cssClass); + }); + + component.MarkupMatches(@$"
"); + } + + [DataTestMethod, + DataRow("test-id"), + DataRow(null) + ] + public void BitStickyShouldRespectId(string id) + { + var component = RenderComponent(parameters => + { + parameters.Add(p => p.Id, id); + }); + + var expectedId = id.HasValue() ? id : component.Instance.UniqueId.ToString(); + + component.MarkupMatches(@$"
"); + } + + [DataTestMethod, + DataRow(BitDir.Rtl), + DataRow(BitDir.Ltr), + DataRow(BitDir.Auto), + DataRow(null) + ] + public void BitStickyShouldRespectDir(BitDir? dir) + { + var component = RenderComponent(parameters => + { + parameters.Add(p => p.Dir, dir); + }); + + if (dir.HasValue) + { + var cssClass = dir is BitDir.Rtl ? " bit-rtl" : null; + component.MarkupMatches(@$"
"); + } + else + { + component.MarkupMatches(@"
"); + } + } + + [DataTestMethod] + public void BitStickyShouldRespectDirChangingAfterRender() + { + var component = RenderComponent(); + + component.MarkupMatches(@"
"); + + component.SetParametersAndRender(parameters => + { + parameters.Add(p => p.Dir, BitDir.Ltr); + }); + + component.MarkupMatches(@"
"); + } + + [DataTestMethod, + DataRow(BitVisibility.Visible), + DataRow(BitVisibility.Collapsed), + DataRow(BitVisibility.Hidden) + ] + public void BitStickyShouldRespectVisibility(BitVisibility visibility) + { + var component = RenderComponent(parameters => + { + parameters.Add(p => p.Visibility, visibility); + }); + + switch (visibility) + { + case BitVisibility.Visible: + component.MarkupMatches(@"
"); + break; + case BitVisibility.Hidden: + component.MarkupMatches(@"
"); + break; + case BitVisibility.Collapsed: + component.MarkupMatches(@"
"); + break; + } + } + + [DataTestMethod] + public void BitStickyShouldRespectVisibilityChangingAfterRender() + { + var component = RenderComponent(); + + component.MarkupMatches(@"
"); + + component.SetParametersAndRender(parameters => + { + parameters.Add(p => p.Visibility, BitVisibility.Collapsed); + }); + + component.MarkupMatches(@"
"); + } + + [DataTestMethod, + DataRow("Bit Blazor UI"), + DataRow(null) + ] + public void BitStickyShouldRespectAriaLabel(string ariaLabel) + { + var component = RenderComponent(parameters => + { + parameters.Add(p => p.AriaLabel, ariaLabel); + }); + + if (ariaLabel.HasValue()) + { + component.MarkupMatches(@$"
"); + } + else + { + component.MarkupMatches(@"
"); + } + } + + [DataTestMethod, + DataRow("Bit Blazor UI"), + DataRow("Bit Blazor UI"), + DataRow(null) + ] + public void BitStickyShouldRespectChildContent(string childContent) + { + var component = RenderComponent(parameters => + { + parameters.AddChildContent(childContent); + }); + + component.MarkupMatches(@$"
{childContent}"); + } + + [DataTestMethod] + public void BitStickyShouldRespectHtmlAttributes() + { + var component = RenderComponent(); + + component.MarkupMatches(@"
I'm a sticky
"); + } + + [DataTestMethod, + DataRow(null), + DataRow(""), + DataRow("14px"), + DataRow("1.5rem") + ] + public void BitStickyShouldRespectTop(string top) + { + var component = RenderComponent(parameters => + { + parameters.Add(p => p.Top, top); + }); + + if (top.HasValue()) + { + component.MarkupMatches(@$"
"); + } + else + { + component.MarkupMatches(@"
"); + } + } + + [DataTestMethod] + public void BitStickyShouldRespectTopChangingAfterRender() + { + var component = RenderComponent(); + + component.MarkupMatches(@"
"); + + var top = "20px"; + + component.SetParametersAndRender(parameters => + { + parameters.Add(p => p.Top, top); + }); + + component.MarkupMatches(@$"
"); + } + + [DataTestMethod, + DataRow(null), + DataRow(""), + DataRow("14px"), + DataRow("1.5rem") + ] + public void BitStickyShouldRespectBottom(string bottom) + { + var component = RenderComponent(parameters => + { + parameters.Add(p => p.Bottom, bottom); + }); + + if (bottom.HasValue()) + { + component.MarkupMatches(@$"
"); + } + else + { + component.MarkupMatches(@"
"); + } + } + + [DataTestMethod] + public void BitStickyShouldRespectBottomChangingAfterRender() + { + var component = RenderComponent(); + + component.MarkupMatches(@"
"); + + var bottom = "20px"; + + component.SetParametersAndRender(parameters => + { + parameters.Add(p => p.Bottom, "20px"); + }); + + component.MarkupMatches(@$"
"); + } + + [DataTestMethod, + DataRow(null), + DataRow(""), + DataRow("14px"), + DataRow("1.5rem") + ] + public void BitStickyShouldRespectLeft(string left) + { + var component = RenderComponent(parameters => + { + parameters.Add(p => p.Left, left); + }); + + if (left.HasValue()) + { + component.MarkupMatches(@$"
"); + } + else + { + component.MarkupMatches(@"
"); + } + } + + [DataTestMethod] + public void BitStickyShouldRespectLeftChangingAfterRender() + { + var component = RenderComponent(); + + component.MarkupMatches(@"
"); + + var left = "20px"; + + component.SetParametersAndRender(parameters => + { + parameters.Add(p => p.Left, left); + }); + + component.MarkupMatches(@$"
"); + } + + [DataTestMethod, + DataRow(null), + DataRow(""), + DataRow("14px"), + DataRow("1.5rem") + ] + public void BitStickyShouldRespectRight(string right) + { + var component = RenderComponent(parameters => + { + parameters.Add(p => p.Right, right); + }); + + if (right.HasValue()) + { + component.MarkupMatches(@$"
"); + } + else + { + component.MarkupMatches(@"
"); + } + } + + [DataTestMethod] + public void BitStickyShouldRespectRightChangingAfterRender() + { + var component = RenderComponent(); + + component.MarkupMatches(@"
"); + + var right = "20px"; + + component.SetParametersAndRender(parameters => + { + parameters.Add(p => p.Right, right); + }); + + component.MarkupMatches(@$"
"); + } + + [DataTestMethod, + DataRow("14px", "15px", "16px", "17px"), + DataRow("1.5rem", "2.5rem", "3.5rem", "4.5rem") + ] + public void BitStickyShouldRespectTopBottomLeftRight(string top, string bottom, string left, string right) + { + var component = RenderComponent(parameters => + { + parameters.Add(p => p.Top, top); + parameters.Add(p => p.Bottom, bottom); + parameters.Add(p => p.Left, left); + parameters.Add(p => p.Right, right); + }); + + if (right.HasValue()) + { + component.MarkupMatches(@$"
"); + } + else + { + component.MarkupMatches(@"
"); + } + } + + [DataTestMethod, + DataRow(null), + DataRow(BitStickyPosition.Top), + DataRow(BitStickyPosition.Bottom), + DataRow(BitStickyPosition.TopAndBottom), + DataRow(BitStickyPosition.Start), + DataRow(BitStickyPosition.End), + DataRow(BitStickyPosition.StartAndEnd) + ] + public void BitStickyShouldRespectPosition(BitStickyPosition? position) + { + var component = RenderComponent(parameters => + { + parameters.Add(p => p.Position, position); + }); + + var cssClass = position switch + { + BitStickyPosition.Top => " bit-stk-top", + BitStickyPosition.Bottom => " bit-stk-btm", + BitStickyPosition.TopAndBottom => " bit-stk-tab", + BitStickyPosition.Start => " bit-stk-srt", + BitStickyPosition.End => " bit-stk-end", + BitStickyPosition.StartAndEnd => " bit-stk-sae", + _ => " bit-stk-top" + }; + + component.MarkupMatches(@$"
"); + } + + [DataTestMethod] + public void BitStickyShouldRespectPositionChangingAfterRender() + { + var component = RenderComponent(); + + component.MarkupMatches(@"
"); + + component.SetParametersAndRender(parameters => + { + parameters.Add(p => p.Position, BitStickyPosition.Start); + }); + + component.MarkupMatches(@"
"); + } +} diff --git a/src/BlazorUI/Bit.BlazorUI.Tests/Components/Utilities/Typography/BitTypographyHtmlAttributesTest.razor b/src/BlazorUI/Bit.BlazorUI.Tests/Components/Utilities/Typography/BitTypographyHtmlAttributesTest.razor new file mode 100644 index 0000000000..dba8aaa99e --- /dev/null +++ b/src/BlazorUI/Bit.BlazorUI.Tests/Components/Utilities/Typography/BitTypographyHtmlAttributesTest.razor @@ -0,0 +1 @@ +I'm a typography \ No newline at end of file diff --git a/src/BlazorUI/Bit.BlazorUI.Tests/Components/Utilities/Typography/BitTypographyTests.cs b/src/BlazorUI/Bit.BlazorUI.Tests/Components/Utilities/Typography/BitTypographyTests.cs new file mode 100644 index 0000000000..af5eb96e24 --- /dev/null +++ b/src/BlazorUI/Bit.BlazorUI.Tests/Components/Utilities/Typography/BitTypographyTests.cs @@ -0,0 +1,386 @@ +using System.Globalization; +using System.Collections.Generic; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Bunit; + +namespace Bit.BlazorUI.Tests.Components.Utilities.Typography; + +[TestClass] +public class BitTypographyTests : BunitTestContext +{ + private static readonly Dictionary VariantMapping = new() + { + { BitTypographyVariant.Body1, "p" }, + { BitTypographyVariant.Body2, "p" }, + { BitTypographyVariant.Button, "span" }, + { BitTypographyVariant.Caption, "span" }, + { BitTypographyVariant.H1, "h1" }, + { BitTypographyVariant.H2, "h2" }, + { BitTypographyVariant.H3, "h3" }, + { BitTypographyVariant.H4, "h4" }, + { BitTypographyVariant.H5, "h5" }, + { BitTypographyVariant.H6, "h6" }, + { BitTypographyVariant.Inherit, "p" }, + { BitTypographyVariant.Overline, "span" }, + { BitTypographyVariant.Subtitle1, "h6" }, + { BitTypographyVariant.Subtitle2, "h6" } + }; + + [DataTestMethod] + public void BitTypographyShouldRenderExpectedElement() + { + var component = RenderComponent(); + + component.MarkupMatches(@"
"); + } + + [DataTestMethod, + DataRow(BitTypographyVariant.Body1), + DataRow(BitTypographyVariant.Body2), + DataRow(BitTypographyVariant.Button), + DataRow(BitTypographyVariant.Caption), + DataRow(BitTypographyVariant.H1), + DataRow(BitTypographyVariant.H2), + DataRow(BitTypographyVariant.H3), + DataRow(BitTypographyVariant.H4), + DataRow(BitTypographyVariant.H5), + DataRow(BitTypographyVariant.H6), + DataRow(BitTypographyVariant.Inherit), + DataRow(BitTypographyVariant.Overline), + DataRow(BitTypographyVariant.Subtitle1), + DataRow(BitTypographyVariant.Subtitle2), + ] + public void BitTypographyShouldRespectVariant(BitTypographyVariant variant) + { + var component = RenderComponent(parameters => + { + parameters.Add(p => p.Variant, variant); + }); + + var el = VariantMapping[variant]; + var cssClass = $"bit-tpg-{variant.ToString().ToLower(CultureInfo.InvariantCulture)}"; + + component.MarkupMatches(@$"<{el} class=""bit-tpg {cssClass}"" id:ignore>"); + } + + [DataTestMethod, + DataRow("h1"), + DataRow("div"), + DataRow(null) + ] + public void BitTypographyShouldRespectElement(string element) + { + var component = RenderComponent(parameters => + { + parameters.Add(p => p.Element, element); + }); + + var defaultVariant = BitTypographyVariant.Subtitle1; + var el = element is null ? VariantMapping[defaultVariant] : element; + + component.MarkupMatches(@$"<{el} class=""bit-tpg bit-tpg-subtitle1"" id:ignore>"); + + } + + [DataTestMethod, + DataRow(true), + DataRow(false) + ] + public void BitTypographyShouldRespectNoWrap(bool noWrap) + { + var component = RenderComponent(parameters => + { + parameters.Add(p => p.NoWrap, noWrap); + }); + + var cssClass = noWrap ? " bit-tpg-nowrap" : null; + + component.MarkupMatches(@$"
"); + } + + [DataTestMethod] + public void BitTypographyShouldRespectNoWrapChangingAfterRender() + { + var component = RenderComponent(); + + component.MarkupMatches(@"
"); + + component.SetParametersAndRender(parameters => + { + parameters.Add(p => p.NoWrap, true); + }); + + component.MarkupMatches(@"
"); + } + + [DataTestMethod, + DataRow(true), + DataRow(false) + ] + public void BitTypographyShouldRespectGutter(bool gutter) + { + var component = RenderComponent(parameters => + { + parameters.Add(p => p.Gutter, gutter); + }); + + var cssClass = gutter ? " bit-tpg-gutter" : null; + + component.MarkupMatches(@$"
"); + } + + [DataTestMethod] + public void BitTypographyShouldRespectGutterChangingAfterRender() + { + var component = RenderComponent(); + + component.MarkupMatches(@"
"); + + component.SetParametersAndRender(parameters => + { + parameters.Add(p => p.Gutter, true); + }); + + component.MarkupMatches(@"
"); + } + + [DataTestMethod, + DataRow(true), + DataRow(false) + ] + public void BitTypographyShouldRespectIsEnabled(bool isEnabled) + { + var component = RenderComponent(parameters => + { + parameters.Add(p => p.IsEnabled, isEnabled); + }); + + var cssClass = isEnabled ? null : " bit-dis"; + + component.MarkupMatches(@$"
"); + } + + [DataTestMethod] + public void BitTypographyShouldRespectIsEnabledChangingAfterRender() + { + var component = RenderComponent(); + + component.MarkupMatches(@"
"); + + component.SetParametersAndRender(parameters => + { + parameters.Add(p => p.IsEnabled, false); + }); + + component.MarkupMatches(@"
"); + } + + [DataTestMethod, + DataRow("font-size: 14px; color: red;"), + DataRow("padding: 1rem;"), + DataRow(null) + ] + public void BitTypographyShouldRespectStyle(string style) + { + var component = RenderComponent(parameters => + { + parameters.Add(p => p.Style, style); + }); + + if (style.HasValue()) + { + component.MarkupMatches(@$"
"); + } + else + { + component.MarkupMatches(@"
"); + } + } + + [DataTestMethod] + public void BitTypographyShouldRespectStyleChangingAfterRender() + { + var component = RenderComponent(); + + component.MarkupMatches(@"
"); + + component.SetParametersAndRender(parameters => + { + parameters.Add(p => p.Style, "padding: 1rem;"); + }); + + component.MarkupMatches(@$"
"); + } + + + [DataTestMethod, + DataRow("test-class"), + DataRow(null) + ] + public void BitTypographyShouldRespectClass(string @class) + { + var component = RenderComponent(parameters => + { + parameters.Add(p => p.Class, @class); + }); + + var cssClass = @class.HasValue() ? $" {@class}" : null; + + component.MarkupMatches(@$"
"); + } + + [DataTestMethod] + public void BitTypographyShouldRespectClassChangingAfterRender() + { + var component = RenderComponent(); + + component.MarkupMatches(@"
"); + + component.SetParametersAndRender(parameters => + { + parameters.Add(p => p.Class, "test-class"); + }); + + component.MarkupMatches(@"
"); + } + + [DataTestMethod, + DataRow("test-id"), + DataRow(null) + ] + public void BitTypographyShouldRespectId(string id) + { + var component = RenderComponent(parameters => + { + parameters.Add(p => p.Id, id); + }); + + var expectedId = id.HasValue() ? id : component.Instance.UniqueId.ToString(); + + component.MarkupMatches(@$"
"); + } + + [DataTestMethod, + DataRow(BitDir.Rtl), + DataRow(BitDir.Ltr), + DataRow(BitDir.Auto), + DataRow(null) + ] + public void BitTypographyShouldRespectDir(BitDir? dir) + { + var component = RenderComponent(parameters => + { + parameters.Add(p => p.Dir, dir); + }); + + if (dir.HasValue) + { + var cssClass = dir is BitDir.Rtl ? " bit-rtl" : null; + component.MarkupMatches(@$"
"); + } + else + { + component.MarkupMatches(@"
"); + } + } + + [DataTestMethod] + public void BitTypographyShouldRespectDirChangingAfterRender() + { + var component = RenderComponent(); + + component.MarkupMatches(@"
"); + + component.SetParametersAndRender(parameters => + { + parameters.Add(p => p.Dir, BitDir.Ltr); + }); + + component.MarkupMatches(@"
"); + } + + [DataTestMethod, + DataRow(BitVisibility.Visible), + DataRow(BitVisibility.Collapsed), + DataRow(BitVisibility.Hidden) + ] + public void BitTypographyShouldRespectVisibility(BitVisibility visibility) + { + var component = RenderComponent(parameters => + { + parameters.Add(p => p.Visibility, visibility); + }); + + switch (visibility) + { + case BitVisibility.Visible: + component.MarkupMatches(@"
"); + break; + case BitVisibility.Hidden: + component.MarkupMatches(@"
"); + break; + case BitVisibility.Collapsed: + component.MarkupMatches(@"
"); + break; + } + } + + [DataTestMethod] + public void BitTypographyShouldRespectVisibilityChangingAfterRender() + { + var component = RenderComponent(); + + component.MarkupMatches(@"
"); + + component.SetParametersAndRender(parameters => + { + parameters.Add(p => p.Visibility, BitVisibility.Collapsed); + }); + + component.MarkupMatches(@"
"); + } + + [DataTestMethod, + DataRow("Bit Blazor UI"), + DataRow(null) + ] + public void BitTypographyShouldRespectAriaLabel(string ariaLabel) + { + var component = RenderComponent(parameters => + { + parameters.Add(p => p.AriaLabel, ariaLabel); + }); + + if (ariaLabel.HasValue()) + { + component.MarkupMatches(@$"
"); + } + else + { + component.MarkupMatches(@"
"); + } + } + + [DataTestMethod, + DataRow("Bit Blazor UI"), + DataRow("Bit Blazor UI"), + DataRow(null) + ] + public void BitTypographyShouldRespectChildContent(string childContent) + { + var component = RenderComponent(parameters => + { + parameters.AddChildContent(childContent); + }); + + component.MarkupMatches(@$"
{childContent}
"); + } + + [DataTestMethod] + public void BitTypographyShouldRespectHtmlAttributes() + { + var component = RenderComponent(); + + component.MarkupMatches(@"
I'm a typography
"); + } +} diff --git a/src/BlazorUI/Bit.BlazorUI.Tests/Element/BitElementTests.cs b/src/BlazorUI/Bit.BlazorUI.Tests/Element/BitElementTests.cs deleted file mode 100644 index 8422522d33..0000000000 --- a/src/BlazorUI/Bit.BlazorUI.Tests/Element/BitElementTests.cs +++ /dev/null @@ -1,54 +0,0 @@ -using System.Collections.Generic; -using Microsoft.VisualStudio.TestTools.UnitTesting; -using Bunit; - -namespace Bit.BlazorUI.Tests.Element; - -[TestClass] -public class BitElementTests : BunitTestContext -{ - [DataTestMethod, - DataRow("div"), - DataRow("button"), - DataRow("input"), - DataRow("a"), - DataRow(null) - ] - [TestMethod] - public void BitElementTagTest(string tag) - { - var com = RenderComponent(parameters => - { - if (tag.HasValue()) - { - parameters.Add(p => p.Tag, tag); - } - }); - - var expectedElement = tag ?? "div"; - - var expectedHtml = $"<{expectedElement} diff:ignore>"; - - com.MarkupMatches(expectedHtml); - } - - [DataTestMethod] - [DataRow("input", "placeholder", "Enter text")] - [DataRow("a", "href", "/")] - public void BitElementTagWithAttributesTest(string tag, string attribute, string attributeValue) - { - var com = RenderComponent(parameters => - { - parameters.Add(p => p.Tag, tag); - parameters.Add(p => p.HtmlAttributes, new Dictionary - { - { attribute, attributeValue } - }); - }); - - var element = com.Find(tag); - - var expectedHtml = $"<{tag} {attribute}=\"{attributeValue}\" diff:ignore>"; - com.MarkupMatches(expectedHtml); - } -} diff --git a/src/BlazorUI/Bit.BlazorUI.Tests/Labels/BitLabelTest.razor b/src/BlazorUI/Bit.BlazorUI.Tests/Labels/BitLabelTest.razor deleted file mode 100644 index 6de7cba2a0..0000000000 --- a/src/BlazorUI/Bit.BlazorUI.Tests/Labels/BitLabelTest.razor +++ /dev/null @@ -1,6 +0,0 @@ - -I'm a label - -@code { - [Parameter] public bool IsRequired { get; set; } -} diff --git a/src/BlazorUI/Bit.BlazorUI.Tests/Labels/BitLabelTests.cs b/src/BlazorUI/Bit.BlazorUI.Tests/Labels/BitLabelTests.cs deleted file mode 100644 index a7a1c66f59..0000000000 --- a/src/BlazorUI/Bit.BlazorUI.Tests/Labels/BitLabelTests.cs +++ /dev/null @@ -1,16 +0,0 @@ -using Bunit; -using Microsoft.VisualStudio.TestTools.UnitTesting; - -namespace Bit.BlazorUI.Tests.Labels; - -[TestClass] -public class BitLabelTests : BunitTestContext -{ - [DataTestMethod, DataRow(true, true), DataRow(false, false)] - public void BitLabelShouldRespectIsRequired(bool isRequired, bool expectedResult) - { - var component = RenderComponent(parameters => parameters.Add(p => p.IsRequired, isRequired)); - var bitLabel = component.Find(".bit-lbl"); - Assert.AreEqual(expectedResult, bitLabel.ClassList.Contains("bit-lbl-req")); - } -} diff --git a/src/BlazorUI/Bit.BlazorUI.Tests/Links/BitLinkTests.cs b/src/BlazorUI/Bit.BlazorUI.Tests/Links/BitLinkTests.cs deleted file mode 100644 index 5aabd1cac6..0000000000 --- a/src/BlazorUI/Bit.BlazorUI.Tests/Links/BitLinkTests.cs +++ /dev/null @@ -1,67 +0,0 @@ -using System; -using Bunit; -using Microsoft.VisualStudio.TestTools.UnitTesting; - -namespace Bit.BlazorUI.Tests.Links; - -[TestClass] -public class BitLinkTests : BunitTestContext -{ - [DataTestMethod, - DataRow("bitplatform.dev"), - DataRow("") - ] - public void BitLinkShouldRenderExpectedElementBaseOnHref(string href) - { - var component = RenderComponent(parameters => - { - parameters.Add(p => p.Href, href); - }); - - var bitLink = component.Find(".bit-lnk"); - - var tagName = href.HasValue() ? "a" : "button"; - - Assert.AreEqual(tagName, bitLink.TagName, ignoreCase: true); - } - - [TestMethod, - DataRow(true), - DataRow(false) - ] - public void BitLinkButtonOnClickTest(bool isEnabled) - { - int currentCount = 0; - var component = RenderComponent(parameters => - { - parameters.Add(p => p.IsEnabled, isEnabled); - parameters.Add(p => p.OnClick, () => currentCount++); - }); - - var bitLinkButton = component.Find(".bit-lnk"); - - bitLinkButton.Click(); - - Assert.AreEqual(isEnabled ? 1 : 0, currentCount); - } - - [DataTestMethod, - DataRow(true), - DataRow(false), - DataRow(null) - ] - public void BitLinkShouldRespectUnderLineStyle(bool? hasUnderline) - { - var component = RenderComponent(parameters => - { - if (hasUnderline.HasValue) - { - parameters.Add(p => p.HasUnderline, hasUnderline.Value); - } - }); - - var bitLink = component.Find(".bit-lnk"); - - Assert.AreEqual(hasUnderline ?? false, bitLink.ClassList.Contains("bit-lnk-und")); - } -} diff --git a/src/BlazorUI/Bit.BlazorUI.Tests/Spinner/BitSpinnerTests.cs b/src/BlazorUI/Bit.BlazorUI.Tests/Spinner/BitSpinnerTests.cs deleted file mode 100644 index aab3cf7a65..0000000000 --- a/src/BlazorUI/Bit.BlazorUI.Tests/Spinner/BitSpinnerTests.cs +++ /dev/null @@ -1,63 +0,0 @@ -using System; -using Bunit; -using Microsoft.VisualStudio.TestTools.UnitTesting; - -namespace Bit.BlazorUI.Tests.Spinner; - -[TestClass] -public class BitSpinnerTests : BunitTestContext -{ - [DataTestMethod, - DataRow(BitSpinnerSize.Large), - DataRow(BitSpinnerSize.Medium), - DataRow(BitSpinnerSize.Small), - DataRow(BitSpinnerSize.XSmall) - ] - public void BitSpinnerShouldRespectSize(BitSpinnerSize size) - { - var component = RenderComponent(parameters => - { - parameters.Add(p => p.Size, size); - }); - - var sizeClass = size switch - { - BitSpinnerSize.XSmall => "bit-spn-xs", - BitSpinnerSize.Small => "bit-spn-sm", - BitSpinnerSize.Medium => "bit-spn-md", - BitSpinnerSize.Large => "bit-spn-lg", - _ => throw new NotSupportedException() - }; - - var bitSpinner = component.Find(".bit-spn"); - - Assert.IsTrue(bitSpinner.ClassList.Contains(sizeClass)); - } - - [DataTestMethod, - DataRow(BitLabelPosition.Top), - DataRow(BitLabelPosition.Bottom), - DataRow(BitLabelPosition.End), - DataRow(BitLabelPosition.Start) - ] - public void BitSpinnerShouldRespectPosition(BitLabelPosition position) - { - var component = RenderComponent(parameters => - { - parameters.Add(p => p.LabelPosition, position); - }); - - var positionClass = position switch - { - BitLabelPosition.Top => "bit-spn-top", - BitLabelPosition.End => "bit-spn-end", - BitLabelPosition.Start => "bit-spn-srt", - BitLabelPosition.Bottom => "bit-spn-btm", - _ => throw new NotSupportedException() - }; - - var bitSpinner = component.Find(".bit-spn"); - - Assert.IsTrue(bitSpinner.ClassList.Contains(positionClass)); - } -} diff --git a/src/BlazorUI/Bit.BlazorUI.Tests/Typography/BitTypographyTests.cs b/src/BlazorUI/Bit.BlazorUI.Tests/Typography/BitTypographyTests.cs deleted file mode 100644 index a902c0cd8c..0000000000 --- a/src/BlazorUI/Bit.BlazorUI.Tests/Typography/BitTypographyTests.cs +++ /dev/null @@ -1,130 +0,0 @@ -using System.Collections.Generic; -using System.Globalization; -using AngleSharp.Text; -using Bunit; -using Microsoft.VisualStudio.TestTools.UnitTesting; - -namespace Bit.BlazorUI.Tests.Typography; - -[TestClass] -public class BitTypographyTests : BunitTestContext -{ - private static readonly Dictionary VariantMapping = new() - { - { BitTypographyVariant.Body1, "p" }, - { BitTypographyVariant.Body2, "p" }, - { BitTypographyVariant.Button, "span" }, - { BitTypographyVariant.Caption, "span" }, - { BitTypographyVariant.H1, "h1" }, - { BitTypographyVariant.H2, "h2" }, - { BitTypographyVariant.H3, "h3" }, - { BitTypographyVariant.H4, "h4" }, - { BitTypographyVariant.H5, "h5" }, - { BitTypographyVariant.H6, "h6" }, - { BitTypographyVariant.Inherit, "p" }, - { BitTypographyVariant.Overline, "span" }, - { BitTypographyVariant.Subtitle1, "h6" }, - { BitTypographyVariant.Subtitle2, "h6" } - }; - - [DataTestMethod, - DataRow(BitTypographyVariant.Body1), - DataRow(BitTypographyVariant.Body2), - DataRow(BitTypographyVariant.Button), - DataRow(BitTypographyVariant.Caption), - DataRow(BitTypographyVariant.H1), - DataRow(BitTypographyVariant.H2), - DataRow(BitTypographyVariant.H3), - DataRow(BitTypographyVariant.H4), - DataRow(BitTypographyVariant.H5), - DataRow(BitTypographyVariant.H6), - DataRow(BitTypographyVariant.Inherit), - DataRow(BitTypographyVariant.Overline), - DataRow(BitTypographyVariant.Subtitle1), - DataRow(BitTypographyVariant.Subtitle2), - DataRow(null) - ] - [TestMethod] - public void BitTypographyVariantTest(BitTypographyVariant? variant) - { - var com = RenderComponent(parameters => - { - if (variant.HasValue) - { - parameters.Add(p => p.Variant, variant.Value); - } - }); - - var expectedVariant = variant ?? BitTypographyVariant.Subtitle1; - var expectedElement = VariantMapping[expectedVariant]; - - var expectedHtml = $"<{expectedElement} diff:ignore>"; - - com.MarkupMatches(expectedHtml); - - var element = com.Find(expectedElement); - - Assert.IsTrue( - element.ClassList.Contains($"bit-tpg-{expectedVariant.ToString().ToLower(CultureInfo.InvariantCulture)}")); - } - - [ - DataRow(true), - DataRow(false) - ] - [TestMethod] - public void BitTypographyNoWrapTest(bool hasNoWrap) - { - var com = RenderComponent(parameters => - { - parameters.Add(p => p.NoWrap, hasNoWrap); - }); - - var defaultVariant = BitTypographyVariant.Subtitle1; - var defaultElement = VariantMapping[defaultVariant]; - - var element = com.Find(defaultElement); - - Assert.AreEqual(hasNoWrap, element.ClassList.Contains("bit-tpg-nowrap")); - } - - [ - DataRow(true), - DataRow(false) - ] - [TestMethod] - public void BitTypographyGutterTest(bool hasGutter) - { - var com = RenderComponent(parameters => - { - parameters.Add(p => p.Gutter, hasGutter); - }); - - var defaultVariant = BitTypographyVariant.Subtitle1; - var defaultElement = VariantMapping[defaultVariant]; - - var element = com.Find(defaultElement); - - Assert.AreEqual(hasGutter, element.ClassList.Contains("bit-tpg-gutter")); - } - - [ - DataRow("div"), - DataRow(null) - ] - [TestMethod] - public void BitTypographyComponentTest(string component) - { - var com = RenderComponent(parameters => - { - parameters.Add(p => p.Component, component); - }); - - var defaultVariant = BitTypographyVariant.Subtitle1; - var defaultElement = VariantMapping[defaultVariant]; - - var element = com.Find(component ?? defaultElement); - - Assert.IsTrue(element.ClassList.Contains("bit-tpg")); - } -} diff --git a/src/BlazorUI/Bit.BlazorUI/Bit.BlazorUI.csproj b/src/BlazorUI/Bit.BlazorUI/Bit.BlazorUI.csproj index b5fad68314..fb047e77a7 100644 --- a/src/BlazorUI/Bit.BlazorUI/Bit.BlazorUI.csproj +++ b/src/BlazorUI/Bit.BlazorUI/Bit.BlazorUI.csproj @@ -7,7 +7,6 @@ true enable - InstallNodejsDependencies; BeforeBuildTasks; $(ResolveStaticWebAssetsInputsDependsOn) @@ -48,16 +47,30 @@ - + + + + + + + + + + + + - - + + + + + True diff --git a/src/BlazorUI/Bit.BlazorUI/Components/Badge/BitBadge.scss b/src/BlazorUI/Bit.BlazorUI/Components/Badge/BitBadge.scss deleted file mode 100644 index 95f24ab1b6..0000000000 --- a/src/BlazorUI/Bit.BlazorUI/Components/Badge/BitBadge.scss +++ /dev/null @@ -1,268 +0,0 @@ -@import "../../Styles/functions.scss"; - -.bit-bdg { - position: relative; - display: inline-block; - - &.bit-dis { - .bit-bdg-ctn { - cursor: default; - pointer-events: none; - color: $color-foreground-disabled; - } - } -} - -.bit-bdg-wrp { - top: 0; - left: 0; - flex: 0 1; - width: 100%; - height: 100%; - display: flex; - position: absolute; - pointer-events: none; - - &.bit-bdg-tlf { - align-items: flex-start; - justify-content: flex-start; - } - - &.bit-bdg-tcr { - align-items: flex-start; - justify-content: center; - } - - &.bit-bdg-trg { - align-items: flex-start; - justify-content: flex-end; - } - - &.bit-bdg-clf { - align-items: center; - } - - &.bit-bdg-ctr { - align-items: center; - justify-content: center - } - - &.bit-bdg-crg { - align-items: center; - justify-content: flex-end; - } - - &.bit-bdg-blf { - align-items: flex-end; - justify-content: flex-start; - } - - &.bit-bdg-bcr { - align-items: flex-end; - justify-content: center; - } - - &.bit-bdg-brg { - align-items: flex-end; - justify-content: flex-end; - } -} - -.bit-bdg-ctn { - top: auto; - text-indent: 0; - line-height: 1; - font-weight: 600; - user-select: none; - letter-spacing: 0; - gap: spacing(0.5); - position: absolute; - text-align: center; - align-items: center; - white-space: nowrap; - height: spacing(2.5); - display: inline-flex; - pointer-events: auto; - box-sizing: border-box; - min-width: spacing(2.5); - font-size: spacing(1.5); - -webkit-user-select: none; - border-radius: spacing(1.25); - border-width: $shape-border-width; - border-style: $shape-border-style; - padding: spacing(0) spacing(0.75); - - &.bit-bdg-tlf { - inset: auto calc(100% - spacing(0.5)) calc(100% - spacing(0.5)) auto; - - &.bit-bdg-orp { - inset: auto calc(100% - spacing(1.5)) calc(100% - spacing(1.5)) auto; - } - } - - &.bit-bdg-tcr { - bottom: calc(100% - spacing(0.5)); - - &.bit-bdg-orp { - bottom: calc(100% - spacing(1.5)); - } - } - - &.bit-bdg-trg { - inset: auto auto calc(100% - spacing(0.5)) calc(100% - spacing(0.5)); - - &.bit-bdg-orp { - inset: auto auto calc(100% - spacing(1.5)) calc(100% - spacing(1.5)); - } - } - - &.bit-bdg-clf { - right: calc(100% - spacing(0.5)); - - &.bit-bdg-orp { - right: calc(100% - spacing(1.5)); - } - } - - &.bit-bdg-crg { - left: calc(100% - spacing(0.5)); - - &.bit-bdg-orp { - left: calc(100% - spacing(1.5)); - } - } - - &.bit-bdg-blf { - inset: calc(100% - spacing(0.5)) calc(100% - spacing(0.5)) auto auto; - - &.bit-bdg-orp { - inset: calc(100% - spacing(1.5)) calc(100% - spacing(1.5)) auto auto; - } - } - - &.bit-bdg-bcr { - top: calc(100% - spacing(0.5)); - - &.bit-bdg-orp { - top: calc(100% - spacing(1.5)); - } - } - - &.bit-bdg-brg { - inset: calc(100% - spacing(0.5)) auto auto calc(100% - spacing(0.5)); - - &.bit-bdg-orp { - inset: calc(100% - spacing(1.5)) auto auto calc(100% - spacing(1.5)); - } - } -} - -.bit-bdg-pri { - color: var(--bit-bdg-pri-clr); - background-color: var(--bit-bdg-bg-clr); - border-color: var(--bit-bdg-pri-brd-clr); - --bit-bdg-bg-clr: #{$color-primary-main}; - --bit-bdg-pri-clr: #{$color-primary-text}; - --bit-bdg-pri-brd-clr: #{$color-primary-main}; - --bit-bdg-ldg-brd-top-clr: #{$color-primary-dark}; - - .bit-dis & { - border-color: $color-border-disabled; - background-color: $color-background-disabled; - } -} - -.bit-bdg-std { - color: var(--bit-bdg-sec-clr); - background-color: $color-secondary-main; - border-color: var(--bit-bdg-sec-brd-clr); - --bit-bdg-sec-clr: #{$color-secondary-text}; - --bit-bdg-sec-brd-clr: #{$color-secondary-text}; - --bit-bdg-ldg-brd-top-clr: #{$color-primary-dark}; - - .bit-dis & { - border-color: $color-border-disabled; - } -} - -.bit-bdg-txt { - border-color: transparent; - color: var(--bit-bdg-sec-clr); - background-color: transparent; - --bit-bdg-sec-clr: #{$color-secondary-text}; - --bit-bdg-ldg-brd-top-clr: #{$color-primary-dark}; -} - -.bit-bdg-icn { - min-width: spacing(2.5); - min-height: spacing(2.5); -} - -.bit-bdg-dot { - padding: 0; - min-width: 0; - border-radius: 50%; - width: spacing(1.125); - height: spacing(1.125); -} - -.bit-bdg-inf { - --bit-bdg-bg-clr: #{$color-state-info-bg}; - --bit-bdg-ldg-brd-top-clr: #{$color-state-info}; - --bit-bdg-pri-clr: #{$color-foreground-primary}; - --bit-bdg-pri-brd-clr: #{$color-state-info-bg}; - --bit-bdg-sec-clr: #{$color-state-info}; - --bit-bdg-sec-brd-clr: #{$color-state-info}; -} - -.bit-bdg-suc { - --bit-bdg-bg-clr: #{$color-state-success-bg}; - --bit-bdg-ldg-brd-top-clr: #{$color-state-success}; - --bit-bdg-pri-clr: #{$color-foreground-primary}; - --bit-bdg-pri-brd-clr: #{$color-state-success-bg}; - --bit-bdg-sec-clr: #{$color-state-success}; - --bit-bdg-sec-brd-clr: #{$color-state-success}; -} - -.bit-bdg-wrn { - --bit-bdg-bg-clr: #{$color-state-warning-bg}; - --bit-bdg-ldg-brd-top-clr: #{$color-state-warning}; - --bit-bdg-pri-clr: #{$color-foreground-primary}; - --bit-bdg-pri-brd-clr: #{$color-state-warning-bg}; - --bit-bdg-sec-clr: #{$color-state-warning}; - --bit-bdg-sec-brd-clr: #{$color-state-warning}; -} - -.bit-bdg-swr { - --bit-bdg-bg-clr: #{$color-state-severe-warning-bg}; - --bit-bdg-ldg-brd-top-clr: #{$color-state-severe-warning}; - --bit-bdg-pri-clr: #{$color-foreground-primary}; - --bit-bdg-pri-brd-clr: #{$color-state-severe-warning-bg}; - --bit-bdg-sec-clr: #{$color-state-severe-warning}; - --bit-bdg-sec-brd-clr: #{$color-state-severe-warning}; -} - -.bit-bdg-err { - --bit-bdg-bg-clr: #{$color-state-error-bg}; - --bit-bdg-ldg-brd-top-clr: #{$color-state-error}; - --bit-bdg-pri-clr: #{$color-foreground-primary}; - --bit-bdg-pri-brd-clr: #{$color-state-error-bg}; - --bit-bdg-sec-clr: #{$color-state-error}; - --bit-bdg-sec-brd-clr: #{$color-state-error}; -} - -.bit-bdg-sm { - height: spacing(2); - min-width: spacing(2); - padding: 0 spacing(0.5); - font-size: spacing(1.25); - border-radius: spacing(1); -} - -.bit-bdg-lg { - height: spacing(3); - min-width: spacing(3); - font-size: spacing(1.75); - border-radius: spacing(1.5); - padding: spacing(0) spacing(0.75); -} diff --git a/src/BlazorUI/Bit.BlazorUI/Components/Badge/BitBadgeSize.cs b/src/BlazorUI/Bit.BlazorUI/Components/Badge/BitBadgeSize.cs deleted file mode 100644 index cbfb3743d7..0000000000 --- a/src/BlazorUI/Bit.BlazorUI/Components/Badge/BitBadgeSize.cs +++ /dev/null @@ -1,19 +0,0 @@ -namespace Bit.BlazorUI; - -public enum BitBadgeSize -{ - /// - /// The small size badge. - /// - Small, - - /// - /// The medium size badge. - /// - Medium, - - /// - /// The large size badge. - /// - Large -} diff --git a/src/BlazorUI/Bit.BlazorUI/Components/BitApearance.cs b/src/BlazorUI/Bit.BlazorUI/Components/BitApearance.cs deleted file mode 100644 index c8563f304f..0000000000 --- a/src/BlazorUI/Bit.BlazorUI/Components/BitApearance.cs +++ /dev/null @@ -1,19 +0,0 @@ -namespace Bit.BlazorUI; - -public enum BitAppearance -{ - /// - /// The appearance for primary actions that are high-emphasis. - /// - Primary, - - /// - /// The appearance for important actions that are medium-emphasis. - /// - Standard, - - /// - /// The appearance for less-pronounced actions. - /// - Text -} diff --git a/src/BlazorUI/Bit.BlazorUI/Components/BitChangeEventArgs.cs b/src/BlazorUI/Bit.BlazorUI/Components/BitChangeEventArgs.cs deleted file mode 100644 index 0cf659b299..0000000000 --- a/src/BlazorUI/Bit.BlazorUI/Components/BitChangeEventArgs.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Bit.BlazorUI; - -public class BitChangeEventArgs(T? oldValue, T? newValue) -{ - public T? OldValue { get; set; } = oldValue; - public T? NewValue { get; set; } = newValue; -} diff --git a/src/BlazorUI/Bit.BlazorUI/Components/BitColor.cs b/src/BlazorUI/Bit.BlazorUI/Components/BitColor.cs index ab41f5c6d4..0a8d9fe169 100644 --- a/src/BlazorUI/Bit.BlazorUI/Components/BitColor.cs +++ b/src/BlazorUI/Bit.BlazorUI/Components/BitColor.cs @@ -1,29 +1,47 @@ namespace Bit.BlazorUI; +/// +/// Defines the general colors available in the bit BlazorUI. +/// public enum BitColor { /// - /// Info styled component. + /// Primary general color. + /// + Primary, + + /// + /// Secondary general color. + /// + Secondary, + + /// + /// Tertiary general color. + /// + Tertiary, + + /// + /// Info general color. /// Info, /// - /// Success styled component. + /// Success general color. /// Success, /// - /// Warning styled component. + /// Warning general color. /// Warning, /// - /// Severe Warning styled component. + /// SevereWarning general color. /// SevereWarning, /// - /// Error styled component. + /// Error general color. /// Error } diff --git a/src/BlazorUI/Bit.BlazorUI/Components/BitComponentBase.cs b/src/BlazorUI/Bit.BlazorUI/Components/BitComponentBase.cs index 2b0f151530..3e2e90a0ac 100644 --- a/src/BlazorUI/Bit.BlazorUI/Components/BitComponentBase.cs +++ b/src/BlazorUI/Bit.BlazorUI/Components/BitComponentBase.cs @@ -2,25 +2,20 @@ public abstract partial class BitComponentBase : ComponentBase { - private BitDir? dir; - private string? style; - private string? @class; - private bool isEnabled = true; - private BitVisibility visibility; - private Guid _uniqueId = Guid.NewGuid(); + private string _uniqueId = BitShortId.NewId(); protected bool Rendered { get; private set; } - protected string _Id => Id ?? _uniqueId.ToString(); + protected string _Id => Id ?? _uniqueId; /// /// The readonly unique id of the root element. it will be assigned to a new Guid at component instance construction. /// - public Guid UniqueId => _uniqueId; + public string UniqueId => _uniqueId; /// /// The ElementReference of the root element. @@ -41,39 +36,17 @@ public abstract partial class BitComponentBase : ComponentBase /// /// Custom CSS class for the root element of the component. /// - [Parameter] - public string? Class - { - get => @class; - set - { - if (@class == value) return; - - @class = value; - ClassBuilder.Reset(); - } - } + [Parameter] public string? Class { get; set; } /// /// Determines the component direction. /// - [Parameter] - public BitDir? Dir - { - get => dir ?? CascadingDir; - set - { - if (dir == value) return; - - dir = value; - ClassBuilder.Reset(); - } - } + [Parameter] public BitDir? Dir { get; set; } /// /// Capture and render additional attributes in addition to the component's parameters. /// - [Parameter] public Dictionary HtmlAttributes { get; set; } = new Dictionary(); + [Parameter] public Dictionary HtmlAttributes { get; set; } = []; /// /// Custom id attribute for the root element. if null the UniqueId will be used instead. @@ -83,51 +56,18 @@ public BitDir? Dir /// /// Whether or not the component is enabled. /// - [Parameter] - public bool IsEnabled - { - get => isEnabled; - set - { - if (isEnabled == value) return; - - isEnabled = value; - ClassBuilder.Reset(); - } - } + [Parameter] public bool IsEnabled { get; set; } = true; /// /// Custom CSS style for the root element of the component. /// - [Parameter] - public string? Style - { - get => style; - set - { - if (style == value) return; - - style = value; - StyleBuilder.Reset(); - } - } + [Parameter] public string? Style { get; set; } /// /// Whether the component is visible, hidden or collapsed. /// - [Parameter] - public BitVisibility Visibility - { - get => visibility; - set - { - if (visibility == value) return; + [Parameter] public BitVisibility Visibility { get; set; } - visibility = value; - OnVisibilityChanged(value); - StyleBuilder.Reset(); - } - } public override Task SetParametersAsync(ParameterView parameters) @@ -149,12 +89,16 @@ public override Task SetParametersAsync(ParameterView parameters) break; case nameof(Class): - Class = (string?)parameter.Value; + var @class = (string?)parameter.Value; + if (Class != @class) ClassBuilder.Reset(); + Class = @class; parametersDictionary.Remove(parameter.Key); break; case nameof(Dir): - Dir = (BitDir?)parameter.Value; + var dir = (BitDir?)parameter.Value; + if (Dir != dir) ClassBuilder.Reset(); + Dir = dir; parametersDictionary.Remove(parameter.Key); break; @@ -164,17 +108,23 @@ public override Task SetParametersAsync(ParameterView parameters) break; case nameof(IsEnabled): - IsEnabled = (bool)parameter.Value; + var isEnabled = (bool)parameter.Value; + if (IsEnabled != isEnabled) ClassBuilder.Reset(); + IsEnabled = isEnabled; parametersDictionary.Remove(parameter.Key); break; case nameof(Style): - Style = (string?)parameter.Value; + var style = (string?)parameter.Value; + if (Style != style) StyleBuilder.Reset(); + Style = style; parametersDictionary.Remove(parameter.Key); break; case nameof(Visibility): - Visibility = (BitVisibility)parameter.Value; + var visibility = (BitVisibility)parameter.Value; + if (Visibility != visibility) StyleBuilder.Reset(); + Visibility = visibility; parametersDictionary.Remove(parameter.Key); break; @@ -186,13 +136,15 @@ public override Task SetParametersAsync(ParameterView parameters) return base.SetParametersAsync(ParameterView.Empty); } + + protected override void OnInitialized() { RegisterCssStyles(); StyleBuilder - .Register(() => style) - .Register(() => visibility switch + .Register(() => Style) + .Register(() => Visibility switch { BitVisibility.Hidden => "visibility:hidden", BitVisibility.Collapsed => "display:none", @@ -206,7 +158,7 @@ protected override void OnInitialized() RegisterCssClasses(); - ClassBuilder.Register(() => @class); + ClassBuilder.Register(() => Class); base.OnInitialized(); } diff --git a/src/BlazorUI/Bit.BlazorUI/Components/BitLayoutFlow.cs b/src/BlazorUI/Bit.BlazorUI/Components/BitLayoutFlow.cs deleted file mode 100644 index 0295fa6c07..0000000000 --- a/src/BlazorUI/Bit.BlazorUI/Components/BitLayoutFlow.cs +++ /dev/null @@ -1,8 +0,0 @@ - -namespace Bit.BlazorUI; - -public enum BitLayoutFlow -{ - Vertical, - Horizontal -} diff --git a/src/BlazorUI/Bit.BlazorUI/Components/BitSeverity.cs b/src/BlazorUI/Bit.BlazorUI/Components/BitSeverity.cs deleted file mode 100644 index d6cd2cc180..0000000000 --- a/src/BlazorUI/Bit.BlazorUI/Components/BitSeverity.cs +++ /dev/null @@ -1,32 +0,0 @@ -namespace Bit.BlazorUI; - -/// -/// Determines the severity of the content that controls the colors of the rendered element(s). -/// -public enum BitSeverity -{ - /// - /// Info styled severity. - /// - Info, - - /// - /// Success styled severity. - /// - Success, - - /// - /// Warning styled severity. - /// - Warning, - - /// - /// SevereWarning styled severity. - /// - SevereWarning, - - /// - /// Error styled severity. - /// - Error -} diff --git a/src/BlazorUI/Bit.BlazorUI/Components/BitSize.cs b/src/BlazorUI/Bit.BlazorUI/Components/BitSize.cs index f1b7b02366..8535f51329 100644 --- a/src/BlazorUI/Bit.BlazorUI/Components/BitSize.cs +++ b/src/BlazorUI/Bit.BlazorUI/Components/BitSize.cs @@ -1,8 +1,19 @@ namespace Bit.BlazorUI; -public struct BitSize(int width, int height) +public enum BitSize { - public int Width { get; set; } = width; - - public int Height { get; set;} = height; + /// + /// The small size. + /// + Small, + + /// + /// The medium size. + /// + Medium, + + /// + /// The large size. + /// + Large } diff --git a/src/BlazorUI/Bit.BlazorUI/Components/BitSpinnerSize.cs b/src/BlazorUI/Bit.BlazorUI/Components/BitSpinnerSize.cs deleted file mode 100644 index 737671a136..0000000000 --- a/src/BlazorUI/Bit.BlazorUI/Components/BitSpinnerSize.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace Bit.BlazorUI; - -public enum BitSpinnerSize -{ - Medium, - Large, - Small, - XSmall, -} diff --git a/src/BlazorUI/Bit.BlazorUI/Components/Buttons/BitActionButton/BitActionButton.razor b/src/BlazorUI/Bit.BlazorUI/Components/Buttons/BitActionButton/BitActionButton.razor index 736cefae48..ae6caa572f 100644 --- a/src/BlazorUI/Bit.BlazorUI/Components/Buttons/BitActionButton/BitActionButton.razor +++ b/src/BlazorUI/Bit.BlazorUI/Components/Buttons/BitActionButton/BitActionButton.razor @@ -1,58 +1,56 @@ @namespace Bit.BlazorUI @inherits BitComponentBase -@if (Href.HasValue() && IsEnabled) +@if (Href.HasNoValue()) +{ + +} +else { - - @if (IconName is not null) - { - - } - @if (ChildContent is not null) - { - - @ChildContent - - } - + @if (IconName is not null) + { + + } + @if (ChildContent is not null) + { +
+ @ChildContent +
+ }
-} -else -{ - } \ No newline at end of file diff --git a/src/BlazorUI/Bit.BlazorUI/Components/Buttons/BitActionButton/BitActionButton.razor.cs b/src/BlazorUI/Bit.BlazorUI/Components/Buttons/BitActionButton/BitActionButton.razor.cs index 477591bae4..2f3949c3e3 100644 --- a/src/BlazorUI/Bit.BlazorUI/Components/Buttons/BitActionButton/BitActionButton.razor.cs +++ b/src/BlazorUI/Bit.BlazorUI/Components/Buttons/BitActionButton/BitActionButton.razor.cs @@ -2,75 +2,96 @@ namespace Bit.BlazorUI; -public partial class BitActionButton +public partial class BitActionButton : BitComponentBase { private int? _tabIndex; private BitButtonType _buttonType; + /// /// The EditContext, which is set if the button is inside an /// [CascadingParameter] public EditContext? EditContext { get; set; } + /// - /// Whether the action button can have focus in disabled mode + /// Whether the button can have focus in disabled mode. /// - [Parameter] public bool AllowDisabledFocus { get; set; } = true; + [Parameter] public bool AllowDisabledFocus { get; set; } /// - /// Detailed description of the action button for the benefit of screen readers + /// Detailed description of the button for the benefit of screen readers. /// [Parameter] public string? AriaDescription { get; set; } /// - /// If true, add an aria-hidden attribute instructing screen readers to ignore the element + /// If true, add an aria-hidden attribute instructing screen readers to ignore the button. /// [Parameter] public bool AriaHidden { get; set; } /// - /// The type of the button + /// The type html attribute of the button element. /// [Parameter] public BitButtonType? ButtonType { get; set; } /// - /// The content of action button, It can be Any custom tag or a text + /// The content of the button. /// [Parameter] public RenderFragment? ChildContent { get; set; } /// - /// Custom CSS classes for different parts of the BitActionButton. + /// Custom CSS classes for different parts of the button. /// [Parameter] public BitActionButtonClassStyles? Classes { get; set; } /// - /// URL the link points to, if provided, button renders as an anchor + /// The general color of the button. + /// + [Parameter, ResetClassBuilder] + public BitColor? Color { get; set; } + + /// + /// The value of the href attribute of the link rendered by the button. + /// If provided, the component will be rendered as an anchor tag instead of button. /// [Parameter] public string? Href { get; set; } /// - /// The icon name for the icon shown in the action button + /// The icon name of the icon to render inside the button. /// [Parameter] public string? IconName { get; set; } /// - /// Callback for when the button clicked + /// The callback for the click event of the button. /// [Parameter] public EventCallback OnClick { get; set; } /// - /// Custom CSS styles for different parts of the BitActionButton. + /// Custom CSS styles for different parts of the button. /// [Parameter] public BitActionButtonClassStyles? Styles { get; set; } /// - /// If Href provided, specifies how to open the link + /// Reverses the positions of the icon and the content of the button. + /// + [Parameter, ResetClassBuilder] + public bool ReversedIcon { get; set; } + + /// + /// The size of the button. + /// + [Parameter, ResetClassBuilder] + public BitSize? Size { get; set; } + + /// + /// Specifies target attribute of the link when the button renders as an anchor (by providing the Href parameter). /// [Parameter] public string? Target { get; set; } /// - /// The title to show when the mouse is placed on the button + /// The tooltip to show when the mouse is placed on the button. /// [Parameter] public string? Title { get; set; } @@ -80,6 +101,29 @@ public partial class BitActionButton protected override void RegisterCssClasses() { ClassBuilder.Register(() => Classes?.Root); + + ClassBuilder.Register(() => Color switch + { + BitColor.Primary => "bit-acb-pri", + BitColor.Secondary => "bit-acb-sec", + BitColor.Tertiary => "bit-acb-ter", + BitColor.Info => "bit-acb-inf", + BitColor.Success => "bit-acb-suc", + BitColor.Warning => "bit-acb-wrn", + BitColor.SevereWarning => "bit-acb-swr", + BitColor.Error => "bit-acb-err", + _ => "bit-acb-pri" + }); + + ClassBuilder.Register(() => Size switch + { + BitSize.Small => "bit-acb-sm", + BitSize.Medium => "bit-acb-md", + BitSize.Large => "bit-acb-lg", + _ => "bit-acb-md" + }); + + ClassBuilder.Register(() => ReversedIcon ? "bit-acb-rvi" : string.Empty); } protected override void RegisterCssStyles() diff --git a/src/BlazorUI/Bit.BlazorUI/Components/Buttons/BitActionButton/BitActionButton.scss b/src/BlazorUI/Bit.BlazorUI/Components/Buttons/BitActionButton/BitActionButton.scss index 5a73c4bb80..3ca0cc3861 100644 --- a/src/BlazorUI/Bit.BlazorUI/Components/Buttons/BitActionButton/BitActionButton.scss +++ b/src/BlazorUI/Bit.BlazorUI/Components/Buttons/BitActionButton/BitActionButton.scss @@ -2,62 +2,178 @@ .bit-acb { border: none; + display: flex; cursor: pointer; + gap: spacing(1); + color: $clr-fg-pri; + align-items: center; text-decoration: none; - min-width: spacing(8); - min-height: spacing(4); box-sizing: border-box; - font-size: spacing(1.75); + justify-content: center; + font-family: $tg-font-family; + font-weight: $tg-font-weight; background-color: transparent; - padding: 0 spacing(0.5); - color: $color-foreground-primary; - border-radius: $shape-border-radius; - font-family: $typography-font-family; + padding: var(--bit-acb-padding); + font-size: var(--bit-acb-fontsize); + + &.bit-dis { + cursor: default; + color: $clr-fg-dis; + pointer-events: none; + --bit-acb-clr-ico: #{$clr-fg-dis}; + } +} + +.bit-acb-ico { + color: var(--bit-acb-clr-ico); +} + +.bit-acb-con { +} + +.bit-acb-rvi { + flex-direction: row-reverse; +} + +.bit-acb-pri { + --bit-acb-clr-ico: #{$clr-pri}; @media (hover: hover) { &:hover { - color: $color-action-hover-primary; + color: #{$clr-pri-hover}; + --bit-acb-clr-ico: #{$clr-pri-hover}; + } + } + + &:active { + color: #{$clr-pri-active}; + --bit-acb-clr-ico: #{$clr-pri-active}; + } +} - .bit-icon { - color: $color-action-hover-primary; - } +.bit-acb-sec { + --bit-acb-clr-ico: #{$clr-sec}; + + @media (hover: hover) { + &:hover { + color: #{$clr-sec-hover}; + --bit-acb-clr-ico: #{$clr-sec-hover}; } } &:active { - color: $color-action-active-primary; + color: #{$clr-sec-active}; + --bit-acb-clr-ico: #{$clr-sec-active}; + } +} + +.bit-acb-ter { + --bit-acb-clr-ico: #{$clr-ter}; - .bit-icon { - color: $color-action-active-primary; + @media (hover: hover) { + &:hover { + color: #{$clr-ter-hover}; + --bit-acb-clr-ico: #{$clr-ter-hover}; } } - &.bit-dis { - cursor: default; - pointer-events: none; - color: $color-foreground-disabled; + &:active { + color: #{$clr-ter-active}; + --bit-acb-clr-ico: #{$clr-ter-active}; + } +} - .bit-icon { - color: $color-foreground-disabled; +.bit-acb-inf { + --bit-acb-clr-ico: #{$clr-inf}; + + @media (hover: hover) { + &:hover { + color: #{$clr-inf-hover}; + --bit-acb-clr-ico: #{$clr-inf-hover}; } } + + &:active { + color: #{$clr-inf-active}; + --bit-acb-clr-ico: #{$clr-inf-active}; + } } -.bit-acb-ictn { - display: flex; - align-items: center; +.bit-acb-suc { + --bit-acb-clr-ico: #{$clr-suc}; - .bit-icon { - flex-shrink: 0; - flex-wrap: nowrap; - text-align: center; - align-items: center; - margin: 0 spacing(0.5); - justify-content: center; - color: $color-primary-main; + @media (hover: hover) { + &:hover { + color: #{$clr-suc-hover}; + --bit-acb-clr-ico: #{$clr-suc-hover}; + } + } + + &:active { + color: #{$clr-suc-active}; + --bit-acb-clr-ico: #{$clr-suc-active}; } } -.bit-acb-con { - margin: 0 spacing(0.5); +.bit-acb-wrn { + --bit-acb-clr-ico: #{$clr-wrn}; + + @media (hover: hover) { + &:hover { + color: #{$clr-wrn-hover}; + --bit-acb-clr-ico: #{$clr-wrn-hover}; + } + } + + &:active { + color: #{$clr-wrn-active}; + --bit-acb-clr-ico: #{$clr-wrn-active}; + } +} + +.bit-acb-swr { + --bit-acb-clr-ico: #{$clr-swr}; + + @media (hover: hover) { + &:hover { + color: #{$clr-swr-hover}; + --bit-acb-clr-ico: #{$clr-swr-hover}; + } + } + + &:active { + color: #{$clr-swr-active}; + --bit-acb-clr-ico: #{$clr-swr-active}; + } +} + +.bit-acb-err { + --bit-acb-clr-ico: #{$clr-err}; + + @media (hover: hover) { + &:hover { + color: #{$clr-err-hover}; + --bit-acb-clr-ico: #{$clr-err-hover}; + } + } + + &:active { + color: #{$clr-err-active}; + --bit-acb-clr-ico: #{$clr-err-active}; + } +} + +.bit-acb-sm { + --bit-acb-fontsize: #{spacing(1.25)}; + --bit-acb-padding: #{spacing(0.50)} #{spacing(1)}; +} + +.bit-acb-md { + --bit-acb-fontsize: #{spacing(1.75)}; + --bit-acb-padding: #{spacing(0.75)} #{spacing(1.5)}; +} + +.bit-acb-lg { + --bit-acb-fontsize: #{spacing(2.25)}; + --bit-acb-padding: #{spacing(1.00)} #{spacing(2.00)}; } diff --git a/src/BlazorUI/Bit.BlazorUI/Components/Buttons/BitActionButton/BitActionButtonClassStyles.cs b/src/BlazorUI/Bit.BlazorUI/Components/Buttons/BitActionButton/BitActionButtonClassStyles.cs index ca05a372b1..09b5245b51 100644 --- a/src/BlazorUI/Bit.BlazorUI/Components/Buttons/BitActionButton/BitActionButtonClassStyles.cs +++ b/src/BlazorUI/Bit.BlazorUI/Components/Buttons/BitActionButton/BitActionButtonClassStyles.cs @@ -7,11 +7,6 @@ public class BitActionButtonClassStyles ///
public string? Root { get; set; } - /// - /// Custom CSS classes/styles for the main container of the BitActionButton. - /// - public string? Container { get; set; } - /// /// Custom CSS classes/styles for the Icon of the BitActionButton. /// diff --git a/src/BlazorUI/Bit.BlazorUI/Components/Buttons/BitButton/BitButton.razor b/src/BlazorUI/Bit.BlazorUI/Components/Buttons/BitButton/BitButton.razor index 9ec7a782a9..8ee398dd36 100644 --- a/src/BlazorUI/Bit.BlazorUI/Components/Buttons/BitButton/BitButton.razor +++ b/src/BlazorUI/Bit.BlazorUI/Components/Buttons/BitButton/BitButton.razor @@ -1,48 +1,61 @@ @namespace Bit.BlazorUI @inherits BitComponentBase -@if (Href.HasValue() && IsEnabled) -{ - - @if (IconName.HasValue()) - { - - } - - @(Content ?? ChildContent) - +@{ + var hasPrimary = (PrimaryTemplate ?? ChildContent) is not null; + var hasSecondary = SecondaryText.HasValue() || SecondaryTemplate is not null; } -else + +@if (Href.HasNoValue()) { } +else +{ + + @if (IconName.HasValue()) + { + + } + @if (hasPrimary || hasSecondary) + { +
+ @if (hasPrimary) + { +
+ @(PrimaryTemplate ?? ChildContent) +
+ } + + @if (hasSecondary) + { +
+ @if (SecondaryTemplate is not null) + { + @SecondaryTemplate + } + else + { + @SecondaryText + } +
+ } +
+ } +
+} diff --git a/src/BlazorUI/Bit.BlazorUI/Components/Buttons/BitButton/BitButton.razor.cs b/src/BlazorUI/Bit.BlazorUI/Components/Buttons/BitButton/BitButton.razor.cs index 51a2f4d151..037c7677c7 100644 --- a/src/BlazorUI/Bit.BlazorUI/Components/Buttons/BitButton/BitButton.razor.cs +++ b/src/BlazorUI/Bit.BlazorUI/Components/Buttons/BitButton/BitButton.razor.cs @@ -2,172 +2,149 @@ namespace Bit.BlazorUI; -public partial class BitButton +public partial class BitButton : BitComponentBase { - private BitColor? color; - private BitButtonSize? size; - private BitButtonStyle buttonStyle = BitButtonStyle.Primary; - private BitButtonIconPosition? iconPosition = BitButtonIconPosition.Start; - private int? _tabIndex; private BitButtonType _buttonType; + /// - /// The EditContext, which is set if the button is inside an + /// The EditContext, which is set if the button is inside an . /// [CascadingParameter] public EditContext? EditContext { get; set; } + /// - /// Whether the button can have focus in disabled mode + /// Whether the button can have focus in disabled mode. /// [Parameter] public bool AllowDisabledFocus { get; set; } = true; /// - /// Detailed description of the button for the benefit of screen readers + /// Detailed description of the button for the benefit of screen readers. /// [Parameter] public string? AriaDescription { get; set; } /// - /// If true, add an aria-hidden attribute instructing screen readers to ignore the element + /// If true, add an aria-hidden attribute instructing screen readers to ignore the element. /// [Parameter] public bool AriaHidden { get; set; } /// - /// The style of button, Possible values: Primary | Standard | Text - /// - [Parameter] - public BitButtonStyle ButtonStyle - { - get => buttonStyle; - set - { - if (buttonStyle == value) return; - - buttonStyle = value; - ClassBuilder.Reset(); - } - } - - /// - /// The type of the button + /// The value of the type attribute of the button. /// [Parameter] public BitButtonType? ButtonType { get; set; } /// - /// The content of button, It can be Any custom tag or a text + /// The content of primary section of the button. /// - [Parameter] public RenderFragment? ChildContent { get; set; } + [Parameter, ResetClassBuilder] + public RenderFragment? ChildContent { get; set; } /// - /// Custom CSS classes for different parts of the BitButton. + /// Custom CSS classes for different parts of the button. /// [Parameter] public BitButtonClassStyles? Classes { get; set; } /// - /// The color of button - /// - [Parameter] - public BitColor? Color - { - get => color; - set - { - if (color == value) return; - - color = value; - ClassBuilder.Reset(); - } - } - - /// - /// Alias of ChildContent. + /// The general color of the button. /// - [Parameter] public RenderFragment? Content { get; set; } + [Parameter, ResetClassBuilder] + public BitColor? Color { get; set; } /// - /// URL the link points to, if provided, button renders as an anchor + /// The value of the href attribute of the link rendered by the button. If provided, the component will be rendered as an anchor tag instead of button. /// [Parameter] public string? Href { get; set; } /// - /// The icon to show inside the BitButton. + /// The name of the icon to render inside the button. /// [Parameter] public string? IconName { get; set; } /// - /// Specifies Icon position which can be rendered either at the start or end of the component. + /// Determines that only the icon should be rendered. /// - [Parameter] - public BitButtonIconPosition? IconPosition - { - get => iconPosition; - set - { - if (iconPosition == value) return; - - iconPosition = value; - ClassBuilder.Reset(); - } - } + [Parameter] public bool IconOnly { get; set; } /// - /// Determine whether the button is in loading mode or not. + /// Determines whether the button is in loading mode or not. /// [Parameter] public bool IsLoading { get; set; } /// - /// The loading label to show next to the spinner. + /// The loading label text to show next to the spinner icon. /// [Parameter] public string? LoadingLabel { get; set; } /// - /// The position of the loading Label in regards to the spinner animation. + /// The position of the loading Label in regards to the spinner icon. /// [Parameter] public BitLabelPosition LoadingLabelPosition { get; set; } = BitLabelPosition.End; /// - /// Used to customize the content inside the Button in the Loading state. + /// The custom template used to replace the default loading text inside the button in the loading state. /// [Parameter] public RenderFragment? LoadingTemplate { get; set; } /// - /// Callback for when the button clicked + /// The callback for the click event of the button. /// [Parameter] public EventCallback OnClick { get; set; } /// - /// The size of button, Possible values: Small | Medium | Large + /// The content of the primary section of the button (alias of the ChildContent). /// - [Parameter] - public BitButtonSize? Size - { - get => size; - set - { - if (size == value) return; + [Parameter, ResetClassBuilder] + public RenderFragment? PrimaryTemplate { get; set; } - size = value; - ClassBuilder.Reset(); - } - } + /// + /// Reverses the positions of the icon and the main content of the button. + /// + [Parameter, ResetClassBuilder] + public bool ReversedIcon { get; set; } + + /// + /// The text of the secondary section of the button. + /// + [Parameter, ResetClassBuilder] + public string? SecondaryText { get; set; } + + /// + /// The custom template for the secondary section of the button. + /// + [Parameter, ResetClassBuilder] + public RenderFragment? SecondaryTemplate { get; set; } + + /// + /// The size of the button. + /// + [Parameter, ResetClassBuilder] + public BitSize? Size { get; set; } /// - /// Custom CSS styles for different parts of the BitButton. + /// Custom CSS styles for different parts of the button. /// [Parameter] public BitButtonClassStyles? Styles { get; set; } /// - /// If Href provided, specifies how to open the link + /// Specifies target attribute of the link when the button renders as an anchor (by providing the Href parameter). /// [Parameter] public string? Target { get; set; } /// - /// The title to show when the mouse is placed on the button + /// The tooltip to show when the mouse is placed on the button. /// [Parameter] public string? Title { get; set; } + /// + /// The visual variant of the button. + /// + [Parameter, ResetClassBuilder] + public BitVariant? Variant { get; set; } + + protected override string RootElementClass => "bit-btn"; @@ -175,38 +152,42 @@ protected override void RegisterCssClasses() { ClassBuilder.Register(() => Classes?.Root); - ClassBuilder.Register(() => ButtonStyle switch + ClassBuilder.Register(() => ((PrimaryTemplate ?? ChildContent) is null && + SecondaryText.HasNoValue() && SecondaryTemplate is null) || + IconOnly + ? "bit-btn-ntx" + : string.Empty); + + ClassBuilder.Register(() => Variant switch { - BitButtonStyle.Primary => "bit-btn-pri", - BitButtonStyle.Standard => "bit-btn-std", - BitButtonStyle.Text => "bit-btn-txt", - _ => "bit-btn-pri" + BitVariant.Fill => "bit-btn-fil", + BitVariant.Outline => "bit-btn-otl", + BitVariant.Text => "bit-btn-txt", + _ => "bit-btn-fil" }); - + ClassBuilder.Register(() => Color switch { + BitColor.Primary => "bit-btn-pri", + BitColor.Secondary => "bit-btn-sec", + BitColor.Tertiary => "bit-btn-ter", BitColor.Info => "bit-btn-inf", BitColor.Success => "bit-btn-suc", BitColor.Warning => "bit-btn-wrn", BitColor.SevereWarning => "bit-btn-swr", BitColor.Error => "bit-btn-err", - _ => string.Empty + _ => "bit-btn-pri" }); - + ClassBuilder.Register(() => Size switch { - BitButtonSize.Small => "bit-btn-sm", - BitButtonSize.Medium => "bit-btn-md", - BitButtonSize.Large => "bit-btn-lg", - _ => string.Empty + BitSize.Small => "bit-btn-sm", + BitSize.Medium => "bit-btn-md", + BitSize.Large => "bit-btn-lg", + _ => "bit-btn-md" }); - ClassBuilder.Register(() => IconPosition switch - { - BitButtonIconPosition.Start => "bit-btn-srt", - BitButtonIconPosition.End => "bit-btn-end", - _ => "bit-btn-srt" - }); + ClassBuilder.Register(() => ReversedIcon ? "bit-btn-rvi" : string.Empty); } protected override void RegisterCssStyles() @@ -225,7 +206,9 @@ protected override void OnParametersSet() base.OnParametersSet(); } - + + + private string GetLabelPositionClass() => LoadingLabelPosition switch { @@ -236,11 +219,10 @@ private string GetLabelPositionClass() _ => "bit-btn-end" }; - protected virtual async Task HandleOnClick(MouseEventArgs e) + private async Task HandleOnClick(MouseEventArgs e) { - if (IsEnabled) - { - await OnClick.InvokeAsync(e); - } + if (IsEnabled is false) return; + + await OnClick.InvokeAsync(e); } } diff --git a/src/BlazorUI/Bit.BlazorUI/Components/Buttons/BitButton/BitButton.scss b/src/BlazorUI/Bit.BlazorUI/Components/Buttons/BitButton/BitButton.scss index fab78e633d..76ed9a88e4 100644 --- a/src/BlazorUI/Bit.BlazorUI/Components/Buttons/BitButton/BitButton.scss +++ b/src/BlazorUI/Bit.BlazorUI/Components/Buttons/BitButton/BitButton.scss @@ -3,27 +3,27 @@ .bit-btn { cursor: pointer; gap: spacing(0.5); - align-items: center; + text-align: start; + flex-direction: row; display: inline-flex; text-decoration: none; - min-width: spacing(8); - min-height: spacing(4); box-sizing: border-box; + align-items: flex-start; justify-content: center; - font-size: spacing(1.75); - padding: spacing(0.5) spacing(2); - border-width: $shape-border-width; - border-style: $shape-border-style; - border-radius: $shape-border-radius; - font-family: $typography-font-family; - font-weight: $typography-font-weight; - --bit-btn-lbl-size: #{spacing(1.5)}; - --bit-btn-spn-size: #{spacing(2.5)}; + color: var(--bit-btn-clr-txt); + font-family: $tg-font-family; + font-weight: $tg-font-weight; + padding: var(--bit-btn-padding); + border-width: $shp-border-width; + border-style: $shp-border-style; + border-radius: $shp-border-radius; + --bit-btn-clr-bg-dis: #{$clr-bg-dis}; + --bit-btn-clr-brd-dis: #{$clr-brd-dis}; &.bit-dis { cursor: default; + color: $clr-fg-dis; pointer-events: none; - color: $color-foreground-disabled; } @keyframes bit-btn-spinner-animation { @@ -37,189 +37,218 @@ } } -.bit-btn-pri { - color: var(--bit-btn-pri-clr); - background-color: var(--bit-btn-bg-clr); - border-color: var(--bit-btn-pri-brd-clr); - --bit-btn-bg-clr: #{$color-primary-main}; - --bit-btn-pri-clr: #{$color-primary-text}; - --bit-btn-pri-brd-clr: #{$color-primary-main}; - --bit-btn-pri-hover-bg-clr: #{$color-action-hover-primary}; - --bit-btn-pri-active-bg-clr: #{$color-action-active-primary}; - --bit-btn-ldg-brd-top-clr: #{$color-primary-dark}; +.bit-btn-tcn { + display: flex; + gap: spacing(0.625); + flex-direction: column; +} + +.bit-btn-prt { + font-size: var(--bit-btn-prt-fontsize); +} + +.bit-btn-sct { + font-size: var(--bit-btn-sct-fontsize); +} + +.bit-btn-icn { + font-size: var(--bit-btn-icn-fontsize); + margin-top: var(--bit-btn-icn-margintop); +} + +.bit-btn-rvi { + flex-direction: row-reverse; +} + +.bit-btn-spn { + border-radius: 50%; + border-width: spacing(0.2125); + width: var(--bit-btn-spn-size); + height: var(--bit-btn-spn-size); + border-color: $clr-brd-sec; + border-style: $shp-border-style; + border-top-color: var(--bit-btn-clr-spn); + animation: bit-btn-spinner-animation 1.3s linear infinite; + animation-timing-function: cubic-bezier(0.53, 0.21, 0.29, 0.67); +} + +.bit-btn-ldg { + display: flex; + gap: spacing(1); + align-items: center; + justify-content: center; + background-color: transparent; +} + +.bit-btn-lbl { + color: inherit; + text-align: center; + font-size: var(--bit-btn-lbl-fontsize); +} + + +.bit-btn-fil { + border-color: var(--bit-btn-clr); + background-color: var(--bit-btn-clr); @media (hover: hover) { &:hover { - border-color: var(--bit-btn-pri-hover-bg-clr); - background-color: var(--bit-btn-pri-hover-bg-clr); + border-color: var(--bit-btn-clr-hover); + background-color: var(--bit-btn-clr-hover); } } &:active { - border-color: var(--bit-btn-pri-active-bg-clr); - background-color: var(--bit-btn-pri-active-bg-clr); + border-color: var(--bit-btn-clr-active); + background-color: var(--bit-btn-clr-active); } &.bit-dis { - border-color: $color-border-disabled; - background-color: $color-background-disabled; + border-color: var(--bit-btn-clr-brd-dis); + background-color: var(--bit-btn-clr-bg-dis); } } -.bit-btn-std { - color: var(--bit-btn-sec-clr); - background-color: $color-secondary-main; - border-color: var(--bit-btn-sec-brd-clr); - --bit-btn-sec-clr: #{$color-secondary-text}; - --bit-btn-sec-brd-clr: #{$color-secondary-text}; - --bit-btn-sec-hover-bg-clr: #{$color-action-hover-secondary}; - --bit-btn-sec-active-bg-clr: #{$color-action-active-secondary}; - --bit-btn-ldg-brd-top-clr: #{$color-primary-dark}; +.bit-btn-otl { + color: var(--bit-btn-clr); + background-color: transparent; + border-color: var(--bit-btn-clr); @media (hover: hover) { &:hover { - background-color: var(--bit-btn-sec-hover-bg-clr); + color: var(--bit-btn-clr-txt); + background-color: var(--bit-btn-clr-hover); } } &:active { - background-color: var(--bit-btn-sec-active-bg-clr); + color: var(--bit-btn-clr-txt); + background-color: var(--bit-btn-clr-active); } &.bit-dis { - border-color: $color-border-disabled; + border-color: var(--bit-btn-clr-brd-dis); } } .bit-btn-txt { + color: var(--bit-btn-clr); border-color: transparent; - color: var(--bit-btn-sec-clr); background-color: transparent; - --bit-btn-sec-clr: #{$color-secondary-text}; - --bit-btn-sec-hover-bg-clr: #{$color-action-hover-secondary}; - --bit-btn-sec-active-bg-clr: #{$color-action-active-secondary}; - --bit-btn-ldg-brd-top-clr: #{$color-primary-dark}; @media (hover: hover) { &:hover { - background-color: var(--bit-btn-sec-hover-bg-clr); + color: var(--bit-btn-clr-txt); + background-color: var(--bit-btn-clr-hover); } } &:active { - background-color: var(--bit-btn-sec-active-bg-clr); + color: var(--bit-btn-clr-txt); + background-color: var(--bit-btn-clr-active); } } -.bit-btn-spn { - border-radius: 50%; - width: var(--bit-btn-spn-size); - height: var(--bit-btn-spn-size); - border-width: spacing(0.2125); - border-style: $shape-border-style; - border-color: $color-border-secondary; - border-top-color: var(--bit-btn-ldg-brd-top-clr); - animation: bit-btn-spinner-animation 1.3s linear infinite; - animation-timing-function: cubic-bezier(0.53, 0.21, 0.29, 0.67); + +.bit-btn-pri { + --bit-btn-clr-txt: #{$clr-pri-text}; + --bit-btn-clr: #{$clr-pri}; + --bit-btn-clr-hover: #{$clr-pri-hover}; + --bit-btn-clr-active: #{$clr-pri-active}; + --bit-btn-clr-spn: #{$clr-pri-dark}; } -.bit-btn-ldg { - display: flex; - gap: spacing(1); - align-items: center; - justify-content: center; - background-color: transparent; +.bit-btn-sec { + --bit-btn-clr-txt: #{$clr-sec-text}; + --bit-btn-clr: #{$clr-sec}; + --bit-btn-clr-hover: #{$clr-sec-hover}; + --bit-btn-clr-active: #{$clr-sec-active}; + --bit-btn-clr-spn: #{$clr-sec-dark}; } -.bit-btn-lbl { - color: inherit; - text-align: center; - font-size: var(--bit-btn-lbl-size); +.bit-btn-ter { + --bit-btn-clr-txt: #{$clr-ter-text}; + --bit-btn-clr: #{$clr-ter}; + --bit-btn-clr-hover: #{$clr-ter-hover}; + --bit-btn-clr-active: #{$clr-ter-active}; + --bit-btn-clr-spn: #{$clr-ter-dark}; } .bit-btn-inf { - --bit-btn-bg-clr: #{$color-state-info-bg}; - --bit-btn-ldg-brd-top-clr: #{$color-state-info}; - --bit-btn-pri-clr: #{$color-foreground-primary}; - --bit-btn-pri-brd-clr: #{$color-state-info-bg}; - --bit-btn-pri-hover-bg-clr: #{$color-action-hover-state-info-bg}; - --bit-btn-pri-active-bg-clr: #{$color-action-active-state-info-bg}; - --bit-btn-sec-clr: #{$color-state-info}; - --bit-btn-sec-brd-clr: #{$color-state-info}; - --bit-btn-sec-hover-bg-clr: #{$color-action-hover-state-info-bg}; - --bit-btn-sec-active-bg-clr: #{$color-action-active-state-info-bg}; + --bit-btn-clr-txt: #{$clr-inf-text}; + --bit-btn-clr: #{$clr-inf}; + --bit-btn-clr-hover: #{$clr-inf-hover}; + --bit-btn-clr-active: #{$clr-inf-active}; + --bit-btn-clr-spn: #{$clr-inf-dark}; } .bit-btn-suc { - --bit-btn-bg-clr: #{$color-state-success-bg}; - --bit-btn-ldg-brd-top-clr: #{$color-state-success}; - --bit-btn-pri-clr: #{$color-foreground-primary}; - --bit-btn-pri-brd-clr: #{$color-state-success-bg}; - --bit-btn-pri-hover-bg-clr: #{$color-action-hover-state-success-bg}; - --bit-btn-pri-active-bg-clr: #{$color-action-active-state-success-bg}; - --bit-btn-sec-clr: #{$color-state-success}; - --bit-btn-sec-brd-clr: #{$color-state-success}; - --bit-btn-sec-hover-bg-clr: #{$color-action-hover-state-success-bg}; - --bit-btn-sec-active-bg-clr: #{$color-action-active-state-success-bg}; + --bit-btn-clr-txt: #{$clr-suc-text}; + --bit-btn-clr: #{$clr-suc}; + --bit-btn-clr-hover: #{$clr-suc-hover}; + --bit-btn-clr-active: #{$clr-suc-active}; + --bit-btn-clr-spn: #{$clr-suc-dark}; } .bit-btn-wrn { - --bit-btn-bg-clr: #{$color-state-warning-bg}; - --bit-btn-ldg-brd-top-clr: #{$color-state-warning}; - --bit-btn-pri-clr: #{$color-foreground-primary}; - --bit-btn-pri-brd-clr: #{$color-state-warning-bg}; - --bit-btn-pri-hover-bg-clr: #{$color-action-hover-state-warning-bg}; - --bit-btn-pri-active-bg-clr: #{$color-action-active-state-warning-bg}; - --bit-btn-sec-clr: #{$color-state-warning}; - --bit-btn-sec-brd-clr: #{$color-state-warning}; - --bit-btn-sec-hover-bg-clr: #{$color-action-hover-state-warning-bg}; - --bit-btn-sec-active-bg-clr: #{$color-action-active-state-warning-bg}; + --bit-btn-clr-txt: #{$clr-wrn-text}; + --bit-btn-clr: #{$clr-wrn}; + --bit-btn-clr-hover: #{$clr-wrn-hover}; + --bit-btn-clr-active: #{$clr-wrn-active}; + --bit-btn-clr-spn: #{$clr-wrn-dark}; } .bit-btn-swr { - --bit-btn-bg-clr: #{$color-state-severe-warning-bg}; - --bit-btn-ldg-brd-top-clr: #{$color-state-severe-warning}; - --bit-btn-pri-clr: #{$color-foreground-primary}; - --bit-btn-pri-brd-clr: #{$color-state-severe-warning-bg}; - --bit-btn-pri-hover-bg-clr: #{$color-action-hover-state-severe-warning-bg}; - --bit-btn-pri-active-bg-clr: #{$color-action-active-state-severe-warning-bg}; - --bit-btn-sec-clr: #{$color-state-severe-warning}; - --bit-btn-sec-brd-clr: #{$color-state-severe-warning}; - --bit-btn-sec-hover-bg-clr: #{$color-action-hover-state-severe-warning-bg}; - --bit-btn-sec-active-bg-clr: #{$color-action-active-state-severe-warning-bg}; + --bit-btn-clr-txt: #{$clr-swr-text}; + --bit-btn-clr: #{$clr-swr}; + --bit-btn-clr-hover: #{$clr-swr-hover}; + --bit-btn-clr-active: #{$clr-swr-active}; + --bit-btn-clr-spn: #{$clr-swr-dark}; } .bit-btn-err { - --bit-btn-bg-clr: #{$color-state-error-bg}; - --bit-btn-ldg-brd-top-clr: #{$color-state-error}; - --bit-btn-pri-clr: #{$color-foreground-primary}; - --bit-btn-pri-brd-clr: #{$color-state-error-bg}; - --bit-btn-pri-hover-bg-clr: #{$color-action-hover-state-error-bg}; - --bit-btn-pri-active-bg-clr: #{$color-action-active-state-error-bg}; - --bit-btn-sec-clr: #{$color-state-error}; - --bit-btn-sec-brd-clr: #{$color-state-error}; - --bit-btn-sec-hover-bg-clr: #{$color-action-hover-state-error-bg}; - --bit-btn-sec-active-bg-clr: #{$color-action-active-state-error-bg}; + --bit-btn-clr-txt: #{$clr-err-text}; + --bit-btn-clr: #{$clr-err}; + --bit-btn-clr-hover: #{$clr-err-hover}; + --bit-btn-clr-active: #{$clr-err-active}; + --bit-btn-clr-spn: #{$clr-err-dark}; } + .bit-btn-sm { - min-width: spacing(6); - min-height: spacing(3); - font-size: spacing(1.5); - padding: spacing(0.3) spacing(1.5); - --bit-btn-lbl-size: #{spacing(1.75)}; --bit-btn-spn-size: #{spacing(1.75)}; + --bit-btn-lbl-fontsize: #{spacing(1.75)}; + --bit-btn-prt-fontsize: #{spacing(1.50)}; + --bit-btn-sct-fontsize: #{spacing(1.25)}; + --bit-btn-icn-fontsize: #{spacing(1.50)}; + --bit-btn-icn-margintop: #{spacing(0.2)}; + --bit-btn-pad-ntx: #{spacing(0.5)}; + --bit-btn-padding: #{spacing(0.5)} #{spacing(1.5)}; +} + +.bit-btn-md { + --bit-btn-spn-size: #{spacing(2.5)}; + --bit-btn-lbl-fontsize: #{spacing(1.50)}; + --bit-btn-prt-fontsize: #{spacing(1.75)}; + --bit-btn-sct-fontsize: #{spacing(1.50)}; + --bit-btn-icn-fontsize: #{spacing(2.00)}; + --bit-btn-icn-margintop: #{spacing(0.25)}; + --bit-btn-pad-ntx: #{spacing(0.75)}; + --bit-btn-padding: #{spacing(0.75)} #{spacing(2.0)}; } .bit-btn-lg { - min-width: spacing(10); - min-height: spacing(5); - font-size: spacing(2); - padding: spacing(0.7) spacing(2.5); - --bit-btn-lbl-size: #{spacing(1.75)}; --bit-btn-spn-size: #{spacing(3.25)}; + --bit-btn-lbl-fontsize: #{spacing(1.75)}; + --bit-btn-prt-fontsize: #{spacing(2.50)}; + --bit-btn-sct-fontsize: #{spacing(2.00)}; + --bit-btn-icn-fontsize: #{spacing(2.50)}; + --bit-btn-icn-margintop: #{spacing(0.5)}; + --bit-btn-pad-ntx: #{spacing(1.0)}; + --bit-btn-padding: #{spacing(1.0)} #{spacing(2.5)}; } + .bit-btn-top { flex-direction: column-reverse; } @@ -228,10 +257,8 @@ flex-direction: column; } -.bit-btn-srt { - flex-direction: row; -} -.bit-btn-end { - flex-direction: row-reverse; +.bit-btn-ntx { + padding: var(--bit-btn-pad-ntx); + --bit-btn-icn-margintop: 0; } diff --git a/src/BlazorUI/Bit.BlazorUI/Components/Buttons/BitButton/BitButtonClassStyles.cs b/src/BlazorUI/Bit.BlazorUI/Components/Buttons/BitButton/BitButtonClassStyles.cs index 8f48d891da..2167cebd6a 100644 --- a/src/BlazorUI/Bit.BlazorUI/Components/Buttons/BitButton/BitButtonClassStyles.cs +++ b/src/BlazorUI/Bit.BlazorUI/Components/Buttons/BitButton/BitButtonClassStyles.cs @@ -15,6 +15,21 @@ public class BitButtonClassStyles /// /// Custom CSS classes/styles for the internal container of the BitButton. /// + public string? Container { get; set; } + + /// + /// Custom CSS classes/styles for the primary section of the BitButton. + /// + public string? Primary { get; set; } + + /// + /// Custom CSS classes/styles for the secondary section of the BitButton. + /// + public string? Secondary { get; set; } + + /// + /// Custom CSS classes/styles for the loading container of the BitButton. + /// public string? LoadingContainer { get; set; } /// @@ -23,7 +38,7 @@ public class BitButtonClassStyles public string? Spinner { get; set; } /// - /// Custom CSS classes/styles for the label of the BitButton. + /// Custom CSS classes/styles for the loading label of the BitButton. /// public string? LoadingLabel { get; set; } } diff --git a/src/BlazorUI/Bit.BlazorUI/Components/Buttons/BitButtonGroup/BitButtonGroup.razor b/src/BlazorUI/Bit.BlazorUI/Components/Buttons/BitButtonGroup/BitButtonGroup.razor index 7414cc93e0..036addc7c6 100644 --- a/src/BlazorUI/Bit.BlazorUI/Components/Buttons/BitButtonGroup/BitButtonGroup.razor +++ b/src/BlazorUI/Bit.BlazorUI/Components/Buttons/BitButtonGroup/BitButtonGroup.razor @@ -22,7 +22,7 @@ disabled="@(isEnabled is false)" aria-disabled="@(isEnabled is false)" style="@GetStyle(item)" - class="bit-btg-itm@(GetItemClass(i, isEnabled)) @GetClass(item)"> + class="bit-btg-itm @GetClass(item)"> @if (template is not null) { @template(item) diff --git a/src/BlazorUI/Bit.BlazorUI/Components/Buttons/BitButtonGroup/BitButtonGroup.razor.cs b/src/BlazorUI/Bit.BlazorUI/Components/Buttons/BitButtonGroup/BitButtonGroup.razor.cs index fb9b0bf810..c71be9d72d 100644 --- a/src/BlazorUI/Bit.BlazorUI/Components/Buttons/BitButtonGroup/BitButtonGroup.razor.cs +++ b/src/BlazorUI/Bit.BlazorUI/Components/Buttons/BitButtonGroup/BitButtonGroup.razor.cs @@ -1,16 +1,10 @@ -using System.Text; -using Microsoft.AspNetCore.Components.Forms; +using Microsoft.AspNetCore.Components.Forms; namespace Bit.BlazorUI; -public partial class BitButtonGroup where TItem : class +public partial class BitButtonGroup : BitComponentBase where TItem : class { - private bool vertical; - private BitColor? color; - private BitButtonSize? size; - private BitButtonStyle buttonStyle = BitButtonStyle.Primary; - - private List _items = new(); + private List _items = []; private IEnumerable _oldItems = default!; @@ -22,69 +16,27 @@ public partial class BitButtonGroup where TItem : class - /// - /// The style of ButtonGroup, Possible values: Primary | Standard - /// - [Parameter] - public BitButtonStyle ButtonStyle - { - get => buttonStyle; - set - { - if (buttonStyle == value) return; - - buttonStyle = value; - ClassBuilder.Reset(); - } - } - /// /// The content of the BitButtonGroup, that are BitButtonGroupOption components. /// [Parameter] public RenderFragment? ChildContent { get; set; } /// - /// The color of ButtonGroup. + /// Defines the general colors available in the bit BlazorUI. /// - [Parameter] - public BitColor? Color - { - get => color; - set - { - if (color == value) return; - - color = value; - ClassBuilder.Reset(); - } - } + [Parameter, ResetClassBuilder] + public BitColor? Color { get; set; } /// /// List of Item, each of which can be a button with different action in the ButtonGroup. /// - [Parameter] public IEnumerable Items { get; set; } = new List(); + [Parameter] public IEnumerable Items { get; set; } = []; /// /// The content inside the item can be customized. /// [Parameter] public RenderFragment? ItemTemplate { get; set; } - /// - /// Defines whether to render ButtonGroup children vertically. - /// - [Parameter] - public bool Vertical - { - get => vertical; - set - { - if (vertical == value) return; - - vertical = value; - StyleBuilder.Reset(); - } - } - /// /// Names and selectors of the custom input type properties. /// @@ -103,18 +55,21 @@ public bool Vertical /// /// The size of ButtonGroup, Possible values: Small | Medium | Large /// - [Parameter] - public BitButtonSize? Size - { - get => size; - set - { - if (size == value) return; + [Parameter, ResetClassBuilder] + public BitSize? Size { get; set; } + + /// + /// The visual variant of the button group. + /// + [Parameter, ResetClassBuilder] + public BitVariant? Variant { get; set; } + + /// + /// Defines whether to render ButtonGroup children vertically. + /// + [Parameter, ResetClassBuilder] + public bool Vertical { get; set; } - size = value; - ClassBuilder.Reset(); - } - } internal void RegisterOption(BitButtonGroupOption option) @@ -133,34 +88,38 @@ internal void UnregisterOption(BitButtonGroupOption option) } + protected override string RootElementClass => "bit-btg"; protected override void RegisterCssClasses() { - ClassBuilder.Register(() => ButtonStyle switch + ClassBuilder.Register(() => Variant switch { - BitButtonStyle.Primary => "bit-btg-pri", - BitButtonStyle.Standard => "bit-btg-std", - BitButtonStyle.Text => "bit-btg-txt", - _ => "bit-btg-pri" + BitVariant.Fill => "bit-btg-fil", + BitVariant.Outline => "bit-btg-otl", + BitVariant.Text => "bit-btg-txt", + _ => "bit-btg-fil" }); ClassBuilder.Register(() => Color switch { + BitColor.Primary => "bit-btg-pri", + BitColor.Secondary => "bit-btg-sec", + BitColor.Tertiary => "bit-btg-ter", BitColor.Info => "bit-btg-inf", BitColor.Success => "bit-btg-suc", - BitColor.Warning => "bit-btg-war", - BitColor.SevereWarning => "bit-btg-swa", + BitColor.Warning => "bit-btg-wrn", + BitColor.SevereWarning => "bit-btg-swr", BitColor.Error => "bit-btg-err", - _ => string.Empty + _ => "bit-btg-pri" }); ClassBuilder.Register(() => Size switch { - BitButtonSize.Small => "bit-btg-sm", - BitButtonSize.Medium => "bit-btg-md", - BitButtonSize.Large => "bit-btg-lg", - _ => string.Empty + BitSize.Small => "bit-btg-sm", + BitSize.Medium => "bit-btg-md", + BitSize.Large => "bit-btg-lg", + _ => "bit-btg-md" }); ClassBuilder.Register(() => Vertical ? "bit-btg-vrt" : ""); @@ -177,55 +136,7 @@ protected override Task OnParametersSetAsync() return base.OnParametersSetAsync(); } - - - private string? GetItemClass(int index, bool isEnabled) - { - StringBuilder className = new StringBuilder(); - className.Append(ButtonStyle switch - { - BitButtonStyle.Primary => " bit-btg-ipr", - BitButtonStyle.Standard => " bit-btg-ist", - BitButtonStyle.Text => " bit-btg-itx", - _ => " bit-btg-ipr" - }); - - className.Append(Color switch - { - BitColor.Info => " bit-btg-iin", - BitColor.Success => " bit-btg-isu", - BitColor.Warning => " bit-btg-iwa", - BitColor.SevereWarning => " bit-btg-isw", - BitColor.Error => " bit-btg-ier", - _ => string.Empty - }); - - className.Append(Size switch - { - BitButtonSize.Small => " bit-btg-ism", - BitButtonSize.Medium => " bit-btg-imd", - BitButtonSize.Large => " bit-btg-ilg", - _ => string.Empty - }); - - if (index == 0) - { - className.Append(" bit-btg-ift"); - } - - if (index == (_items.Count - 1)) - { - className.Append(" bit-btg-ilt"); - } - - if(isEnabled is false) - { - className.Append(" bit-btg-ids"); - } - - return className.ToString(); - } private async Task HandleOnItemClick(TItem item) { @@ -256,7 +167,6 @@ private async Task HandleOnItemClick(TItem item) } } - private string? GetClass(TItem? item) { if (item is null) return null; diff --git a/src/BlazorUI/Bit.BlazorUI/Components/Buttons/BitButtonGroup/BitButtonGroup.scss b/src/BlazorUI/Bit.BlazorUI/Components/Buttons/BitButtonGroup/BitButtonGroup.scss index 70ece987f6..f1daf7c6fc 100644 --- a/src/BlazorUI/Bit.BlazorUI/Components/Buttons/BitButtonGroup/BitButtonGroup.scss +++ b/src/BlazorUI/Bit.BlazorUI/Components/Buttons/BitButtonGroup/BitButtonGroup.scss @@ -5,37 +5,22 @@ flex-direction: row; display: inline-flex; max-width: fit-content; - border-width: $shape-border-width; - border-style: $shape-border-style; - border-radius: $shape-border-radius; - - &.bit-dis { - border-color: $color-border-disabled; - - .bit-btg-itm { - border-color: $color-border-disabled; - } + border-width: $shp-border-width; + border-style: $shp-border-style; + border-radius: $shp-border-radius; + --bit-btg-itm-brd-wid: #{$shp-border-width}; + --bit-btg-itm-brd-wid-ver: 0; + + &.bit-dis, &.bit-dis * { + cursor: default; + color: $clr-fg-dis; + pointer-events: none; } -} - -.bit-btg-pri { - border-color: var(--bit-btg-pri-brd-clr); - --bit-btg-pri-brd-clr: #{$color-primary-main}; - --bit-btg-clr-bg-dis: #{$color-background-disabled}; -} - -.bit-btg-std { - border-color: var(--bit-btg-sec-brd-clr); - --bit-btg-sec-brd-clr: #{$color-secondary-text}; - --bit-btg-clr-bg-dis: #{$color-background-primary}; -} - -.bit-btg-txt { - border-color: transparent; - --bit-btg-clr-bg-dis: transparent; &.bit-dis { - border-color: transparent; + border-color: $clr-brd-dis; + --bit-btg-itm-clr-bg: #{$clr-bg-dis}; + --bit-btg-itm-clr-brd: #{$clr-brd-dis}; } } @@ -43,207 +28,230 @@ display: flex; gap: spacing(1); cursor: pointer; + border-width: 0; text-align: left; align-items: center; line-height: inherit; text-decoration: none; box-sizing: border-box; - font-size: spacing(1.75); - border-style: $shape-border-style; - border-width: $shape-border-width; - padding: spacing(0.7) spacing(2); - font-family: $typography-font-family; - font-weight: $typography-font-weight; - border-block-end-width: 0; - border-block-start-width: 0; - border-inline-start-width: 0; -} - -.bit-btg-ilt { - border-inline-end-width: 0; -} - -.bit-btg-ipr { - color: var(--bit-btg-itm-pri-clr); - background-color: var(--bit-btg-itm-bg-clr); - border-color: var(--bit-btg-itm-pri-brd-clr); - --bit-btg-itm-bg-clr: #{$color-primary-main}; - --bit-btg-itm-pri-clr: #{$color-primary-text}; - --bit-btg-itm-pri-brd-clr: #{$color-primary-dark}; - --bit-btg-itm-pri-hover-bg-clr: #{$color-action-hover-primary}; - --bit-btg-itm-pri-active-bg-clr: #{$color-action-active-primary}; + font-family: $tg-font-family; + font-weight: $tg-font-weight; + border-style: $shp-border-style; + color: var(--bit-btg-itm-clr); + padding: var(--bit-btg-itm-padding); + font-size: var(--bit-btg-itm-fontsize); + border-color: var(--bit-btg-itm-clr-brd); + background-color: var(--bit-btg-itm-clr-bg); + border-inline-end-width: var(--bit-btg-itm-brd-wid); + border-block-end-width: var(--bit-btg-itm-brd-wid-ver); @media (hover: hover) { &:hover { - background-color: var(--bit-btg-itm-pri-hover-bg-clr); + color: var(--bit-btg-itm-clr-hover); + background-color: var(--bit-btg-itm-clr-bg-hover); } } &:active { - background-color: var(--bit-btg-itm-pri-active-bg-clr); + background-color: var(--bit-btg-itm-clr-bg-active); + } + + &[disabled] { + cursor: default; + color: $clr-fg-dis; + pointer-events: none; + background-color: var(--bit-btg-itm-clr-bg-dis); + } + + &:last-child { + border-block-end-width: 0; + border-inline-end-width: 0; } } -.bit-btg-ist { - color: var(--bit-btg-itm-sec-clr); - background-color: $color-secondary-main; - border-color: var(--bit-btg-itm-sec-brd-clr); - --bit-btg-itm-sec-clr: #{$color-secondary-text}; - --bit-btg-itm-sec-brd-clr: #{$color-secondary-text}; - --bit-btg-itm-sec-hover-bg-clr: #{$color-action-hover-secondary}; - --bit-btg-itm-sec-active-bg-clr: #{$color-action-active-secondary}; +.bit-btg-btx { + white-space: nowrap; + text-overflow: ellipsis; +} + +.bit-btg-fil { + border-color: var(--bit-btg-clr-brd); + --bit-btg-itm-clr: var(--bit-btg-clr); + --bit-btg-itm-clr-bg: var(--bit-btg-clr-bg); + --bit-btg-itm-clr-brd: var(--bit-btg-clr-brd2); + --bit-btg-itm-clr-hover: var(--bit-btg-clr-hover); + --bit-btg-itm-clr-bg-hover: var(--bit-btg-clr-bg-hover); + --bit-btg-itm-clr-bg-active: var(--bit-btg-clr-bg-active); + --bit-btg-itm-clr-bg-dis: var(--bit-btg-clr-bg-dis); @media (hover: hover) { &:hover { - background-color: var(--bit-btg-itm-sec-hover-bg-clr); + border-color: var(--bit-btg-clr-brd-hover); } } &:active { - background-color: var(--bit-btg-itm-sec-active-bg-clr); + border-color: var(--bit-btg-clr-brd-active); } } -.bit-btg-itx { - color: var(--bit-btg-itm-sec-clr); - background-color: transparent; - border-color: var(--bit-btg-itm-sec-brd-clr); - --bit-btg-itm-sec-clr: #{$color-secondary-text}; - --bit-btg-itm-sec-brd-clr: #{$color-secondary-text}; - --bit-btg-itm-sec-hover-bg-clr: #{$color-action-hover-secondary}; - --bit-btg-itm-sec-active-bg-clr: #{$color-action-active-secondary}; +.bit-btg-otl { + border-color: var(--bit-btg-clr-brd); + --bit-btg-itm-clr: var(--bit-btg-clr-bg); + --bit-btg-itm-clr-bg: transparent; + --bit-btg-itm-clr-brd: var(--bit-btg-clr-brd2); + --bit-btg-itm-clr-hover: var(--bit-btg-clr-hover); + --bit-btg-itm-clr-bg-hover: var(--bit-btg-clr-bg-hover); + --bit-btg-itm-clr-bg-active: var(--bit-btg-clr-bg-active); + --bit-btg-itm-clr-bg-dis: transprent; @media (hover: hover) { &:hover { - background-color: var(--bit-btg-itm-sec-hover-bg-clr); + border-color: var(--bit-btg-clr-brd-hover); } } &:active { - background-color: var(--bit-btg-itm-sec-active-bg-clr); + border-color: var(--bit-btg-clr-brd-active); } } -.bit-btg-inf { - --bit-btg-pri-brd-clr: #{$color-state-info-bg}; - --bit-btg-sec-brd-clr: #{$color-state-info}; -} - -.bit-btg-iin { - --bit-btg-itm-bg-clr: #{$color-state-info-bg}; - --bit-btg-itm-pri-clr: #{$color-foreground-primary}; - --bit-btg-itm-pri-brd-clr: #{$color-state-info-brd}; - --bit-btg-itm-pri-hover-bg-clr: #{$color-action-hover-state-info-bg}; - --bit-btg-itm-pri-active-bg-clr: #{$color-action-active-state-info-bg}; - --bit-btg-itm-sec-clr: #{$color-state-info}; - --bit-btg-itm-sec-brd-clr: #{$color-state-info}; - --bit-btg-itm-sec-hover-bg-clr: #{$color-action-hover-state-info-bg}; - --bit-btg-itm-sec-active-bg-clr: #{$color-action-active-state-info-bg}; -} +.bit-btg-txt { + border-color: transparent; + --bit-btg-itm-clr: var(--bit-btg-clr-bg); + --bit-btg-itm-clr-bg: transparent; + --bit-btg-itm-clr-brd: var(--bit-btg-clr-brd2); + --bit-btg-itm-clr-hover: var(--bit-btg-clr-hover); + --bit-btg-itm-clr-bg-hover: var(--bit-btg-clr-bg-hover); + --bit-btg-itm-clr-bg-active: var(--bit-btg-clr-bg-active); + --bit-btg-itm-clr-bg-dis: transprent; -.bit-btg-suc { - --bit-btg-pri-brd-clr: #{$color-state-success-bg}; - --bit-btg-sec-brd-clr: #{$color-state-success}; + &.bit-dis { + border-color: transparent; + } } -.bit-btg-isu { - --bit-btg-itm-bg-clr: #{$color-state-success-bg}; - --bit-btg-itm-pri-clr: #{$color-foreground-primary}; - --bit-btg-itm-pri-brd-clr: #{$color-state-success-brd}; - --bit-btg-itm-pri-hover-bg-clr: #{$color-action-hover-state-success-bg}; - --bit-btg-itm-pri-active-bg-clr: #{$color-action-active-state-success-bg}; - --bit-btg-itm-sec-clr: #{$color-state-success}; - --bit-btg-itm-sec-brd-clr: #{$color-state-success}; - --bit-btg-itm-sec-hover-bg-clr: #{$color-action-hover-state-success-bg}; - --bit-btg-itm-sec-active-bg-clr: #{$color-action-active-state-success-bg}; +.bit-btg-pri { + --bit-btg-clr-brd: #{$clr-pri}; + --bit-btg-clr: #{$clr-pri-text}; + --bit-btg-clr-bg: #{$clr-pri}; + --bit-btg-clr-brd2: #{$clr-pri-dark}; + --bit-btg-clr-hover: #{$clr-pri-text}; + --bit-btg-clr-brd-hover: #{$clr-pri-hover}; + --bit-btg-clr-brd-active: #{$clr-pri-active}; + --bit-btg-clr-bg-hover: #{$clr-pri-hover}; + --bit-btg-clr-bg-active: #{$clr-pri-active}; + --bit-btg-clr-bg-dis: #{$clr-bg-dis}; } -.bit-btg-war { - --bit-btg-pri-brd-clr: #{$color-state-warning-bg}; - --bit-btg-sec-brd-clr: #{$color-state-warning}; +.bit-btg-sec { + --bit-btg-clr-brd: #{$clr-sec}; + --bit-btg-clr: #{$clr-sec-text}; + --bit-btg-clr-bg: #{$clr-sec}; + --bit-btg-clr-brd2: #{$clr-sec-dark}; + --bit-btg-clr-hover: #{$clr-sec-text}; + --bit-btg-clr-brd-hover: #{$clr-sec-hover}; + --bit-btg-clr-brd-active: #{$clr-sec-active}; + --bit-btg-clr-bg-hover: #{$clr-sec-hover}; + --bit-btg-clr-bg-active: #{$clr-sec-active}; + --bit-btg-clr-bg-dis: #{$clr-bg-dis}; } -.bit-btg-iwa { - --bit-btg-itm-bg-clr: #{$color-state-warning-bg}; - --bit-btg-itm-pri-clr: #{$color-foreground-primary}; - --bit-btg-itm-pri-brd-clr: #{$color-state-warning-brd}; - --bit-btg-itm-pri-hover-bg-clr: #{$color-action-hover-state-warning-bg}; - --bit-btg-itm-pri-active-bg-clr: #{$color-action-active-state-warning-bg}; - --bit-btg-itm-sec-clr: #{$color-state-warning}; - --bit-btg-itm-sec-brd-clr: #{$color-state-warning}; - --bit-btg-itm-sec-hover-bg-clr: #{$color-action-hover-state-warning-bg}; - --bit-btg-itm-sec-active-bg-clr: #{$color-action-active-state-warning-bg}; +.bit-btg-ter { + --bit-btg-clr-brd: #{$clr-ter}; + --bit-btg-clr: #{$clr-ter-text}; + --bit-btg-clr-bg: #{$clr-ter}; + --bit-btg-clr-brd2: #{$clr-ter-dark}; + --bit-btg-clr-hover: #{$clr-ter-text}; + --bit-btg-clr-brd-hover: #{$clr-ter-hover}; + --bit-btg-clr-brd-active: #{$clr-ter-active}; + --bit-btg-clr-bg-hover: #{$clr-ter-hover}; + --bit-btg-clr-bg-active: #{$clr-ter-active}; + --bit-btg-clr-bg-dis: #{$clr-bg-dis}; } -.bit-btg-swa { - --bit-btg-pri-brd-clr: #{$color-state-severe-warning-bg}; - --bit-btg-sec-brd-clr: #{$color-state-severe-warning}; +.bit-btg-inf { + --bit-btg-clr-brd: #{$clr-inf}; + --bit-btg-clr: #{$clr-inf-text}; + --bit-btg-clr-bg: #{$clr-inf}; + --bit-btg-clr-brd2: #{$clr-inf-dark}; + --bit-btg-clr-hover: #{$clr-inf-text}; + --bit-btg-clr-brd-hover: #{$clr-inf-hover}; + --bit-btg-clr-brd-active: #{$clr-inf-active}; + --bit-btg-clr-bg-hover: #{$clr-inf-hover}; + --bit-btg-clr-bg-active: #{$clr-inf-active}; + --bit-btg-clr-bg-dis: #{$clr-bg-dis}; } -.bit-btg-isw { - --bit-btg-itm-bg-clr: #{$color-state-severe-warning-bg}; - --bit-btg-itm-pri-clr: #{$color-foreground-primary}; - --bit-btg-itm-pri-brd-clr: #{$color-state-severe-warning-brd}; - --bit-btg-itm-pri-hover-bg-clr: #{$color-action-hover-state-severe-warning-bg}; - --bit-btg-itm-pri-active-bg-clr: #{$color-action-active-state-severe-warning-bg}; - --bit-btg-itm-sec-clr: #{$color-state-severe-warning}; - --bit-btg-itm-sec-brd-clr: #{$color-state-severe-warning}; - --bit-btg-itm-sec-hover-bg-clr: #{$color-action-hover-state-severe-warning-bg}; - --bit-btg-itm-sec-active-bg-clr: #{$color-action-active-state-severe-warning-bg}; +.bit-btg-suc { + --bit-btg-clr-brd: #{$clr-suc}; + --bit-btg-clr: #{$clr-suc-text}; + --bit-btg-clr-bg: #{$clr-suc}; + --bit-btg-clr-brd2: #{$clr-suc-dark}; + --bit-btg-clr-hover: #{$clr-suc-text}; + --bit-btg-clr-brd-hover: #{$clr-suc-hover}; + --bit-btg-clr-brd-active: #{$clr-suc-active}; + --bit-btg-clr-bg-hover: #{$clr-suc-hover}; + --bit-btg-clr-bg-active: #{$clr-suc-active}; + --bit-btg-clr-bg-dis: #{$clr-bg-dis}; } -.bit-btg-err { - --bit-btg-pri-brd-clr: #{$color-state-error-bg}; - --bit-btg-sec-brd-clr: #{$color-state-error}; +.bit-btg-wrn { + --bit-btg-clr-brd: #{$clr-wrn}; + --bit-btg-clr: #{$clr-wrn-text}; + --bit-btg-clr-bg: #{$clr-wrn}; + --bit-btg-clr-brd2: #{$clr-wrn-dark}; + --bit-btg-clr-hover: #{$clr-wrn-text}; + --bit-btg-clr-brd-hover: #{$clr-wrn-hover}; + --bit-btg-clr-brd-active: #{$clr-wrn-active}; + --bit-btg-clr-bg-hover: #{$clr-wrn-hover}; + --bit-btg-clr-bg-active: #{$clr-wrn-active}; + --bit-btg-clr-bg-dis: #{$clr-bg-dis}; } -.bit-btg-ier { - --bit-btg-itm-bg-clr: #{$color-state-error-bg}; - --bit-btg-itm-pri-clr: #{$color-foreground-primary}; - --bit-btg-itm-pri-brd-clr: #{$color-state-error-brd}; - --bit-btg-itm-pri-hover-bg-clr: #{$color-action-hover-state-error-bg}; - --bit-btg-itm-pri-active-bg-clr: #{$color-action-active-state-error-bg}; - --bit-btg-itm-sec-clr: #{$color-state-error}; - --bit-btg-itm-sec-brd-clr: #{$color-state-error}; - --bit-btg-itm-sec-hover-bg-clr: #{$color-action-hover-state-error-bg}; - --bit-btg-itm-sec-active-bg-clr: #{$color-action-active-state-error-bg}; +.bit-btg-swr { + --bit-btg-clr-brd: #{$clr-swr}; + --bit-btg-clr: #{$clr-swr-text}; + --bit-btg-clr-bg: #{$clr-swr}; + --bit-btg-clr-brd2: #{$clr-swr-dark}; + --bit-btg-clr-hover: #{$clr-swr-text}; + --bit-btg-clr-brd-hover: #{$clr-swr-hover}; + --bit-btg-clr-brd-active: #{$clr-swr-active}; + --bit-btg-clr-bg-hover: #{$clr-swr-hover}; + --bit-btg-clr-bg-active: #{$clr-swr-active}; + --bit-btg-clr-bg-dis: #{$clr-bg-dis}; } -.bit-btg-vrt { - flex-direction: column; - - .bit-btg-itm { - border-width: $shape-border-width; - border-block-start-width: 0; - border-inline-start-width: 0; - border-inline-end-width: 0; - } - - .bit-btg-ilt { - border-block-end-width: 0; - } +.bit-btg-err { + --bit-btg-clr-brd: #{$clr-err}; + --bit-btg-clr: #{$clr-err-text}; + --bit-btg-clr-bg: #{$clr-err}; + --bit-btg-clr-brd2: #{$clr-err-dark}; + --bit-btg-clr-hover: #{$clr-err-text}; + --bit-btg-clr-brd-hover: #{$clr-err-hover}; + --bit-btg-clr-brd-active: #{$clr-err-active}; + --bit-btg-clr-bg-hover: #{$clr-err-hover}; + --bit-btg-clr-bg-active: #{$clr-err-active}; + --bit-btg-clr-bg-dis: #{$clr-bg-dis}; } -.bit-btg-ism { - font-size: spacing(1.5); - padding: spacing(0.5) spacing(1.5); +.bit-btg-sm { + --bit-btg-itm-fontsize: #{spacing(1.5)}; + --bit-btg-itm-padding: #{spacing(0.5)} #{spacing(1.5)}; } -.bit-btg-ilg { - font-size: spacing(2); - padding: spacing(0.9) spacing(2.5); +.bit-btg-md { + --bit-btg-itm-fontsize: #{spacing(1.75)}; + --bit-btg-itm-padding: #{spacing(0.7)} #{spacing(2.0)}; } -.bit-btg-btx { - white-space: nowrap; - text-overflow: ellipsis; +.bit-btg-lg { + --bit-btg-itm-fontsize: #{spacing(2.0)}; + --bit-btg-itm-padding: #{spacing(0.9)} #{spacing(2.5)}; } -.bit-btg-ids { - cursor: default; - user-select: none; - pointer-events: none; - -webkit-user-select: none; - color: $color-foreground-disabled; - background-color: var(--bit-btg-clr-bg-dis); +.bit-btg-vrt { + flex-direction: column; + --bit-btg-itm-brd-wid: 0; + --bit-btg-itm-brd-wid-ver: #{$shp-border-width}; } diff --git a/src/BlazorUI/Bit.BlazorUI/Components/Buttons/BitButtonIconPosition.cs b/src/BlazorUI/Bit.BlazorUI/Components/Buttons/BitButtonIconPosition.cs deleted file mode 100644 index 9e391c9b8c..0000000000 --- a/src/BlazorUI/Bit.BlazorUI/Components/Buttons/BitButtonIconPosition.cs +++ /dev/null @@ -1,14 +0,0 @@ -namespace Bit.BlazorUI; - -public enum BitButtonIconPosition -{ - /// - /// Renders the icon at the start of component. - /// - Start, - - /// - /// Renders the icon at the end of component. - /// - End -} diff --git a/src/BlazorUI/Bit.BlazorUI/Components/Buttons/BitButtonSize.cs b/src/BlazorUI/Bit.BlazorUI/Components/Buttons/BitButtonSize.cs deleted file mode 100644 index 7d7d09ff4d..0000000000 --- a/src/BlazorUI/Bit.BlazorUI/Components/Buttons/BitButtonSize.cs +++ /dev/null @@ -1,19 +0,0 @@ -namespace Bit.BlazorUI; - -public enum BitButtonSize -{ - /// - /// The small size button - /// - Small, - - /// - /// The medium size button - /// - Medium, - - /// - /// The large size button - /// - Large -} diff --git a/src/BlazorUI/Bit.BlazorUI/Components/Buttons/BitButtonStyle.cs b/src/BlazorUI/Bit.BlazorUI/Components/Buttons/BitButtonStyle.cs deleted file mode 100644 index f926b047b9..0000000000 --- a/src/BlazorUI/Bit.BlazorUI/Components/Buttons/BitButtonStyle.cs +++ /dev/null @@ -1,19 +0,0 @@ -namespace Bit.BlazorUI; - -public enum BitButtonStyle -{ - /// - /// The button for primary actions that are high-emphasis - /// - Primary, - - /// - /// The button for important actions that are medium-emphasis - /// - Standard, - - /// - /// The button for less-pronounced actions - /// - Text -} diff --git a/src/BlazorUI/Bit.BlazorUI/Components/Buttons/BitCompoundButton/BitCompoundButton.razor b/src/BlazorUI/Bit.BlazorUI/Components/Buttons/BitCompoundButton/BitCompoundButton.razor deleted file mode 100644 index 89ee226ace..0000000000 --- a/src/BlazorUI/Bit.BlazorUI/Components/Buttons/BitCompoundButton/BitCompoundButton.razor +++ /dev/null @@ -1,68 +0,0 @@ -@namespace Bit.BlazorUI -@inherits BitComponentBase - -@if (Href.HasValue() && IsEnabled) -{ - - @if (IconName.HasValue()) - { - - } - - - @(PrimaryTemplate ?? ChildContent) - - @if (SecondaryTemplate is not null) - { - @SecondaryTemplate - } - else - { - @SecondaryText - } - - -} -else -{ - -} \ No newline at end of file diff --git a/src/BlazorUI/Bit.BlazorUI/Components/Buttons/BitCompoundButton/BitCompoundButton.razor.cs b/src/BlazorUI/Bit.BlazorUI/Components/Buttons/BitCompoundButton/BitCompoundButton.razor.cs deleted file mode 100644 index 9c575bdbcd..0000000000 --- a/src/BlazorUI/Bit.BlazorUI/Components/Buttons/BitCompoundButton/BitCompoundButton.razor.cs +++ /dev/null @@ -1,225 +0,0 @@ -using Microsoft.AspNetCore.Components.Forms; - -namespace Bit.BlazorUI; - -public partial class BitCompoundButton -{ - private BitColor? color; - private BitButtonSize? size; - private BitButtonStyle buttonStyle = BitButtonStyle.Primary; - private BitButtonIconPosition? iconPosition = BitButtonIconPosition.Start; - - private int? _tabIndex; - private BitButtonType _buttonType; - - - /// - /// The EditContext, which is set if the button is inside an - /// - [CascadingParameter] public EditContext? EditContext { get; set; } - - - /// - /// Whether the BitCompoundButton can have focus in disabled mode. - /// - [Parameter] public bool AllowDisabledFocus { get; set; } = true; - - /// - /// Detailed description of the BitCompoundButton for the benefit of screen readers. - /// - [Parameter] public string? AriaDescription { get; set; } - - /// - /// If true, adds an aria-hidden attribute instructing screen readers to ignore the element. - /// - [Parameter] public bool AriaHidden { get; set; } - - /// - /// The style of the BitCompoundButton. - /// - [Parameter] - public BitButtonStyle ButtonStyle - { - get => buttonStyle; - set - { - buttonStyle = value; - ClassBuilder.Reset(); - } - } - - /// - /// The value of the type attribute of the button rendered by the BitCompoundButton. - /// - [Parameter] public BitButtonType? ButtonType { get; set; } - - /// - /// The content of primary section of the BitCompoundButton. - /// - [Parameter] public RenderFragment? ChildContent { get; set; } - - /// - /// Custom CSS classes for different parts of the BitCompoundButton. - /// - [Parameter] public BitCompoundButtonClassStyles? Classes { get; set; } - - /// - /// The color of button - /// - [Parameter] - public BitColor? Color - { - get => color; - set - { - if (color == value) return; - - color = value; - ClassBuilder.Reset(); - } - } - - /// - /// The value of the href attribute of the link rendered by the BitCompoundButton. If provided, the component will be rendered as an anchor. - /// - [Parameter] public string? Href { get; set; } - - /// - /// The icon to show inside the BitCompoundButton. - /// - [Parameter] public string? IconName { get; set; } - - /// - /// Specifies Icon position which can be rendered either at the start or end of the component. - /// - [Parameter] - public BitButtonIconPosition? IconPosition - { - get => iconPosition; - set - { - if (iconPosition == value) return; - - iconPosition = value; - ClassBuilder.Reset(); - } - } - - /// - /// The callback for the click event of the BitCompoundButton. - /// - [Parameter] public EventCallback OnClick { get; set; } - - /// - /// The content of primary section of the BitCompoundButton (alias of the ChildContent). - /// - [Parameter] public RenderFragment? PrimaryTemplate { get; set; } - - /// - /// The text of the secondary section of the BitCompoundButton. - /// - [Parameter] public string? SecondaryText { get; set; } - - /// - /// The RenderFragment for the secondary section of the BitCompoundButton. - /// - [Parameter] public RenderFragment? SecondaryTemplate { get; set; } - - /// - /// The size of button, Possible values: Small | Medium | Large - /// - [Parameter] - public BitButtonSize? Size - { - get => size; - set - { - if (size == value) return; - - size = value; - ClassBuilder.Reset(); - } - } - - /// - /// Custom CSS styles for different parts of the BitCompoundButton. - /// - [Parameter] public BitCompoundButtonClassStyles? Styles { get; set; } - - /// - /// Specifies target attribute of the link when the BitComponentButton renders as an anchor. - /// - [Parameter] public string? Target { get; set; } - - /// - /// The tooltip to show when the mouse is placed on the button. - /// - [Parameter] public string? Title { get; set; } - - - protected override string RootElementClass => "bit-cmb"; - - protected override void RegisterCssClasses() - { - ClassBuilder.Register(() => Classes?.Root); - - ClassBuilder.Register(() => ButtonStyle switch - { - BitButtonStyle.Primary => "bit-cmb-pri", - BitButtonStyle.Standard => "bit-cmb-std", - BitButtonStyle.Text => "bit-cmb-txt", - _ => "bit-cmb-pri" - }); - - ClassBuilder.Register(() => Color switch - { - BitColor.Info => "bit-cmb-inf", - BitColor.Success => "bit-cmb-suc", - BitColor.Warning => "bit-cmb-wrn", - BitColor.SevereWarning => "bit-cmb-swr", - BitColor.Error => "bit-cmb-err", - _ => string.Empty - }); - - ClassBuilder.Register(() => Size switch - { - BitButtonSize.Small => "bit-cmb-sm", - BitButtonSize.Medium => "bit-cmb-md", - BitButtonSize.Large => "bit-cmb-lg", - _ => string.Empty - }); - - ClassBuilder.Register(() => IconPosition switch - { - BitButtonIconPosition.Start => "bit-cmb-srt", - BitButtonIconPosition.End => "bit-cmb-end", - _ => "bit-cmb-srt" - }); - } - - protected override void RegisterCssStyles() - { - StyleBuilder.Register(() => Styles?.Root); - } - - protected override void OnParametersSet() - { - if (IsEnabled is false) - { - _tabIndex = AllowDisabledFocus ? null : -1; - } - - _buttonType = ButtonType ?? (EditContext is null ? BitButtonType.Button : BitButtonType.Submit); - - base.OnParametersSet(); - } - - - protected virtual async Task HandleOnClick(MouseEventArgs e) - { - if (IsEnabled) - { - await OnClick.InvokeAsync(e); - } - } -} diff --git a/src/BlazorUI/Bit.BlazorUI/Components/Buttons/BitCompoundButton/BitCompoundButton.scss b/src/BlazorUI/Bit.BlazorUI/Components/Buttons/BitCompoundButton/BitCompoundButton.scss deleted file mode 100644 index 0b799cb76f..0000000000 --- a/src/BlazorUI/Bit.BlazorUI/Components/Buttons/BitCompoundButton/BitCompoundButton.scss +++ /dev/null @@ -1,221 +0,0 @@ -@import "../../../Styles/functions.scss"; - -.bit-cmb { - cursor: pointer; - text-align: start; - gap: spacing(1.5); - position: relative; - display: inline-flex; - min-width: spacing(9); - text-decoration: none; - box-sizing: border-box; - padding: spacing(2) spacing(1.5); - border-width: $shape-border-width; - border-style: $shape-border-style; - border-radius: $shape-border-radius; - font-family: $typography-font-family; - font-weight: $typography-font-weight; - - &.bit-dis { - cursor: default; - user-select: none; - pointer-events: none; - -webkit-user-select: none; - color: $color-foreground-disabled; - } -} - -.bit-cmb-pri { - color: var(--bit-cmb-pri-clr); - background-color: var(--bit-cmb-bg-clr); - border-color: var(--bit-cmb-pri-brd-clr); - --bit-cmb-bg-clr: #{$color-primary-main}; - --bit-cmb-pri-clr: #{$color-primary-text}; - --bit-cmb-pri-brd-clr: #{$color-primary-main}; - --bit-cmb-pri-hover-bg-clr: #{$color-action-hover-primary}; - --bit-cmb-pri-active-bg-clr: #{$color-action-active-primary}; - - @media (hover: hover) { - &:hover { - border-color: var(--bit-cmb-pri-hover-bg-clr); - background-color: var(--bit-cmb-pri-hover-bg-clr); - } - } - - &:active { - border-color: var(--bit-cmb-pri-active-bg-clr); - background-color: var(--bit-cmb-pri-active-bg-clr); - } - - &.bit-dis { - border-color: $color-border-disabled; - background-color: $color-background-disabled; - } -} - -.bit-cmb-std { - color: var(--bit-cmb-sec-clr); - background-color: $color-secondary-main; - border-color: var(--bit-cmb-sec-brd-clr); - --bit-cmb-sec-clr: #{$color-secondary-text}; - --bit-cmb-sec-brd-clr: #{$color-secondary-text}; - --bit-cmb-sec-hover-bg-clr: #{$color-action-hover-secondary}; - --bit-cmb-sec-active-bg-clr: #{$color-action-active-secondary}; - - @media (hover: hover) { - &:hover { - background-color: var(--bit-cmb-sec-hover-bg-clr); - } - } - - &:active { - background-color: var(--bit-cmb-sec-active-bg-clr); - } - - &.bit-dis { - border-color: $color-border-disabled; - } -} - -.bit-cmb-txt { - border-color: transparent; - color: var(--bit-cmb-sec-clr); - background-color: transparent; - --bit-cmb-sec-clr: #{$color-secondary-text}; - --bit-cmb-sec-hover-bg-clr: #{$color-action-hover-secondary}; - --bit-cmb-sec-active-bg-clr: #{$color-action-active-secondary}; - - @media (hover: hover) { - &:hover { - background-color: var(--bit-cmb-sec-hover-bg-clr); - } - } - - &:active { - background-color: var(--bit-cmb-sec-active-bg-clr); - } -} - -.bit-cmb-srt { - flex-direction: row; -} - -.bit-cmb-end { - flex-direction: row-reverse; -} - -.bit-cmb-icn { - font-size: spacing(5); -} - -.bit-cmb-tcn { - display: block; -} - -.bit-cmb-prt { - display: block; - font-size: spacing(1.75); - margin-bottom: spacing(0.625); -} - -.bit-cmb-sct { - display: block; - font-weight: 400; - font-size: spacing(1.5); -} - -.bit-cmb-inf { - --bit-cmb-bg-clr: #{$color-state-info-bg}; - --bit-cmb-pri-clr: #{$color-foreground-primary}; - --bit-cmb-pri-brd-clr: #{$color-state-info-bg}; - --bit-cmb-pri-hover-bg-clr: #{$color-action-hover-state-info-bg}; - --bit-cmb-pri-active-bg-clr: #{$color-action-active-state-info-bg}; - --bit-cmb-sec-clr: #{$color-state-info}; - --bit-cmb-sec-brd-clr: #{$color-state-info}; - --bit-cmb-sec-hover-bg-clr: #{$color-action-hover-state-info-bg}; - --bit-cmb-sec-active-bg-clr: #{$color-action-active-state-info-bg}; -} - -.bit-cmb-suc { - --bit-cmb-bg-clr: #{$color-state-success-bg}; - --bit-cmb-pri-clr: #{$color-foreground-primary}; - --bit-cmb-pri-brd-clr: #{$color-state-success-bg}; - --bit-cmb-pri-hover-bg-clr: #{$color-action-hover-state-success-bg}; - --bit-cmb-pri-active-bg-clr: #{$color-action-active-state-success-bg}; - --bit-cmb-sec-clr: #{$color-state-success}; - --bit-cmb-sec-brd-clr: #{$color-state-success}; - --bit-cmb-sec-hover-bg-clr: #{$color-action-hover-state-success-bg}; - --bit-cmb-sec-active-bg-clr: #{$color-action-active-state-success-bg}; -} - -.bit-cmb-wrn { - --bit-cmb-bg-clr: #{$color-state-warning-bg}; - --bit-cmb-pri-clr: #{$color-foreground-primary}; - --bit-cmb-pri-brd-clr: #{$color-state-warning-bg}; - --bit-cmb-pri-hover-bg-clr: #{$color-action-hover-state-warning-bg}; - --bit-cmb-pri-active-bg-clr: #{$color-action-active-state-warning-bg}; - --bit-cmb-sec-clr: #{$color-state-warning}; - --bit-cmb-sec-brd-clr: #{$color-state-warning}; - --bit-cmb-sec-hover-bg-clr: #{$color-action-hover-state-warning-bg}; - --bit-cmb-sec-active-bg-clr: #{$color-action-active-state-warning-bg}; -} - -.bit-cmb-swr { - --bit-cmb-bg-clr: #{$color-state-severe-warning-bg}; - --bit-cmb-pri-clr: #{$color-foreground-primary}; - --bit-cmb-pri-brd-clr: #{$color-state-severe-warning-bg}; - --bit-cmb-pri-hover-bg-clr: #{$color-action-hover-state-severe-warning-bg}; - --bit-cmb-pri-active-bg-clr: #{$color-action-active-state-severe-warning-bg}; - --bit-cmb-sec-clr: #{$color-state-severe-warning}; - --bit-cmb-sec-brd-clr: #{$color-state-severe-warning}; - --bit-cmb-sec-hover-bg-clr: #{$color-action-hover-state-severe-warning-bg}; - --bit-cmb-sec-active-bg-clr: #{$color-action-active-state-severe-warning-bg}; -} - -.bit-cmb-err { - --bit-cmb-bg-clr: #{$color-state-error-bg}; - --bit-cmb-pri-clr: #{$color-foreground-primary}; - --bit-cmb-pri-brd-clr: #{$color-state-error-bg}; - --bit-cmb-pri-hover-bg-clr: #{$color-action-hover-state-error-bg}; - --bit-cmb-pri-active-bg-clr: #{$color-action-active-state-error-bg}; - --bit-cmb-sec-clr: #{$color-state-error}; - --bit-cmb-sec-brd-clr: #{$color-state-error}; - --bit-cmb-sec-hover-bg-clr: #{$color-action-hover-state-error-bg}; - --bit-cmb-sec-active-bg-clr: #{$color-action-active-state-error-bg}; -} - -.bit-cmb-sm { - min-width: spacing(6); - min-height: spacing(3); - padding: spacing(1.75) spacing(1.25); - - .bit-cmb-prt { - font-size: spacing(1.5); - } - - .bit-cmb-sct { - font-size: spacing(1.25); - } - - .bit-cmb-icn { - font-size: spacing(4.25); - } -} - -.bit-cmb-lg { - min-width: spacing(10); - min-height: spacing(5); - padding: spacing(2.25) spacing(1.75); - - .bit-cmb-prt { - font-size: spacing(2.5); - } - - .bit-cmb-sct { - font-size: spacing(2); - } - - .bit-cmb-icn { - font-size: spacing(6.75); - } -} diff --git a/src/BlazorUI/Bit.BlazorUI/Components/Buttons/BitCompoundButton/BitCompoundButtonClassStyles.cs b/src/BlazorUI/Bit.BlazorUI/Components/Buttons/BitCompoundButton/BitCompoundButtonClassStyles.cs deleted file mode 100644 index 123d30bad3..0000000000 --- a/src/BlazorUI/Bit.BlazorUI/Components/Buttons/BitCompoundButton/BitCompoundButtonClassStyles.cs +++ /dev/null @@ -1,29 +0,0 @@ -namespace Bit.BlazorUI; - -public class BitCompoundButtonClassStyles -{ - /// - /// Custom CSS classes/styles for the root element of the BitCompoundButton. - /// - public string? Root { get; set; } - - /// - /// Custom CSS classes/styles for the internal container of the BitCompoundButton. - /// - public string? Container { get; set; } - - /// - /// Custom CSS classes/styles for the icon of the BitCompoundButton. - /// - public string? Icon { get; set; } - - /// - /// Custom CSS classes/styles for the primary section of the BitCompoundButton. - /// - public string? Primary { get; set; } - - /// - /// Custom CSS classes/styles for the secondary section of the BitCompoundButton. - /// - public string? Secondary { get; set; } -} diff --git a/src/BlazorUI/Bit.BlazorUI/Components/Buttons/BitIconButton/BitIconButton.razor b/src/BlazorUI/Bit.BlazorUI/Components/Buttons/BitIconButton/BitIconButton.razor deleted file mode 100644 index 763af90b61..0000000000 --- a/src/BlazorUI/Bit.BlazorUI/Components/Buttons/BitIconButton/BitIconButton.razor +++ /dev/null @@ -1,40 +0,0 @@ -@namespace Bit.BlazorUI -@inherits BitComponentBase - -@if (Href.HasValue() && IsEnabled) -{ - - - - - -} -else -{ - -} \ No newline at end of file diff --git a/src/BlazorUI/Bit.BlazorUI/Components/Buttons/BitIconButton/BitIconButton.razor.cs b/src/BlazorUI/Bit.BlazorUI/Components/Buttons/BitIconButton/BitIconButton.razor.cs deleted file mode 100644 index fb5f59b442..0000000000 --- a/src/BlazorUI/Bit.BlazorUI/Components/Buttons/BitIconButton/BitIconButton.razor.cs +++ /dev/null @@ -1,131 +0,0 @@ -using Microsoft.AspNetCore.Components.Forms; - -namespace Bit.BlazorUI; - -public partial class BitIconButton -{ - private BitButtonSize? size; - - private int? _tabIndex; - private BitButtonType _buttonType; - - - /// - /// The EditContext, which is set if the button is inside an - /// - [CascadingParameter] public EditContext? EditContext { get; set; } - - - /// - /// Whether the icon button can have focus in disabled mode - /// - [Parameter] public bool AllowDisabledFocus { get; set; } = true; - - /// - /// Detailed description of the icon button for the benefit of screen readers - /// - [Parameter] public string? AriaDescription { get; set; } - - /// - /// If true, add an aria-hidden attribute instructing screen readers to ignore the element - /// - [Parameter] public bool AriaHidden { get; set; } - - /// - /// The type of the button - /// - [Parameter] public BitButtonType? ButtonType { get; set; } - - /// - /// Custom CSS classes for different parts of the BitIconButton component. - /// - [Parameter] public BitIconButtonClassStyles? Classes { get; set; } - - /// - /// URL the link points to, if provided, button renders as an anchor - /// - [Parameter] public string? Href { get; set; } - - /// - /// The icon name for the icon shown in the button - /// - [Parameter] public string? IconName { get; set; } - - /// - /// Callback for when the button clicked - /// - [Parameter] public EventCallback OnClick { get; set; } - - /// - /// The size of button, Possible values: Small | Medium | Large - /// - [Parameter] - public BitButtonSize? Size - { - get => size; - set - { - if (size == value) return; - - size = value; - ClassBuilder.Reset(); - } - } - - /// - /// Custom CSS styles for different parts of the BitIconButton component. - /// - [Parameter] public BitIconButtonClassStyles? Styles { get; set; } - - /// - /// The tooltip to show when the mouse is placed on the icon button - /// - [Parameter] public string? Title { get; set; } - - /// - /// If Href provided, specifies how to open the link - /// - [Parameter] public string? Target { get; set; } - - - protected override string RootElementClass => "bit-icb"; - - protected override void RegisterCssClasses() - { - ClassBuilder.Register(() => Classes?.Root); - - ClassBuilder.Register(() => Size switch - { - BitButtonSize.Small => "bit-icb-sm", - BitButtonSize.Medium => "bit-icb-md", - BitButtonSize.Large => "bit-icb-lg", - _ => string.Empty - }); - } - - protected override void RegisterCssStyles() - { - StyleBuilder.Register(() => Styles?.Root); - } - - protected override void OnParametersSet() - { - if (IsEnabled is false) - { - _tabIndex = AllowDisabledFocus ? null : -1; - } - - _buttonType = ButtonType ?? (EditContext is null ? BitButtonType.Button : BitButtonType.Submit); - - base.OnParametersSet(); - } - - - protected virtual async Task HandleOnClick(MouseEventArgs e) - { - if (IsEnabled) - { - await OnClick.InvokeAsync(e); - } - } -} diff --git a/src/BlazorUI/Bit.BlazorUI/Components/Buttons/BitIconButton/BitIconButton.scss b/src/BlazorUI/Bit.BlazorUI/Components/Buttons/BitIconButton/BitIconButton.scss deleted file mode 100644 index ec4d383ffd..0000000000 --- a/src/BlazorUI/Bit.BlazorUI/Components/Buttons/BitIconButton/BitIconButton.scss +++ /dev/null @@ -1,62 +0,0 @@ -@import "../../../Styles/functions.scss"; - -.bit-icb { - border: none; - cursor: pointer; - width: spacing(4); - height: spacing(4); - display: inline-block; - text-decoration: none; - box-sizing: border-box; - font-size: spacing(1.75); - color: $color-primary-main; - background-color: transparent; - border-radius: $shape-border-radius; - font-family: $typography-font-family; - - @media (hover: hover) { - &:hover { - color: $color-action-hover-primary; - background-color: $color-action-hover-background-primary; - } - } - - &:active { - color: $color-action-active-primary; - background-color: $color-action-active-background-primary; - } - - &.bit-dis { - cursor: default; - pointer-events: none; - color: $color-foreground-disabled; - border-width: $shape-border-width; - border-style: $shape-border-style; - border-color: $color-border-disabled; - background-color: $color-background-disabled; - } -} - -.bit-icb-ict { - height: 100%; - display: flex; - flex-wrap: nowrap; - align-items: center; - justify-content: center; - - .bit-icon { - margin: 0 spacing(0.5); - } -} - -.bit-icb-sm { - width: spacing(3); - height: spacing(3); - font-size: spacing(1.5); -} - -.bit-icb-lg { - width: spacing(5); - height: spacing(5); - font-size: spacing(2); -} diff --git a/src/BlazorUI/Bit.BlazorUI/Components/Buttons/BitIconButton/BitIconButtonClassStyles.cs b/src/BlazorUI/Bit.BlazorUI/Components/Buttons/BitIconButton/BitIconButtonClassStyles.cs deleted file mode 100644 index 27facc440b..0000000000 --- a/src/BlazorUI/Bit.BlazorUI/Components/Buttons/BitIconButton/BitIconButtonClassStyles.cs +++ /dev/null @@ -1,19 +0,0 @@ -namespace Bit.BlazorUI; - -public class BitIconButtonClassStyles -{ - /// - /// Custom CSS classes/styles for the root element of the BitIconButton. - /// - public string? Root { get; set; } - - /// - /// Custom CSS classes/styles for the main container of the BitIconButton. - /// - public string? Container { get; set; } - - /// - /// Custom CSS classes/styles for the Icon of the BitIconButton. - /// - public string? Icon { get; set; } -} diff --git a/src/BlazorUI/Bit.BlazorUI/Components/Buttons/BitMenuButton/BitMenuButton.razor b/src/BlazorUI/Bit.BlazorUI/Components/Buttons/BitMenuButton/BitMenuButton.razor index 96ea7a6330..ccc09966a5 100644 --- a/src/BlazorUI/Bit.BlazorUI/Components/Buttons/BitMenuButton/BitMenuButton.razor +++ b/src/BlazorUI/Bit.BlazorUI/Components/Buttons/BitMenuButton/BitMenuButton.razor @@ -12,14 +12,14 @@ style="@StyleBuilder.Value" class="@ClassBuilder.Value" dir="@Dir?.ToString().ToLower()"> - public string? Root { get; set; } + /// + /// Custom CSS classes/styles for the opened callout state of the BitMenuButton. + /// + public string? Opened { get; set; } + /// /// Custom CSS classes/styles for operator button of the BitMenuButton. /// diff --git a/src/BlazorUI/Bit.BlazorUI/Components/Buttons/BitToggleButton/BitToggleButton.razor b/src/BlazorUI/Bit.BlazorUI/Components/Buttons/BitToggleButton/BitToggleButton.razor index b8fcdc67b4..208b826569 100644 --- a/src/BlazorUI/Bit.BlazorUI/Components/Buttons/BitToggleButton/BitToggleButton.razor +++ b/src/BlazorUI/Bit.BlazorUI/Components/Buttons/BitToggleButton/BitToggleButton.razor @@ -12,19 +12,17 @@ aria-label="@AriaLabel" aria-hidden="@AriaHidden" aria-describedby="@AriaDescription"> - - @if (ChildContent is not null) + @if (ChildContent is not null) + { + @ChildContent + } + else + { + var iconName = GetIconName(); + if (iconName.HasValue()) { - @ChildContent + } - else - { - var iconName = GetIconName(); - if (iconName.HasValue()) - { - - } - @GetText() - } - + @GetText() + } diff --git a/src/BlazorUI/Bit.BlazorUI/Components/Buttons/BitToggleButton/BitToggleButton.razor.cs b/src/BlazorUI/Bit.BlazorUI/Components/Buttons/BitToggleButton/BitToggleButton.razor.cs index 4f47c3295b..42e3dc4d47 100644 --- a/src/BlazorUI/Bit.BlazorUI/Components/Buttons/BitToggleButton/BitToggleButton.razor.cs +++ b/src/BlazorUI/Bit.BlazorUI/Components/Buttons/BitToggleButton/BitToggleButton.razor.cs @@ -1,20 +1,15 @@ namespace Bit.BlazorUI; -public partial class BitToggleButton +public partial class BitToggleButton : BitComponentBase { - private bool IsCheckedHasBeenSet; - - private bool isChecked; - private BitButtonSize? size; - private BitButtonStyle buttonStyle = BitButtonStyle.Primary; - private int? _tabIndex; + /// /// Whether the toggle button can have focus in disabled mode. /// - [Parameter] public bool AllowDisabledFocus { get; set; } = true; + [Parameter] public bool AllowDisabledFocus { get; set; } /// /// Detailed description of the toggle button for the benefit of screen readers. @@ -27,128 +22,105 @@ public partial class BitToggleButton [Parameter] public bool AriaHidden { get; set; } /// - /// The style of compound button, Possible values: Primary | Standard. + /// The content of the toggle button. /// - [Parameter] - public BitButtonStyle ButtonStyle - { - get => buttonStyle; - set - { - buttonStyle = value; - ClassBuilder.Reset(); - } - } + [Parameter] public RenderFragment? ChildContent { get; set; } /// - /// The content of BitToggleButton. + /// Custom CSS classes for different parts of the toggle button. /// - [Parameter] public RenderFragment? ChildContent { get; set; } + [Parameter] public BitToggleButtonClassStyles? Classes { get; set; } /// - /// Custom CSS classes for different parts of the BitToggleButton component. + /// The general color of the toggle button. /// - [Parameter] public BitToggleButtonClassStyles? Classes { get; set; } + [Parameter, ResetClassBuilder] + public BitColor? Color { get; set; } /// - /// Default value of the IsChecked. + /// Default value of the IsChecked parameter. /// [Parameter] public bool? DefaultIsChecked { get; set; } /// - /// The icon that shows in the button. + /// The icon name that renders inside the toggle button. /// [Parameter] public string? IconName { get; set; } /// - /// Determine if the button is in checked state, default is true. + /// Determines if the toggle button is in the checked state. /// - [Parameter] - public bool IsChecked - { - get => isChecked; - set - { - if (value == isChecked) return; - isChecked = value; - ClassBuilder.Reset(); - _ = IsCheckedChanged.InvokeAsync(value); - } - } - - [Parameter] public EventCallback IsCheckedChanged { get; set; } + [Parameter, ResetClassBuilder, ResetStyleBuilder, TwoWayBound] + public bool IsChecked { get; set; } /// - /// Callback that is called when the IsChecked value has changed. + /// Callback for when the IsChecked value has changed. /// [Parameter] public EventCallback OnChange { get; set; } /// - /// Callback that is called when the button is clicked. + /// Callback for when the toggle button is clicked. /// [Parameter] public EventCallback OnClick { get; set; } /// - /// The icon of the BitToggleButton when it is not checked. + /// The icon of the toggle button when it is not checked. /// [Parameter] public string? OffIconName { get; set; } /// - /// The text of the BitToggleButton when it is not checked. + /// The text of the toggle button when it is not checked. /// [Parameter] public string? OffText { get; set; } /// - /// The title of the BitToggleButton when it is not checked. + /// The title of the toggle button when it is not checked. /// [Parameter] public string? OffTitle { get; set; } /// - /// The icon of the BitToggleButton when it is checked. + /// The icon of the toggle button when it is checked. /// [Parameter] public string? OnIconName { get; set; } /// - /// The text of the BitToggleButton when it is checked. + /// The text of the toggle button when it is checked. /// [Parameter] public string? OnText { get; set; } /// - /// The title of the BitToggleButton when it is checked. + /// The title of the toggle button when it is checked. /// [Parameter] public string? OnTitle { get; set; } /// - /// The size of button, Possible values: Small | Medium | Large + /// The size of the toggle button. /// - [Parameter] - public BitButtonSize? Size - { - get => size; - set - { - if (size == value) return; - - size = value; - ClassBuilder.Reset(); - } - } + [Parameter, ResetClassBuilder] + public BitSize? Size { get; set; } /// - /// Custom CSS styles for different parts of the BitToggleButton component. + /// Custom CSS styles for different parts of the toggle button. /// [Parameter] public BitToggleButtonClassStyles? Styles { get; set; } /// - /// The text of the BitToggleButton. + /// The text of the toggle button. /// [Parameter] public string? Text { get; set; } /// - /// The title to show when the mouse is placed on the button. + /// The title to show when the mouse is placed on the toggle button. /// [Parameter] public string? Title { get; set; } + /// + /// The visual variant of the toggle button. + /// + [Parameter, ResetClassBuilder] + public BitVariant? Variant { get; set; } + + protected override string RootElementClass => "bit-tgb"; @@ -158,23 +130,36 @@ protected override void RegisterCssClasses() ClassBuilder.Register(() => IsChecked ? $"bit-tgb-chk {Classes?.Checked}" : string.Empty); - ClassBuilder.Register(() => ButtonStyle switch + ClassBuilder.Register(() => Color switch { - BitButtonStyle.Primary => "bit-tgb-pri", - BitButtonStyle.Standard => "bit-tgb-std", - BitButtonStyle.Text => "bit-tgb-txt", + BitColor.Primary => "bit-tgb-pri", + BitColor.Secondary => "bit-tgb-sec", + BitColor.Tertiary => "bit-tgb-ter", + BitColor.Info => "bit-tgb-inf", + BitColor.Success => "bit-tgb-suc", + BitColor.Warning => "bit-tgb-wrn", + BitColor.SevereWarning => "bit-tgb-swr", + BitColor.Error => "bit-tgb-err", _ => "bit-tgb-pri" }); ClassBuilder.Register(() => Size switch { - BitButtonSize.Small => "bit-tgb-sm", - BitButtonSize.Medium => "bit-tgb-md", - BitButtonSize.Large => "bit-tgb-lg", - _ => string.Empty + BitSize.Small => "bit-tgb-sm", + BitSize.Medium => "bit-tgb-md", + BitSize.Large => "bit-tgb-lg", + _ => "bit-tgb-md" + }); + + ClassBuilder.Register(() => Variant switch + { + BitVariant.Fill => "bit-tgb-fil", + BitVariant.Outline => "bit-tgb-otl", + BitVariant.Text => "bit-tgb-txt", + _ => "bit-tgb-fil" }); } - + protected override void RegisterCssStyles() { StyleBuilder.Register(() => Styles?.Root); @@ -191,25 +176,25 @@ protected override async Task OnInitializedAsync() if (IsCheckedHasBeenSet is false && DefaultIsChecked.HasValue) { - IsChecked = DefaultIsChecked.Value; + await AssignIsChecked(DefaultIsChecked.Value); } await base.OnInitializedAsync(); } - protected virtual async Task HandleOnClick(MouseEventArgs e) + private async Task HandleOnClick(MouseEventArgs e) { if (IsEnabled is false) return; await OnClick.InvokeAsync(e); - if (IsCheckedHasBeenSet && IsCheckedChanged.HasDelegate is false) return; + if (await AssignIsChecked(IsChecked is false) is false) return; - IsChecked = !IsChecked; await OnChange.InvokeAsync(IsChecked); } + private string? GetIconName() { if (IsChecked && OnIconName.HasValue()) return OnIconName; diff --git a/src/BlazorUI/Bit.BlazorUI/Components/Buttons/BitToggleButton/BitToggleButton.scss b/src/BlazorUI/Bit.BlazorUI/Components/Buttons/BitToggleButton/BitToggleButton.scss index 370a1ff642..3ce0a1ed93 100644 --- a/src/BlazorUI/Bit.BlazorUI/Components/Buttons/BitToggleButton/BitToggleButton.scss +++ b/src/BlazorUI/Bit.BlazorUI/Components/Buttons/BitToggleButton/BitToggleButton.scss @@ -7,146 +7,208 @@ align-items: center; display: inline-flex; text-decoration: none; - min-width: spacing(10); - min-height: spacing(4); + box-sizing: border-box; justify-content: center; - font-size: spacing(1.75); - padding: spacing(0.5) spacing(2); - border-width: $shape-border-width; - border-style: $shape-border-style; - border-radius: $shape-border-radius; - font-family: $typography-font-family; - font-weight: $typography-font-weight; + font-family: $tg-font-family; + font-weight: $tg-font-weight; + border-width: $shp-border-width; + border-style: $shp-border-style; + border-radius: $shp-border-radius; &.bit-dis { cursor: default; pointer-events: none; - color: $color-foreground-disabled; + color: $clr-fg-dis; } } -.bit-tgb-pri { - color: var(--bit-tgb-pri-clr); - background-color: var(--bit-tgb-bg-clr); - border-color: var(--bit-tgb-pri-brd-clr); - --bit-tgb-bg-clr: #{$color-primary-main}; - --bit-tgb-pri-clr: #{$color-primary-text}; - --bit-tgb-pri-brd-clr: #{$color-primary-main}; - --bit-tgb-pri-hover-bg-clr: #{$color-action-hover-primary}; - --bit-tgb-pri-active-bg-clr: #{$color-action-active-primary}; - --bit-tgb-chk-bg-clr: #{$color-primary-dark}; - --bit-tgb-chk-brd-clr: #{$color-primary-dark}; +.bit-tgb-ico { + flex-shrink: 0; + text-align: center; + margin: 0 spacing(0.5); +} + +.bit-tgb-btx { + display: block; +} + +.bit-tgb-fil { + color: var(--bit-tgb-clr-txt); + border-color: var(--bit-tgb-clr); + background-color: var(--bit-tgb-clr); @media (hover: hover) { &:hover { - border-color: var(--bit-tgb-pri-hover-bg-clr); - background-color: var(--bit-tgb-pri-hover-bg-clr); + border-color: var(--bit-tgb-clr-hover); + background-color: var(--bit-tgb-clr-hover); } } &:active { - border-color: var(--bit-tgb-pri-active-bg-clr); - background-color: var(--bit-tgb-pri-active-bg-clr); + border-color: var(--bit-tgb-clr-active); + background-color: var(--bit-tgb-clr-active); } &.bit-dis { - border-color: $color-border-disabled; - background-color: $color-background-disabled; + border-color: $clr-brd-dis; + background-color: $clr-bg-dis; } } -.bit-tgb-std { - color: var(--bit-tgb-sec-clr); - background-color: $color-secondary-main; - border-color: var(--bit-tgb-sec-brd-clr); - --bit-tgb-sec-clr: #{$color-secondary-text}; - --bit-tgb-sec-brd-clr: #{$color-secondary-text}; - --bit-tgb-sec-hover-bg-clr: #{$color-action-hover-secondary}; - --bit-tgb-sec-active-bg-clr: #{$color-action-active-secondary}; - --bit-tgb-chk-bg-clr: #{$color-secondary-dark}; - --bit-tgb-chk-brd-clr: #{$color-secondary-text}; +.bit-tgb-otl { + color: var(--bit-tgb-clr); + border-color: var(--bit-tgb-clr); + background-color: transparent; @media (hover: hover) { &:hover { - background-color: var(--bit-tgb-sec-hover-bg-clr); + color: var(--bit-tgb-clr-txt); + border-color: var(--bit-tgb-clr-hover); + background-color: var(--bit-tgb-clr-hover); } } &:active { - background-color: var(--bit-tgb-sec-active-bg-clr); + color: var(--bit-tgb-clr-txt); + border-color: var(--bit-tgb-clr-active); + background-color: var(--bit-tgb-clr-active); } &.bit-dis { - border-color: $color-border-disabled; + border-color: $clr-brd-dis; } } .bit-tgb-txt { + color: var(--bit-tgb-clr); border-color: transparent; - color: var(--bit-tgb-sec-clr); background-color: transparent; - --bit-tgb-sec-clr: #{$color-secondary-text}; - --bit-tgb-sec-hover-bg-clr: #{$color-action-hover-secondary}; - --bit-tgb-sec-active-bg-clr: #{$color-action-active-secondary}; - --bit-tgb-chk-bg-clr: #{$color-secondary-dark}; - --bit-tgb-chk-brd-clr: transparent; @media (hover: hover) { &:hover { - background-color: var(--bit-tgb-sec-hover-bg-clr); + color: var(--bit-tgb-clr-txt); + border-color: var(--bit-tgb-clr-hover); + background-color: var(--bit-tgb-clr-hover); } } &:active { - background-color: var(--bit-tgb-sec-active-bg-clr); + color: var(--bit-tgb-clr-txt); + border-color: var(--bit-tgb-clr-active); + background-color: var(--bit-tgb-clr-active); } } .bit-tgb-chk { - border-color: var(--bit-tgb-chk-brd-clr); - background-color: var(--bit-tgb-chk-bg-clr); + color: var(--bit-tgb-clr-txt); + border-color: var(--bit-tgb-clr-dark); + background-color: var(--bit-tgb-clr-dark); @media (hover: hover) { &:hover { - border-color: var(--bit-tgb-chk-brd-clr); - background-color: var(--bit-tgb-chk-bg-clr); + border-color: var(--bit-tgb-clr-dark-hover); + background-color: var(--bit-tgb-clr-dark-hover); } } &:active { - border-color: var(--bit-tgb-chk-brd-clr); - background-color: var(--bit-tgb-chk-bg-clr); + border-color: var(--bit-tgb-clr-dark-active); + background-color: var(--bit-tgb-clr-dark-active); } } -.bit-tgb-con { - display: flex; - align-items: center; - flex-flow: row nowrap; - justify-content: center; +.bit-tgb-pri { + --bit-tgb-clr-txt: #{$clr-pri-text}; + --bit-tgb-clr: #{$clr-pri}; + --bit-tgb-clr-hover: #{$clr-pri-hover}; + --bit-tgb-clr-active: #{$clr-pri-active}; + --bit-tgb-clr-dark: #{$clr-pri-dark}; + --bit-tgb-clr-dark-hover: #{$clr-pri-dark-hover}; + --bit-tgb-clr-dark-active: #{$clr-pri-dark-active}; +} - .bit-icon { - flex-shrink: 0; - text-align: center; - margin: 0 spacing(0.5); - } +.bit-tgb-sec { + --bit-tgb-clr-txt: #{$clr-sec-text}; + --bit-tgb-clr: #{$clr-sec}; + --bit-tgb-clr-hover: #{$clr-sec-hover}; + --bit-tgb-clr-active: #{$clr-sec-active}; + --bit-tgb-clr-dark: #{$clr-sec-dark}; + --bit-tgb-clr-dark-hover: #{$clr-sec-dark-hover}; + --bit-tgb-clr-dark-active: #{$clr-sec-dark-active}; } -.bit-tgb-btx { - display: block; +.bit-tgb-ter { + --bit-tgb-clr-txt: #{$clr-ter-text}; + --bit-tgb-clr: #{$clr-ter}; + --bit-tgb-clr-hover: #{$clr-ter-hover}; + --bit-tgb-clr-active: #{$clr-ter-active}; + --bit-tgb-clr-dark: #{$clr-ter-dark}; + --bit-tgb-clr-dark-hover: #{$clr-ter-dark-hover}; + --bit-tgb-clr-dark-active: #{$clr-ter-dark-active}; +} + +.bit-tgb-inf { + --bit-tgb-clr-txt: #{$clr-inf-text}; + --bit-tgb-clr: #{$clr-inf}; + --bit-tgb-clr-hover: #{$clr-inf-hover}; + --bit-tgb-clr-active: #{$clr-inf-active}; + --bit-tgb-clr-dark: #{$clr-inf-dark}; + --bit-tgb-clr-dark-hover: #{$clr-inf-dark-hover}; + --bit-tgb-clr-dark-active: #{$clr-inf-dark-active}; +} + +.bit-tgb-suc { + --bit-tgb-clr-txt: #{$clr-suc-text}; + --bit-tgb-clr: #{$clr-suc}; + --bit-tgb-clr-hover: #{$clr-suc-hover}; + --bit-tgb-clr-active: #{$clr-suc-active}; + --bit-tgb-clr-dark: #{$clr-suc-dark}; + --bit-tgb-clr-dark-hover: #{$clr-suc-dark-hover}; + --bit-tgb-clr-dark-active: #{$clr-suc-dark-active}; +} + +.bit-tgb-wrn { + --bit-tgb-clr-txt: #{$clr-wrn-text}; + --bit-tgb-clr: #{$clr-wrn}; + --bit-tgb-clr-hover: #{$clr-wrn-hover}; + --bit-tgb-clr-active: #{$clr-wrn-active}; + --bit-tgb-clr-dark: #{$clr-wrn-dark}; + --bit-tgb-clr-dark-hover: #{$clr-wrn-dark-hover}; + --bit-tgb-clr-dark-active: #{$clr-wrn-dark-active}; +} + +.bit-tgb-swr { + --bit-tgb-clr-txt: #{$clr-swr-text}; + --bit-tgb-clr: #{$clr-swr}; + --bit-tgb-clr-hover: #{$clr-swr-hover}; + --bit-tgb-clr-active: #{$clr-swr-active}; + --bit-tgb-clr-dark: #{$clr-swr-dark}; + --bit-tgb-clr-dark-hover: #{$clr-swr-dark-hover}; + --bit-tgb-clr-dark-active: #{$clr-swr-dark-active}; +} + +.bit-tgb-err { + --bit-tgb-clr-txt: #{$clr-err-text}; + --bit-tgb-clr: #{$clr-err}; + --bit-tgb-clr-hover: #{$clr-err-hover}; + --bit-tgb-clr-active: #{$clr-err-active}; + --bit-tgb-clr-dark: #{$clr-err-dark}; + --bit-tgb-clr-dark-hover: #{$clr-err-dark-hover}; + --bit-tgb-clr-dark-active: #{$clr-err-dark-active}; } .bit-tgb-sm { - min-width: spacing(6); - min-height: spacing(3); font-size: spacing(1.5); - padding: spacing(0.3) spacing(1.5); + padding: spacing(0.5) spacing(1.5); +} + +.bit-tgb-md { + font-size: spacing(1.75); + padding: spacing(0.75) spacing(2); } .bit-tgb-lg { - min-width: spacing(10); - min-height: spacing(5); font-size: spacing(2); - padding: spacing(0.7) spacing(2.5); + padding: spacing(1) spacing(2.5); } diff --git a/src/BlazorUI/Bit.BlazorUI/Components/Buttons/BitToggleButton/BitToggleButtonClassStyles.cs b/src/BlazorUI/Bit.BlazorUI/Components/Buttons/BitToggleButton/BitToggleButtonClassStyles.cs index 8611a5d835..3424850b2f 100644 --- a/src/BlazorUI/Bit.BlazorUI/Components/Buttons/BitToggleButton/BitToggleButtonClassStyles.cs +++ b/src/BlazorUI/Bit.BlazorUI/Components/Buttons/BitToggleButton/BitToggleButtonClassStyles.cs @@ -17,11 +17,6 @@ public class BitToggleButtonClassStyles /// public string? Checked { get; set; } - /// - /// Custom CSS classes/styles for the label and icon container of the BitToggleButton. - /// - public string? Container { get; set; } - /// /// Custom CSS classes/styles for the text element of the BitToggleButton. /// diff --git a/src/BlazorUI/Bit.BlazorUI/Components/Element/BitElement.cs b/src/BlazorUI/Bit.BlazorUI/Components/Element/BitElement.cs deleted file mode 100644 index 4ca23da7ee..0000000000 --- a/src/BlazorUI/Bit.BlazorUI/Components/Element/BitElement.cs +++ /dev/null @@ -1,36 +0,0 @@ -namespace Bit.BlazorUI; - -public partial class BitElement : BitComponentBase -{ - /// - /// The content of the element. - /// - [Parameter] public RenderFragment? ChildContent { get; set; } - - /// - /// The HTML tag used for the root node. - /// - [Parameter] public string Tag { get; set; } = "div"; - - - protected override string RootElementClass => "bit-elm"; - - - protected override void BuildRenderTree(RenderTreeBuilder builder) - { - var seq = 0; - builder.OpenElement(seq++, Tag); - builder.AddMultipleAttributes(seq++, Microsoft.AspNetCore.Components.CompilerServices.RuntimeHelpers.TypeCheck>>(HtmlAttributes)); - builder.AddAttribute(seq++, "id", _Id); - builder.AddAttribute(seq++, "style", StyleBuilder.Value); - builder.AddAttribute(seq++, "class", ClassBuilder.Value); - builder.AddAttribute(seq++, "dir", Dir?.ToString().ToLower()); - builder.AddElementReferenceCapture(seq++, v => RootElement = v); - - builder.AddContent(seq++, ChildContent); - - builder.CloseElement(); - - base.BuildRenderTree(builder); - } -} diff --git a/src/BlazorUI/Bit.BlazorUI/Components/Icon/BitIcon.razor.cs b/src/BlazorUI/Bit.BlazorUI/Components/Icon/BitIcon.razor.cs deleted file mode 100644 index 233191471e..0000000000 --- a/src/BlazorUI/Bit.BlazorUI/Components/Icon/BitIcon.razor.cs +++ /dev/null @@ -1,11 +0,0 @@ -namespace Bit.BlazorUI; - -public partial class BitIcon -{ - /// - /// The icon name for the icon shown in the button - /// - [Parameter] public string? IconName { get; set; } - - protected override string RootElementClass => "bit-ico"; -} diff --git a/src/BlazorUI/Bit.BlazorUI/Components/Icon/BitIcon.scss b/src/BlazorUI/Bit.BlazorUI/Components/Icon/BitIcon.scss deleted file mode 100644 index 2afca3abd9..0000000000 --- a/src/BlazorUI/Bit.BlazorUI/Components/Icon/BitIcon.scss +++ /dev/null @@ -1,6 +0,0 @@ -@import "../../Styles/functions.scss"; - -.bit-ico { - display: inline-block; - font-size: spacing(3); -} diff --git a/src/BlazorUI/Bit.BlazorUI/Components/Inputs/BitInputBase.cs b/src/BlazorUI/Bit.BlazorUI/Components/Inputs/BitInputBase.cs index 6bb8017bb5..e709c7ba73 100644 --- a/src/BlazorUI/Bit.BlazorUI/Components/Inputs/BitInputBase.cs +++ b/src/BlazorUI/Bit.BlazorUI/Components/Inputs/BitInputBase.cs @@ -1,34 +1,54 @@ -using System.Reflection; -using System.Linq.Expressions; +using System.Linq.Expressions; using System.Diagnostics.CodeAnalysis; using Microsoft.AspNetCore.Components.Forms; namespace Bit.BlazorUI; +/// +/// A base class for bit BlazorUI input components. This base class automatically +/// integrates with an , which must be supplied +/// as a cascading parameter. +/// public abstract class BitInputBase : BitComponentBase, IDisposable { protected bool IsDisposed; protected bool ValueHasBeenSet; - private TValue? value; + + private TValue? value; private bool? valueInvalid; + + + private bool _parsingFailed; private bool _isUnderlyingTypeNullable; private bool _hasInitializedParameters; private bool _previousParsingAttemptFailed; + private string? _incomingValueBeforeParsing; private ValidationMessageStore? _parsingValidationMessages; private readonly EventHandler _validationStateChangedHandler; + + protected event EventHandler OnValueChanged = default!; + + protected BitInputBase() + { + _validationStateChangedHandler = OnValidateStateChanged; + } + + + [CascadingParameter] private EditContext? CascadedEditContext { get; set; } + /// /// Gets or sets the display name for this field. - /// This value is used when generating error messages when the input value fails to parse correctly. + /// This value is used when generating error messages when the input value fails to parse correctly. /// [Parameter] public string? DisplayName { get; set; } @@ -37,6 +57,27 @@ public abstract class BitInputBase : BitComponentBase, IDisposable ///
[Parameter] public IReadOnlyDictionary? InputHtmlAttributes { get; set; } + /// + /// Gets or sets the name of the element. + /// Allows access by name from the associated form. + /// + [Parameter] public string? Name { get; set; } + + /// + /// Callback for when the input value changes. + /// + [Parameter] public EventCallback OnChange { get; set; } + + /// + /// Makes the input read-only. + /// + [Parameter] public bool ReadOnly { get; set; } + + /// + /// Makes the input required. + /// + [Parameter] public bool Required { get; set; } + /// /// Gets or sets the value of the input. This should be used with two-way binding. /// @@ -53,10 +94,7 @@ public TValue? Value this.value = value; - if (OnValueChanged is not null) - { - OnValueChanged(this, EventArgs.Empty); - } + OnValueChanged?.Invoke(this, EventArgs.Empty); } } @@ -71,10 +109,34 @@ public TValue? Value [Parameter] public Expression>? ValueExpression { get; set; } + + /// + /// The ElementReference of the input element. + /// + public ElementReference InputElement { get; internal set; } + + /// + /// Gives focus to the input element. + /// + public ValueTask FocusAsync() => InputElement.FocusAsync(); + + /// + /// Gives focus to the input element. + /// + /// A Boolean value indicating whether or not the browser should scroll + /// the document to bring the newly-focused element into view. A value of false for preventScroll (the default) + /// means that the browser will scroll the element into view after focusing it. + /// If preventScroll is set to true, no scrolling will occur. + public ValueTask FocusAsync(bool preventScroll) => InputElement.FocusAsync(preventScroll); + + + public override Task SetParametersAsync(ParameterView parameters) { ValueHasBeenSet = false; + var parametersDictionary = parameters.ToDictionary() as Dictionary; + foreach (var parameter in parametersDictionary!) { switch (parameter.Key) @@ -84,11 +146,40 @@ public override Task SetParametersAsync(ParameterView parameters) parametersDictionary.Remove(parameter.Key); break; + case nameof(DisplayName): + DisplayName = (string?)parameter.Value; + parametersDictionary.Remove(parameter.Key); + break; + case nameof(InputHtmlAttributes): InputHtmlAttributes = (IReadOnlyDictionary?)parameter.Value; parametersDictionary.Remove(parameter.Key); break; + case nameof(Name): + Name = (string?)parameter.Value; + parametersDictionary.Remove(parameter.Key); + break; + + case nameof(OnChange): + OnChange = (EventCallback)parameter.Value; + parametersDictionary.Remove(parameter.Key); + break; + + case nameof(ReadOnly): + var readOnly = (bool)parameter.Value; + if (ReadOnly != readOnly) ClassBuilder.Reset(); + ReadOnly = readOnly; + parametersDictionary.Remove(parameter.Key); + break; + + case nameof(Required): + var required = (bool)parameter.Value; + if (Required != required) ClassBuilder.Reset(); + Required = required; + parametersDictionary.Remove(parameter.Key); + break; + case nameof(Value): ValueHasBeenSet = true; Value = (TValue?)parameter.Value; @@ -104,11 +195,6 @@ public override Task SetParametersAsync(ParameterView parameters) ValueExpression = (Expression>?)parameter.Value; parametersDictionary.Remove(parameter.Key); break; - - case nameof(DisplayName): - DisplayName = (string?)parameter.Value; - parametersDictionary.Remove(parameter.Key); - break; } } @@ -117,7 +203,7 @@ public override Task SetParametersAsync(ParameterView parameters) // This is the first run // Could put this logic in OnInit, but its nice to avoid forcing people who override OnInitialized to call base.OnInitialized() - RegisterFieldIdentifier(); + CreateFieldIdentifier(); _hasInitializedParameters = true; } @@ -137,12 +223,6 @@ public override Task SetParametersAsync(ParameterView parameters) return base.SetParametersAsync(ParameterView.FromDictionary(parametersDictionary!)); } - - protected BitInputBase() - { - _validationStateChangedHandler = OnValidateStateChanged; - } - protected override void OnInitialized() { ClassBuilder.Register(() => ValueInvalid is true ? "bit-inv" : string.Empty); @@ -151,12 +231,16 @@ protected override void OnInitialized() } + protected bool? ValueInvalid { get => valueInvalid; private set { + if (valueInvalid == value) return; + valueInvalid = value; + ClassBuilder.Reset(); } } @@ -170,91 +254,123 @@ protected TValue? CurrentValue get => Value; set { - if (ValueHasBeenSet && ValueChanged.HasDelegate is false) return; + if (IsEnabled is false) return; - var hasChanged = EqualityComparer.Default.Equals(value, Value) is false; - if (hasChanged is false) return; + if (EqualityComparer.Default.Equals(value, Value)) return; - Value = value; - _ = ValueChanged.InvokeAsync(value); + _parsingFailed = false; - EditContext?.NotifyFieldChanged(FieldIdentifier); + _ = SetCurrentValueAsync(value); } } protected string? CurrentValueAsString { - get => FormatValueAsString(CurrentValue); - set - { - _parsingValidationMessages?.Clear(); + // BitInputBase-derived components can hold invalid states (e.g., an BitNumberField being blank even when bound + // to an int value). So, if parsing fails, we keep the rejected string in the UI even though it doesn't + // match what's on the .NET model. This avoids interfering with typing, but still notifies the EditContext + // about the validation error message. + get => _parsingFailed ? _incomingValueBeforeParsing : FormatValueAsString(CurrentValue); + set => _ = SetCurrentValueAsStringAsync(value); + } - bool parsingFailed; - if (_isUnderlyingTypeNullable && value.HasNoValue()) - { - // Assume if it's a nullable type, null/empty inputs should correspond to default(T) - // Then all subclasses get nullable support almost automatically (they just have to - // not reject Nullable based on the type itself). - parsingFailed = false; - CurrentValue = default; - } - else if (TryParseValueFromString(value, out var parsedValue, out var validationErrorMessage)) - { - parsingFailed = false; - CurrentValue = parsedValue!; - } - else - { - parsingFailed = true; - // EditContext may be null if the input is not a child component of EditForm. - if (EditContext is not null) - { - _parsingValidationMessages ??= new ValidationMessageStore(EditContext); - _parsingValidationMessages.Add(FieldIdentifier, validationErrorMessage); + protected virtual void CreateFieldIdentifier() + { + CreateFieldIdentifier(ValueExpression, typeof(TValue)); + } - // Since we're not writing to CurrentValue, we'll need to notify about modification from here - EditContext.NotifyFieldChanged(FieldIdentifier); - } - } + protected void CreateFieldIdentifier(Expression>? valueExpression, Type valueType) + { + if (valueExpression is not null) + { + FieldIdentifier = FieldIdentifier.Create(valueExpression); + } + else if (ValueChanged.HasDelegate) + { + FieldIdentifier = FieldIdentifier.Create(() => Value); + } - // We can skip the validation notification if we were previously valid and still are - if (parsingFailed || _previousParsingAttemptFailed) - { - EditContext?.NotifyValidationStateChanged(); - _previousParsingAttemptFailed = parsingFailed; - } + if (CascadedEditContext is not null) + { + EditContext = CascadedEditContext; + EditContext.OnValidationStateChanged += _validationStateChangedHandler; } + + _isUnderlyingTypeNullable = Nullable.GetUnderlyingType(valueType) is not null || default(TValue) is null; } protected virtual string? FormatValueAsString(TValue? value) => value?.ToString(); - protected abstract bool TryParseValueFromString(string? value, [MaybeNullWhen(false)] out TValue result, [NotNullWhen(false)] out string? validationErrorMessage); + protected abstract bool TryParseValueFromString(string? value, [MaybeNullWhen(false)] out TValue result, [NotNullWhen(false)] out string? parsingErrorMessage); - protected virtual void RegisterFieldIdentifier() + protected async Task SetCurrentValueAsStringAsync(string? value, bool bypass = false) { - RegisterFieldIdentifier(ValueExpression, typeof(TValue)); - } + if (bypass && IsEnabled is false) return; - protected void RegisterFieldIdentifier(Expression>? valueExpression, Type valueType) - { - if (CascadedEditContext is not null && valueExpression is not null) + _incomingValueBeforeParsing = value; + _parsingValidationMessages?.Clear(); + + if (_isUnderlyingTypeNullable && value.HasNoValue()) { - FieldIdentifier = FieldIdentifier.Create(valueExpression); - EditContext = CascadedEditContext; - EditContext.OnValidationStateChanged += _validationStateChangedHandler; + // Assume if it's a nullable type, null/empty inputs should correspond to default(T) + // Then all subclasses get nullable support almost automatically (they just have to + // not reject Nullable based on the type itself). + _parsingFailed = false; + + CurrentValue = default; } + else if (TryParseValueFromString(value, out var parsedValue, out var parsingErrorMessage)) + { + _parsingFailed = false; - if (Nullable.GetUnderlyingType(valueType) is not null) + if (bypass) + { + Value = parsedValue; + } + else + { + await SetCurrentValueAsync(parsedValue); + } + } + else { - _isUnderlyingTypeNullable = true; - return; + _parsingFailed = true; + + // EditContext may be null if the input is not a child component of EditForm. + if (EditContext is not null) + { + _parsingValidationMessages ??= new ValidationMessageStore(EditContext); + _parsingValidationMessages.Add(FieldIdentifier, parsingErrorMessage); + + // Since we're not writing to CurrentValue, we'll need to notify about modification from here + EditContext.NotifyFieldChanged(FieldIdentifier); + } } - _isUnderlyingTypeNullable = default(TValue) is null; + // We can skip the validation notification if we were previously valid and still are + if (_parsingFailed || _previousParsingAttemptFailed) + { + EditContext?.NotifyValidationStateChanged(); + _previousParsingAttemptFailed = _parsingFailed; + } } + protected async Task SetCurrentValueAsync(TValue? value) + { + if (ValueHasBeenSet && ValueChanged.HasDelegate is false) return; + + Value = value; + + await ValueChanged.InvokeAsync(value); + + EditContext?.NotifyFieldChanged(FieldIdentifier); + + await OnChange.InvokeAsync(value); + } + + private void OnValidateStateChanged(object? sender, ValidationStateChangedEventArgs eventArgs) { @@ -268,11 +384,12 @@ private void UpdateValidationAttributes() if (EditContext is null) return; var hasAriaInvalidAttribute = InputHtmlAttributes is not null && InputHtmlAttributes.ContainsKey("aria-invalid"); + if (EditContext.GetValidationMessages(FieldIdentifier).Any()) { if (hasAriaInvalidAttribute) return; // Do not overwrite the attribute value - if (ConvertToDictionary(InputHtmlAttributes, out var inputHtmlAttributes)) + if (TryConvertingToDictionary(InputHtmlAttributes, out var inputHtmlAttributes)) { InputHtmlAttributes = inputHtmlAttributes; } @@ -288,34 +405,34 @@ private void UpdateValidationAttributes() { ValueInvalid = false; - if (hasAriaInvalidAttribute) - { - // No validation errors. Need to remove `aria-invalid` if it was rendered already + if (hasAriaInvalidAttribute is false) return; + + // No validation errors. Need to remove `aria-invalid` if it was rendered already - if (InputHtmlAttributes!.Count == 1) + if (InputHtmlAttributes!.Count == 1) + { + // Only aria-invalid argument is present which we don't need any more + InputHtmlAttributes = null; + } + else + { + if (TryConvertingToDictionary(InputHtmlAttributes, out var inputHtmlAttributes)) { - // Only aria-invalid argument is present which we don't need any more - InputHtmlAttributes = null; + InputHtmlAttributes = inputHtmlAttributes; } - else - { - if (ConvertToDictionary(InputHtmlAttributes, out var inputHtmlAttributes)) - { - InputHtmlAttributes = inputHtmlAttributes; - } - inputHtmlAttributes.Remove("aria-invalid"); - } + inputHtmlAttributes.Remove("aria-invalid"); } } } - private static bool ConvertToDictionary(IReadOnlyDictionary? source, out Dictionary result) + private static bool TryConvertingToDictionary(IReadOnlyDictionary? source, out Dictionary result) { var newDictionaryCreated = true; - if (source == null) + + if (source is null) { - result = new Dictionary(); + result = []; } else if (source is Dictionary currentDictionary) { @@ -324,7 +441,7 @@ private static bool ConvertToDictionary(IReadOnlyDictionary? sou } else { - result = new Dictionary(); + result = []; foreach (var item in source) { result.Add(item.Key, item.Value); @@ -335,6 +452,7 @@ private static bool ConvertToDictionary(IReadOnlyDictionary? sou } + public void Dispose() { if (IsDisposed) return; diff --git a/src/BlazorUI/Bit.BlazorUI/Components/Inputs/BitTextInputBase.cs b/src/BlazorUI/Bit.BlazorUI/Components/Inputs/BitTextInputBase.cs new file mode 100644 index 0000000000..da041c08de --- /dev/null +++ b/src/BlazorUI/Bit.BlazorUI/Components/Inputs/BitTextInputBase.cs @@ -0,0 +1,97 @@ +namespace Bit.BlazorUI; + +/// +/// A base class for the text-based input components of bit BlazorUI. +/// +/// +public abstract class BitTextInputBase : BitInputBase +{ + private readonly BitDebouncer _debouncer = new(); + private readonly BitThrottler _throttler = new(); + private ChangeEventArgs _lastThrottleEventArgs = default!; + + + + /// + /// The debounce time in milliseconds. + /// + [Parameter] public int DebounceTime { get; set; } + + /// + /// Change the content of the input field when the user write text (based on 'oninput' HTML event). + /// + [Parameter] public bool Immediate { get; set; } + + /// + /// The throttle time in milliseconds. + /// + [Parameter] public int ThrottleTime { get; set; } + + + + public override Task SetParametersAsync(ParameterView parameters) + { + var parametersDictionary = parameters.ToDictionary() as Dictionary; + + foreach (var parameter in parametersDictionary!) + { + switch (parameter.Key) + { + case nameof(DebounceTime): + DebounceTime = (int)parameter.Value; + parametersDictionary.Remove(parameter.Key); + break; + + case nameof(Immediate): + Immediate = (bool)parameter.Value; + parametersDictionary.Remove(parameter.Key); + break; + + case nameof(ThrottleTime): + ThrottleTime = (int)parameter.Value; + parametersDictionary.Remove(parameter.Key); + break; + } + } + + return base.SetParametersAsync(ParameterView.FromDictionary(parametersDictionary!)); + } + + + + /// + /// Handler for the OnChange event. + /// + /// + protected virtual async Task HandleOnStringValueChangeAsync(ChangeEventArgs e) + { + if (IsEnabled is false || ReadOnly) return; + + await SetCurrentValueAsStringAsync(e.Value?.ToString()); + } + + /// + /// Handler for the OnInput event, with an optional delay to avoid to raise the event too often. + /// + /// + protected virtual async Task HandleOnStringValueInputAsync(ChangeEventArgs e) + { + if (IsEnabled is false || ReadOnly) return; + + if (Immediate is false) return; + + if (DebounceTime > 0) + { + await _debouncer.Do(DebounceTime, async () => await InvokeAsync(async () => await HandleOnStringValueChangeAsync(e))); + } + else if (ThrottleTime > 0) + { + _lastThrottleEventArgs = e; + await _throttler.Do(ThrottleTime, async () => await InvokeAsync(async () => await HandleOnStringValueChangeAsync(_lastThrottleEventArgs))); + } + else + { + await HandleOnStringValueChangeAsync(e); + } + } +} diff --git a/src/BlazorUI/Bit.BlazorUI/Components/Inputs/BitTimeFormat.cs b/src/BlazorUI/Bit.BlazorUI/Components/Inputs/BitTimeFormat.cs index 3bad345c03..88aafb4c48 100644 --- a/src/BlazorUI/Bit.BlazorUI/Components/Inputs/BitTimeFormat.cs +++ b/src/BlazorUI/Bit.BlazorUI/Components/Inputs/BitTimeFormat.cs @@ -1,4 +1,5 @@ namespace Bit.BlazorUI; + public enum BitTimeFormat { /// diff --git a/src/BlazorUI/Bit.BlazorUI/Components/Inputs/Calendar/BitCalendar.razor b/src/BlazorUI/Bit.BlazorUI/Components/Inputs/Calendar/BitCalendar.razor index 995244693e..4751b4ec92 100644 --- a/src/BlazorUI/Bit.BlazorUI/Components/Inputs/Calendar/BitCalendar.razor +++ b/src/BlazorUI/Bit.BlazorUI/Components/Inputs/Calendar/BitCalendar.razor @@ -13,9 +13,9 @@
@{ - var todayYear = Culture.Calendar.GetYear(DateTime.Now); - var todayMonth = Culture.Calendar.GetMonth(DateTime.Now); - var todayDay = Culture.Calendar.GetDayOfMonth(DateTime.Now); + var todayYear = _culture.Calendar.GetYear(DateTime.Now); + var todayMonth = _culture.Calendar.GetMonth(DateTime.Now); + var todayDay = _culture.Calendar.GetDayOfMonth(DateTime.Now); } @if (DayPickerIsVisible()) @@ -113,7 +113,7 @@ @for (var index = 0; index < 7; index++) { - var dayOfWeekName = Culture.DateTimeFormat.GetShortestDayName(GetDayOfWeek(index)); + var dayOfWeekName = _culture.DateTimeFormat.GetShortestDayName(GetDayOfWeek(index));
@@ -261,7 +261,7 @@ @for (var cellIndex = 1; cellIndex <= 4; cellIndex++) { var month = (rowIndex * 4) + cellIndex; - var monthName = Culture.DateTimeFormat.GetMonthName(month); + var monthName = _culture.DateTimeFormat.GetMonthName(month); var disabled = IsMonthOutOfMinAndMaxDate(month); var selected = month == _currentMonth;