Git Product home page Git Product logo

tailblazor's Introduction

activity commit deploy

I'm currently working on an overhaul of tailblazor.dev and tailblazor-templates. For tailblazor.dev, this is primarily a content rehash. It will be moved to .NET 7, but it seems the only functional difference will be making use of the new progress properties.

  • Bump to .NET 7
    • make use of .NET 7's new progress info
    • Rewrite content to use the new blazorwasm-empty template
  • Make home page more of a hybrid TOC / "What's in the box" landing page for tailblazor-templates users.
  • Flatten things out a bit, consider breaking it down differently.
  • mention wasm tools
  • @import gotcha re: QuickGrid / other external stuff
  • Finish the "see also" page and link it.
  • Ensure settings.json are up to date: things like explorer.fileNesting, terminal.integrated.autoReplies, etc.
  • Ensure tasks and watch scripts are up to date.
    • For instance, put everything related to VS, VS Code, dotnet CLI in their own location rather than peppered throughout.
  • Make sure to mention suggested vscode settings.
  • Other current issues
  • ...

tailblazor's People

Contributors

mcnerdius avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

tailblazor's Issues

Question: Blazor Hot Reload + Tailwind JIT

Hi there,

Thank you so much for sharing information on this, it's very difficult to find info about this.

I've got a question for you - did you not run into the below issue with Blazor Hot Reload and Tailwind JIT?

dotnet/aspnetcore#34116

I'm using the same approach as you (npx tailwind --watch and dotnet watch run) just without using VScode to run the commands. I did try cloning your TailBlazorLite repo and giving it a spin, but I had some issues, and figured I'm using the same approach, no reason it should work differently.

Feel free to close if not relevant, just thought i'd ask!

Finish migration to .NET 6

  • WASM, Server, RCL projects => 6.0.0
    • Update .NET version in deployment workflow
  • FunctionsAPI, Shared projects - yay !
    • Switch to out-of-process, as this will be the only option in .NET 7

move to tailwind 2.2

  • Try out the new CLI. I've been using postcss-cli rather than the Tailwind CLI as the latter's watch wasn't quite up to snuff. If the new CLI's watch does the job, i'd be able to drop csso explicit dependency in favor of --minify, and build scripts might be a tad simpler with the --watch parameter.
  • Use new opacity shorthand where relevant.
  • Drop explicit usage of transform and filter classes, keeping an eye on variant usage.

Potential Readme updates:

- [ ] Installation steps: csso, cross-env and postcss-cli installs may not be needed if the new CLI is used
- [ ] PostCSS Config: possibly no csso
- [ ] NPM Scripts: possibly swap postcss for tailwind and: watch-* stays largely the same; build-* simply omits --watch rather than specifying TAILWIND_MODE=build; publish-* swaps --env production for --minify
- [ ] ... ?

improve WIP content

  • See Also page
  • Templates page: Add note about the Hosted mode Hot Reload issue
  • About page: move personal ramblings about Tailwind CSS extension here
  • Notes page: mention using "Add Existing Item..." for tailwind-related files in Solution/Project explorer
  • Increase prose plugin's small font size, maybe dial in/prune some other minor prose classes. (It balloons pre-compressed .min.css to 55kb here, 46kb for templates)

Simplify CSS production build steps

As of 0.1:

  • tailwind.css imports /obj/Debug/net5.0/scopedcss/bundle/Shared.styles.css which includes scopes based on build "foo"
  • github workflow runs npm run-script publish-client which includes those scopes
  • github workflow's Static Web Apps runs dotnet publish which generates scopes based on build "bar"
  • By default "foo" and "bar" will have different, random scopes. Adding a static CssScope to csproj per CSS isolated component to circumvent the "foo" vs "bar" scope inconsistency.

The fix:

  • Add <AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath> and <IntermediateOutputPath>obj</IntermediateOutputPath> to Shared.csproj, shortening the tailwind.css import to obj/scopedcss/bundle/Shared.styles.css for both Debug and Release builds.
  • Add a release-config-only post-build event to trigger npm run publish-client to Shared.csproj
  • Change github workflow's npm run-script publish-client to dotnet publish ./Client -c Release which will trigger the above and keep CSS scopes in sync.
  • Change github workflow's Static Web Apps deploy app_location from Client to ./Client/bin/Release/net5.0/publish/wwwroot to the deploy already-published project.

While you're at it: the build-*** scripts in package.json are "broken" - even though --watch has not been passed to postcss, tailwind itself will be in watch mode unless NODE_ENV == production OR TAILWIND_MODE == build. Since we're using production to decide whether or not to minify, setting TAILWIND_MODE to build is the way to go here.

Move to new Tailwind CLI

I'd be able to drop three cross-env, postcss-cli, and csso dependencies as well as simplify the npm scripts a bit.

However, watch behavior was erratic, using the following:

"watch-client": "npx tailwindcss --watch --config tailwind.config.js --postcss postcss.config.js -i ./Shared/Styles/tailwind.css -o ./Client/wwwroot/css/site.min.css"

Watch itself picked up changes, but the builds themselves were incomplete. Same behavior if i passed -p './{Client,Server,Shared}/**/*.{razor,html,cshtml}' explicitly.

I'll try again after upgrading to .NET 6 and getting that end of watch sorted.

untrack generated CSS

early on i tweaked gitignore to track generated CSS: App.min.css and scoped CSS found in /obj/scopedcss to mitigate possible build-chain errors. With the tailwindcss build targets in place this is a non-issue, unless something else is going wrong.

DO NOT CLOSE until possible "something else" scenarios are identified and mitigated in a non-hacky manner.

loading indicator

the functions app can take a while to spin up, add a loading indicator.

Explore template package creation

I'd like to keep this repo a straightforward reference that can be browsed or cloned to get an idea as to what pairing Tailwind with various Blazor project types looks like. But, after one gains an understanding of the tweaks needed, being able to do a dotnet new ... would be great, too.

I created the TailBlazor-Lite repo as a minimal Blazor-Wasm project template - dotnet new tailblazor outputs a tailwindcss version of the default dotnet new blazorwasm template. This is my first and only experience working with dotnet templates.

What i'd like to do is create a template package here and retire TailBlazor-Lite. The TailBlazor-Lite repo is still usable as a "reference" in that it can be browsed and cloned without the template bits getting in the way too much - it is a "Runnable Template". That needs to be the case here as well.

  • Create and structure projects:
    • StaticWebAppsDemo - not a template, for now. Will contain the linked docs-demo.
    • Minimal - Single-project clones of the dotnet templates, like TailBlazorLite
      • TailBlazorWasm / tailblazor-wasm
      • TailBlazorServer / tailblazor-server
      • TailBlazorMaui / tailblazor-maui
      • TailBlazorPages / tailblazor-pages - (Razor Pages w/ Component)
    • TailBlazorFull / tailblazor-full - Basically the repo as it is now, adding Maui and Razor Pages
      • BlazorWasm
      • BlazorServer
      • BlazorMaui
      • RazorPages
  • Create the template package
  • Set up GH Actions to package it up !
  • Plop it on Nuget

Some issues/questions:

  • Should there be multiple template names (tailblazor-wasm, tailblazor-maui, etc) or template options ?
  • There will be a lot of code duplication due to my insisting this all be "Runnable Templates"
  • ...

Show use of CSS custom properties / variables in tailwind.config.js

Overriding/extending the values Tailwind uses when generating classes is trivial - i've shown extending tailwind utilities by adding primary/secondary/accent colors to the config file. Something like class="bg-primary-100" is baked into your HTML; The value of primary is configurable but baked into the CSS on build. It's possible to go a step further and use CSS custom properties/variables in config.

Generated CSS not copied as expected

Client references Shared.

Ideal Publish Steps:

  1. Shared compiles, outputting Isolated CSS - Works as expected.
  2. After Shared compiles, msbuild Target tailwind build feeds Isolated CSS into Tailwind CSS, outputting ./Shared/wwwroot/Shared.css - Works as expected.
  3. Client publishes, taking ./Shared/wwwroot/Shared.css over to /_content/Shared/Shared.css. - Does not work as expected.

Shared.css is only copied over to _content if it existed before the build run began - it will be missing on first build, and one version behind on subsequent builds. Using Message and Exec Command=type Shared.css msbuild Tasks confirms the CSS is on disk before Client begins compiling.

  • The workaround is to use Copy Tasks to put Shared.css directly into Client/wwwroot. - Copy Task not triggered by Hot Reload, tho.
  • A "solution" implies: A) No "manual" copying. B) link href being /_content/Shared/Shared.css. So, the same behavior as expected, presumably with some msbuild help/hinting.

Azure Functions 4 / .NET 6 API

Oryx build fails using the isolated-process / Worker approach for net5.0 with Azure Functions - it has a dependency on 3.1 somewhere. It installs 5.0 SDK and later can't a find 3.1 runtime.

I'm sure installing the 3.1 runtime for the Oryx build is doable but my attempts have failed. If that's accomplished, does Static Web Apps even support the new isolated-process net5.0 Functions ?

ensure new watch/run experience is well-behaved

Given empty node_modules/obj/bin:

  • Ensure best-case Visual Studio debug
    • Triggering npm run build via msbuild Target on Hot Reload not possible; Hot Reload does not trigger msbuild.
  • Ensure best-case VS Code F5 debug
  • Ensure best-case VS Code F5 watch
  • Ensure best-case watch.ps1

tabindex/keyboard toggling

  • Light/Dark toggler in Minimal projects
  • Light/System/Dark switcher in SWA-Demo and Full
  • Hamburger menu in Minimal projects
  • Hamburger menu in SWA-Demo

Proper text overflow handling for Person.Bio

Right now it's a hack, setting Height to 2/3 which works for the wrong reason and cuts off the text in an ugly manner. If i were better at CSS i'd know why the child div is the same height as the parent div, and why the overflow behaves the way it does.

parallel builds fail

The compound launch configurations ("Watch/Debug API & Client") kick off parallel builds which sometimes fail with "file in use". The fix for the Watch compound is to give is a preLaunchTask of Clean & Build All, and point it at two new hidden sub-configs, --no-build versions of the existing Watch sub-configs. For Debug, i'm not so sure: those launch configs are a bit more black-magic.

rename the projects

As it's meant to be a reference rather than a template, it may be better for the project & project folder names reflected exactly what they are:

  • API => FunctionsAPI
  • Client => BlazorWasm
  • Server => BlazorServer
  • Shared => RazorClassLibrary
  • Core => Shared (?)

reduce full rebuilds when using CLI/VSC watch

IDK if this is a dotnet watch regression or if i've just been blind to it as Hot Reload is newish...

(This is all dotnet watch flavor of Hot Reload, not VS)


Prior to Hot Reload

I set up TailWindBuild msbuild property as a hint to dotnet watch to skip the tailwind build Target - npm run watch is taking care of that:
dotnet watch -- run -p:TailwindBuild=false

Scenario:

  • Edit a file
  • dotnet watch does a full rebuild, spitting out a new *.styles.css
  • npm run watch sees the new *.styles.css and does its JIT magic behind the scenes, spitting out a new *.min.css
-p:TailwindBuild=false dotnet tailwind
with ~1.5s 0
without ~1.5s ~2.5s

The choice is simple: 1.5s per edit or 4s ?


With Hot Reload

When passing -p:TailwindBuild=false, some edits trigger a full rebuild, some trigger a Hot Reload. There are no "Unable to apply hot reload because of a rude edit / Do you want to restart your app ?" messages, it just goes and does it. (Edit to clarify: passing the property seems to make a full rebuild much more likely than the normal "rude edits", probably 3-4x moreso).

As expected, the full rebuilds do not trigger the tailwind build Target.

However, dotnet watch -- run -p:TailwindBuild=false results in more full rebuilds than vanilla dotnet watch run.

The scenarios now look like this:

-p:TailwindBuild=false likely edit/rebuild time
with 1.5s
without "fast" + 0

Abandoning -p:TailwindBuild=false:

Hot Reload dotnet tailwind likelyhood
yes "fast" 0 most likely
no ("Rude Edit") ~1.5s ~2.5s unlikely

This may result in slower full rebuilds but as the majority of edits will result in Hot Reloads, the best option for now is to abandon -p:TailwindBuild=false for watch purposes. Perhaps in the future dotnet watch will not trigger full rebuilds when msbuild parameters are passed.

Note on Tailwind CSS build times

On my machine for the (tiny) StaticWebAppsDemo project, Tailwind's incremental builds clock in at around 75ms.

For full builds via npm run build, tailwindcss self-reports ~300ms, but ohmyposh executiontime reports ~2.5s.

Add documentation pages

Readme is bulky. Break it down into sections / Pages, making the demo site more than just a scrolling card thingy. Incorporate FluentUI, see issue #62.

pin static web apps deploy to preview 6

Preview 7 has an issue that breaks the build (ignoring IntermediateOutputPath). Static Web Apps build/deploy will fail using dotnet-version: "6.0.x" as it will install Preview 7. Specify dotnet-version: "6.0.100-preview.6.21355.2"

Improve CSS build steps

As of 0.1:

  1. package.json build-*** scripts are "broken" in that they do not behave as i intended. I don't pass --watch to postcss, but tailwind itself is a watching task (albeit not sufficiently "watchy" compared to the postcss --watch, but i digress). It appeared to work as it didn't stall the dotnet build process. Turns out it just wasn't finishing. ๐Ÿคทโ€โ™‚๏ธ
  2. I haven't sorted out how make the watch-*** scripts (or equivalent) Visual Studio friendly - that is, having tailwind do its JIT thing in the background when you hit F5, not blocking the build, and stopping when you're done debugging. Using Build Tasks in the .csproj to run build-*** are a suboptimal compromise. Including them would have hindered the VS Code experience.

The fix:

  1. Set TAILWIND_MODE=build in the build-*** scripts, using cross-env to be windows friendly.
  2. Changes made for issue #12 means i can specify a launch configuration in VS Code's launch.json (calling it vscode because i'm clever). Result being optimal tailwind JIT experience in VS Code "F5"; minifying one-off build in Release/Publish/Deploy; one-off non-minifying in VS Debug "F5".

Redo structure of CSS

Currently:

  • The "master" input CSS lies in Shared, referencing its css bundle in obj
  • Client and Server have their own npm scripts, outputting directly to their wwwroot

Goal phase 1:

  • "master" site.css lives at root directory, referencing Shared.css and others as need be.
  • Shared.css will @import the bundled CSS from obj and little else.
  • One set of npm scripts, outputting to Shared's wwwroot folder, the html link href being wwwroot/_content/Shared/Shared.css - blocked by #34
  • If Client or Server create their own CSS one of two things happens:
    • Vanilla CSS: link it directly in index.html/_Host.cshtml
    • PostCSS: @import it in site.css and note that it will end up in Shared.css. Hacky and weird but it works. All UI should be in Shared though.

Goal phase 2 - maybe:

Currently, we're relying on not just Blazor's CSS Isolation but the bundling as well. A minor side effect of this is unneeded bundles are copied to wwwroot. Also, a full rebundle happens even if only one component is changed. (OK there's only one component in this project but you get it...) A newish option "Disable Automatic Bundling" exists, leaving it up to us to do the bundling. Faster incremental rebuilds i'd imagine, and no stray files in wwwroot. Downside being either manual referencing of individual components's isolated CSS in Shared.css or adding a dependency on node-glob and doing something like this

  • apply <DisableScopedCssBundling>true</DisableScopedCssBundling> to Shared
  • Change Shared.css to reference individual components' bundled CSS - just obj\scopedcss\Components\PersonCard\PersonCard.razor.rz.scp.css for now.

add a no-hover screen

simple and handy for responsive design:

extend: {
  screens: {
      'no-hover': { 'raw': '(hover:none)' }
  }
}

example usage:

filter blur-md hover:blur-0 no-hover:blur-0

darkswitch regression (flickering)

While #89 had a great fix overall, the light/dark state is only stored in browser localStorage and the DOM, resulting in a flicker when used in RazorPages/MVC. ๐Ÿฅบ

generalize DarkSwitch to ThemeSwitch

Currently, DarkSwitch is used with Tailwind's class dark mode. All it really does is apply a class to <body>, which would play well with CSS variables:

Each theme would have a css class name to apply to <body> and what is essentially a RenderFragment: Currently SVGs and light / dark / system. Generalizing this to Themes rather than just dark/light, the C# and JS would be largely the same, but the UI would differ - perhaps a dropdown if in a menu, or radio buttons if in a settings page. The RenderFragments would be text instead of the current light/system/dark SVGs.

tl;dr: arbitrary UI; click on a RenderFragment and its associated class name is applied to <body>

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.