-
-
Notifications
You must be signed in to change notification settings - Fork 407
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
RFC: Yield link-to component state #275
Closed
Closed
Changes from all commits
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,126 @@ | ||
- Start Date: 2017-12-10 | ||
- RFC PR: | ||
- Ember Issue: | ||
|
||
# Summary | ||
|
||
A proposal to allow the `link-to` helper to expose the active state via | ||
`yield`. Doing so can allow more flexible use cases and DOM layouts. | ||
|
||
# Motivation | ||
|
||
`link-to` will add an `active` class to its element when the route matches. | ||
However, many CSS frameworks or addons require a more specific layout where the | ||
inner child needs the `active` class but the `onclick` event needs to be on the | ||
parent link-to element. For example, Bootstrap CSS requires the child element to | ||
have the `active` state to render correctly but the parent element must have the | ||
`onclick` event handler otherwise the target area when rendered does not cover the | ||
entire UI (due to margins/padding). | ||
|
||
`link-to` also knows how to generate a URL (href) based on the route name. | ||
Doing this conversion manually each time means the understanding of route name to | ||
URL will be in multiple places in the app when instead could be calculated if | ||
exposed by `link-to`. | ||
|
||
# Detailed design | ||
|
||
The syntax for `link-to` follows the convention of yielding to the consumer. It is | ||
expected that clicking the `link-to` element will perform the route transition and | ||
when the target route matches the current route the same element receives the | ||
`active` class. The content of the element rendered to the DOM is often provided | ||
by the consumer as yielded content. | ||
|
||
```hbs | ||
{{#link-to "my-route" tagName="li"}} | ||
<a href="/hard/coded">Yielded Content</a> | ||
{{/link-to}} | ||
``` | ||
|
||
Which renders as: | ||
|
||
```html | ||
<li class="active"> | ||
<a href="/hard/coded">Yielded Content</a> | ||
</li> | ||
``` | ||
|
||
By yielding the active and href state we can leverage the `link-to` logic in the | ||
context of our own code: | ||
|
||
```hbs | ||
{{! Example 1 }} | ||
{{#link-to "my-route" tagName="li" as |link|}} | ||
<a href={{link.href}} class="{{if link.active 'active'}}">My Route</a> | ||
{{/link-to}} | ||
|
||
{{! Example 2 }} | ||
{{#link-to "my-route" tagName="li" as |link|}} | ||
{{#if link.active}} | ||
<span class="current-route red">Current Route</span> | ||
{{else}} | ||
<a href={{link.href}}>My Route</a> | ||
{{/if}} | ||
{{/link-to}} | ||
``` | ||
|
||
# How We Teach This | ||
|
||
The documentation for `link-to` will change the yield example to include a yielded | ||
variable called `link` which will have two properties `link.active` and | ||
`link.href`. A paragraph to explain that meaning of them and an example (see | ||
above) to illustrate a possible use case. | ||
|
||
Since this feature adds functionality to an existing API the current guides on | ||
the link-to helper are enough as they are since it covers most use cases. When a | ||
user needs more information (such as looking up `tagName` and `class`) via the | ||
API section they can also discover the use of this feature. | ||
|
||
This change would **not** modify how Ember is taught. It is backwards-compatible with current practices and typical usage out in the wild. The added | ||
functionality need only documented once in the API for link-to. | ||
|
||
Most existing Ember users are familiar with the use of yielded variables and | ||
adding this would not need much education beyond just letting them know it is | ||
available via a ChangeLog and in the API documentation for the link-to component. | ||
|
||
# Drawbacks | ||
|
||
A tradeoff is that the two exposed values now become public. Which means it does | ||
add the slight overhead to maintaining this part of the code since once made | ||
public it will require more scrutiny before changing. | ||
|
||
# Alternatives | ||
|
||
This section could also include prior art, that is, how other frameworks in the | ||
same domain have solved this problem. | ||
|
||
Per this [Stack Overflow question][1] you can nest the link-to twice to cover | ||
the specific Bootstrap problem. Unfortunately, it does not offer the flexibility | ||
this feature allows for more advanced use cases. | ||
|
||
The same [Stack Overflow question][1] also has a suggestion of wrapping the | ||
link-to in a custom component which can investigate its DOM for active elements: | ||
|
||
```js | ||
export default Ember.Component.extend({ | ||
tagName: 'li', | ||
classNameBindings: ['active'], | ||
active: Ember.computed('[email protected]', { | ||
get() { | ||
return this.get('childViews').anyBy('active'); | ||
} | ||
}) | ||
}); | ||
``` | ||
|
||
The disadvantage here is that the `onclick` handler is not on the parent element | ||
and can cause styling problems if that requirement is needed. **This alternative | ||
is no longer available since use of Glimmer.** | ||
|
||
[1]: https://stackoverflow.com/questions/14328295/how-do-i-bind-to-the-active-class-of-a-link-using-the-new-ember-router | ||
|
||
# Unresolved questions | ||
|
||
1. What other drawbacks exist? | ||
2. Are there other alternatives/workarounds that haven't been explored in | ||
this RFC? | ||
3. Which other use cases should be documented in this RFC? |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We have a Guide dedicated to
link-to
, where it would likely be warranted for the API in this RFC to be covered.