fix(vue): all ionic vue components can now use router link (#22743)

This commit is contained in:
Liam DeBeasi
2021-01-07 15:52:06 -05:00
committed by GitHub
parent 9a02ec8402
commit 3d6ac1382e
5 changed files with 46 additions and 70 deletions

19
core/package-lock.json generated
View File

@ -17,7 +17,7 @@
"@rollup/plugin-virtual": "^2.0.3", "@rollup/plugin-virtual": "^2.0.3",
"@stencil/core": "2.1.2", "@stencil/core": "2.1.2",
"@stencil/sass": "1.3.2", "@stencil/sass": "1.3.2",
"@stencil/vue-output-target": "0.2.2", "@stencil/vue-output-target": "0.2.3",
"@types/jest": "^26.0.10", "@types/jest": "^26.0.10",
"@types/node": "^14.6.0", "@types/node": "^14.6.0",
"@types/puppeteer": "3.0.1", "@types/puppeteer": "3.0.1",
@ -1657,10 +1657,13 @@
"dev": true "dev": true
}, },
"node_modules/@stencil/vue-output-target": { "node_modules/@stencil/vue-output-target": {
"version": "0.2.2", "version": "0.2.3",
"resolved": "https://registry.npmjs.org/@stencil/vue-output-target/-/vue-output-target-0.2.2.tgz", "resolved": "https://registry.npmjs.org/@stencil/vue-output-target/-/vue-output-target-0.2.3.tgz",
"integrity": "sha512-WBnN/8ggIVYgKbJOML1DVzjFnKv7RaQpTa+XNeY0r/EG6MbXlUjUC/4Cpkg5wQ94WNuPpphAR4oRWGsmiQDxPQ==", "integrity": "sha512-jxFElPUVp56DHxLvYTvlnHMFnVQ0ITAUCLYfHvV8TY49PUbV5Gw1nYhhJQfpi5gJU2PPoWtIJjUGMsof8lmh6Q==",
"dev": true "dev": true,
"peerDependencies": {
"@stencil/core": ">=1.8.0"
}
}, },
"node_modules/@stylelint/postcss-css-in-js": { "node_modules/@stylelint/postcss-css-in-js": {
"version": "0.37.2", "version": "0.37.2",
@ -16387,9 +16390,9 @@
"dev": true "dev": true
}, },
"@stencil/vue-output-target": { "@stencil/vue-output-target": {
"version": "0.2.2", "version": "0.2.3",
"resolved": "https://registry.npmjs.org/@stencil/vue-output-target/-/vue-output-target-0.2.2.tgz", "resolved": "https://registry.npmjs.org/@stencil/vue-output-target/-/vue-output-target-0.2.3.tgz",
"integrity": "sha512-WBnN/8ggIVYgKbJOML1DVzjFnKv7RaQpTa+XNeY0r/EG6MbXlUjUC/4Cpkg5wQ94WNuPpphAR4oRWGsmiQDxPQ==", "integrity": "sha512-jxFElPUVp56DHxLvYTvlnHMFnVQ0ITAUCLYfHvV8TY49PUbV5Gw1nYhhJQfpi5gJU2PPoWtIJjUGMsof8lmh6Q==",
"dev": true "dev": true
}, },
"@stylelint/postcss-css-in-js": { "@stylelint/postcss-css-in-js": {

View File

@ -38,7 +38,7 @@
"@rollup/plugin-virtual": "^2.0.3", "@rollup/plugin-virtual": "^2.0.3",
"@stencil/core": "2.1.2", "@stencil/core": "2.1.2",
"@stencil/sass": "1.3.2", "@stencil/sass": "1.3.2",
"@stencil/vue-output-target": "0.2.2", "@stencil/vue-output-target": "0.2.3",
"@types/jest": "^26.0.10", "@types/jest": "^26.0.10",
"@types/node": "^14.6.0", "@types/node": "^14.6.0",
"@types/puppeteer": "3.0.1", "@types/puppeteer": "3.0.1",

View File

@ -87,13 +87,6 @@ export const config: Config = {
'ion-app', 'ion-app',
'ion-icon' 'ion-icon'
], ],
routerLinkComponents: [
'ion-card',
'ion-item',
'ion-button',
'ion-fab-button',
],
componentModels: [ componentModels: [
{ {
elements: ['ion-checkbox', 'ion-toggle'], elements: ['ion-checkbox', 'ion-toggle'],

View File

@ -42,10 +42,7 @@ export const IonButton = /*@__PURE__*/ defineContainer<JSX.IonButton>('ion-butto
'type', 'type',
'ionFocus', 'ionFocus',
'ionBlur' 'ionBlur'
], ]);
{
"routerLinkComponent": true
});
export const IonButtons = /*@__PURE__*/ defineContainer<JSX.IonButtons>('ion-buttons', [ export const IonButtons = /*@__PURE__*/ defineContainer<JSX.IonButtons>('ion-buttons', [
@ -64,10 +61,7 @@ export const IonCard = /*@__PURE__*/ defineContainer<JSX.IonCard>('ion-card', [
'routerDirection', 'routerDirection',
'routerAnimation', 'routerAnimation',
'target' 'target'
], ]);
{
"routerLinkComponent": true
});
export const IonCardContent = /*@__PURE__*/ defineContainer<JSX.IonCardContent>('ion-card-content'); export const IonCardContent = /*@__PURE__*/ defineContainer<JSX.IonCardContent>('ion-card-content');
@ -195,10 +189,7 @@ export const IonFab = /*@__PURE__*/ defineContainer<JSX.IonFab>('ion-fab', [
'vertical', 'vertical',
'edge', 'edge',
'activated' 'activated'
], ]);
{
"routerLinkComponent": true
});
export const IonFabButton = /*@__PURE__*/ defineContainer<JSX.IonFabButton>('ion-fab-button', [ export const IonFabButton = /*@__PURE__*/ defineContainer<JSX.IonFabButton>('ion-fab-button', [
@ -218,10 +209,7 @@ export const IonFabButton = /*@__PURE__*/ defineContainer<JSX.IonFabButton>('ion
'closeIcon', 'closeIcon',
'ionFocus', 'ionFocus',
'ionBlur' 'ionBlur'
], ]);
{
"routerLinkComponent": true
});
export const IonFabList = /*@__PURE__*/ defineContainer<JSX.IonFabList>('ion-fab-list', [ export const IonFabList = /*@__PURE__*/ defineContainer<JSX.IonFabList>('ion-fab-list', [
@ -324,10 +312,7 @@ export const IonItem = /*@__PURE__*/ defineContainer<JSX.IonItem>('ion-item', [
'routerDirection', 'routerDirection',
'target', 'target',
'type' 'type'
], ]);
{
"routerLinkComponent": true
});
export const IonItemDivider = /*@__PURE__*/ defineContainer<JSX.IonItemDivider>('ion-item-divider', [ export const IonItemDivider = /*@__PURE__*/ defineContainer<JSX.IonItemDivider>('ion-item-divider', [

View File

@ -17,7 +17,6 @@ interface NavManager<T = any> {
interface ComponentOptions { interface ComponentOptions {
modelProp?: string; modelProp?: string;
modelUpdateEvent?: string; modelUpdateEvent?: string;
routerLinkComponent?: boolean;
} }
const getComponentClasses = (classes: unknown) => { const getComponentClasses = (classes: unknown) => {
@ -41,7 +40,7 @@ const getElementClasses = (ref: Ref<HTMLElement | undefined>, componentClasses:
* integrations. * integrations.
*/ */
export const defineContainer = <Props>(name: string, componentProps: string[] = [], componentOptions: ComponentOptions = {}) => { export const defineContainer = <Props>(name: string, componentProps: string[] = [], componentOptions: ComponentOptions = {}) => {
const { modelProp, modelUpdateEvent, routerLinkComponent } = componentOptions; const { modelProp, modelUpdateEvent } = componentOptions;
/** /**
* Create a Vue component wrapper around a Web Component. * Create a Vue component wrapper around a Web Component.
@ -60,14 +59,14 @@ export const defineContainer = <Props>(name: string, componentProps: string[] =
} }
}; };
let handleClick: (ev: Event) => void;
if (routerLinkComponent) {
const currentInstance = getCurrentInstance(); const currentInstance = getCurrentInstance();
const hasRouter = currentInstance?.appContext?.provides[NAV_MANAGER]; const hasRouter = currentInstance?.appContext?.provides[NAV_MANAGER];
const navManager: NavManager | undefined = hasRouter ? inject(NAV_MANAGER) : undefined; const navManager: NavManager | undefined = hasRouter ? inject(NAV_MANAGER) : undefined;
handleClick = (ev: Event) => { const handleRouterLink = (ev: Event) => {
const { routerLink } = props as any;
if (!routerLink) return;
const routerProps = Object.keys(props).filter(p => p.startsWith(ROUTER_PROP_REFIX)); const routerProps = Object.keys(props).filter(p => p.startsWith(ROUTER_PROP_REFIX));
if (routerProps.length === 0) return;
if (navManager !== undefined) { if (navManager !== undefined) {
let navigationPayload: any = { event: ev }; let navigationPayload: any = { event: ev };
@ -79,31 +78,30 @@ export const defineContainer = <Props>(name: string, componentProps: string[] =
console.warn('Tried to navigate, but no router was found. Make sure you have mounted Vue Router.'); console.warn('Tried to navigate, but no router was found. Make sure you have mounted Vue Router.');
} }
} }
}
return () => { return () => {
getComponentClasses(attrs.class).forEach(value => { getComponentClasses(attrs.class).forEach(value => {
classes.add(value); classes.add(value);
}); });
const oldClick = (props as any).onClick;
const handleClick = (ev: Event) => {
if (oldClick !== undefined) {
oldClick(ev);
}
if (!ev.defaultPrevented) {
handleRouterLink(ev);
}
}
let propsToAdd = { let propsToAdd = {
...props, ...props,
ref: containerRef, ref: containerRef,
class: getElementClasses(containerRef, classes), class: getElementClasses(containerRef, classes),
onClick: (routerLinkComponent) ? handleClick : (props as any).onClick, onClick: handleClick,
onVnodeBeforeMount: (modelUpdateEvent) ? onVnodeBeforeMount : undefined onVnodeBeforeMount: (modelUpdateEvent) ? onVnodeBeforeMount : undefined
}; };
if ((props as any).onClick) {
const oldClick = (props as any).onClick;
propsToAdd.onClick = (ev: Event) => {
oldClick(ev);
if (!ev.defaultPrevented) {
handleClick(ev);
}
};
}
if (modelProp) { if (modelProp) {
propsToAdd = { propsToAdd = {
...propsToAdd, ...propsToAdd,
@ -116,14 +114,11 @@ export const defineContainer = <Props>(name: string, componentProps: string[] =
}); });
Container.displayName = name; Container.displayName = name;
Container.props = componentProps; Container.props = [...componentProps, ROUTER_LINK_VALUE];
if (modelProp) { if (modelProp) {
Container.props.push(MODEL_VALUE); Container.props.push(MODEL_VALUE);
Container.emits = [UPDATE_VALUE_EVENT]; Container.emits = [UPDATE_VALUE_EVENT];
} }
if (routerLinkComponent) {
Container.props.push(ROUTER_LINK_VALUE);
}
return Container; return Container;
}; };