fix(vue): pass router-link value to href to properly render clickable elements (#29745)

Issue number: N/A

---------

## What is the current behavior?
Ionic Framework Vue components using `router-link` do not apply an
`href` property which causes components to render `div` or `button`
elements when they should render an `a`. This is inconsistent with the
way Angular and Vue handle router link.

## What is the new behavior?
Updates `@stencil/vue-output-target` to latest which adds the code from
the following PR:
https://github.com/ionic-team/stencil-ds-output-targets/pull/446

The update in vue output target checks if `router-link` and `navManager`
are defined so this fix only applies to Ionic Framework components. If
both are defined then it adds the `href` property to the element with
the value of `router-link`.

## Does this introduce a breaking change?

- [ ] Yes
- [x] No

## Other information

Dev build: `8.2.7-dev.11722629362.1ac136c4`
This commit is contained in:
Brandy Carney
2024-08-05 17:35:26 -04:00
committed by GitHub
parent a9f278ad67
commit ab4f2791c1
10 changed files with 77 additions and 38 deletions

View File

@ -2,13 +2,13 @@
<ion-page>
<ion-content>
<ion-list>
<ion-item button router-link="/components/breadcrumbs">
<ion-item router-link="/components/breadcrumbs">
<ion-label>Breadcrumbs</ion-label>
</ion-item>
<ion-item button router-link="/components/select">
<ion-item router-link="/components/select">
<ion-label>Select</ion-label>
</ion-item>
<ion-item button router-link="/components/range">
<ion-item router-link="/components/range">
<ion-label>Range</ion-label>
</ion-item>
</ion-list>

View File

@ -17,43 +17,43 @@
</ion-header>
<ion-list>
<ion-item button router-link="/overlays">
<ion-item router-link="/overlays">
<ion-label>Overlays</ion-label>
</ion-item>
<ion-item button router-link="/icons">
<ion-item router-link="/icons">
<ion-label>Icons</ion-label>
</ion-item>
<ion-item button router-link="/inputs">
<ion-item router-link="/inputs">
<ion-label>Inputs</ion-label>
</ion-item>
<ion-item button router-link="/navigation" id="navigation">
<ion-item router-link="/navigation" id="navigation">
<ion-label>Navigation</ion-label>
</ion-item>
<ion-item button router-link="/routing" id="routing">
<ion-item router-link="/routing" id="routing">
<ion-label>Routing</ion-label>
</ion-item>
<ion-item button router-link="/default-href" id="default-href">
<ion-item router-link="/default-href" id="default-href">
<ion-label>Default Href</ion-label>
</ion-item>
<ion-item button router-link="/nested" id="nested">
<ion-item router-link="/nested" id="nested">
<ion-label>Nested Router Outlet</ion-label>
</ion-item>
<ion-item button router-link="/tabs" id="tabs">
<ion-item router-link="/tabs" id="tabs">
<ion-label>Tabs</ion-label>
</ion-item>
<ion-item button router-link="/tabs-secondary" id="tab-secondary">
<ion-item router-link="/tabs-secondary" id="tab-secondary">
<ion-label>Tabs Secondary</ion-label>
</ion-item>
<ion-item button router-link="/lifecycle" id="lifecycle">
<ion-item router-link="/lifecycle" id="lifecycle">
<ion-label>Lifecycle</ion-label>
</ion-item>
<ion-item button router-link="/lifecycle-setup" id="lifecycle-setup">
<ion-item router-link="/lifecycle-setup" id="lifecycle-setup">
<ion-label>Lifecycle (Setup)</ion-label>
</ion-item>
<ion-item button router-link="/delayed-redirect" id="delayed-redirect">
<ion-item router-link="/delayed-redirect" id="delayed-redirect">
<ion-label>Delayed Redirect</ion-label>
</ion-item>
<ion-item button router-link="/components">
<ion-item router-link="/components">
<ion-label>Components</ion-label>
</ion-item>
</ion-list>

View File

@ -16,31 +16,31 @@
</ion-toolbar>
</ion-header>
<ion-item button @click="setRouteParams" id="route-params">
<ion-item @click="setRouteParams" id="route-params">
<ion-label>Set Route Parameters</ion-label>
</ion-item>
<ion-item button router-link="/routing/child" id="child">
<ion-item router-link="/routing/child" id="child">
<ion-label>Go to Child Page</ion-label>
</ion-item>
<ion-item button router-link="/routing/abc" id="parameter-abc">
<ion-item router-link="/routing/abc" id="parameter-abc">
<ion-label>Go to Parameter Page ABC</ion-label>
</ion-item>
<ion-item button router-link="/routing/xyz" id="parameter-xyz">
<ion-item router-link="/routing/xyz" id="parameter-xyz">
<ion-label>Go to Parameter Page XYZ</ion-label>
</ion-item>
<ion-item button router-link="/routing/123/view" id="parameter-view-item">
<ion-item router-link="/routing/123/view" id="parameter-view-item">
<ion-label>Go to Parameterized Page View</ion-label>
</ion-item>
<ion-item button @click="replace" id="replace">
<ion-item @click="replace" id="replace">
<ion-label>Replace to Navigation page</ion-label>
</ion-item>
<ion-item button router-link="/tabs/tab1" id="tab1">
<ion-item router-link="/tabs/tab1" id="tab1">
<ion-label>Go to /tabs/tab1</ion-label>
</ion-item>
</ion-content>

View File

@ -17,18 +17,18 @@
<ExploreContainer name="Tab 1 page" />
<ion-item button router-link="/tabs/tab1/childone" id="child-one">
<ion-item router-link="/tabs/tab1/childone" id="child-one">
<ion-label>Go to Tab 1 Child 1</ion-label>
</ion-item>
<ion-item button router-link="/nested" id="nested">
<ion-item router-link="/nested" id="nested">
<ion-label>Go to Nested Outlet</ion-label>
</ion-item>
<ion-item button router-link="/tabs-secondary" id="tabs-secondary">
<ion-item router-link="/tabs-secondary" id="tabs-secondary">
<ion-label>Go to Secondary Tabs</ion-label>
</ion-item>
<ion-item button router-link="/tabs" id="tabs-primary">
<ion-item router-link="/tabs" id="tabs-primary">
<ion-label>Go to Primary Tabs</ion-label>
</ion-item>

View File

@ -15,7 +15,7 @@
</ion-toolbar>
</ion-header>
<ion-item button router-link="/routing" id="routing">
<ion-item router-link="/routing" id="routing">
<ion-label>Go to /routing</ion-label>
</ion-item>
</ion-content>

View File

@ -584,4 +584,10 @@ describe('Routing - Swipe to Go Back', () => {
cy.ionPageDoesNotExist('routingparameter-abc');
cy.ionPageVisible('routing');
})
it('should be activatable when router-link is used on an item without the button property', () => {
cy.visit('/');
cy.get('ion-item[routerlink="/overlays"]').should('have.class', 'ion-activatable');
});
})