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

WIP: Locale Inputs, Resolving broken embroiderer dependencies, Unfocus Formatting #541

Draft
wants to merge 11 commits into
base: main
Choose a base branch
from
1 change: 1 addition & 0 deletions packages/ember-headless-form/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
"babel-eslint": "^10.1.0",
"ember-async-data": "^1.0.3",
"ember-modifier": "^4.1.0",
"intl-number-parser": "^1.0.5",
"tracked-built-ins": "^3.1.0"
},
"peerDependencies": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import { assert } from '@ember/debug';
import { on } from '@ember/modifier';
import { action } from '@ember/object';

import NumberParser from 'intl-number-parser';

// Possible values for the input type, see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#input_types
// for the sake of completeness, we list all here, with some commented out that are better handled elsewhere, or not at all...
export type InputType =
Expand Down Expand Up @@ -50,6 +52,29 @@ export interface HeadlessFormControlInputComponentSignature {
*/
type?: InputType;

/**
* Some inputs are specific to locales, like numbers.
* Ex:
* "en-us"
* If this ends up being undefined it will simply use the locale of the user.
*
* ? While the linked resource below mentions you can pass in a Intl.Locale object, the current library we use for this doesn't
* ? support it. So stick with strings using a BCP 47 language tag.
*
* @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat/NumberFormat#locales
* @see https://datatracker.ietf.org/doc/html/rfc4647
*/
locale?: string

/**
* Adding the ability to add additional options for the formatter. This currently only applies to number types.
* Ex:
* { style: 'currency', currency: 'EUR' }
*
* @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat
*/
formatOptions?: Intl.NumberFormatOptions,

// the following are private arguments curried by the component helper, so users will never have to use those

/*
Expand Down Expand Up @@ -85,6 +110,8 @@ export interface HeadlessFormControlInputComponentSignature {
}

export default class HeadlessFormControlInputComponent extends Component<HeadlessFormControlInputComponentSignature> {
public formatter: NumberParser;

constructor(
owner: unknown,
args: HeadlessFormControlInputComponentSignature['Args']
Expand All @@ -95,21 +122,38 @@ export default class HeadlessFormControlInputComponent extends Component<Headles
// TS would guard us against using an unsupported `InputType`, but for JS consumers we add a dev-only runtime check here
!['checkbox', 'radio'].includes(args.type as string)
);

super(owner, args);

this.formatter = NumberParser(this.locale, this.formatOptions);
}

get type(): InputType {
return this.args.type ?? 'text';
}

get locale(): String {
return this.args.locale;
}

get formatOptions(): Object {
return this.args.formatOptions ?? {};
}

@action
handleInput(e: Event | InputEvent): void {
assert('Expected HTMLInputElement', e.target instanceof HTMLInputElement);
this.args.setValue(
this.type === 'number' ? parseFloat(e.target.value) : e.target.value
);
this.args.setValue(e.target.value);
}

@action
handleUnfocus(e: Event | InputEvent): void {
assert('Expected HTMLInputElement', e.target instanceof HTMLInputElement);

if(this.type === "number"){
this.args.setValue(this.formatter(e.target.value));
}
}

<template>
<input
name={{@name}}
Expand All @@ -120,6 +164,7 @@ export default class HeadlessFormControlInputComponent extends Component<Headles
aria-describedby={{if @invalid @errorId}}
...attributes
{{on "input" this.handleInput}}
{{on "focusout" this.handleUnfocus}}
/>
</template>
}
10 changes: 10 additions & 0 deletions pnpm-lock.yaml

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

14 changes: 13 additions & 1 deletion test-app/app/templates/index.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,25 @@
<div class='my-2 flex flex-col'>
<field.Label class={{if field.isInvalid 'text-red-500'}}>Last name</field.Label>
<field.Input
@max='10'
class='border rounded px-2 {{if field.isInvalid "border-red-500"}}'
required
/>
<field.Errors class='text-red-600' />
</div>
</form.Field>

<form.Field @name='rating' as |field|>
<div class='my-2 flex flex-col'>
<field.Label class={{if field.isInvalid 'text-red-500'}}>How likely are
you to recommend us?</field.Label>
<field.Input
@type='number'
min='1'
max='10'
class='border rounded px-2 {{if field.isInvalid "border-red-500"}}'
/>
</div>
</form.Field>
<form.Field @name='gender' as |field|>
<field.RadioGroup class='my-2 flex flex-col' as |group|>
<group.Label>Gender</group.Label>
Expand Down
21 changes: 9 additions & 12 deletions test-app/config/ember-try.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,9 @@ module.exports = async function () {
npm: {
devDependencies: {
'ember-source': '~4.8.0',
// @todo remove this once we have a stable release that includes https://github.com/embroider-build/embroider/pull/1383
'@embroider/core': '2.1.2-unstable.3a9d8ad',
'@embroider/compat': '2.1.2-unstable.3a9d8ad',
'@embroider/webpack': '2.1.2-unstable.3a9d8ad',
'@embroider/core': '3.5.0',
'@embroider/compat': '3.8.0',
'@embroider/webpack': '4.0.9',
},
},
}),
Expand All @@ -66,10 +65,9 @@ module.exports = async function () {
npm: {
devDependencies: {
'ember-source': '~4.8.0',
// @todo remove this once we have a stable release that includes https://github.com/embroider-build/embroider/pull/1383
'@embroider/core': '2.1.2-unstable.3a9d8ad',
'@embroider/compat': '2.1.2-unstable.3a9d8ad',
'@embroider/webpack': '2.1.2-unstable.3a9d8ad',
'@embroider/core': '3.5.0',
'@embroider/compat': '3.8.0',
'@embroider/webpack': '4.0.9',
},
},
}),
Expand All @@ -78,10 +76,9 @@ module.exports = async function () {
npm: {
devDependencies: {
'ember-source': releaseVersion,
// @todo remove this once we have a stable release that includes https://github.com/embroider-build/embroider/pull/1383
'@embroider/core': '2.1.2-unstable.3a9d8ad',
'@embroider/compat': '2.1.2-unstable.3a9d8ad',
'@embroider/webpack': '2.1.2-unstable.3a9d8ad',
'@embroider/core': '3.5.0',
'@embroider/compat': '3.8.0',
'@embroider/webpack': '4.0.9',
},
},
}),
Expand Down