Skip to content

Commit

Permalink
feat(linked-item): add current when argument for tab and subnav items
Browse files Browse the repository at this point in the history
  • Loading branch information
anehx authored and czosel committed Oct 3, 2023
1 parent 7c7e7fa commit b4557b0
Show file tree
Hide file tree
Showing 8 changed files with 95 additions and 19 deletions.
46 changes: 28 additions & 18 deletions addon/components/-private/linked-list-item.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,25 +28,45 @@ export default class LinkedListItemComponent extends Component {
}

get href() {
if (!this.args.href) return null;
return this.getAbsoluteHref(this.args.href);
}

get route() {
return this.getRouteInfo(this.href, this.args.linkToIndex);
}

get active() {
if (!this.route || this.args.active !== undefined) {
return this.args.active ?? false;
}

const { name, args } = this.args.currentWhen
? this.getRouteInfo(this.getAbsoluteHref(this.args.currentWhen))
: this.route;

return this.router.isActive(name, ...args);
}

getAbsoluteHref(relativeHref) {
if (!relativeHref) return null;

/* istanbul ignore next */
if (this.isEngineRouter) {
const engineRoot = this._router.urlFor("application");

// Append the engine root to the url in case the engine didn't already
return this.args.href.startsWith(engineRoot)
? this.args.href
: `${engineRoot}${this.args.href}`;
? relativeHref
: `${engineRoot}${relativeHref}`;
}

return this.args.href;
return relativeHref;
}

get route() {
if (!this.href) return null;
getRouteInfo(absoluteHref, linkToIndex = false) {
if (!absoluteHref) return null;

let href = this.href;
let href = absoluteHref;

/* istanbul ignore next */
if (this.router.location.implementation === "hash") {
Expand All @@ -64,7 +84,7 @@ export default class LinkedListItemComponent extends Component {
if (!routeInfo) return null;

return {
name: this.args.linkToIndex
name: linkToIndex
? routeInfo.name
: routeInfo.name.replace(/\.index$/, ""),
args: [
Expand All @@ -76,16 +96,6 @@ export default class LinkedListItemComponent extends Component {
};
}

get active() {
if (!this.route || this.args.active !== undefined) {
return this.args.active ?? false;
}

const { name, args } = this.route;

return this.router.isActive(name, ...args);
}

@action
navigate(event) {
event.preventDefault();
Expand Down
3 changes: 3 additions & 0 deletions tests/dummy/app/components/option-select.hbs
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
<select class="uk-select" {{on "change" this.change}}>
{{#if @hasEmpty}}
<option value="" selected={{not @selected}}>-</option>
{{/if}}
{{#each @options as |opt|}}
<option value={{opt}} selected={{eq opt @selected}}>{{opt}}</option>
{{/each}}
Expand Down
3 changes: 2 additions & 1 deletion tests/dummy/app/components/option-select.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ export default class OptionSelectComponent extends Component {
change(event) {
event.preventDefault();

this.args.onChange(event.target.value);
const value = event.target.value;
this.args.onChange(value === "" ? null : value);
}
}
1 change: 1 addition & 0 deletions tests/dummy/app/controllers/docs/components/subnav.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export default class DocsComponentsSubnavController extends Controller {
@tracked itemDisabled = false;
@tracked linkItemDisabled = false;
@tracked href = this.router.currentURL;
@tracked currentWhen = null;
@tracked linkToIndex = false;

get availableRoutes() {
Expand Down
1 change: 1 addition & 0 deletions tests/dummy/app/controllers/docs/components/tab.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export default class DocsComponentsTabController extends Controller {
@tracked itemDisabled = false;
@tracked linkItemDisabled = false;
@tracked href = this.router.currentURL;
@tracked currentWhen = null;
@tracked linkToIndex = false;

get availableRoutes() {
Expand Down
19 changes: 19 additions & 0 deletions tests/dummy/app/templates/docs/components/subnav.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,25 @@
/>
</td>
</tr>
<tr>
<td><code>currentWhen</code></td>
<td><code>String</code></td>
<td></td>
<td>
URL of a route which causes the item to be marked as active if
that route is active (similar to the functionality
<code>LinkTo</code>
provides).
</td>
<td>
<OptionSelect
@hasEmpty={{true}}
@options={{this.availableRoutes}}
@selected={{this.currentWhen}}
@onChange={{fn (mut this.currentWhen)}}
/>
</td>
</tr>
<tr>
<td><code>linkToIndex</code></td>
<td><code>Boolean</code></td>
Expand Down
20 changes: 20 additions & 0 deletions tests/dummy/app/templates/docs/components/tab.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
</tab.item>
<tab.item
@href={{this.href}}
@currentWhen={{this.currentWhen}}
@disabled={{this.linkItemDisabled}}
@linkToIndex={{this.linkToIndex}}
>
Expand Down Expand Up @@ -173,6 +174,25 @@
/>
</td>
</tr>
<tr>
<td><code>currentWhen</code></td>
<td><code>String</code></td>
<td></td>
<td>
URL of a route which causes the item to be marked as active if
that route is active (similar to the functionality
<code>LinkTo</code>
provides).
</td>
<td>
<OptionSelect
@hasEmpty={{true}}
@options={{this.availableRoutes}}
@selected={{this.currentWhen}}
@onChange={{fn (mut this.currentWhen)}}
/>
</td>
</tr>
<tr>
<td><code>linkToIndex</code></td>
<td><code>Boolean</code></td>
Expand Down
21 changes: 21 additions & 0 deletions tests/integration/components/-private/linked-list-item-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -122,5 +122,26 @@ module(

this.set("linkToIndex", true);
});

test("uses currentWhen for active state if passed", async function (assert) {
this.owner.lookup("service:router").isActive = (routeName) => {
assert.strictEqual(routeName, "foo.bar");
return true;
};

this.owner.lookup("service:router").recognize = (url) => ({
name: url.replace(/^\//, "").replace(/\//g, "."),
paramNames: [],
queryParams: {},
});

await render(hbs`<this.LinkedListItem @href="/" @currentWhen="/foo/bar" as |active|>{{unless
active
"not"
}}
active</this.LinkedListItem>`);

assert.dom("a").hasText("active");
});
},
);

0 comments on commit b4557b0

Please sign in to comment.