Skip to content

Commit

Permalink
Merge pull request #7 from pepsico-ecommerce/pure-css-with-tooltip
Browse files Browse the repository at this point in the history
Replace with simple css solution while keeping tooltip
  • Loading branch information
vssrcj committed Nov 18, 2022
2 parents 3caab68 + bf344bf commit 817d75d
Show file tree
Hide file tree
Showing 5 changed files with 162 additions and 298 deletions.
156 changes: 13 additions & 143 deletions dist/pep-p.es.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,4 @@
import { define, css } from 'uce';
import { ResizeObserver } from '@juggle/resize-observer';

/**
* Removes the last word from text and returns the new string.
* Trims text before starting.
* A "word" is text seprated with one or more spaces.
* @param {[type]} text [description]
* @return {[type]} [description]
*/
function removeLastWord(text) {
return text.trim().substring(0, text.lastIndexOf(' '));
}

/**
* <pep-p>PepsiCo Paragraph Custom Element.</pep-p>
Expand All @@ -20,150 +8,32 @@ function removeLastWord(text) {
define('pep-p', {
style: (selector) => css`
${selector} {
/* Prevent the overflow from flashing */
overflow: hidden;
/* Need defined width/height, so use the parents values */
/* height: 100%; */ /* removed height so text can center in parent. */
text-align: inherit;
text-overflow: ellipsis;
white-space: nowrap;
width: 100%;
display: block;
display: inline-block;
}
${selector} textarea {
box-sizing: border-box;
}
`,
init() {
// Create a Resize Observer so we can re-adjust the length of the text content
// when the element changes size.
try {
this._resizeObserver = new ResizeObserver((elms) => {
this.render();
});
// Start observing.
this._resizeObserver.observe(this);
}
catch(e) {
console.log('<pep-p /> _resizeObserver error', e, this);
handleHover() {
const isTruncated = this.offsetWidth < this.scrollWidth;
const hasTooltip = this.hasAttribute('tooltip');
if (isTruncated && !hasTooltip) {
this.setAttribute('tooltip', this.originalTextContent.trim());
} else if (!isTruncated && hasTooltip) {
this.removeAttribute('tooltip');
}
},
connected() {
// Create a copy of the children and text before we start modifying it.
this.originalChildNodes = Array.from(this.childNodes).map(node => node.cloneNode(true));
this.originalTextContent = this.textContent;
this.setAttribute('tooltip', this.originalTextContent.trim());
this.trimTextContent();
this.addEventListener("mouseenter", this.handleHover);
},
disconnected() {
try {
this._resizeObserver.disconnect();
this.restoreChildren();
}
catch(e) {
console.log('<pep-p /> Disconnected error', e, this);
}
},

// Restores the original children
restoreChildren() {
this.innerHTML = ''; // clear out all the children
// Create clones of the original children and put them back.
this.originalChildNodes.forEach(child => this.appendChild(child.cloneNode(true)));
},

// render by updating the trimmed text to match the current size.
render() {
// Clear the tooltip.
this.removeAttribute('tooltip');
// Find the minimum height needed to display text.
this.innerHTML = 'ÀEIOUhy';
this.minHeight = this.scrollHeight;
// restore the children and then re-trim to the new size.
this.restoreChildren();
this.trimTextContent();

if (!this.didTrim) {
this.removeAttribute('tooltip');
}

if (this.didTrim) {
this.setAttribute('tooltip', this.originalTextContent.trim());
}
},

// Returns true if the content overflows.
get hasOverflow() {
if (this.scrollWidth <= this.clientWidth
&& this.scrollHeight <= this.minHeight) {
return false;
}

return true;
},
// Returns true if the element has a size.
get hasSize() {
if (0 === this.scrollWidth || 0 === this.scrollHeight) {
return false;
}
return true;
},

// Trims the text content of the children to make them fit without overflowing.
trimTextContent() {
this.didTrim = false;

// Skip if the element has no size. We can't trim to an unknown.
if (!this.hasSize) {
return;
}
// Loop over each child starting with the last,
// untill we are no longer overflowing, or we run out of children.
for (let idx=(this.childNodes.length-1);
idx >= 0 && this.hasOverflow;
idx--) {

const childElm = this.childNodes[idx];

// We don't want to change user's input, so skip those elements.
if (['TEXTAREA', 'INPUT', 'SELECT'].includes(childElm.nodeName)) {
continue;
}

// We can remove line breaks if we are trying to shrink the content.
if (childElm.nodeName === 'BR') {
childElm.remove();
continue;
}

// Remove one word at a time until either the content fits,
// or we run out of text.
let shorterText = childElm.textContent;
do {
this.didTrim = true;
// Remove the last word.
shorterText = removeLastWord(shorterText);
// update the element so we can check the new size.
childElm.textContent = shorterText;
}
// Stop when we run out of text, or we are no longer overflowing.
while(this.hasOverflow && shorterText.length > 0);

// If the text is empty, remove the element,
if ((!shorterText || shorterText.length === 0)) {
childElm.remove();
}
}

// Check if we did anything.
if (this.didTrim) {
// Find the last text element so we can add ellipsis.
let lastTextElm = this.childNodes[this.childNodes.length-1];
while (lastTextElm && lastTextElm.nodeName !== '#text') {
lastTextElm = lastTextElm.previousSibling;
}
// there is a chance there are no text elements left.
if (lastTextElm) {
lastTextElm.textContent = removeLastWord(lastTextElm.textContent) + ' ...';
}
}

this.removeEventListener("mouseenter", this.handleHover);
}
});
137 changes: 130 additions & 7 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 5 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
{
"name": "pep-p",
"version": "0.0.5",
"version": "0.0.8",
"description": "custom element",
"main": "dist/pep-p.es.js",
"engines": {
"node": ">=16.16",
"npm": ">=8.2"
},
"repository": {
"type": "git",
"url": "git+https://github.com/pepsico-ecommerce/pep-p.git"
Expand All @@ -14,7 +18,6 @@
},
"homepage": "https://github.com/pepsico-ecommerce/pep-p#readme",
"dependencies": {
"@juggle/resize-observer": "^3.3.0",
"uce": "^1.16.0"
},
"devDependencies": {
Expand Down
Loading

0 comments on commit 817d75d

Please sign in to comment.