Skip to content

Commit

Permalink
feat: add spread support to BoltElement + demo usage in Link component
Browse files Browse the repository at this point in the history
  • Loading branch information
sghoweri committed Mar 26, 2020
1 parent fc3b70c commit e61a748
Show file tree
Hide file tree
Showing 6 changed files with 49 additions and 40 deletions.
Expand Up @@ -16,8 +16,10 @@
{% endset %}

{% set link_demo_icon %}

{# dummy data attribute set on this <bolt-link> <a> tag to confirm extra attributes added to inner HTML elements are automatically retained #}
<p>
<bolt-link><a href="https://pega.com"><bolt-icon slot="before" name="info-open"></bolt-icon>This is a link with icon</a></bolt-link>
<bolt-link><a href="https://pega.com" data-analytics="click"><bolt-icon slot="before" name="info-open"></bolt-icon>This is a link with icon</a></bolt-link>
</p>
<p>
<bolt-link><a href="https://pega.com">This is a link with icon<bolt-icon slot="after" name="info-open"></bolt-icon></a></bolt-link>
Expand Down
1 change: 1 addition & 0 deletions packages/base-element/index.js
Expand Up @@ -11,6 +11,7 @@ export {
findParentTag,
} from './src/lib/utils';

export { spread } from '@open-wc/lit-helpers';
export { convertInitialTags } from './src/lib/decorators';
export { css, html, unsafeCSS } from 'lit-element';
export { render } from 'lit-html';
Expand Down
1 change: 1 addition & 0 deletions packages/base-element/package.json
Expand Up @@ -7,6 +7,7 @@
"dependencies": {
"@bolt/core-v3.x": "^2.20.0",
"@bolt/polyfills": "^2.19.0",
"@open-wc/lit-helpers": "^0.3.5",
"lit-element": "2.2.1"
},
"publishConfig": {
Expand Down
4 changes: 3 additions & 1 deletion packages/base-element/src/lib/decorators.js
Expand Up @@ -13,7 +13,6 @@ import { getComponentRootElement, shouldUseShadowDom } from './utils';
const convertInitialClass = (tags, moveChildrenToRoot, clazz) => {
return class extends clazz {
connectedCallback() {
super.connectedCallback && super.connectedCallback();
// Make sure the component ONLY ever reuses any existing HTML ONCE.
if (
(this._wasInitiallyRendered === false ||
Expand All @@ -37,6 +36,9 @@ const convertInitialClass = (tags, moveChildrenToRoot, clazz) => {
this._convertedInitialTags = true;
}
}

// call super AFTER prep work so we can use this initial element within a component's connectedCallback
super.connectedCallback && super.connectedCallback();
}
};
};
Expand Down
74 changes: 36 additions & 38 deletions packages/components/bolt-link/src/link.js
Expand Up @@ -5,8 +5,8 @@ import {
html,
ifDefined,
customElement,
BoltElement,
convertInitialTags,
spread,
} from '@bolt/element';
import classNames from 'classnames/bind';
import linkStyles from './link.scss';
Expand Down Expand Up @@ -42,30 +42,41 @@ class BoltLink extends BoltActionElement {
return self;
}

render() {
// 1. Remove line breaks before and after lit-html template tags, causes unwanted space inside and around inline links
// 2. Zero Width No-break Space (&#xfeff;) is needed to make the last word always stick with the icon, so the icon will never become an orphan.
connectedCallback() {
super.connectedCallback && super.connectedCallback();

// Validate the original prop data passed along -- returns back the validated data w/ added default values
// const { display, valign, url, target, isHeadline } = this.validateProps(
// this.props,
// );
// collect any extra HTML attributes from the rootElement to retain
this.rootElementAttributes = {};

if (this.rootElement) {
Array.from(this.rootElement.firstChild.attributes).forEach(item => {
let propName;
switch (item.name) {
case 'href':
propName = 'url';
break;
default:
propName = item.name;
}

// use the element's HTML attribute value as prop defaults
if (!this[propName]) {
this[propName] = item.value; // use element props if not already defined
}

// extra HTML attributes to include on the rendered <a> tag
this.rootElementAttributes[item.name] = item.value;
});
}
}

render() {
const classes = cx('c-bolt-link', {
[`c-bolt-link--display-${this.display}`]: this.display,
[`c-bolt-link--valign-${this.valign}`]: this.valign,
[`c-bolt-link--headline`]: this.isHeadline,
});

// Decide on if the rendered button tag should be a <button> or <a> tag, based on if a URL exists OR if a link was passed in from the getgo
const hasUrl = this.url && this.url.length > 0 && this.url !== 'null';

// Assign default target attribute value if one isn't specified
const anchorTarget = this.target && hasUrl ? this.target : '_self';

// The linkElement to render, based on the initial HTML passed alone.
let renderedLink;

// 1. Remove line breaks before and after lit-html template tags, causes unwanted space inside and around inline links
// 2. Zero Width No-break Space (&#xfeff;) is needed to make the last word always stick with the icon, so the icon will never become an orphan.
// prettier-ignore
Expand All @@ -81,27 +92,14 @@ class BoltLink extends BoltActionElement {
? html`<span class="${cx(`c-bolt-link__icon`)}">&#xfeff;${this.slotify('after')}</span>`
: html`<slot name="after" />`}`;

if (this.rootElement) {
renderedLink = this.rootElement.firstChild.cloneNode(true);
if (hasUrl) {
renderedLink.setAttribute('href', this.url);
}
if (anchorTarget) {
renderedLink.setAttribute('target', anchorTarget);
}
renderedLink.className += ' ' + classes;
render(innerSlots, renderedLink);
} else {
// [1]
// prettier-ignore
renderedLink = html`<a href="${ifDefined(hasUrl ? this.url : undefined)}" class="${classes}" target="${anchorTarget}"
>${innerSlots}</a
>`;
}

// [1]
// prettier-ignore
return html`${renderedLink}`;
return html`
<a ...="${spread(this.rootElementAttributes)}"
href="${ifDefined(this.url ? this.url : undefined)}"
class="${classes}"
target="${ifDefined(this.target ? this.target : undefined)}">
${innerSlots}
</a>
`;
}
}

Expand Down
5 changes: 5 additions & 0 deletions yarn.lock
Expand Up @@ -2471,6 +2471,11 @@
dependencies:
"@types/node" ">= 8"

"@open-wc/lit-helpers@^0.3.5":
version "0.3.5"
resolved "https://registry.yarnpkg.com/@open-wc/lit-helpers/-/lit-helpers-0.3.5.tgz#a459267f2e7fd7fd6e9f26e10e39394e828dab8c"
integrity sha512-qfZJDPWSk0yHPFjKTUz8KnY+zQ/Rh2Y76Yju2RcM4gh2sSy7Oiyxrdl/98Ec63//yPhWExMwpMo6xxd0gKhMKw==

"@open-wc/testing-helpers@^0.9.4":
version "0.9.6"
resolved "https://registry.yarnpkg.com/@open-wc/testing-helpers/-/testing-helpers-0.9.6.tgz#fc1ebf51a54122bc6e105211d0d182bc70b2ca6e"
Expand Down

0 comments on commit e61a748

Please sign in to comment.