Skip to content

Commit

Permalink
Merge pull request #4551 from alphagov/cw-add-rel
Browse files Browse the repository at this point in the history
Add rel attribute to component wrapper
  • Loading branch information
andysellick authored Jan 15, 2025
2 parents 4043e62 + 0fd801e commit ac48418
Show file tree
Hide file tree
Showing 5 changed files with 83 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
* **BREAKING** Use component wrapper on big number component ([PR #4550](https://github.com/alphagov/govuk_publishing_components/pull/4550))
* **BREAKING** Use component wrapper on attachment component ([PR #4545](https://github.com/alphagov/govuk_publishing_components/pull/4545))
* **BREAKING** Use component wrapper on attachment link component ([PR #4549](https://github.com/alphagov/govuk_publishing_components/pull/4549))
* Add rel attribute to component wrapper ([PR #4551](https://github.com/alphagov/govuk_publishing_components/pull/4551))
* Add 'draggable' attribute to component wrapper helper ([PR #4544](https://github.com/alphagov/govuk_publishing_components/pull/4544))

## 48.0.0
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ def self.description
- `tabindex` - accepts an integer. The integer can also be passed as a string.
- `dir` - accepts 'rtl', 'ltr', or 'auto'.
- `type` - accepts any valid type attribute e.g. 'button', 'submit', 'text'.
- `rel` - accepts any valid rel attribute e.g. 'nofollow'.
- `draggable` - accepts a draggable attribute value (\"true\" or \"false\")
"
end
Expand Down
34 changes: 34 additions & 0 deletions docs/component-wrapper-helper.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ These options can be passed to any component that uses the component wrapper.
- `tabindex` - accepts an integer. The integer can also be passed as a string.
- `dir` - accepts 'rtl', 'ltr', or 'auto'.
- `type` - accepts any valid type attribute e.g. 'button', 'submit', 'text'
- `rel` - accepts any valid rel attribute e.g. 'nofollow'
- `draggable` - accepts a draggable attribute value ("true" or "false")
To prevent breaking [component isolation](https://github.com/alphagov/govuk_publishing_components/blob/main/docs/component_principles.md#a-component-is-isolated-when), passed classes should only be used for JavaScript hooks and not styling. All component styling should be included only in the component itself. Any passed classes should be prefixed with `js-`. To allow for extending this option, classes prefixed with `gem-c-`, `govuk-`, `app-c-`, `brand--`, or `brand__` are also permitted, as well as an exact match of `direction-rtl`, but these classes should only be used within the component and not passed to it.
Expand Down Expand Up @@ -84,9 +85,42 @@ The component wrapper includes several methods to make managing options easier,
component_helper.set_dir("rtl")
component_helper.set_type("text")
component_helper.set_draggable("true")
component_helper.set_rel("nofollow") # overrides any existing rel
component_helper.add_rel("noopener") # adds to existing rel
component_helper.set_margin_bottom(3) # can pass any number from 1 to 9
%>
<%= tag.div(**component_helper.all_attributes) do %>
component content
<% end %>
```
### Set and add methods
There are two kinds of methods for options shown above: `set` (e.g. `set_id`) and `add` (e.g. `add_class`). Either or both methods may be available for any option.
Set methods are used to override a passed value with a new one, particularly for situations where the option can be only one value (e.g. `id`). This might be used with conditional logic or because the option should never be changed.
```ruby
<%
component_helper = GovukPublishingComponents::Presenters::ComponentWrapperHelper.new(local_assigns)
component_helper.set_lang("en") if some_other_option # conditionally set the lang based on other variables
%>
```

```ruby
<%
component_helper = GovukPublishingComponents::Presenters::ComponentWrapperHelper.new(local_assigns)
component_helper.set_tabindex(-1) # effectively hardcode the option
%>
```
Add methods are used to combine one or more values. This includes adding to anything that has already been passed to the component.
```ruby
<%
component_helper = GovukPublishingComponents::Presenters::ComponentWrapperHelper.new(local_assigns)
component_helper.add_class("gem-c-example")
component_helper.add_class("gem-c-example--large") if size == 'large'
# class output could be `js-passed-class gem-c-example gem-c-example--large
%>
```
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ def initialize(options)
check_dir_is_valid(@options[:dir]) if @options.include?(:dir)
check_type_is_valid(@options[:type]) if @options.include?(:type)
check_draggable_is_valid(@options[:draggable]) if @options.include?(:draggable)
check_rel_is_valid(@options[:rel]) if @options.include?(:rel)
check_margin_bottom_is_valid(@options[:margin_bottom]) if @options.include?(:margin_bottom)
end

Expand All @@ -37,6 +38,7 @@ def all_attributes
attributes[:dir] = @options[:dir] unless @options[:dir].blank?
attributes[:type] = @options[:type] unless @options[:type].blank?
attributes[:draggable] = @options[:draggable] unless @options[:draggable].blank?
attributes[:rel] = @options[:rel] unless @options[:rel].blank?

attributes
end
Expand Down Expand Up @@ -101,6 +103,16 @@ def set_draggable(draggable_attribute)
@options[:draggable] = draggable_attribute
end

def add_rel(rel_attribute)
check_rel_is_valid(rel_attribute)
extend_string(:rel, rel_attribute)
end

def set_rel(rel_attribute)
check_rel_is_valid(rel_attribute)
@options[:rel] = rel_attribute
end

def set_margin_bottom(margin_bottom)
check_margin_bottom_is_valid(margin_bottom)
@options[:margin_bottom] = margin_bottom
Expand Down Expand Up @@ -224,6 +236,15 @@ def check_draggable_is_valid(draggable_attribute)
end
end

def check_rel_is_valid(rel_attribute)
return if rel_attribute.blank?

options = %w[alternate author bookmark canonical dns-prefetch external expect help icon license manifest me modulepreload next nofollow noopener noreferrer opener pingback preconnect prefetch preload prerender prev privacy-policy search stylesheet tag terms-of-service]
unless options.include? rel_attribute
raise(ArgumentError, "rel attribute (#{rel_attribute}) is not recognised")
end
end

def extend_string(option, string)
((@options[option] ||= "") << " #{string}").strip!
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -388,6 +388,32 @@
end
end

describe "rel" do
it "does not accept an invalid rel value" do
error = "rel attribute (hubris) is not recognised"
expect {
GovukPublishingComponents::Presenters::ComponentWrapperHelper.new(rel: "hubris")
}.to raise_error(ArgumentError, error)
end

it "accepts valid rel value" do
component_helper = GovukPublishingComponents::Presenters::ComponentWrapperHelper.new(rel: "nofollow")
expect(component_helper.all_attributes[:rel]).to eql("nofollow")
end

it "can set a rel, overriding a passed value" do
helper = GovukPublishingComponents::Presenters::ComponentWrapperHelper.new(rel: "nofollow")
helper.set_rel("noreferrer")
expect(helper.all_attributes[:rel]).to eql("noreferrer")
end

it "can add a rel to an existing rel" do
helper = GovukPublishingComponents::Presenters::ComponentWrapperHelper.new(rel: "nofollow")
helper.add_rel("noreferrer")
expect(helper.all_attributes[:rel]).to eql("nofollow noreferrer")
end
end

describe "margins" do
it "complains about an invalid margin" do
error = "margin_bottom option (15) is not recognised"
Expand Down

0 comments on commit ac48418

Please sign in to comment.