VCDry
Simple DSL designed with View Components in mind to make defining and setting keyword arguments and instance variables easier.
Before:
class HeadingComponent < ApplicationComponent
def initialize(text:, tag: "h1", **options)
@text = text
@tag = tag
@options = options
end
endAfter:
class HeadingComponent < ApplicationComponent
include VCDry::DSL
keyword :text
keyword :tag, default: "h1"
other_keywords :options
endTable of Contents
- VCDry
- Table of Contents
- Installation
- General Usage
- Overview
- keyword
- other_keywords
- strict_keywords
- remove_keyword
- Callbacks
- Types
- Development
- Contributing
- License
Installation
Add this line to your application's Gemfile:
gem "vcdry"And then execute:
bundle installGeneral Usage
Overview
Include VCDry::DSL in your component.
class ApplicationComponent < ViewComponent::Base
include VCDry::DSL
endUse the keyword method to define a keyword.
class MyComponent < ApplicationComponent
keyword :name
endBy default, specifying an unknown keyword results in an error.
MyComponent.new(class: "mt-1")
# unknown keyword: :class (VCDry::UnknownArgumentError)To disable this behavior, specify strick_keywords false.
class MyComponent < ApplicationComponent
strict_keywords false
endOr, to save those unknown keywords into a variable, use other_keywords.
class MyComponent < ApplicationComponent
other_keywords :options
endKeywords specified on a parent component are inherited by a child component.
class ApplicationComponent < ViewComponent::Base
include VCDry::DSL
other_keywords :options
end
class ParentComponent < ApplicationComponent
keyword :name
end
class ChildComponent < ParentComponent
keyword :age
end
ChildComponent.new(name: "Child", age: 7, class: "mt-1").instance_variables
# => [:@name, :@age, :@options]keyword
Define a keyword variable to read and store to an instance variable when instantiating a component.
class MyComponent
keyword :name
endSpecify a type to typecast the value specified.
class MyComponent
keyword :name, :string
endYou can use any of the built-in types or create your own as defined in Types. Additionally you can specify a proc to define your own one off type for a component.
class MyComponent
keyword :name, ->(value) { "custom #{value}" }
endBy default, keywords are required. To make a keyword optional, specify a default
value using the :default or pass optional: true.
class MyComponent
keyword :padding, :integer, optional: true
keyword :size, :symbol, default: :md
endWhen specifying a default, you can also pass the value as a proc to resolve the default value.
class MyComponent
keyword :options, :hash, default: -> { Hash.new }
endYou can instruct a keyword to only accept a predefined set of values by using
the :values option.
class MyComponent
keyword :size, :symbol, values: [:sm, :md, :lg]
endYou can also instruct a keyword to accept an array of values by passing the
array: true option.
class MyComponent
keyword :author_ids, :string, array: true
endA child component can override the declaration of a keyword from a parent component.
class MyOtherComponent < MyComponent
keyword :author_ids, :integer, array: true
endother_keywords
To gather all keywords not explicitly defined by the keyword method, use the
other_keywords method.
class MyComponent
keyword :name
other_keywords :options
endIn the example above, the :name keyword would be stored in the variable
@name while all other keywords specified would be stored in the variable
@options.
If you have a custom type defined that acts similarly to a Hash (like the
TagOptions::Hash gem), you can pass
that in to the other_keywords declaration.
class MyComponent
other_keywords :options, :tag_options
endNote: You must register a custom type using VCDry::Types.add_type as
detailed in Types.
strict_keywords
By default, if you specify a unknown keyword when instantiating a component an
error will be raised. To silently discard the additional keywords, use the
strict_keywords false declaration.
class MyComponent
keyword :name
strict_keywords false
endTo turn it back on for a component that inherits from parent component that
turned off strict keywords, use the strict_keywords true declaration.
class MyOtherComponent < MyComponent
strict_keywords true
endremove_keyword
To remove a keyword specified on a component that inherits from parent
component, use the remove_keyword method.
class MyOtherComponent < MyComponent
remove_keyword :name
endCallbacks
Including VCDry::DSL adds support through ActiveModel::Callbacks for the
before_initialize, after_initialization, and around_initialize callbacks
to minimize the need to override the initlialize method.
class MyComponent < MyComponent
before_initialize ->() { @links = [] }
after_intialize :some_method
private
def some_method
# do something fancy
end
endTypes
The following types are built-in to vcdry.
- boolean
- datetime
- hash
- integer
- string
- symbol
Additionally you can define custom, or override built-in, types by using
VCDry::Types.add_type.
# config/initializers/vcdry_types.rb
VCDry::Types.add_type(:boolean, ->(value) { ActiveRecord::Type::Boolean.new.cast(value) })
VCDry::Types.add_type(:custom_hash, ->(value) { CustomHash.new(value) })Mix-in Behavior
To mix-in the keyword behavior without using the VCDry::DSL (and its
initialize method), you can call include VCDry::Core instead and then call
vcdry_parse_keywords against the hash you wish to parse out keywords from.
The vcdry_parse_keywords accepts a hash and returns a hash of all key/value
pairs that were not pulled out as a keyword.
Note: Including
VCDry::Coredoes not include support forother_keywords,strict_keywords, or enable support for callbacks.
class HeadingComponent
include VCDry::Core
keyword :size, :symbol, default: :md
other_keywords :options
def initialize(text, **options)
@text = text
@options = vcdry_parse_keywords(options)
end
endDevelopment
After checking out the repo, run bin/setup to install dependencies. Then, run
bin/rspec to run the tests. You can also run:
-
bin/consolefor an interactive prompt that will allow you to experiment -
bin/rubocopto run RuboCop to check the code style and formatting
To build this gem on your local machine, run bundle exec rake build. To
release a new version, update the version number in version.rb, and then run
bundle exec rake release, which will create a git tag for the version, push
git commits and the created tag, and push the .gem file to
rubygems.org.
Contributing
Bug reports and pull requests are welcome on GitHub at https://github.com/wamonroe/vcdry.
License
The gem is available as open source under the terms of the MIT License.