CLI

The CLI overview. Briefly mentions the CLI's internals.

Commands

Root

Use the CLI from the project directory.

shadcnblazor [command]
1
2
3
4
5
6
7
8
9
10
USAGE:
    ShadcnBlazor.Cli.dll [OPTIONS] <COMMAND>

OPTIONS:
    -h, --help    Display help

COMMANDS:
    new          Creates a new Blazor project from a template
    repair       Re-add Shared component with overwrite. Use if setup was broken or incomplete
    component    Component management. Shared and its dependencies are added automatically

new

Creates a new Blazor project from a template.

shadcnblazor new --wasm --proj MyApp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
DESCRIPTION:
Creates a new Blazor project from a template

USAGE:
    ShadcnBlazor.Cli.dll new [OPTIONS]

OPTIONS:
                        DEFAULT
    -h, --help                        Display help
    --wasm                            Use the WebAssembly standalone template
    --server                          Use the Blazor Server (global interactivity) template
    -p, --proj <NAME>                 Project name, root namespace, and default output folder
    -o, --out <DIR>                   Output directory. Default: ./{proj}
    --net <VERSION>         9         Target .NET version (9 only for now)

repair

Re-add Shared component with overwrite. Use if setup was broken or incomplete.

shadcnblazor repair
1
2
3
4
5
6
7
8
9
10
DESCRIPTION:
Re-add Shared component with overwrite. Use if setup was broken or incomplete

USAGE:
    ShadcnBlazor.Cli.dll repair [OPTIONS]

OPTIONS:
                DEFAULT
    -h, --help                Display help
    --silent    false         Mutes output

component

Component management. Shared and its dependencies are added automatically.

shadcnblazor component add [component]
1
2
3
4
5
6
7
8
9
10
11
12
13
DESCRIPTION:
Component management. Shared and its dependencies are added automatically

USAGE:
    ShadcnBlazor.Cli.dll component [OPTIONS] <COMMAND>

OPTIONS:
    -h, --help    Display help

COMMANDS:
    add [name]     Adds a component to a project. Use --all to add all. Runs first-time setup automatically if needed
    list           Lists all available components
    info <name>    Displays details related to a component

add

Adds a component to a project. Runs first-time setup automatically if needed.

shadcnblazor component add [component]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
DESCRIPTION:
Adds a component to a project. Runs first-time setup automatically if needed

USAGE:
    ShadcnBlazor.Cli.dll component add [OPTIONS] [name]

ARGUMENTS:
    name    The name of the component to add (input, textarea, checkbox, etc.). Omit when using --all

OPTIONS:
                DEFAULT
    -h, --help                Display help
    -a, --all    false        Adds all available components (name not required)
    --silent    false         Mutes output
    --overwrite  false        Overwrite if component already exists (no prompt)

Internals

Components Registry

The CLI tool contains a hardcoded registry which contains all components, as well as their dependencies and additional actions required for a full installation. An example of a component entry in the registry looks like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
[
    {
        "name": "Shared",
        "description": "Base classes, enums, services, and utilities required by all components",
        "dependencies": [],
        "required_actions": [
            {
                "$type": "copyCss",
                "css_file_name": "shadcn_blazor_in.css",
                "link": false
            },
            {
                "$type": "copyCss",
                "css_file_name": "shadcn_blazor_out.css",
                "link": false
            },
            {
                "$type": "addCssLinksToRoot"
            },
            {
                "$type": "addNugetDependency",
                "package_name": "TailwindMerge.NET",
                "version": "1.2.0"
            },
            {
                "$type": "addProgramService",
                "using_namespace": "TailwindMerge.Extensions",
                "service_call": "AddTailwindMerge()"
            },
            {
                "$type": "mergeToImports",
                "namespaces": ["ShadcnBlazor.Components.Shared"]
            }
        ]
    }
]

That is to say that that CLI automatically handles actions such as namespace conversion/resolution, adding .js and .css files to wwwroot, adding C# Nuget dependencies, etc. In addition to these actions, the CLI resolves dependencies between components, adding any declared sub-components if not present in the output path. For example, take below:

1
2
3
4
5
Component Dependency Tree:      (2 dependencies)
Select
├── Popover
│   └── Shared
└── Shared

The CLI starts at the deepest node, then walks up the dependency tree, copying the component into the output path, fixing namespaces and performing any additional declared actions. For the above component, the CLI would first copy Shared, then Popover, then finally the intended component, Select.

Component Structure

Most components are simple, containing the main .razor file and sometimes a backing .razor.cs file.

1
2
3
Card/
├── Card.razor
└── Card.razor.cs

However, for more complex components, additional files such as sub-components, models, and service files are bundled within the directory (such as the below Dialog component).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Dialog/
├── Declarative/
│   ├── DialogRoot.razor
│   ├── DialogContent.razor
│   ├── DialogTrigger.razor
│   └── ... (5 more files)
├── Models/
│   ├── DialogOptions.cs
│   ├── DialogResult.cs
│   └── ... (4 more files)
├── Services/
│   ├── DialogService.cs
│   └── IDialogService.cs
├── Dialog.razor
├── DialogProvider.razor
├── DialogReference.cs
└── ... (3 more files)

Recall that components are added to the Components directory within the project. It may seem counterintuitive to have models and services within the components folder, but this is an intentional design choice to ensure that the components self-contained and independently copyable. That is to say that it also allows arguably better integration with existing projects, as it prevents the "pollution" of the components' code with that of the project.

The "Shared" Component

Continuing with the aforementioned idea of keeping all component functionality self-contained within the component's directory, you can find that we apply the exact same principle with the shared/common code between all components. Instead of populating Services, Models, etc. in the project root, all common code is shipped as a "pseudo-component" Shared.

1
2
3
4
5
6
7
8
9
10
11
12
13
Shared/
├── Models/
│   ├── Enums/
│   │   ├── Size.cs
│   │   ├── Variant.cs
│   │   └── ... (2 more files)
│   └── Options/
│       └── ... (2 more files)
├── Services/
│   └── ... (service files)
├── Interop/
│   └── ... (interop files)
└── ShadcnComponentBase.cs

As can be seen from above, this includes enums, common interop services, options, etc. Doing this allows the bulk majority code changes to happen within a specific folder within the Components directory, rather than to different folders spread out within the project.

Unlike other component libraries, this setup means that there isn't a single "core" function AddShadcnServices() or "core" .js script <script src="_content/MudBlazor/MudBlazor.min.js?v=1"></script>. While it can be argued that this makes the overall setup more fragmented and complex, it can be reasoned that this is a side effect of the design choices to make components self-contained and independently copyable, which is a core principle of this library.

Loading...

An unhandled error has occurred. Reload 🗙