Lesson 1 — Base classes and the inheritance chain
Why a base class?
In Module 2 every component inherited directly from Phlex::HTML. That works for isolated scripts, but as soon as you have a library of components you want to share behaviour across all of them — helper methods, property declarations, a consistent inheritance root. The base class is where that shared behaviour lives.
The base class
|
|
Three things are happening here:
extend Literal::Properties gives every component the prop macro for declaring its interface. Instead of writing:
|
|
We write:
|
|
Literal generates the initialize method, validates types at instantiation, and assigns instance variables automatically. If you pass the wrong type, Literal raises Literal::TypeError at instantiation — catching bugs at the call site rather than deep inside a template.
class_names is a private helper that builds a class string from multiple sources, filtering out nil and empty strings:
|
|
The inheritance chain every component will follow:
Phlex::HTML
└── Components::Base (shared behaviour)
├── Components::Button
├── Components::Badge
├── Components::Card
└── ... every other componentProp types
Literal supports any Ruby class as a type, plus built-in type constructors:
|
|
Exercise — Components::Heading
Create app/components/heading.rb. Build a Components::Heading component that accepts a text: prop (String) and a level: prop restricted to integers 1–6, defaulting to 1. It should render the correct heading tag based on the level.
Expected output:
|
|
Hint: tag methods are just Ruby methods — call them dynamically with send(:"h#{@level}") { @text }.
Hint: use _Union(1, 2, 3, 4, 5, 6) to restrict the level to valid values. Passing level: 7 should raise Literal::TypeError.
Solution to Exercise 1
|
|
The demo page — first version
Now that we have a component, we can create demo.rb and demo.css. At this stage we use explicit render Components::Heading.new(...) syntax — we will replace this with the cleaner Kit syntax in Lesson 2.
|
|
Don’t forget to download You will need to download the demo CSS file
Run it:
|
|
Your browser opens with three headings, correctly sized and styled by Pico. This is the beginning of the component showcase.