Skip to content

Commit

Permalink
fix(resize): correct check for overflow in wrapper (#5)
Browse files Browse the repository at this point in the history
Was incorrectly checking for overflow using getBoundingClientRect(), which wasn't consistently returning the width of the child element if there was actually overflow in the parent.
  • Loading branch information
dmatchley authored May 9, 2017
1 parent 24852b2 commit cf738ef
Show file tree
Hide file tree
Showing 4 changed files with 90 additions and 9 deletions.
20 changes: 17 additions & 3 deletions examples/simple/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,14 @@ CenteredText.propTypes = {
class App extends Component {
constructor(props) {
super(props);
this.state = { custom: 'custom' };
this.state = {
custom: 'custom',
custom2: '24000'
};
}

render() {
const { custom } = this.state;
const { custom, custom2 } = this.state;
return (
<div>
<div className="box-container">
Expand Down Expand Up @@ -79,15 +82,26 @@ class App extends Component {
<CenteredText text={custom} />
</ScaleText>
</div>
<div className="box">
<ScaleText>
<div>{custom2}</div>
</ScaleText>
</div>
</div>
<div>
<hr />
Resizing based on prop changes:<br />
<input
Custom 1: <input
type="text"
size="40"
value={custom}
onChange={ev => this.setState({ custom: ev.target.value })}
/><br />
Custom 2: <input
type="text"
size="40"
value={custom2}
onChange={ev => this.setState({ custom2: ev.target.value })}
/>
</div>
</div>
Expand Down
10 changes: 10 additions & 0 deletions src/dom-utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,13 @@ export function getStyle(el, styleProp) {
}
return el.style[camelize(styleProp)];
}

export function getOverflow(el) {
return [
el.clientWidth < el.scrollWidth,
el.clientHeight < el.scrollHeight
];
}

export const hasOverflow = el => getOverflow(el).some(v => v === true);

7 changes: 2 additions & 5 deletions src/get-fillsize.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
/* eslint-disable no-param-reassign */
import { getOverflow } from './dom-utils';

// Determine the font-size to set on the element `el` that will
// allow the first child of that element to fill the maximum height
Expand All @@ -17,11 +18,7 @@ export default function getFillSize(el, minFontSize, maxFontSize, factor = 1) {

while (!complete) {
el.style.fontSize = `${fontSize}px`;
const wrap = el.getBoundingClientRect();
const child = el.firstChild.getBoundingClientRect();

const overflowHeight = ((wrap.top > child.top) || (wrap.bottom < child.bottom));
const overflowWidth = ((wrap.left > child.left) || (wrap.right < child.right));
const [overflowWidth, overflowHeight] = getOverflow(el);

if (overflowHeight || overflowWidth) {
if (fontSize <= minFontSize) {
Expand Down
62 changes: 61 additions & 1 deletion tests/dom-utils.spec.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import chai, { expect } from 'chai';
import { camelize, css, getStyle } from '../src/dom-utils';
import { camelize, css, getStyle, getOverflow } from '../src/dom-utils';

describe('dom util functions', () => {

Expand Down Expand Up @@ -56,4 +56,64 @@ describe('dom util functions', () => {
});
});

describe('getOverflow', () => {
it('properly detects element overflow', () => {
// setup some common styles we can use to build our test divs
const standard = { position: 'static' };
const absolute = { position: 'absolute', top: '0px', left: '0px' };
const relative = { position: 'relative', top: '0px', left: '0px' };
const boxStyles = {
display: 'inline-block',
padding: '5px',
overflow: 'hidden',
width: '120px',
height: '120px'
};
const contentStyles = {
padding: '2px',
whiteSpace: 'nowrap'
};
const iterations = [
[standard, standard],
[standard, absolute],
[standard, relative],
[relative, absolute],
[absolute, relative],
[absolute, absolute]
];
const overflows = [
[true, false],
[false, false], // always fail absolute child in static parent
[true, false],
[true, false],
[true, false],
[true, false]
];

// our test div container
const container = document.createElement('div');

// making divs....
for (let [parent, child] of iterations) {
const box = document.createElement('div');
css(box, { ...boxStyles, ...parent });
box.className = "box";
const content = document.createElement('p');
content.textContent = 'test content which overflows container';
css(content, { ...contentStyles, ...child });
box.appendChild(content);
container.appendChild(box);
}
document.body.appendChild(container);

// gather up our test divs
const boxes = document.querySelectorAll('.box');

for (let i in Array.from(boxes)) {
const box = boxes[i];
const expected = overflows[i];
expect(getOverflow(box)).to.eql(expected);
}
})
})
});

0 comments on commit cf738ef

Please sign in to comment.