don't calculate pixel width (#694)

This commit is contained in:
Konstantin Vyatkin 2019-10-28 15:27:10 -04:00 committed by Josh Johnson
parent 99f945bc03
commit dbd15d7823
3 changed files with 18 additions and 124 deletions

View file

@ -1,4 +1,4 @@
import { calcWidthOfInput, sanitise } from '../lib/utils';
import { sanitise } from '../lib/utils';
export default class Input {
constructor({ element, type, classNames, placeholderValue }) {
@ -89,30 +89,12 @@ export default class Input {
/**
* Set the correct input width based on placeholder
* value or input value
* @return
*/
setWidth(enforceWidth) {
const callback = width => {
this.element.style.width = width;
};
if (this._placeholderValue) {
// If there is a placeholder, we only want to set the width of the input when it is a greater
// length than 75% of the placeholder. This stops the input jumping around.
const valueHasDesiredLength =
this.element.value.length >= this._placeholderValue.length / 1.25;
if ((this.element.value && valueHasDesiredLength) || enforceWidth) {
this.calcWidth(callback);
}
} else {
// If there is no placeholder, resize input to contents
this.calcWidth(callback);
}
}
calcWidth(callback) {
return calcWidthOfInput(this.element, callback);
setWidth() {
// Resize input to contents or placeholder
const { style, value, placeholder } = this.element;
style.minWidth = `${placeholder.length + 1}ch`;
style.width = `${value.length + 1}ch`;
}
setActiveDescendant(activeDescendantID) {

View file

@ -264,61 +264,21 @@ describe('components/input', () => {
});
});
/**
* Blocked by lack of ch support in JSDOM
* @see {@link https://github.com/jsdom/cssstyle/pull/107}
*
describe('setWidth', () => {
let calcWidthStub;
const inputWidth = '200px';
beforeEach(() => {
calcWidthStub = stub(instance, 'calcWidth').callsArgWith(0, inputWidth);
});
afterEach(() => {
calcWidthStub.restore();
});
describe('with a placeholder', () => {
describe('when value length is greater or equal to 75% of the placeholder length', () => {
it('sets the width of the element based on input value', () => {
instance._placeholderValue = 'This is a test';
instance.element.value = 'This is a test';
expect(instance.element.style.width).to.not.equal(inputWidth);
instance.setWidth();
expect(calcWidthStub.callCount).to.equal(1);
expect(instance.element.style.width).to.equal(inputWidth);
});
});
describe('when width is enforced', () => {
it('sets the width of the element based on input value', () => {
instance._placeholderValue = 'This is a test';
instance.element.value = '';
expect(instance.element.style.width).to.not.equal(inputWidth);
instance.setWidth(true);
expect(calcWidthStub.callCount).to.equal(1);
expect(instance.element.style.width).to.equal(inputWidth);
});
});
describe('when value length is less than 75% of the placeholder length', () => {
it('does not set the width of the element', () => {
instance._placeholderValue = 'This is a test';
instance.element.value = 'Test';
instance.setWidth();
expect(calcWidthStub.callCount).to.equal(0);
});
});
});
describe('without a placeholder', () => {
it('sets the width of the element based on input value', () => {
instance.placeholder = null;
expect(instance.element.style.width).to.not.equal(inputWidth);
instance.setWidth();
expect(calcWidthStub.callCount).to.equal(1);
expect(instance.element.style.width).to.equal(inputWidth);
});
it('sets the width of the element based on input value and placeholder', () => {
instance.placeholder = 'This is a placeholder';
instance.element.value = 'This is a value';
expect(instance.element.style.width).to.not.equal('16ch');
instance.setWidth();
expect(instance.element.style.width).to.equal('16ch');
expect(instance.element.style.minWidth).to.equal('22ch');
});
});
*/
describe('placeholder setter', () => {
it('sets value of element to passed placeholder', () => {

View file

@ -113,54 +113,6 @@ export const strToEl = (() => {
};
})();
/**
* Determines the width of a passed input based on its value and passes
* it to the supplied callback function.
*/
export const calcWidthOfInput = (input, callback) => {
const value = input.value || input.placeholder;
let width = input.offsetWidth;
if (value) {
const testEl = strToEl(`<span>${sanitise(value)}</span>`);
testEl.style.position = 'absolute';
testEl.style.padding = '0';
testEl.style.top = '-9999px';
testEl.style.left = '-9999px';
testEl.style.width = 'auto';
testEl.style.whiteSpace = 'pre';
if (document.body.contains(input) && window.getComputedStyle) {
const inputStyle = window.getComputedStyle(input);
if (inputStyle) {
testEl.style.fontSize = inputStyle.fontSize;
testEl.style.fontFamily = inputStyle.fontFamily;
testEl.style.fontWeight = inputStyle.fontWeight;
testEl.style.fontStyle = inputStyle.fontStyle;
testEl.style.letterSpacing = inputStyle.letterSpacing;
testEl.style.textTransform = inputStyle.textTransform;
testEl.style.paddingLeft = inputStyle.paddingLeft;
testEl.style.paddingRight = inputStyle.paddingRight;
}
}
document.body.appendChild(testEl);
requestAnimationFrame(() => {
if (value && testEl.offsetWidth !== input.offsetWidth) {
width = testEl.offsetWidth + 4;
}
document.body.removeChild(testEl);
callback.call(this, `${width}px`);
});
} else {
callback.call(this, `${width}px`);
}
};
export const sortByAlpha = (a, b) => {
const labelA = `${a.label || a.value}`.toLowerCase();
const labelB = `${b.label || b.value}`.toLowerCase();