Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve pasting from clipboard values support #774

Merged
merged 2 commits into from
Mar 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions ember-amount-input/src/components/amount-input.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
readonly={{@readonly}}
{{on 'keydown' this.onKeyDown}}
{{on 'input' this.onInput}}
{{on 'paste' this.onPaste}}
{{on 'focusout' this.onFocusOut}}
/>
</div>
12 changes: 12 additions & 0 deletions ember-amount-input/src/components/amount-input.ts
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,18 @@ export default class AmountInput extends Component<AmountInputSignature> {
return true;
}

@action
vscav marked this conversation as resolved.
Show resolved Hide resolved
onPaste(event: ClipboardEvent): boolean {
const pastedValue = event.clipboardData?.getData('text');
const parsedValue = parseFloat(pastedValue?.replace(/\s/g, '') ?? '');

if (!isNaN(parsedValue)) {
this.args.update(parsedValue.toFixed(this.numberOfDecimal));
}

return true;
}

@action
onFocusOut(event: FocusEvent): boolean {
if (event.target instanceof HTMLInputElement) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { setupRenderingTest } from 'ember-qunit';
import { blur, fillIn, render, typeIn } from '@ember/test-helpers';
import { hbs } from 'ember-cli-htmlbars';
import type { TestContext as TestContextBase } from '@ember/test-helpers';
import { simulateUserPasteValue } from './helpers/paste-value';

interface TestContext extends TestContextBase {
value: number | string;
Expand Down Expand Up @@ -105,7 +106,7 @@ module('Integration | Component | amount-input', function (hooks) {
await render<TestContext>(hbs`
<AmountInput
@value={{this.value}}
@update={{fn (mut this.value)}}
@update={{fn (mut this.value)}}
@readonly={{true}}
/>
`);
Expand Down Expand Up @@ -185,4 +186,40 @@ module('Integration | Component | amount-input', function (hooks) {

assert.dom('input').hasValue('61');
});

module('when user pastes a value with spaces', function () {
module('and the value contains spaces', function () {
test('calls update with the formatted value on blur without the spaces', async function (assert) {
await render<TestContext>(hbs`
<AmountInput
@value={{this.value}}
@update={{fn (mut this.value)}}
/>
`);

await simulateUserPasteValue('input', '1 061,00');

assert.dom('input').hasValue('1061.00');

await simulateUserPasteValue('input', ' 1 061');

assert.dom('input').hasValue('1061.00');
});
});

module('and the value is not a valid amount', function () {
test('calls update with an empty string value', async function (assert) {
await render<TestContext>(hbs`
<AmountInput
@value={{this.value}}
@update={{fn (mut this.value)}}
/>
`);

await simulateUserPasteValue('input', 'foo');

assert.dom('input').hasValue('');
});
});
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { triggerEvent } from '@ember/test-helpers';
import type { Target } from '@ember/test-helpers';

/**
* Simulates a user pasting a value into a target element.
*
* @param {Target} target - The target element to paste the value into
* @param {string} value - The value to paste
* @return {Promise<void>} A Promise that resolves when the paste event is triggered
*/
export function simulateUserPasteValue(
target: Target,
value: string,
): Promise<void> {
const getData = (): string => value;
return triggerEvent(target, 'paste', {
clipboardData: {
getData,
},
});
}
Loading