-
-
Notifications
You must be signed in to change notification settings - Fork 5
Extensible Design
Provide a default theme, but still allow customization with Tailwind.
- Use all components out of the box with no customizations required
this use case is fairly straightforward and should not require much outside of choosing a balanced, accessible color scheme.
- Use all components with minor customizations and overrides
this use case is slightly more complicated, due to the question - how can someone easily tweak one or two Tailwind classes without completely re-theming the entire component?
- Use all components with a choice of slightly varied themes based around the core style
this use case may require a dictionary/record type lookup or using
@apply
in Tailwind
- Use all components for logic and functionality with an entirely new theme
same as #3
To modify themes, structures, and sizes many libraries provide an enum
. What needs to be determined is,
- Does this pattern work with extensibility in Tailwind?
- If so, how would this look to a user of the library?
public enum Color
{
Primary,
Secondary,
// etc
}
For sizing, many libraries provide an enum such as Size
public enum Size
{
Small,
Medium,
Large,
}
- Use
@apply
to combine Tailwind classes into custom CSS - Add a
[Parameter]
that allows the caller of the component to pass in their own Tailwind classes, effectively overriding the built-in style
Example
@tailwind base;
@tailwind components;
@tailwind utilities;
@layer components {
.btn-default {
@apply inline-flex items-center bg-gray-800 border-0 py-1 px-3 focus:outline-none hover:bg-gray-700 rounded text-base mt-4 md:mt-0;
}
}
<button class="@Tailwind">@ChildContent</button>
@code {
[Parameter]
public string Tailwind { get; set; } = "btn-default";
[Parameter]
public RenderFragment? ChildContent { get; set; }
private string GetTailwind()
{
switch (ButtonType)
{
case ButtonType.Default
{
return "btn-default";
}
// ...
}
}
}
<!-- No style changes -->
<MakaniButton>Default Button</MakaniButton>
<!-- Overwrites all default styles -->
<MakaniButton Tailwind="bg-gray-700">Customized Button</MakaniButton>
<!-- Adds only bg-gray-600 -->
<MakaniButton Css="bg-gray-600">Default Button with Additional Styling</MakaniButton>
Pros
- Provides default styling to components
- Easy adoption, familiar pattern for those used to other libraries such as Bootstrap
Cons
- Significantly changing styling may require copying styles. could be ok
- See note below from Tailwind Documentation.
Use Tailwind’s utilities directly in your markup the way they are intended to be used, and don’t abuse the @apply feature to do things like this > and you will have a much better experience.
Example
<button class="@Tailwind">@ChildContent</button>
@code {
[Parameter]
public ButtonType ButtonType { get; set; } = ButtonType.Default;
[Parameter]
public string Tailwind { get; set; } = GetTailwind();
[Parameter]
public RenderFragment? ChildContent { get; set; }
private string GetTailwind()
{
switch (ButtonType)
{
case ButtonType.Default
{
return "inline-flex items-center bg-gray-800 border-0 py-1 px-3 focus:outline-none hover:bg-gray-700 rounded text-base mt-4 md:mt-0";
}
// ...
}
}
}
<!-- No style changes -->
<MakaniButton>Default Button</MakaniButton>
<!-- Overwrites all default styles -->
<MakaniButton Tailwind="bg-gray-700">Customized Button</MakaniButton>
<!-- Adds only bg-gray-600 -->
<MakaniButton Css="bg-gray-600">Default Button with Additional Styling</MakaniButton>
Pros
- Less complexity with Makani project structure
- Smaller CSS bundle
- Easier to debug and modify in dev tools
Cons
- Potentially harder for community to customize?
- Harder to debug