mirror of
https://github.com/Choices-js/Choices.git
synced 2024-05-02 22:03:11 +02:00
don't calculate pixel width (#694)
This commit is contained in:
parent
99f945bc03
commit
dbd15d7823
|
@ -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) {
|
||||
|
|
|
@ -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', () => {
|
||||
|
|
|
@ -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();
|
||||
|
|
Loading…
Reference in a new issue