vira
Version:
A simple and highly versatile design system using element-vir.
86 lines (83 loc) • 2.7 kB
JavaScript
import { attributes, css, html, ifDefined, listen, } from 'element-vir';
import { defineViraElement } from './define-vira-element.js';
/**
* A hyperlink wrapper element that can be configured to emit route change events rather than just
* being a raw link.
*
* @category Link
* @category Elements
* @see https://electrovir.github.io/element-vir/vira/book/elements/vira-link
*/
export const ViraLink = defineViraElement()({
tagName: 'vira-link',
cssVars: {
'vira-link-hover-color': 'currentColor',
},
styles: ({ cssVars }) => css `
:host {
display: inline;
text-decoration: underline;
}
a,
a:visited,
a:active,
a:link,
a:hover {
color: inherit;
text-decoration: inherit;
white-space: inherit;
}
:host(:hover) a,
a:hover,
:host(:active) a,
a:active {
color: ${cssVars['vira-link-hover-color'].value};
}
`,
render({ inputs }) {
function clickCallback(event) {
if (!inputs.route) {
return;
}
const routed = inputs.route.router.setRouteOnDirectNavigation(inputs.route.route, event);
if (inputs.route.scrollToTop) {
window.scrollTo({
left: 0,
top: 0,
behavior: routed ? 'instant' : 'smooth',
});
}
}
if (inputs.link?.newTab) {
/** Noopener and noreferrer are needed for security reasons, do not remove! */
return html `
<a
href=${inputs.link.url}
target="_blank"
rel="noopener noreferrer"
${attributes(inputs.attributePassthrough?.a)}
style=${ifDefined(inputs.stylePassthrough?.a)}
>
<slot></slot>
</a>
`;
}
else {
const linkUrl = inputs.link
? inputs.link.url
: inputs.route.router.createRouteUrl(inputs.route.route);
/** Noopener and noreferrer are needed for security reasons, do not remove! */
return html `
<a
href=${linkUrl}
rel="noopener noreferrer"
${attributes(inputs.attributePassthrough?.a)}
style=${ifDefined(inputs.stylePassthrough?.a)}
${listen('click', clickCallback)}
>
<slot></slot>
</a>
`;
}
},
});