Skip to content

Commit

Permalink
feat: dynamic styling via block params
Browse files Browse the repository at this point in the history
  • Loading branch information
palkan committed Nov 26, 2023
1 parent 88c5153 commit 25d0aa0
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 1 deletion.
26 changes: 26 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,32 @@ class ButtonComponent < ViewComponent::Base
end
```

### Dependent (or compound) styles

Sometimes it might be necessary to define complex styling rules, e.g., when a combination of variants requires adding additional styles. That's where usage of Ruby blocks for configuration becomes useful. For example:

```ruby
style do
variants {
size {
sm { "text-sm" }
md { "text-base" }
lg { "px-4 py-3 text-lg" }
}
theme {
primary do |size:, **|
%w[bg-blue-500 text-white].tap do
_1 << "uppercase" if size == :lg
end
end
secondary { %w[bg-purple-500 text-white] }
}
}
end
```

The specified variants are passed as block arguments, so you can implement dynamic styling.

### Using with TailwindCSS LSP

To make completions (and other LSP features) work with our DSL, try the following configuration:
Expand Down
2 changes: 1 addition & 1 deletion lib/view_component_contrib/style_variants.rb
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ def compile(**variants)

@defaults.merge(variants.compact).each do |variant, value|
variant = @variants.dig(variant, value) || next
styles = variant.is_a?(::Proc) ? variant.call : variant
styles = variant.is_a?(::Proc) ? variant.call(**variants) : variant
acc.concat(Array(styles))
end

Expand Down
35 changes: 35 additions & 0 deletions test/cases/style_variants_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,27 @@ class DiffStyleSubcomponent < Component
end
end

class CompoundComponent < Component
style do
variants {
size {
sm { %w[text-sm] }
md { %w[text-md] }
lg { %w[text-lg] }
}
theme {
primary do |size:, **|
%w[primary-color primary-bg].tap do
_1 << "uppercase" if size == :lg
end
end

secondary { %w[secondary-color secondary-bg] }
}
}
end
end

def test_render_variants
component = Component.new

Expand Down Expand Up @@ -153,4 +174,18 @@ def test_style_config_inheritance

assert_css "div.text-white.font-md"
end

def test_dynamic_variants
component = CompoundComponent.new

render_inline(component)

assert_css "div.primary-color.primary-bg.text-md"

component = CompoundComponent.new(theme: :primary, size: :lg)

render_inline(component)

assert_css "div.primary-color.primary-bg.text-lg.uppercase"
end
end

0 comments on commit 25d0aa0

Please sign in to comment.