Is the CoreComponents module a prelude of an official Phoenix components library? Or are they just a great example of defining function components to be reused throughout our application.
Is there any point in the Phoenix roadmap to add an official set of components?
PS:
do you think that open sourcing components is a nice idea (if they don’t really have a specific feature that makes them stand out)?
I am asking because my fear is that a user could be baffled by having to choose between a pletora of similar component libraries (looking at you linux distros!)
I don’t think that components would be officially changed a lot. Phoenix core team prefers Tailwind and they are most probably not going to add support for let’s say Bootstrap or other CSS framework/library. Also the Tailwind styles are prepared for a default look of Phoenix applications.
It would be amazing if somebody would write a library that defines a set of components (i.e. HEEX + live part) and gives a user not only choice which framework/library to use, but also which theme should be applied.
defmodule MyApp.ComponentManager do
use MyLib.ComponentManager, otp_app: :my_app
component :custom_component, MyApp.Components.CustomComponent
style :bootstrap, MyLib.Styles.Bootstrap
# …
theme :theme_name, MyApp.Themes.ThemeName
# …
manage config, %{profile: profile} do
%{
theme: profile.preferred_theme || config[:default_theme],
# …
}
end
prepare _config, _component_module, data do
data
end
end
defimpl MyApp.Themes.ThemeName, for: MyLib.ComponentTheme.Button do
def dark_variant(opts) do
# …
end
def light_variant(opts) do
# …
end
end
defimpl MyLib.Styles.Bootstrap for: MyLib.Component.Button do
def basic_style(opts) do
type = opts[:type] || :primary
# …
end
def render(assigns) do
~H"""
<!-- … -->
"""
end
def sizing_style(opts) do
# …
end
# …
end
alias MyApp.ComponentManager
<ComponentManager.button phx-click="…" profile={@current_user.profile} type: :primary>
Button text …
</ComponentManager.button>
They try to be that while containing all the components needed to support the variuous generators phoenix ships with. They’re meant to be flexible enough to be used outside of that, but they primarily serve that usecase.
There is a direct support for themes in the alpha3 version of Bootstrap 5.3
I took some time this weekend to translate core_components.ex to BS5, but it does not really behave like Tailwind. The modal needs to be different, but the rest is just changing markup and css classes.
There is no reason to make the components module be a config option for your application. It’s just a module you can import… If you want component modules that respond to some styling options, just define a a macro that generates the right AST and generate that AST inside a module. Otherwise if you want some kind of runtime configuration just make your components get those configuration values at runtime.
I’ve been working on this too. It’s available here: GitHub - tmbb/bootstrap5_components: Phoenix components using the bootstrap CSS framework (it used a GitHub dependency which hasn’t bee published on Hex). Not that there are some spacing issues I’m still trying to solve (I’m not by all means a CSS pro) and that Icon handling isn’t great yet (I’m still writing inline CSS in the webpage)
You basically use it like this:
defmodule MyAppWeb.CoreComponents do
use CodeGen,
module: Bootstrap5Components
end
You use my CodeGen module instead of just using Bootstrap5Components directly because CodeGen contains some utilities to dump the source code of the functions defined by Bootstrap5Components so that they can be customized. That way you have the benefits of code generators without the added bloat of the code you don’t want to change.