Skip to content

Commit

Permalink
Allow recursively nested tokens in attributes (#807)
Browse files Browse the repository at this point in the history
If you have a component that you want to take in an attribute of a token
list, like `class`, and you want your interface to be polymorphic like
an element method's attributes would be, you currently need to type
check the provided attribute and handle it manually.

```rb
class Card < Phlex::HTML
  def initialize(class:)
    @Class = grab(class:)
  end

  def view_template
    div(class: ["component-classes", @Class])
  end
end
```

Before this PR, the above example will break if the person using the
Card component tries to supply an array of classes, because `Array` is
not a valid token type for `__nested_tokens__`.

```rb
render Card.new(class: "fine") # => <div class="component-classes fine"></div>
render Card.new(class: ["not-fine"]) # => 💥 
```

Now if an array is passed, it will also have `__nested_tokens__` called
on it.

```rb
render Card.new(class: ["now-fine"]) # => <div class="component-classes now-fine"></div>
```
  • Loading branch information
willcosgrove authored Oct 4, 2024
1 parent 42228c2 commit 86e565d
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 0 deletions.
8 changes: 8 additions & 0 deletions lib/phlex/sgml.rb
Original file line number Diff line number Diff line change
Expand Up @@ -502,6 +502,14 @@ def __nested_tokens__(tokens)
else
buffer << token.to_s
end
when Array
if token.length > 0
if i > 0
buffer << " " << __nested_tokens__(token)
else
buffer << __nested_tokens__(token)
end
end
when nil
# Do nothing
else
Expand Down
18 changes: 18 additions & 0 deletions quickdraw/sgml/attributes.test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,24 @@
) == %(<div attribute="Hello"></div>)
end

test "_, Array(String | Array)" do
expect(
phlex { div(attribute: ["hello", ["world"]]) },
) == %(<div attribute="hello world"></div>)
end

test "_, Array(Array | String)" do
expect(
phlex { div(attribute: [["hello"], "world"]) },
) == %(<div attribute="hello world"></div>)
end

test "_, Array(String | EmptyArray)" do
expect(
phlex { div(attribute: ["hello", []]) },
) == %(<div attribute="hello"></div>)
end

test "_, Array(*invalid*)" do
expect {
phlex { div(attribute: [Object.new]) }
Expand Down

0 comments on commit 86e565d

Please sign in to comment.