ember-primitives 0.52.0 → 0.53.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2,5 +2,5 @@
2
2
  * If the user provides an onChange or similar function, use that,
3
3
  * otherwise fallback to the uncontrolled toggle
4
4
  */
5
- export declare function toggleWithFallback(uncontrolledToggle: (...args: unknown[]) => void, controlledToggle?: (...args: any[]) => void, ...args: unknown[]): void;
5
+ export declare function toggleWithFallback(uncontrolledToggle: undefined | ((...args: any[]) => void) | (() => void), controlledToggle?: (...args: any[]) => void, ...args: unknown[]): void;
6
6
  //# sourceMappingURL=utils.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/components/-private/utils.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,wBAAgB,kBAAkB,CAChC,kBAAkB,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,EAEhD,gBAAgB,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,IAAI,EAC3C,GAAG,IAAI,EAAE,OAAO,EAAE,QAOnB"}
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/components/-private/utils.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,wBAAgB,kBAAkB,CAChC,kBAAkB,EAAE,SAAS,GAAG,CAAC,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,IAAI,CAAC,GAAG,CAAC,MAAM,IAAI,CAAC,EACzE,gBAAgB,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,IAAI,EAC3C,GAAG,IAAI,EAAE,OAAO,EAAE,QAOnB"}
@@ -16,7 +16,7 @@ export interface Signature {
16
16
  /**
17
17
  * A separator component to place between breadcrumb items.
18
18
  * Typically renders as "/" or ">" and is decorative (aria-hidden="true").
19
- * Pre-configured to render as an <li> element for proper HTML structure.
19
+ * Pre-configured to render as an `<li>` element for proper HTML structure.
20
20
  */
21
21
  Separator: WithBoundArgs<typeof Separator, "as" | "decorative">;
22
22
  }
@@ -1,3 +1,5 @@
1
+ import Component from "@glimmer/component";
2
+ import { cell } from "ember-resources";
1
3
  import { Label } from './-private/typed-elements';
2
4
  import type { TOC } from "@ember/component/template-only";
3
5
  import type { WithBoundArgs } from "@glint/template";
@@ -18,13 +20,27 @@ export interface Signature {
18
20
  Blocks: {
19
21
  default?: [
20
22
  {
23
+ /**
24
+ * The current state of the Switch.
25
+ *
26
+ * ```gjs
27
+ * import { Switch } from 'ember-primitives/components/switch';
28
+ *
29
+ * <template>
30
+ * <Switch as |s|>
31
+ * {{s.isChecked}}
32
+ * </Switch>
33
+ * </template>
34
+ * ```
35
+ */
36
+ isChecked: boolean;
21
37
  /**
22
38
  * The Switch Element.
23
39
  * It has a pre-wired `id` so that the relevant Label is
24
40
  * appropriately associated via the `for` property of the Label.
25
41
  *
26
42
  * ```gjs
27
- * import { Switch } from 'ember-primitives';
43
+ * import { Switch } from 'ember-primitives/components/switch';
28
44
  *
29
45
  * <template>
30
46
  * <Switch as |s|>
@@ -39,7 +55,7 @@ export interface Signature {
39
55
  * the association to the Control by setting the `for` attribute to the `id` of the Control
40
56
  *
41
57
  * ```gjs
42
- * import { Switch } from 'ember-primitives';
58
+ * import { Switch } from 'ember-primitive/components/switchs';
43
59
  *
44
60
  * <template>
45
61
  * <Switch as |s|>
@@ -57,11 +73,13 @@ interface ControlSignature {
57
73
  Element: HTMLInputElement;
58
74
  Args: {
59
75
  id: string;
60
- checked?: boolean;
61
- onChange: () => void;
76
+ checked?: ReturnType<typeof cell<boolean>>;
77
+ onChange?: (checked: boolean, event: Event) => void;
62
78
  };
63
79
  }
64
- declare const Checkbox: TOC<ControlSignature>;
80
+ declare class Checkbox extends Component<ControlSignature> {
81
+ handleClick: (event: Event) => void;
82
+ }
65
83
  /**
66
84
  * @public
67
85
  */
@@ -1 +1 @@
1
- {"version":3,"file":"switch.d.ts","sourceRoot":"","sources":["../../src/components/switch.gts"],"names":[],"mappings":"AA6GA,OAAO,EAAE,KAAK,EAAE,MAAM,+BAA+B,CAAC;AAGtD,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,gCAAgC,CAAC;AAC1D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAErD,MAAM,WAAW,SAAS;IACxB,OAAO,EAAE,gBAAgB,CAAC;IAC1B,IAAI,EAAE;QACJ;;;;WAIG;QACH,OAAO,CAAC,EAAE,OAAO,CAAC;QAClB;;WAEG;QACH,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;KACrD,CAAC;IACF,MAAM,EAAE;QACN,OAAO,CAAC,EAAE;YACR;gBACE;;;;;;;;;;;;;;mBAcG;gBACH,OAAO,EAAE,aAAa,CAAC,OAAO,QAAQ,EAAE,SAAS,GAAG,IAAI,GAAG,UAAU,CAAC,CAAC;gBACvE;;;;;;;;;;;;;mBAaG;gBACH,KAAK,EAAE,aAAa,CAAC,OAAO,KAAK,EAAE,KAAK,CAAC,CAAC;aAC3C;SACF,CAAC;KACH,CAAC;CACH;AAED,UAAU,gBAAgB;IACxB,OAAO,EAAE,gBAAgB,CAAC;IAC1B,IAAI,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,OAAO,CAAC;QAAC,QAAQ,EAAE,MAAM,IAAI,CAAA;KAAE,CAAC;CAC/D;AAED,QAAA,MAAM,QAAQ,EAAE,GAAG,CAAC,gBAAgB,CA6BlC,CAAC;AAEH;;GAEG;AACH,eAAO,MAAM,MAAM,EAAE,GAAG,CAAC,SAAS,CAwBhC,CAAC;AAEH,eAAe,MAAM,CAAC"}
1
+ {"version":3,"file":"switch.d.ts","sourceRoot":"","sources":["../../src/components/switch.gts"],"names":[],"mappings":"AAAA,OA0IO,SAAS,MAAM,oBAAoB,CAAC;AAI3C,OAAO,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAGvC,OAAO,EAAE,KAAK,EAAE,MAAM,+BAA+B,CAAC;AAEtD,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,gCAAgC,CAAC;AAC1D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAErD,MAAM,WAAW,SAAS;IACxB,OAAO,EAAE,gBAAgB,CAAC;IAC1B,IAAI,EAAE;QACJ;;;;WAIG;QACH,OAAO,CAAC,EAAE,OAAO,CAAC;QAClB;;WAEG;QACH,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;KACrD,CAAC;IACF,MAAM,EAAE;QACN,OAAO,CAAC,EAAE;YACR;gBACE;;;;;;;;;;;;mBAYG;gBACH,SAAS,EAAE,OAAO,CAAC;gBACnB;;;;;;;;;;;;;;mBAcG;gBACH,OAAO,EAAE,aAAa,CAAC,OAAO,QAAQ,EAAE,SAAS,GAAG,IAAI,GAAG,UAAU,CAAC,CAAC;gBACvE;;;;;;;;;;;;;mBAaG;gBACH,KAAK,EAAE,aAAa,CAAC,OAAO,KAAK,EAAE,KAAK,CAAC,CAAC;aAC3C;SACF,CAAC;KACH,CAAC;CACH;AAED,UAAU,gBAAgB;IACxB,OAAO,EAAE,gBAAgB,CAAC;IAC1B,IAAI,EAAE;QACJ,EAAE,EAAE,MAAM,CAAC;QACX,OAAO,CAAC,EAAE,UAAU,CAAC,OAAO,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;QAC3C,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;KACrD,CAAC;CACH;AAED,cAAM,QAAS,SAAQ,SAAS,CAAC,gBAAgB,CAAC;IAChD,WAAW,GAAI,OAAO,KAAK,UAQzB;CAyBH;AAMD;;GAEG;AACH,eAAO,MAAM,MAAM,EAAE,GAAG,CAAC,SAAS,CAgChC,CAAC;AAEH,eAAe,MAAM,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"breadcrumb.js","sources":["../../src/components/breadcrumb.gts"],"sourcesContent":["import { hash } from \"@ember/helper\";\n\nimport { Separator } from \"./separator.gts\";\n\nimport type { TOC } from \"@ember/component/template-only\";\nimport type { WithBoundArgs } from \"@glint/template\";\n\nexport interface Signature {\n Element: HTMLElement;\n Args: {\n /**\n * The accessible label for the breadcrumb navigation.\n * Defaults to \"Breadcrumb\"\n */\n label?: string;\n };\n Blocks: {\n default: [\n {\n /**\n * A separator component to place between breadcrumb items.\n * Typically renders as \"/\" or \">\" and is decorative (aria-hidden=\"true\").\n * Pre-configured to render as an <li> element for proper HTML structure.\n */\n Separator: WithBoundArgs<typeof Separator, \"as\" | \"decorative\">;\n },\n ];\n };\n}\n\n/**\n * A breadcrumb navigation component that displays the current page's location within a navigational hierarchy.\n *\n * Breadcrumbs help users understand their current location and provide a way to navigate back through the hierarchy.\n *\n * For example:\n *\n * ```gjs live preview\n * import { Breadcrumb } from 'ember-primitives';\n *\n * <template>\n * <Breadcrumb as |b|>\n * <li>\n * <a href=\"/\">Home</a>\n * </li>\n * <b.Separator>/</b.Separator>\n * <li>\n * <a href=\"/docs\">Docs</a>\n * </li>\n * <b.Separator>/</b.Separator>\n * <li aria-current=\"page\">\n * Breadcrumb\n * </li>\n * </Breadcrumb>\n * </template>\n * ```\n */\nexport const Breadcrumb: TOC<Signature> = <template>\n <nav aria-label={{if @label @label \"Breadcrumb\"}} ...attributes>\n <ol>\n {{yield (hash Separator=(component Separator as=\"li\" decorative=true))}}\n </ol>\n </nav>\n</template>;\n\nexport default Breadcrumb;\n"],"names":["Breadcrumb","setComponentTemplate","precompileTemplate","strictMode","scope","hash","Separator","templateOnly"],"mappings":";;;;;;AA8BA;;;;;;;;;;;;;;;;;;;;;;;;;;AA0BC;MACYA,UAAgB,GAAAC,oBAAA,CAAaC,kBAAA,CAAA,6KAAA,EAM1C;EAAAC,UAAA,EAAA,IAAA;AAAAC,EAAAA,KAAA,EAAAA,OAAA;IAAAC,IAAA;AAAAC,IAAAA;AAAA,GAAA;AAAU,CAAA,CAAA,EAAAC,YAAA,EAAA;;;;"}
1
+ {"version":3,"file":"breadcrumb.js","sources":["../../src/components/breadcrumb.gts"],"sourcesContent":["import { hash } from \"@ember/helper\";\n\nimport { Separator } from \"./separator.gts\";\n\nimport type { TOC } from \"@ember/component/template-only\";\nimport type { WithBoundArgs } from \"@glint/template\";\n\nexport interface Signature {\n Element: HTMLElement;\n Args: {\n /**\n * The accessible label for the breadcrumb navigation.\n * Defaults to \"Breadcrumb\"\n */\n label?: string;\n };\n Blocks: {\n default: [\n {\n /**\n * A separator component to place between breadcrumb items.\n * Typically renders as \"/\" or \">\" and is decorative (aria-hidden=\"true\").\n * Pre-configured to render as an `<li>` element for proper HTML structure.\n */\n Separator: WithBoundArgs<typeof Separator, \"as\" | \"decorative\">;\n },\n ];\n };\n}\n\n/**\n * A breadcrumb navigation component that displays the current page's location within a navigational hierarchy.\n *\n * Breadcrumbs help users understand their current location and provide a way to navigate back through the hierarchy.\n *\n * For example:\n *\n * ```gjs live preview\n * import { Breadcrumb } from 'ember-primitives';\n *\n * <template>\n * <Breadcrumb as |b|>\n * <li>\n * <a href=\"/\">Home</a>\n * </li>\n * <b.Separator>/</b.Separator>\n * <li>\n * <a href=\"/docs\">Docs</a>\n * </li>\n * <b.Separator>/</b.Separator>\n * <li aria-current=\"page\">\n * Breadcrumb\n * </li>\n * </Breadcrumb>\n * </template>\n * ```\n */\nexport const Breadcrumb: TOC<Signature> = <template>\n <nav aria-label={{if @label @label \"Breadcrumb\"}} ...attributes>\n <ol>\n {{yield (hash Separator=(component Separator as=\"li\" decorative=true))}}\n </ol>\n </nav>\n</template>;\n\nexport default Breadcrumb;\n"],"names":["Breadcrumb","setComponentTemplate","precompileTemplate","strictMode","scope","hash","Separator","templateOnly"],"mappings":";;;;;;AA8BA;;;;;;;;;;;;;;;;;;;;;;;;;;AA0BC;MACYA,UAAgB,GAAAC,oBAAA,CAAaC,kBAAA,CAAA,6KAAA,EAM1C;EAAAC,UAAA,EAAA,IAAA;AAAAC,EAAAA,KAAA,EAAAA,OAAA;IAAAC,IAAA;AAAAC,IAAAA;AAAA,GAAA;AAAU,CAAA,CAAA,EAAAC,YAAA,EAAA;;;;"}
@@ -1,2 +1,2 @@
1
- export { a as OTP, O as OTPInput } from '../otp-7rz1PWP0.js';
1
+ export { O as OTP, a as OTPInput } from '../otp-H5a4B4yu.js';
2
2
  //# sourceMappingURL=one-time-password.js.map
@@ -2,7 +2,7 @@ import { assert } from '@ember/debug';
2
2
  import { schedule } from '@ember/runloop';
3
3
  import { buildWaiter } from '@ember/test-waiters';
4
4
  import { modifier } from 'ember-modifier';
5
- import { resourceFactory, cell, resource } from 'ember-resources';
5
+ import { resourceFactory, resource, cell } from 'ember-resources';
6
6
  import { isElement } from '../narrowing.js';
7
7
  import { findNearestTarget } from './portal-targets.js';
8
8
  import { precompileTemplate } from '@ember/template-compilation';
@@ -1,11 +1,11 @@
1
- import { fn, hash } from '@ember/helper';
1
+ import Component from '@glimmer/component';
2
+ import { hash } from '@ember/helper';
2
3
  import { on } from '@ember/modifier';
3
4
  import { cell } from 'ember-resources';
4
5
  import { uniqueId } from '../utils.js';
5
6
  import { precompileTemplate } from '@ember/template-compilation';
6
7
  import { setComponentTemplate } from '@ember/component';
7
8
  import templateOnly from '@ember/component/template-only';
8
- import { t as toggleWithFallback } from '../utils-D0v9WKmV.js';
9
9
 
10
10
  setComponentTemplate(precompileTemplate("<div ...attributes>{{yield}}</div>", {
11
11
  strictMode: true
@@ -14,22 +14,36 @@ const Label = setComponentTemplate(precompileTemplate("<label for={{@for}} ...at
14
14
  strictMode: true
15
15
  }), templateOnly());
16
16
 
17
- const Checkbox = setComponentTemplate(precompileTemplate("{{#let (cell @checked) as |checked|}}\n <input id={{@id}} type=\"checkbox\" role=\"switch\" checked={{checked.current}} aria-checked={{checked.current}} data-state={{if checked.current \"on\" \"off\"}} {{on \"click\" (fn toggleWithFallback checked.toggle @onChange)}} ...attributes />\n{{/let}}", {
18
- strictMode: true,
19
- scope: () => ({
20
- cell,
21
- on,
22
- fn,
23
- toggleWithFallback
24
- })
25
- }), templateOnly());
17
+ class Checkbox extends Component {
18
+ handleClick = event => {
19
+ const newChecked = event.target.checked;
20
+ if (this.args.onChange) {
21
+ this.args.onChange(newChecked, event);
22
+ } else {
23
+ this.args.checked?.toggle();
24
+ }
25
+ };
26
+ static {
27
+ setComponentTemplate(precompileTemplate("<input id={{@id}} type=\"checkbox\" role=\"switch\" checked={{@checked.current}} aria-checked={{@checked.current}} data-state={{if @checked.current \"on\" \"off\"}} {{on \"click\" this.handleClick}} ...attributes />", {
28
+ strictMode: true,
29
+ scope: () => ({
30
+ on
31
+ })
32
+ }), this);
33
+ }
34
+ }
35
+ function defaultFalse(value) {
36
+ return value ?? false;
37
+ }
26
38
  /**
27
39
  * @public
28
40
  */
29
- const Switch = setComponentTemplate(precompileTemplate("<div ...attributes data-prim-switch>\n {{!-- @glint-nocheck --}}\n {{#let (uniqueId) as |id|}}\n {{yield (hash Control=(component Checkbox checked=@checked id=id onChange=@onChange) Label=(component Label for=id))}}\n {{/let}}\n</div>", {
41
+ const Switch = setComponentTemplate(precompileTemplate("<div ...attributes data-prim-switch>\n {{#let (uniqueId) as |id|}}\n {{#let (cell (defaultFalse @checked)) as |checked|}}\n {{!-- @glint-nocheck --}}\n {{yield (hash isChecked=checked.current Control=(component Checkbox checked=checked id=id onChange=@onChange) Label=(component Label for=id))}}\n {{/let}}\n {{/let}}\n</div>", {
30
42
  strictMode: true,
31
43
  scope: () => ({
32
44
  uniqueId,
45
+ cell,
46
+ defaultFalse,
33
47
  hash,
34
48
  Checkbox,
35
49
  Label
@@ -1 +1 @@
1
- {"version":3,"file":"switch.js","sources":["../../src/components/-private/typed-elements.gts","../../src/components/switch.gts"],"sourcesContent":["import type { TOC } from \"@ember/component/template-only\";\n\nexport const Div: TOC<{ Element: HTMLDivElement; Blocks: { default: [] } }> = <template>\n <div ...attributes>{{yield}}</div>\n</template>;\n\nexport const Label: TOC<{\n Element: HTMLLabelElement;\n Args: { for: string };\n Blocks: { default: [] };\n}> = <template>\n <label for={{@for}} ...attributes>{{yield}}</label>\n</template>;\n","import { fn, hash } from \"@ember/helper\";\nimport { on } from \"@ember/modifier\";\n\nimport { cell } from \"ember-resources\";\n\nimport { uniqueId } from \"../utils.ts\";\nimport { Label } from \"./-private/typed-elements.gts\";\nimport { toggleWithFallback } from \"./-private/utils.ts\";\n\nimport type { TOC } from \"@ember/component/template-only\";\nimport type { WithBoundArgs } from \"@glint/template\";\n\nexport interface Signature {\n Element: HTMLInputElement;\n Args: {\n /**\n * The initial checked value of the Switch.\n * This value is reactive, so if the value that\n * `@checked` is set to updates, the state of the Switch will also update.\n */\n checked?: boolean;\n /**\n * Callback when the Switch state is toggled\n */\n onChange?: (checked: boolean, event: Event) => void;\n };\n Blocks: {\n default?: [\n {\n /**\n * The Switch Element.\n * It has a pre-wired `id` so that the relevant Label is\n * appropriately associated via the `for` property of the Label.\n *\n * ```gjs\n * import { Switch } from 'ember-primitives';\n *\n * <template>\n * <Switch as |s|>\n * <s.Control />\n * </Switch>\n * </template>\n * ```\n */\n Control: WithBoundArgs<typeof Checkbox, \"checked\" | \"id\" | \"onChange\">;\n /**\n * The Switch element requires a label, and this label already has\n * the association to the Control by setting the `for` attribute to the `id` of the Control\n *\n * ```gjs\n * import { Switch } from 'ember-primitives';\n *\n * <template>\n * <Switch as |s|>\n * <s.Label />\n * </Switch>\n * </template>\n * ```\n */\n Label: WithBoundArgs<typeof Label, \"for\">;\n },\n ];\n };\n}\n\ninterface ControlSignature {\n Element: HTMLInputElement;\n Args: { id: string; checked?: boolean; onChange: () => void };\n}\n\nconst Checkbox: TOC<ControlSignature> = <template>\n {{#let (cell @checked) as |checked|}}\n <input\n id={{@id}}\n type=\"checkbox\"\n role=\"switch\"\n checked={{checked.current}}\n aria-checked={{checked.current}}\n data-state={{if checked.current \"on\" \"off\"}}\n {{on \"click\" (fn toggleWithFallback checked.toggle @onChange)}}\n ...attributes\n />\n {{/let}}\n</template>;\n\n/**\n * @public\n */\nexport const Switch: TOC<Signature> = <template>\n <div ...attributes data-prim-switch>\n {{! @glint-nocheck }}\n {{#let (uniqueId) as |id|}}\n {{yield\n (hash\n Control=(component Checkbox checked=@checked id=id onChange=@onChange)\n Label=(component Label for=id)\n )\n }}\n {{/let}}\n </div>\n</template>;\n\nexport default Switch;\n"],"names":["precompileTemplate","strictMode","templateOnly","Label","Checkbox","setComponentTemplate","scope","cell","on","fn","toggleWithFallback","Switch","uniqueId","hash"],"mappings":";;;;;;;;;qBAE8EA,kBAAA,CAAA,oCAAA,EAE9E;EAAAC,UAAA,EAAA;AAAU,CAAA,CAAA,EAAAC,YAAA,EAAA;AAEH,MAAMC,6BAIRH,kBAAA,CAAA,qDAAA,EAEL;EAAAC,UAAA,EAAA;AAAU,CAAA,CAAA,EAAAC,YAAA,EAAA,CAAA;;AC0DV,MAAME,QAAc,GAAAC,oBAAA,CAAoBL,kBAAA,CAAA,ySAAA,EAaxC;EAAAC,UAAA,EAAA,IAAA;AAAAK,EAAAA,KAAA,EAAAA,OAAA;IAAAC,IAAA;IAAAC,EAAA;IAAAC,EAAA;AAAAC,IAAAA;AAAA,GAAA;AAAU,CAAA,CAAA,EAAAR,YAAA,EAAA,CAAA;AAEV;;AAEC;MACYS,MAAY,GAAAN,oBAAA,CAAaL,kBAAA,CAAA,kPAAA,EAYtC;EAAAC,UAAA,EAAA,IAAA;AAAAK,EAAAA,KAAA,EAAAA,OAAA;IAAAM,QAAA;IAAAC,IAAA;IAAAT,QAAA;AAAAD,IAAAA;AAAA,GAAA;AAAU,CAAA,CAAA,EAAAD,YAAA,EAAA;;;;"}
1
+ {"version":3,"file":"switch.js","sources":["../../src/components/-private/typed-elements.gts","../../src/components/switch.gts"],"sourcesContent":["import type { TOC } from \"@ember/component/template-only\";\n\nexport const Div: TOC<{ Element: HTMLDivElement; Blocks: { default: [] } }> = <template>\n <div ...attributes>{{yield}}</div>\n</template>;\n\nexport const Label: TOC<{\n Element: HTMLLabelElement;\n Args: { for: string };\n Blocks: { default: [] };\n}> = <template>\n <label for={{@for}} ...attributes>{{yield}}</label>\n</template>;\n","import Component from \"@glimmer/component\";\nimport { hash } from \"@ember/helper\";\nimport { on } from \"@ember/modifier\";\n\nimport { cell } from \"ember-resources\";\n\nimport { uniqueId } from \"../utils.ts\";\nimport { Label } from \"./-private/typed-elements.gts\";\n\nimport type { TOC } from \"@ember/component/template-only\";\nimport type { WithBoundArgs } from \"@glint/template\";\n\nexport interface Signature {\n Element: HTMLInputElement;\n Args: {\n /**\n * The initial checked value of the Switch.\n * This value is reactive, so if the value that\n * `@checked` is set to updates, the state of the Switch will also update.\n */\n checked?: boolean;\n /**\n * Callback when the Switch state is toggled\n */\n onChange?: (checked: boolean, event: Event) => void;\n };\n Blocks: {\n default?: [\n {\n /**\n * The current state of the Switch.\n *\n * ```gjs\n * import { Switch } from 'ember-primitives/components/switch';\n *\n * <template>\n * <Switch as |s|>\n * {{s.isChecked}}\n * </Switch>\n * </template>\n * ```\n */\n isChecked: boolean;\n /**\n * The Switch Element.\n * It has a pre-wired `id` so that the relevant Label is\n * appropriately associated via the `for` property of the Label.\n *\n * ```gjs\n * import { Switch } from 'ember-primitives/components/switch';\n *\n * <template>\n * <Switch as |s|>\n * <s.Control />\n * </Switch>\n * </template>\n * ```\n */\n Control: WithBoundArgs<typeof Checkbox, \"checked\" | \"id\" | \"onChange\">;\n /**\n * The Switch element requires a label, and this label already has\n * the association to the Control by setting the `for` attribute to the `id` of the Control\n *\n * ```gjs\n * import { Switch } from 'ember-primitive/components/switchs';\n *\n * <template>\n * <Switch as |s|>\n * <s.Label />\n * </Switch>\n * </template>\n * ```\n */\n Label: WithBoundArgs<typeof Label, \"for\">;\n },\n ];\n };\n}\n\ninterface ControlSignature {\n Element: HTMLInputElement;\n Args: {\n id: string;\n checked?: ReturnType<typeof cell<boolean>>;\n onChange?: (checked: boolean, event: Event) => void;\n };\n}\n\nclass Checkbox extends Component<ControlSignature> {\n handleClick = (event: Event) => {\n const newChecked = (event.target as HTMLInputElement).checked;\n\n if (this.args.onChange) {\n this.args.onChange(newChecked, event);\n } else {\n this.args.checked?.toggle();\n }\n };\n\n <template>\n <input\n id={{@id}}\n type=\"checkbox\"\n role=\"switch\"\n checked={{@checked.current}}\n aria-checked={{@checked.current}}\n data-state={{if @checked.current \"on\" \"off\"}}\n {{on \"click\" this.handleClick}}\n ...attributes\n />\n </template>\n}\n\nfunction defaultFalse(value: unknown) {\n return value ?? false;\n}\n\n/**\n * @public\n */\nexport const Switch: TOC<Signature> = <template>\n <div ...attributes data-prim-switch>\n {{#let (uniqueId) as |id|}}\n {{#let (cell (defaultFalse @checked)) as |checked|}}\n {{! @glint-nocheck }}\n {{yield\n (hash\n isChecked=checked.current\n Control=(component Checkbox checked=checked id=id onChange=@onChange)\n Label=(component Label for=id)\n )\n }}\n {{/let}}\n {{/let}}\n </div>\n</template>;\n\nexport default Switch;\n"],"names":["precompileTemplate","strictMode","templateOnly","Label","Checkbox","Component","handleClick","event","newChecked","target","checked","args","onChange","toggle","setComponentTemplate","scope","on","defaultFalse","value","Switch","uniqueId","cell","hash"],"mappings":";;;;;;;;;qBAE8EA,kBAAA,CAAA,oCAAA,EAE9E;EAAAC,UAAA,EAAA;AAAU,CAAA,CAAA,EAAAC,YAAA,EAAA;AAEH,MAAMC,6BAIRH,kBAAA,CAAA,qDAAA,EAEL;EAAAC,UAAA,EAAA;AAAU,CAAA,CAAA,EAAAC,YAAA,EAAA,CAAA;;AC4EV,MAAME,iBAAiBC,SAAA,CAAU;EAC/BC,WAAA,GAAeC,KAAO,IAAA;AACpB,IAAA,MAAMC,aAAcD,KAAA,CAAME,MAAM,CAAsBC,OAAO;AAE7D,IAAA,IAAI,IAAI,CAACC,IAAI,CAACC,QAAQ,EAAE;MACtB,IAAI,CAACD,IAAI,CAACC,QAAQ,CAACJ,UAAA,EAAYD,KAAA,CAAA;AACjC,IAAA,CAAA,MAAO;AACL,MAAA,IAAI,CAACI,IAAI,CAACD,OAAO,EAAEG,MAAA,EAAA;AACrB,IAAA;EACF,CAAA;AAEA,EAAA;IAAAC,oBAAA,CAAAd,kBAAA,CAAA,yNAAA,EAWA;MAAAC,UAAA,EAAA,IAAA;AAAAc,MAAAA,KAAA,EAAAA,OAAA;AAAAC,QAAAA;AAAA,OAAA;KAAU,CAAA,EAAV,IAAW,CAAA;AAAD;AACZ;AAEA,SAASC,YAAAA,CAAaC,KAAc,EAAA;EAClC,OAAOA,KAAA,IAAS,KAAA;AAClB;AAEA;;AAEC;MACYC,MAAY,GAAAL,oBAAA,CAAad,kBAAA,CAAA,yVAAA,EAetC;EAAAC,UAAA,EAAA,IAAA;AAAAc,EAAAA,KAAA,EAAAA,OAAA;IAAAK,QAAA;IAAAC,IAAA;IAAAJ,YAAA;IAAAK,IAAA;IAAAlB,QAAA;AAAAD,IAAAA;AAAA,GAAA;AAAU,CAAA,CAAA,EAAAD,YAAA,EAAA;;;;"}
@@ -1,11 +1,21 @@
1
1
  import { fn } from '@ember/helper';
2
2
  import { on } from '@ember/modifier';
3
3
  import { cell } from 'ember-resources';
4
- import { t as toggleWithFallback } from '../utils-D0v9WKmV.js';
5
4
  import { precompileTemplate } from '@ember/template-compilation';
6
5
  import { setComponentTemplate } from '@ember/component';
7
6
  import templateOnly from '@ember/component/template-only';
8
7
 
8
+ /**
9
+ * If the user provides an onChange or similar function, use that,
10
+ * otherwise fallback to the uncontrolled toggle
11
+ */
12
+ function toggleWithFallback(uncontrolledToggle, controlledToggle, ...args) {
13
+ if (controlledToggle) {
14
+ return controlledToggle(...args);
15
+ }
16
+ uncontrolledToggle?.(...args);
17
+ }
18
+
9
19
  // import Component from '@glimmer/component';
10
20
 
11
21
  function isPressed(pressed, value, isPressed) {
@@ -1 +1 @@
1
- {"version":3,"file":"toggle.js","sources":["../../src/components/toggle.gts"],"sourcesContent":["// import Component from '@glimmer/component';\nimport { fn } from \"@ember/helper\";\nimport { on } from \"@ember/modifier\";\n\nimport { cell } from \"ember-resources\";\n\nimport { toggleWithFallback } from \"./-private/utils.ts\";\n\nimport type { TOC } from \"@ember/component/template-only\";\n\nexport interface Signature<Value = any> {\n Element: HTMLButtonElement;\n Args: {\n /**\n * The pressed-state of the toggle.\n *\n * Can be used to control the state of the component.\n */\n pressed?: boolean;\n /**\n * Callback for when the toggle's state is changed.\n *\n * Can be used to control the state of the component.\n *\n * if a `@value` is passed to this `<Toggle>`, that @value will\n * be passed to the `@onChange` handler.\n *\n * This can be useful when using the same function for the `@onChange`\n * handler with multiple `<Toggle>` components.\n */\n onChange?: (value: Value | undefined, pressed: boolean) => void;\n\n /**\n * When used in a group of Toggles, this option will be helpful to\n * know which toggle was pressed if you're using the same @onChange\n * handler for multiple toggles.\n */\n value?: Value;\n\n /**\n * When controlling state in a wrapping component, this function can be used in conjunction with `@value` to determine if this `<Toggle>` should appear pressed.\n */\n isPressed?: (value?: Value) => boolean;\n };\n Blocks: {\n default: [\n /**\n * the current pressed state of the toggle button\n *\n * Useful when using the toggle button as an uncontrolled component\n */\n pressed: boolean,\n ];\n };\n}\n\nfunction isPressed(\n pressed?: boolean,\n value?: unknown,\n isPressed?: (value?: unknown) => boolean,\n): boolean {\n if (!value) return Boolean(pressed);\n if (!isPressed) return Boolean(pressed);\n\n return isPressed(value);\n}\n\nexport const Toggle: TOC<Signature> = <template>\n {{#let (cell (isPressed @pressed @value @isPressed)) as |pressed|}}\n <button\n type=\"button\"\n aria-pressed=\"{{pressed.current}}\"\n {{on \"click\" (fn toggleWithFallback pressed.toggle @onChange @value)}}\n ...attributes\n >\n {{yield pressed.current}}\n </button>\n {{/let}}\n</template>;\n\nexport default Toggle;\n"],"names":["isPressed","pressed","value","Boolean","Toggle","setComponentTemplate","precompileTemplate","strictMode","scope","cell","on","fn","toggleWithFallback","templateOnly"],"mappings":";;;;;;;;AAAA;;AAwDA,SAASA,SAAAA,CACPC,OAAiB,EACjBC,KAAe,EACfF,SAAwC,EAChC;AACR,EAAA,IAAI,CAACE,KAAA,EAAO,OAAOC,OAAA,CAAQF,OAAA,CAAA;AAC3B,EAAA,IAAI,CAACD,SAAA,EAAW,OAAOG,OAAA,CAAQF,OAAA,CAAA;EAE/B,OAAOD,SAAA,CAAUE,KAAA,CAAA;AACnB;MAEaE,MAAY,GAAAC,oBAAA,CAAaC,kBAAA,CAAA,mRAAA,EAWtC;EAAAC,UAAA,EAAA,IAAA;AAAAC,EAAAA,KAAA,EAAAA,OAAA;IAAAC,IAAA;IAAAT,SAAA;IAAAU,EAAA;IAAAC,EAAA;AAAAC,IAAAA;AAAA,GAAA;AAAU,CAAA,CAAA,EAAAC,YAAA,EAAA;;;;"}
1
+ {"version":3,"file":"toggle.js","sources":["../../src/components/-private/utils.ts","../../src/components/toggle.gts"],"sourcesContent":["/**\n * If the user provides an onChange or similar function, use that,\n * otherwise fallback to the uncontrolled toggle\n */\nexport function toggleWithFallback(\n uncontrolledToggle: undefined | ((...args: any[]) => void) | (() => void),\n controlledToggle?: (...args: any[]) => void,\n ...args: unknown[]\n) {\n if (controlledToggle) {\n return controlledToggle(...args);\n }\n\n uncontrolledToggle?.(...args);\n}\n","// import Component from '@glimmer/component';\nimport { fn } from \"@ember/helper\";\nimport { on } from \"@ember/modifier\";\n\nimport { cell } from \"ember-resources\";\n\nimport { toggleWithFallback } from \"./-private/utils.ts\";\n\nimport type { TOC } from \"@ember/component/template-only\";\n\nexport interface Signature<Value = any> {\n Element: HTMLButtonElement;\n Args: {\n /**\n * The pressed-state of the toggle.\n *\n * Can be used to control the state of the component.\n */\n pressed?: boolean;\n /**\n * Callback for when the toggle's state is changed.\n *\n * Can be used to control the state of the component.\n *\n * if a `@value` is passed to this `<Toggle>`, that @value will\n * be passed to the `@onChange` handler.\n *\n * This can be useful when using the same function for the `@onChange`\n * handler with multiple `<Toggle>` components.\n */\n onChange?: (value: Value | undefined, pressed: boolean) => void;\n\n /**\n * When used in a group of Toggles, this option will be helpful to\n * know which toggle was pressed if you're using the same @onChange\n * handler for multiple toggles.\n */\n value?: Value;\n\n /**\n * When controlling state in a wrapping component, this function can be used in conjunction with `@value` to determine if this `<Toggle>` should appear pressed.\n */\n isPressed?: (value?: Value) => boolean;\n };\n Blocks: {\n default: [\n /**\n * the current pressed state of the toggle button\n *\n * Useful when using the toggle button as an uncontrolled component\n */\n pressed: boolean,\n ];\n };\n}\n\nfunction isPressed(\n pressed?: boolean,\n value?: unknown,\n isPressed?: (value?: unknown) => boolean,\n): boolean {\n if (!value) return Boolean(pressed);\n if (!isPressed) return Boolean(pressed);\n\n return isPressed(value);\n}\n\nexport const Toggle: TOC<Signature> = <template>\n {{#let (cell (isPressed @pressed @value @isPressed)) as |pressed|}}\n <button\n type=\"button\"\n aria-pressed=\"{{pressed.current}}\"\n {{on \"click\" (fn toggleWithFallback pressed.toggle @onChange @value)}}\n ...attributes\n >\n {{yield pressed.current}}\n </button>\n {{/let}}\n</template>;\n\nexport default Toggle;\n"],"names":["toggleWithFallback","uncontrolledToggle","controlledToggle","args","isPressed","pressed","value","Boolean","Toggle","setComponentTemplate","precompileTemplate","strictMode","scope","cell","on","fn","templateOnly"],"mappings":";;;;;;;AAAA;AACA;AACA;AACA;AACO,SAASA,kBAAkBA,CAChCC,kBAAyE,EACzEC,gBAA2C,EAC3C,GAAGC,IAAe,EAClB;AACA,EAAA,IAAID,gBAAgB,EAAE;AACpB,IAAA,OAAOA,gBAAgB,CAAC,GAAGC,IAAI,CAAC;AAClC,EAAA;EAEAF,kBAAkB,GAAG,GAAGE,IAAI,CAAC;AAC/B;;ACdA;;AAwDA,SAASC,SAAAA,CACPC,OAAiB,EACjBC,KAAe,EACfF,SAAwC,EAChC;AACR,EAAA,IAAI,CAACE,KAAA,EAAO,OAAOC,OAAA,CAAQF,OAAA,CAAA;AAC3B,EAAA,IAAI,CAACD,SAAA,EAAW,OAAOG,OAAA,CAAQF,OAAA,CAAA;EAE/B,OAAOD,SAAA,CAAUE,KAAA,CAAA;AACnB;MAEaE,MAAY,GAAAC,oBAAA,CAAaC,kBAAA,CAAA,mRAAA,EAWtC;EAAAC,UAAA,EAAA,IAAA;AAAAC,EAAAA,KAAA,EAAAA,OAAA;IAAAC,IAAA;IAAAT,SAAA;IAAAU,EAAA;IAAAC,EAAA;AAAAf,IAAAA;AAAA,GAAA;AAAU,CAAA,CAAA,EAAAgB,YAAA,EAAA;;;;"}
package/dist/index.js CHANGED
@@ -10,7 +10,7 @@ export { Key, KeyCombo } from './components/keys.js';
10
10
  export { StickyFooter } from './components/layout/sticky-footer.js';
11
11
  export { Link } from './components/link.js';
12
12
  export { Menu } from './components/menu.js';
13
- export { a as OTP, O as OTPInput } from './otp-7rz1PWP0.js';
13
+ export { O as OTP, a as OTPInput } from './otp-H5a4B4yu.js';
14
14
  export { Popover } from './components/popover.js';
15
15
  export { Portal } from './components/portal.js';
16
16
  export { TARGETS as PORTALS, PortalTargets } from './components/portal-targets.js';
@@ -286,5 +286,5 @@ const OTP = setComponentTemplate(precompileTemplate("<form {{on \"submit\" (fn h
286
286
  })
287
287
  }), templateOnly());
288
288
 
289
- export { OTPInput as O, OTP as a };
290
- //# sourceMappingURL=otp-7rz1PWP0.js.map
289
+ export { OTP as O, OTPInput as a };
290
+ //# sourceMappingURL=otp-H5a4B4yu.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"otp-7rz1PWP0.js","sources":["../src/components/one-time-password/utils.ts","../src/components/one-time-password/input.gts","../src/components/one-time-password/buttons.gts","../src/components/one-time-password/otp.gts"],"sourcesContent":["import { assert } from '@ember/debug';\n\nfunction getInputs(current: HTMLInputElement) {\n const fieldset = current.closest('fieldset');\n\n assert('[BUG]: fieldset went missing', fieldset);\n\n return [...fieldset.querySelectorAll('input')];\n}\n\nfunction nextInput(current: HTMLInputElement) {\n const inputs = getInputs(current);\n const currentIndex = inputs.indexOf(current);\n\n return inputs[currentIndex + 1];\n}\n\nexport function selectAll(event: Event) {\n const target = event.target;\n\n assert(`selectAll is only meant for use with input elements`, target instanceof HTMLInputElement);\n\n target.select();\n}\n\nexport function handlePaste(event: Event) {\n const target = event.target;\n\n assert(\n `handlePaste is only meant for use with input elements`,\n target instanceof HTMLInputElement\n );\n\n const clipboardData = (event as ClipboardEvent).clipboardData;\n\n assert(\n `Could not get clipboardData while handling the paste event on OTP. Please report this issue on the ember-primitives repo with a reproduction. Thanks!`,\n clipboardData\n );\n\n // This is typically not good to prevent paste.\n // But because of the UX we're implementing,\n // we want to split the pasted value across\n // multiple text fields\n event.preventDefault();\n\n const value = clipboardData.getData('Text');\n const digits = value;\n let i = 0;\n let currElement: HTMLInputElement | null = target;\n\n while (currElement) {\n currElement.value = digits[i++] || '';\n\n const next = nextInput(currElement);\n\n if (next instanceof HTMLInputElement) {\n currElement = next;\n } else {\n break;\n }\n }\n\n // We want to select the first field again\n // so that if someone holds paste, or\n // pastes again, they get the same result.\n target.select();\n}\n\nexport function handleNavigation(event: KeyboardEvent) {\n switch (event.key) {\n case 'Backspace':\n return handleBackspace(event);\n case 'ArrowLeft':\n return focusLeft(event);\n case 'ArrowRight':\n return focusRight(event);\n }\n}\n\nfunction focusLeft(event: Pick<Event, 'target'>) {\n const target = event.target;\n\n assert(`only allowed on input elements`, target instanceof HTMLInputElement);\n\n const input = previousInput(target);\n\n input?.focus();\n requestAnimationFrame(() => {\n input?.select();\n });\n}\n\nfunction focusRight(event: Pick<Event, 'target'>) {\n const target = event.target;\n\n assert(`only allowed on input elements`, target instanceof HTMLInputElement);\n\n const input = nextInput(target);\n\n input?.focus();\n requestAnimationFrame(() => {\n input?.select();\n });\n}\n\nconst syntheticEvent = new InputEvent('input');\n\nfunction handleBackspace(event: KeyboardEvent) {\n if (event.key !== 'Backspace') return;\n\n /**\n * We have to prevent default because we\n * - want to clear the whole field\n * - have the focus behavior keep up with the key-repeat\n * speed of the user's computer\n */\n event.preventDefault();\n\n const target = event.target;\n\n if (target && 'value' in target) {\n if (target.value === '') {\n focusLeft({ target });\n } else {\n target.value = '';\n }\n }\n\n target?.dispatchEvent(syntheticEvent);\n}\n\nfunction previousInput(current: HTMLInputElement) {\n const inputs = getInputs(current);\n const currentIndex = inputs.indexOf(current);\n\n return inputs[currentIndex - 1];\n}\n\nexport const autoAdvance = (event: Event) => {\n assert(\n '[BUG]: autoAdvance called on non-input element',\n event.target instanceof HTMLInputElement\n );\n\n const value = event.target.value;\n\n if (value.length === 0) return;\n\n if (value.length > 0) {\n if ('data' in event && event.data && typeof event.data === 'string') {\n event.target.value = event.data;\n }\n\n return focusRight(event);\n }\n};\n\nexport function getCollectiveValue(elementTarget: EventTarget | null, length: number) {\n if (!elementTarget) return;\n\n assert(\n `[BUG]: somehow the element target is not HTMLElement`,\n elementTarget instanceof HTMLElement\n );\n\n let parent: null | HTMLElement | ShadowRoot;\n\n // TODO: should this logic be extracted?\n // why is getting the target element within a shadow root hard?\n if (!(elementTarget instanceof HTMLInputElement)) {\n if (elementTarget.shadowRoot) {\n parent = elementTarget.shadowRoot;\n } else {\n parent = elementTarget.closest('fieldset');\n }\n } else {\n parent = elementTarget.closest('fieldset');\n }\n\n assert(`[BUG]: somehow the input fields were rendered without a parent element`, parent);\n\n const elements = parent.querySelectorAll('input');\n\n let value = '';\n\n assert(\n `found elements (${elements.length}) do not match length (${length}). Was the same OTP input rendered more than once?`,\n elements.length === length\n );\n\n for (const element of elements) {\n assert(\n '[BUG]: how did the queried elements become a non-input element?',\n element instanceof HTMLInputElement\n );\n value += element.value;\n }\n\n return value;\n}\n","import Component from \"@glimmer/component\";\nimport { warn } from \"@ember/debug\";\nimport { isDestroyed, isDestroying } from \"@ember/destroyable\";\nimport { on } from \"@ember/modifier\";\nimport { buildWaiter } from \"@ember/test-waiters\";\n\nimport {\n autoAdvance,\n getCollectiveValue,\n handleNavigation,\n handlePaste,\n selectAll,\n} from \"./utils.ts\";\n\nimport type { TOC } from \"@ember/component/template-only\";\nimport type { WithBoundArgs } from \"@glint/template\";\n\nconst DEFAULT_LENGTH = 6;\n\nfunction labelFor(inputIndex: number, labelFn: undefined | ((index: number) => string)) {\n if (labelFn) {\n return labelFn(inputIndex);\n }\n\n return `Please enter OTP character ${inputIndex + 1}`;\n}\n\nconst waiter = buildWaiter(\"ember-primitives:OTPInput:handleChange\");\n\nconst Fields: TOC<{\n /**\n * Any attributes passed to this component will be applied to each input.\n */\n Element: HTMLInputElement;\n Args: {\n fields: unknown[];\n labelFn: (index: number) => string;\n handleChange: (event: Event) => void;\n };\n}> = <template>\n {{#each @fields as |_field i|}}\n <label>\n <span class=\"ember-primitives__sr-only\">{{labelFor i @labelFn}}</span>\n <input\n name=\"code{{i}}\"\n type=\"text\"\n inputmode=\"numeric\"\n autocomplete=\"off\"\n ...attributes\n {{on \"click\" selectAll}}\n {{on \"paste\" handlePaste}}\n {{on \"input\" autoAdvance}}\n {{on \"input\" @handleChange}}\n {{on \"keydown\" handleNavigation}}\n />\n </label>\n {{/each}}\n</template>;\n\nexport class OTPInput extends Component<{\n /**\n * The collection of individual OTP inputs are contained by a fieldset.\n * Applying the `disabled` attribute to this fieldset will disable\n * all of the inputs, if that's desired.\n */\n Element: HTMLFieldSetElement;\n Args: {\n /**\n * How many characters the one-time-password field should be\n * Defaults to 6\n */\n length?: number;\n\n /**\n * To Customize the label of the input fields, you may pass a function.\n * By default, this is `Please enter OTP character ${index + 1}`.\n */\n labelFn?: (index: number) => string;\n\n /**\n * If passed, this function will be called when the <Input> changes.\n * All fields are considered one input.\n */\n onChange?: (\n data: {\n /**\n * The text from the collective `<Input>`\n *\n * `code` _may_ be shorter than `length`\n * if the user has not finished typing / pasting their code\n */\n code: string;\n /**\n * will be `true` if `code`'s length matches the passed `@length` or the default of 6\n */\n complete: boolean;\n },\n /**\n * The last input event received\n */\n event: Event,\n ) => void;\n };\n Blocks: {\n /**\n * Optionally, you may control how the Fields are rendered, with proceeding text,\n * additional attributes added, etc.\n *\n * This is how you can add custom validation to each input field.\n */\n default?: [fields: WithBoundArgs<typeof Fields, \"fields\" | \"handleChange\" | \"labelFn\">];\n };\n}> {\n /**\n * This is debounced, because we bind to each input,\n * but only want to emit one change event if someone pastes\n * multiple characters\n */\n handleChange = (event: Event) => {\n if (!this.args.onChange) return;\n\n if (!this.#token) {\n this.#token = waiter.beginAsync();\n }\n\n if (this.#frame) {\n cancelAnimationFrame(this.#frame);\n }\n\n // We use requestAnimationFrame to be friendly to rendering.\n // We don't know if onChange is going to want to cause paints\n // (it's also how we debounce, under the assumption that \"paste\" behavior\n // would be fast enough to be quicker than individual frames\n // (see logic in autoAdvance)\n // )\n this.#frame = requestAnimationFrame(() => {\n waiter.endAsync(this.#token);\n\n if (isDestroyed(this) || isDestroying(this)) return;\n if (!this.args.onChange) return;\n\n const value = getCollectiveValue(event.target, this.length);\n\n if (value === undefined) {\n warn(`Value could not be determined for the OTP field. was it removed from the DOM?`, {\n id: \"ember-primitives.OTPInput.missing-value\",\n });\n\n return;\n }\n\n this.args.onChange({ code: value, complete: value.length === this.length }, event);\n });\n };\n\n #token: unknown;\n #frame: number | undefined;\n\n get length() {\n return this.args.length ?? DEFAULT_LENGTH;\n }\n\n get fields() {\n // We only need to iterate a number of times,\n // so we don't care about the actual value or\n // referential integrity here\n return new Array<undefined>(this.length);\n }\n\n <template>\n <fieldset ...attributes>\n {{#let\n (component Fields fields=this.fields handleChange=this.handleChange labelFn=@labelFn)\n as |CurriedFields|\n }}\n {{#if (has-block)}}\n {{yield CurriedFields}}\n {{else}}\n <CurriedFields />\n {{/if}}\n {{/let}}\n\n <style>\n .ember-primitives__sr-only {\n position: absolute;\n width: 1px;\n height: 1px;\n padding: 0;\n margin: -1px;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n white-space: nowrap;\n border-width: 0;\n }\n </style>\n </fieldset>\n </template>\n}\n","import { assert } from \"@ember/debug\";\nimport { on } from \"@ember/modifier\";\n\nimport type { TOC } from \"@ember/component/template-only\";\n\nconst reset = (event: Event) => {\n assert(\"[BUG]: reset called without an event.target\", event.target instanceof HTMLElement);\n\n const form = event.target.closest(\"form\");\n\n assert(\n \"Form is missing. Cannot use <Reset> without being contained within a <form>\",\n form instanceof HTMLFormElement,\n );\n\n form.reset();\n};\n\nexport const Submit: TOC<{\n Element: HTMLButtonElement;\n Blocks: { default: [] };\n}> = <template>\n <button type=\"submit\" ...attributes>Submit</button>\n</template>;\n\nexport const Reset: TOC<{\n Element: HTMLButtonElement;\n Blocks: { default: [] };\n}> = <template>\n <button type=\"button\" {{on \"click\" reset}} ...attributes>{{yield}}</button>\n</template>;\n","import { assert } from \"@ember/debug\";\nimport { fn, hash } from \"@ember/helper\";\nimport { on } from \"@ember/modifier\";\nimport { buildWaiter } from \"@ember/test-waiters\";\n\nimport { Reset, Submit } from \"./buttons.gts\";\nimport { OTPInput } from \"./input.gts\";\n\nimport type { TOC } from \"@ember/component/template-only\";\nimport type { WithBoundArgs } from \"@glint/template\";\n\nconst waiter = buildWaiter(\"ember-primitives:OTP:handleAutoSubmitAttempt\");\n\nconst handleFormSubmit = (submit: (data: { code: string }) => void, event: SubmitEvent) => {\n event.preventDefault();\n\n assert(\n \"[BUG]: handleFormSubmit was not attached to a form. Please open an issue.\",\n event.currentTarget instanceof HTMLFormElement,\n );\n\n const formData = new FormData(event.currentTarget);\n\n let code = \"\";\n\n for (const [key, value] of formData.entries()) {\n if (key.startsWith(\"code\")) {\n // eslint-disable-next-line @typescript-eslint/restrict-plus-operands, @typescript-eslint/no-base-to-string\n code += value;\n }\n }\n\n submit({\n code,\n });\n};\n\nfunction handleChange(\n autoSubmit: boolean | undefined,\n data: { code: string; complete: boolean },\n event: Event,\n) {\n if (!autoSubmit) return;\n if (!data.complete) return;\n\n assert(\n \"[BUG]: event target is not a known element type\",\n event.target instanceof HTMLElement || event.target instanceof SVGElement,\n );\n\n const form = event.target.closest(\"form\");\n\n assert(\"[BUG]: Cannot handle event when <OTP> Inputs are not rendered within their <form>\", form);\n\n const token = waiter.beginAsync();\n const finished = () => {\n waiter.endAsync(token);\n form.removeEventListener(\"submit\", finished);\n };\n\n form.addEventListener(\"submit\", finished);\n\n // NOTE: when calling .submit() the submit event handlers are not run\n form.requestSubmit();\n}\n\nexport const OTP: TOC<{\n /**\n * The overall OTP Input is in its own form.\n * Modern UI/UX Patterns usually have this sort of field\n * as its own page, thus within its own form.\n *\n * By default, only the 'submit' event is bound, and is\n * what calls the `@onSubmit` argument.\n */\n Element: HTMLFormElement;\n Args: {\n /**\n * How many characters the one-time-password field should be\n * Defaults to 6\n */\n length?: number;\n\n /**\n * The on submit callback will give you the entered\n * one-time-password code.\n *\n * It will be called when the user manually clicks the 'submit'\n * button or when the full code is pasted and meats the validation\n * criteria.\n */\n onSubmit: (data: { code: string }) => void;\n\n /**\n * Whether or not to auto-submit after the code has been pasted\n * in to the collective \"field\". Default is true\n */\n autoSubmit?: boolean;\n };\n Blocks: {\n default: [\n {\n /**\n * The collective input field that the OTP code will be typed/pasted in to\n */\n Input: WithBoundArgs<typeof OTPInput, \"length\" | \"onChange\">;\n /**\n * Button with `type=\"submit\"` to submit the form\n */\n Submit: typeof Submit;\n /**\n * Pre-wired button to reset the form\n */\n Reset: typeof Reset;\n },\n ];\n };\n}> = <template>\n <form {{on \"submit\" (fn handleFormSubmit @onSubmit)}} ...attributes>\n {{yield\n (hash\n Input=(component\n OTPInput length=@length onChange=(if @autoSubmit (fn handleChange @autoSubmit))\n )\n Submit=Submit\n Reset=Reset\n )\n }}\n </form>\n</template>;\n"],"names":["getInputs","current","fieldset","closest","assert","querySelectorAll","nextInput","inputs","currentIndex","indexOf","selectAll","event","target","HTMLInputElement","select","handlePaste","clipboardData","preventDefault","value","getData","digits","i","currElement","next","handleNavigation","key","handleBackspace","focusLeft","focusRight","input","previousInput","focus","requestAnimationFrame","syntheticEvent","InputEvent","dispatchEvent","autoAdvance","length","data","getCollectiveValue","elementTarget","HTMLElement","parent","shadowRoot","elements","element","DEFAULT_LENGTH","labelFor","inputIndex","labelFn","waiter","buildWaiter","Fields","setComponentTemplate","precompileTemplate","strictMode","scope","on","templateOnly","OTPInput","Component","handleChange","args","onChange","beginAsync","cancelAnimationFrame","endAsync","isDestroyed","isDestroying","undefined","warn","id","code","complete","fields","Array","reset","form","HTMLFormElement","Submit","Reset","handleFormSubmit","submit","currentTarget","formData","FormData","entries","startsWith","autoSubmit","SVGElement","token","finished","removeEventListener","addEventListener","requestSubmit","OTP","fn","hash"],"mappings":"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"}
1
+ {"version":3,"file":"otp-H5a4B4yu.js","sources":["../src/components/one-time-password/utils.ts","../src/components/one-time-password/input.gts","../src/components/one-time-password/buttons.gts","../src/components/one-time-password/otp.gts"],"sourcesContent":["import { assert } from '@ember/debug';\n\nfunction getInputs(current: HTMLInputElement) {\n const fieldset = current.closest('fieldset');\n\n assert('[BUG]: fieldset went missing', fieldset);\n\n return [...fieldset.querySelectorAll('input')];\n}\n\nfunction nextInput(current: HTMLInputElement) {\n const inputs = getInputs(current);\n const currentIndex = inputs.indexOf(current);\n\n return inputs[currentIndex + 1];\n}\n\nexport function selectAll(event: Event) {\n const target = event.target;\n\n assert(`selectAll is only meant for use with input elements`, target instanceof HTMLInputElement);\n\n target.select();\n}\n\nexport function handlePaste(event: Event) {\n const target = event.target;\n\n assert(\n `handlePaste is only meant for use with input elements`,\n target instanceof HTMLInputElement\n );\n\n const clipboardData = (event as ClipboardEvent).clipboardData;\n\n assert(\n `Could not get clipboardData while handling the paste event on OTP. Please report this issue on the ember-primitives repo with a reproduction. Thanks!`,\n clipboardData\n );\n\n // This is typically not good to prevent paste.\n // But because of the UX we're implementing,\n // we want to split the pasted value across\n // multiple text fields\n event.preventDefault();\n\n const value = clipboardData.getData('Text');\n const digits = value;\n let i = 0;\n let currElement: HTMLInputElement | null = target;\n\n while (currElement) {\n currElement.value = digits[i++] || '';\n\n const next = nextInput(currElement);\n\n if (next instanceof HTMLInputElement) {\n currElement = next;\n } else {\n break;\n }\n }\n\n // We want to select the first field again\n // so that if someone holds paste, or\n // pastes again, they get the same result.\n target.select();\n}\n\nexport function handleNavigation(event: KeyboardEvent) {\n switch (event.key) {\n case 'Backspace':\n return handleBackspace(event);\n case 'ArrowLeft':\n return focusLeft(event);\n case 'ArrowRight':\n return focusRight(event);\n }\n}\n\nfunction focusLeft(event: Pick<Event, 'target'>) {\n const target = event.target;\n\n assert(`only allowed on input elements`, target instanceof HTMLInputElement);\n\n const input = previousInput(target);\n\n input?.focus();\n requestAnimationFrame(() => {\n input?.select();\n });\n}\n\nfunction focusRight(event: Pick<Event, 'target'>) {\n const target = event.target;\n\n assert(`only allowed on input elements`, target instanceof HTMLInputElement);\n\n const input = nextInput(target);\n\n input?.focus();\n requestAnimationFrame(() => {\n input?.select();\n });\n}\n\nconst syntheticEvent = new InputEvent('input');\n\nfunction handleBackspace(event: KeyboardEvent) {\n if (event.key !== 'Backspace') return;\n\n /**\n * We have to prevent default because we\n * - want to clear the whole field\n * - have the focus behavior keep up with the key-repeat\n * speed of the user's computer\n */\n event.preventDefault();\n\n const target = event.target;\n\n if (target && 'value' in target) {\n if (target.value === '') {\n focusLeft({ target });\n } else {\n target.value = '';\n }\n }\n\n target?.dispatchEvent(syntheticEvent);\n}\n\nfunction previousInput(current: HTMLInputElement) {\n const inputs = getInputs(current);\n const currentIndex = inputs.indexOf(current);\n\n return inputs[currentIndex - 1];\n}\n\nexport const autoAdvance = (event: Event) => {\n assert(\n '[BUG]: autoAdvance called on non-input element',\n event.target instanceof HTMLInputElement\n );\n\n const value = event.target.value;\n\n if (value.length === 0) return;\n\n if (value.length > 0) {\n if ('data' in event && event.data && typeof event.data === 'string') {\n event.target.value = event.data;\n }\n\n return focusRight(event);\n }\n};\n\nexport function getCollectiveValue(elementTarget: EventTarget | null, length: number) {\n if (!elementTarget) return;\n\n assert(\n `[BUG]: somehow the element target is not HTMLElement`,\n elementTarget instanceof HTMLElement\n );\n\n let parent: null | HTMLElement | ShadowRoot;\n\n // TODO: should this logic be extracted?\n // why is getting the target element within a shadow root hard?\n if (!(elementTarget instanceof HTMLInputElement)) {\n if (elementTarget.shadowRoot) {\n parent = elementTarget.shadowRoot;\n } else {\n parent = elementTarget.closest('fieldset');\n }\n } else {\n parent = elementTarget.closest('fieldset');\n }\n\n assert(`[BUG]: somehow the input fields were rendered without a parent element`, parent);\n\n const elements = parent.querySelectorAll('input');\n\n let value = '';\n\n assert(\n `found elements (${elements.length}) do not match length (${length}). Was the same OTP input rendered more than once?`,\n elements.length === length\n );\n\n for (const element of elements) {\n assert(\n '[BUG]: how did the queried elements become a non-input element?',\n element instanceof HTMLInputElement\n );\n value += element.value;\n }\n\n return value;\n}\n","import Component from \"@glimmer/component\";\nimport { warn } from \"@ember/debug\";\nimport { isDestroyed, isDestroying } from \"@ember/destroyable\";\nimport { on } from \"@ember/modifier\";\nimport { buildWaiter } from \"@ember/test-waiters\";\n\nimport {\n autoAdvance,\n getCollectiveValue,\n handleNavigation,\n handlePaste,\n selectAll,\n} from \"./utils.ts\";\n\nimport type { TOC } from \"@ember/component/template-only\";\nimport type { WithBoundArgs } from \"@glint/template\";\n\nconst DEFAULT_LENGTH = 6;\n\nfunction labelFor(inputIndex: number, labelFn: undefined | ((index: number) => string)) {\n if (labelFn) {\n return labelFn(inputIndex);\n }\n\n return `Please enter OTP character ${inputIndex + 1}`;\n}\n\nconst waiter = buildWaiter(\"ember-primitives:OTPInput:handleChange\");\n\nconst Fields: TOC<{\n /**\n * Any attributes passed to this component will be applied to each input.\n */\n Element: HTMLInputElement;\n Args: {\n fields: unknown[];\n labelFn: (index: number) => string;\n handleChange: (event: Event) => void;\n };\n}> = <template>\n {{#each @fields as |_field i|}}\n <label>\n <span class=\"ember-primitives__sr-only\">{{labelFor i @labelFn}}</span>\n <input\n name=\"code{{i}}\"\n type=\"text\"\n inputmode=\"numeric\"\n autocomplete=\"off\"\n ...attributes\n {{on \"click\" selectAll}}\n {{on \"paste\" handlePaste}}\n {{on \"input\" autoAdvance}}\n {{on \"input\" @handleChange}}\n {{on \"keydown\" handleNavigation}}\n />\n </label>\n {{/each}}\n</template>;\n\nexport class OTPInput extends Component<{\n /**\n * The collection of individual OTP inputs are contained by a fieldset.\n * Applying the `disabled` attribute to this fieldset will disable\n * all of the inputs, if that's desired.\n */\n Element: HTMLFieldSetElement;\n Args: {\n /**\n * How many characters the one-time-password field should be\n * Defaults to 6\n */\n length?: number;\n\n /**\n * To Customize the label of the input fields, you may pass a function.\n * By default, this is `Please enter OTP character ${index + 1}`.\n */\n labelFn?: (index: number) => string;\n\n /**\n * If passed, this function will be called when the <Input> changes.\n * All fields are considered one input.\n */\n onChange?: (\n data: {\n /**\n * The text from the collective `<Input>`\n *\n * `code` _may_ be shorter than `length`\n * if the user has not finished typing / pasting their code\n */\n code: string;\n /**\n * will be `true` if `code`'s length matches the passed `@length` or the default of 6\n */\n complete: boolean;\n },\n /**\n * The last input event received\n */\n event: Event,\n ) => void;\n };\n Blocks: {\n /**\n * Optionally, you may control how the Fields are rendered, with proceeding text,\n * additional attributes added, etc.\n *\n * This is how you can add custom validation to each input field.\n */\n default?: [fields: WithBoundArgs<typeof Fields, \"fields\" | \"handleChange\" | \"labelFn\">];\n };\n}> {\n /**\n * This is debounced, because we bind to each input,\n * but only want to emit one change event if someone pastes\n * multiple characters\n */\n handleChange = (event: Event) => {\n if (!this.args.onChange) return;\n\n if (!this.#token) {\n this.#token = waiter.beginAsync();\n }\n\n if (this.#frame) {\n cancelAnimationFrame(this.#frame);\n }\n\n // We use requestAnimationFrame to be friendly to rendering.\n // We don't know if onChange is going to want to cause paints\n // (it's also how we debounce, under the assumption that \"paste\" behavior\n // would be fast enough to be quicker than individual frames\n // (see logic in autoAdvance)\n // )\n this.#frame = requestAnimationFrame(() => {\n waiter.endAsync(this.#token);\n\n if (isDestroyed(this) || isDestroying(this)) return;\n if (!this.args.onChange) return;\n\n const value = getCollectiveValue(event.target, this.length);\n\n if (value === undefined) {\n warn(`Value could not be determined for the OTP field. was it removed from the DOM?`, {\n id: \"ember-primitives.OTPInput.missing-value\",\n });\n\n return;\n }\n\n this.args.onChange({ code: value, complete: value.length === this.length }, event);\n });\n };\n\n #token: unknown;\n #frame: number | undefined;\n\n get length() {\n return this.args.length ?? DEFAULT_LENGTH;\n }\n\n get fields() {\n // We only need to iterate a number of times,\n // so we don't care about the actual value or\n // referential integrity here\n return new Array<undefined>(this.length);\n }\n\n <template>\n <fieldset ...attributes>\n {{#let\n (component Fields fields=this.fields handleChange=this.handleChange labelFn=@labelFn)\n as |CurriedFields|\n }}\n {{#if (has-block)}}\n {{yield CurriedFields}}\n {{else}}\n <CurriedFields />\n {{/if}}\n {{/let}}\n\n <style>\n .ember-primitives__sr-only {\n position: absolute;\n width: 1px;\n height: 1px;\n padding: 0;\n margin: -1px;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n white-space: nowrap;\n border-width: 0;\n }\n </style>\n </fieldset>\n </template>\n}\n","import { assert } from \"@ember/debug\";\nimport { on } from \"@ember/modifier\";\n\nimport type { TOC } from \"@ember/component/template-only\";\n\nconst reset = (event: Event) => {\n assert(\"[BUG]: reset called without an event.target\", event.target instanceof HTMLElement);\n\n const form = event.target.closest(\"form\");\n\n assert(\n \"Form is missing. Cannot use <Reset> without being contained within a <form>\",\n form instanceof HTMLFormElement,\n );\n\n form.reset();\n};\n\nexport const Submit: TOC<{\n Element: HTMLButtonElement;\n Blocks: { default: [] };\n}> = <template>\n <button type=\"submit\" ...attributes>Submit</button>\n</template>;\n\nexport const Reset: TOC<{\n Element: HTMLButtonElement;\n Blocks: { default: [] };\n}> = <template>\n <button type=\"button\" {{on \"click\" reset}} ...attributes>{{yield}}</button>\n</template>;\n","import { assert } from \"@ember/debug\";\nimport { fn, hash } from \"@ember/helper\";\nimport { on } from \"@ember/modifier\";\nimport { buildWaiter } from \"@ember/test-waiters\";\n\nimport { Reset, Submit } from \"./buttons.gts\";\nimport { OTPInput } from \"./input.gts\";\n\nimport type { TOC } from \"@ember/component/template-only\";\nimport type { WithBoundArgs } from \"@glint/template\";\n\nconst waiter = buildWaiter(\"ember-primitives:OTP:handleAutoSubmitAttempt\");\n\nconst handleFormSubmit = (submit: (data: { code: string }) => void, event: SubmitEvent) => {\n event.preventDefault();\n\n assert(\n \"[BUG]: handleFormSubmit was not attached to a form. Please open an issue.\",\n event.currentTarget instanceof HTMLFormElement,\n );\n\n const formData = new FormData(event.currentTarget);\n\n let code = \"\";\n\n for (const [key, value] of formData.entries()) {\n if (key.startsWith(\"code\")) {\n // eslint-disable-next-line @typescript-eslint/restrict-plus-operands, @typescript-eslint/no-base-to-string\n code += value;\n }\n }\n\n submit({\n code,\n });\n};\n\nfunction handleChange(\n autoSubmit: boolean | undefined,\n data: { code: string; complete: boolean },\n event: Event,\n) {\n if (!autoSubmit) return;\n if (!data.complete) return;\n\n assert(\n \"[BUG]: event target is not a known element type\",\n event.target instanceof HTMLElement || event.target instanceof SVGElement,\n );\n\n const form = event.target.closest(\"form\");\n\n assert(\"[BUG]: Cannot handle event when <OTP> Inputs are not rendered within their <form>\", form);\n\n const token = waiter.beginAsync();\n const finished = () => {\n waiter.endAsync(token);\n form.removeEventListener(\"submit\", finished);\n };\n\n form.addEventListener(\"submit\", finished);\n\n // NOTE: when calling .submit() the submit event handlers are not run\n form.requestSubmit();\n}\n\nexport const OTP: TOC<{\n /**\n * The overall OTP Input is in its own form.\n * Modern UI/UX Patterns usually have this sort of field\n * as its own page, thus within its own form.\n *\n * By default, only the 'submit' event is bound, and is\n * what calls the `@onSubmit` argument.\n */\n Element: HTMLFormElement;\n Args: {\n /**\n * How many characters the one-time-password field should be\n * Defaults to 6\n */\n length?: number;\n\n /**\n * The on submit callback will give you the entered\n * one-time-password code.\n *\n * It will be called when the user manually clicks the 'submit'\n * button or when the full code is pasted and meats the validation\n * criteria.\n */\n onSubmit: (data: { code: string }) => void;\n\n /**\n * Whether or not to auto-submit after the code has been pasted\n * in to the collective \"field\". Default is true\n */\n autoSubmit?: boolean;\n };\n Blocks: {\n default: [\n {\n /**\n * The collective input field that the OTP code will be typed/pasted in to\n */\n Input: WithBoundArgs<typeof OTPInput, \"length\" | \"onChange\">;\n /**\n * Button with `type=\"submit\"` to submit the form\n */\n Submit: typeof Submit;\n /**\n * Pre-wired button to reset the form\n */\n Reset: typeof Reset;\n },\n ];\n };\n}> = <template>\n <form {{on \"submit\" (fn handleFormSubmit @onSubmit)}} ...attributes>\n {{yield\n (hash\n Input=(component\n OTPInput length=@length onChange=(if @autoSubmit (fn handleChange @autoSubmit))\n )\n Submit=Submit\n Reset=Reset\n )\n }}\n </form>\n</template>;\n"],"names":["getInputs","current","fieldset","closest","assert","querySelectorAll","nextInput","inputs","currentIndex","indexOf","selectAll","event","target","HTMLInputElement","select","handlePaste","clipboardData","preventDefault","value","getData","digits","i","currElement","next","handleNavigation","key","handleBackspace","focusLeft","focusRight","input","previousInput","focus","requestAnimationFrame","syntheticEvent","InputEvent","dispatchEvent","autoAdvance","length","data","getCollectiveValue","elementTarget","HTMLElement","parent","shadowRoot","elements","element","DEFAULT_LENGTH","labelFor","inputIndex","labelFn","waiter","buildWaiter","Fields","setComponentTemplate","precompileTemplate","strictMode","scope","on","templateOnly","OTPInput","Component","handleChange","args","onChange","beginAsync","cancelAnimationFrame","endAsync","isDestroyed","isDestroying","undefined","warn","id","code","complete","fields","Array","reset","form","HTMLFormElement","Submit","Reset","handleFormSubmit","submit","currentTarget","formData","FormData","entries","startsWith","autoSubmit","SVGElement","token","finished","removeEventListener","addEventListener","requestSubmit","OTP","fn","hash"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ember-primitives",
3
- "version": "0.52.0",
3
+ "version": "0.53.1",
4
4
  "description": "Making apps easier to build",
5
5
  "keywords": [
6
6
  "ember-addon"
@@ -17,56 +17,56 @@
17
17
  ],
18
18
  "bin": "./bin/index.mjs",
19
19
  "dependencies": {
20
- "@babel/runtime": "^7.28.4",
20
+ "@babel/runtime": "^7.28.6",
21
21
  "@embroider/addon-shim": "^1.10.2",
22
- "@embroider/macros": "^1.19.6",
23
- "@floating-ui/dom": "^1.7.0",
24
- "decorator-transforms": "^2.3.0",
22
+ "@embroider/macros": "^1.19.7",
23
+ "@floating-ui/dom": "^1.7.5",
24
+ "decorator-transforms": "2.3.1",
25
25
  "ember-element-helper": "^0.8.8",
26
26
  "form-data-utils": "^0.6.0",
27
27
  "reactiveweb": "^1.9.1",
28
28
  "should-handle-link": "^1.2.2",
29
29
  "tabster": "^8.7.0",
30
30
  "tracked-built-ins": "^4.1.0",
31
- "tracked-toolbox": "^2.0.0",
32
- "which-heading-do-i-need": "0.2.4"
31
+ "tracked-toolbox": "^2.2.0",
32
+ "which-heading-do-i-need": "0.2.6"
33
33
  },
34
34
  "devDependencies": {
35
35
  "@arethetypeswrong/cli": "^0.18.0",
36
- "@babel/core": "^7.28.5",
36
+ "@babel/core": "^7.29.0",
37
37
  "@babel/plugin-proposal-class-properties": "^7.18.6",
38
- "@babel/plugin-proposal-decorators": "^7.27.1",
38
+ "@babel/plugin-proposal-decorators": "^7.29.0",
39
39
  "@babel/plugin-proposal-object-rest-spread": "^7.20.7",
40
- "@babel/plugin-syntax-decorators": "^7.27.1",
41
- "@babel/plugin-transform-class-static-block": "^7.27.1",
42
- "@babel/plugin-transform-private-methods": "^7.27.1",
43
- "@babel/plugin-transform-typescript": "^7.28.5",
40
+ "@babel/plugin-syntax-decorators": "^7.28.6",
41
+ "@babel/plugin-transform-class-static-block": "^7.28.6",
42
+ "@babel/plugin-transform-private-methods": "^7.28.6",
43
+ "@babel/plugin-transform-typescript": "^7.28.6",
44
44
  "@babel/preset-typescript": "^7.28.5",
45
45
  "@ember/library-tsconfig": "^2.0.0",
46
46
  "@ember/test-helpers": "^5.4.1",
47
47
  "@ember/test-waiters": "^4.1.0",
48
- "@embroider/addon-dev": "^8.2.0",
48
+ "@embroider/addon-dev": "^8.3.0",
49
49
  "@glimmer/component": "^2.0.0",
50
50
  "@glimmer/tracking": "^1.1.2",
51
- "@glint/ember-tsc": "^1.0.8",
52
- "@glint/template": "^1.7.3",
53
- "@glint/tsserver-plugin": "^2.0.8",
51
+ "@glint/ember-tsc": "^1.1.1",
52
+ "@glint/template": "1.7.4",
53
+ "@glint/tsserver-plugin": "^2.1.0",
54
54
  "@nullvoxpopuli/eslint-configs": "^5.5.0",
55
55
  "@rollup/plugin-babel": "^6.1.0",
56
56
  "@tsconfig/ember": "^3.0.12",
57
- "babel-plugin-ember-template-compilation": "^3.0.1",
57
+ "babel-plugin-ember-template-compilation": "^4.0.0",
58
58
  "concurrently": "^9.2.1",
59
- "ember-modifier": "^4.2.2",
59
+ "ember-modifier": "^4.3.0",
60
60
  "ember-resources": "^7.0.7",
61
- "ember-source": "^6.9.0",
61
+ "ember-source": "^6.10.1",
62
62
  "ember-template-lint": "^7.9.3",
63
63
  "eslint": "^9.39.2",
64
64
  "execa": "^9.6.0",
65
65
  "fix-bad-declaration-output": "^1.1.5",
66
- "prettier": "^3.7.4",
67
- "prettier-plugin-ember-template-tag": "^2.1.2",
68
- "publint": "^0.3.16",
69
- "rollup": "^4.54.0",
66
+ "prettier": "^3.8.1",
67
+ "prettier-plugin-ember-template-tag": "^2.1.3",
68
+ "publint": "^0.3.17",
69
+ "rollup": "^4.57.1",
70
70
  "rollup-plugin-copy": "^3.5.0",
71
71
  "typescript": "^5.9.3"
72
72
  },
@@ -117,7 +117,7 @@
117
117
  "@ember/test-helpers": ">= 3.2.0",
118
118
  "@ember/test-waiters": ">= 3.0.2",
119
119
  "@glimmer/component": "^2.0.0",
120
- "@glint/template": ">= 1.0.0",
120
+ "@glint/template": "1.7.4",
121
121
  "ember-modifier": ">= 4.1.0",
122
122
  "ember-resources": ">= 6.1.0"
123
123
  },
@@ -131,16 +131,14 @@
131
131
  },
132
132
  "scripts": {
133
133
  "build": "rollup --config ./rollup.config.mjs",
134
- "lint": "pnpm -w exec lint",
135
- "lint:fix": "pnpm -w exec lint fix",
136
- "lint:js": "pnpm -w exec lint js",
137
- "lint:js:fix": "pnpm -w exec lint js:fix",
138
- "lint:hbs": "pnpm -w exec lint hbs",
139
- "lint:hbs:fix": "pnpm -w exec lint hbs:fix",
140
- "_lint:package": "pnpm publint",
134
+ "lint": "concurrently 'pnpm:lint:*(!fix)' --names 'lint:'",
135
+ "lint:fix": "concurrently 'pnpm:lint:*:fix' --names 'fix:' && pnpm format",
136
+ "lint:js": "eslint . --cache",
137
+ "lint:js:fix": "eslint . --fix",
138
+ "lint:prettier": "prettier --check .",
139
+ "format": "prettier --write .",
140
+ "lint:package": "pnpm publint",
141
141
  "lint:published-types": "attw *.tgz || exit 0",
142
- "lint:prettier:fix": "pnpm -w exec lint prettier:fix",
143
- "lint:prettier": "pnpm -w exec lint prettier",
144
142
  "lint:types": "ember-tsc --noEmit --declaration false --declarationMap false --emitDeclarationOnly false",
145
143
  "pack": "pnpm pack",
146
144
  "start": "rollup --config --watch",
@@ -3,8 +3,7 @@
3
3
  * otherwise fallback to the uncontrolled toggle
4
4
  */
5
5
  export function toggleWithFallback(
6
- uncontrolledToggle: (...args: unknown[]) => void,
7
-
6
+ uncontrolledToggle: undefined | ((...args: any[]) => void) | (() => void),
8
7
  controlledToggle?: (...args: any[]) => void,
9
8
  ...args: unknown[]
10
9
  ) {
@@ -12,5 +11,5 @@ export function toggleWithFallback(
12
11
  return controlledToggle(...args);
13
12
  }
14
13
 
15
- uncontrolledToggle(...args);
14
+ uncontrolledToggle?.(...args);
16
15
  }
@@ -20,7 +20,7 @@ export interface Signature {
20
20
  /**
21
21
  * A separator component to place between breadcrumb items.
22
22
  * Typically renders as "/" or ">" and is decorative (aria-hidden="true").
23
- * Pre-configured to render as an <li> element for proper HTML structure.
23
+ * Pre-configured to render as an `<li>` element for proper HTML structure.
24
24
  */
25
25
  Separator: WithBoundArgs<typeof Separator, "as" | "decorative">;
26
26
  },
@@ -1,11 +1,11 @@
1
- import { fn, hash } from "@ember/helper";
1
+ import Component from "@glimmer/component";
2
+ import { hash } from "@ember/helper";
2
3
  import { on } from "@ember/modifier";
3
4
 
4
5
  import { cell } from "ember-resources";
5
6
 
6
7
  import { uniqueId } from "../utils.ts";
7
8
  import { Label } from "./-private/typed-elements.gts";
8
- import { toggleWithFallback } from "./-private/utils.ts";
9
9
 
10
10
  import type { TOC } from "@ember/component/template-only";
11
11
  import type { WithBoundArgs } from "@glint/template";
@@ -27,13 +27,27 @@ export interface Signature {
27
27
  Blocks: {
28
28
  default?: [
29
29
  {
30
+ /**
31
+ * The current state of the Switch.
32
+ *
33
+ * ```gjs
34
+ * import { Switch } from 'ember-primitives/components/switch';
35
+ *
36
+ * <template>
37
+ * <Switch as |s|>
38
+ * {{s.isChecked}}
39
+ * </Switch>
40
+ * </template>
41
+ * ```
42
+ */
43
+ isChecked: boolean;
30
44
  /**
31
45
  * The Switch Element.
32
46
  * It has a pre-wired `id` so that the relevant Label is
33
47
  * appropriately associated via the `for` property of the Label.
34
48
  *
35
49
  * ```gjs
36
- * import { Switch } from 'ember-primitives';
50
+ * import { Switch } from 'ember-primitives/components/switch';
37
51
  *
38
52
  * <template>
39
53
  * <Switch as |s|>
@@ -48,7 +62,7 @@ export interface Signature {
48
62
  * the association to the Control by setting the `for` attribute to the `id` of the Control
49
63
  *
50
64
  * ```gjs
51
- * import { Switch } from 'ember-primitives';
65
+ * import { Switch } from 'ember-primitive/components/switchs';
52
66
  *
53
67
  * <template>
54
68
  * <Switch as |s|>
@@ -65,37 +79,58 @@ export interface Signature {
65
79
 
66
80
  interface ControlSignature {
67
81
  Element: HTMLInputElement;
68
- Args: { id: string; checked?: boolean; onChange: () => void };
82
+ Args: {
83
+ id: string;
84
+ checked?: ReturnType<typeof cell<boolean>>;
85
+ onChange?: (checked: boolean, event: Event) => void;
86
+ };
69
87
  }
70
88
 
71
- const Checkbox: TOC<ControlSignature> = <template>
72
- {{#let (cell @checked) as |checked|}}
89
+ class Checkbox extends Component<ControlSignature> {
90
+ handleClick = (event: Event) => {
91
+ const newChecked = (event.target as HTMLInputElement).checked;
92
+
93
+ if (this.args.onChange) {
94
+ this.args.onChange(newChecked, event);
95
+ } else {
96
+ this.args.checked?.toggle();
97
+ }
98
+ };
99
+
100
+ <template>
73
101
  <input
74
102
  id={{@id}}
75
103
  type="checkbox"
76
104
  role="switch"
77
- checked={{checked.current}}
78
- aria-checked={{checked.current}}
79
- data-state={{if checked.current "on" "off"}}
80
- {{on "click" (fn toggleWithFallback checked.toggle @onChange)}}
105
+ checked={{@checked.current}}
106
+ aria-checked={{@checked.current}}
107
+ data-state={{if @checked.current "on" "off"}}
108
+ {{on "click" this.handleClick}}
81
109
  ...attributes
82
110
  />
83
- {{/let}}
84
- </template>;
111
+ </template>
112
+ }
113
+
114
+ function defaultFalse(value: unknown) {
115
+ return value ?? false;
116
+ }
85
117
 
86
118
  /**
87
119
  * @public
88
120
  */
89
121
  export const Switch: TOC<Signature> = <template>
90
122
  <div ...attributes data-prim-switch>
91
- {{! @glint-nocheck }}
92
123
  {{#let (uniqueId) as |id|}}
93
- {{yield
94
- (hash
95
- Control=(component Checkbox checked=@checked id=id onChange=@onChange)
96
- Label=(component Label for=id)
97
- )
98
- }}
124
+ {{#let (cell (defaultFalse @checked)) as |checked|}}
125
+ {{! @glint-nocheck }}
126
+ {{yield
127
+ (hash
128
+ isChecked=checked.current
129
+ Control=(component Checkbox checked=checked id=id onChange=@onChange)
130
+ Label=(component Label for=id)
131
+ )
132
+ }}
133
+ {{/let}}
99
134
  {{/let}}
100
135
  </div>
101
136
  </template>;
@@ -1,13 +0,0 @@
1
- /**
2
- * If the user provides an onChange or similar function, use that,
3
- * otherwise fallback to the uncontrolled toggle
4
- */
5
- function toggleWithFallback(uncontrolledToggle, controlledToggle, ...args) {
6
- if (controlledToggle) {
7
- return controlledToggle(...args);
8
- }
9
- uncontrolledToggle(...args);
10
- }
11
-
12
- export { toggleWithFallback as t };
13
- //# sourceMappingURL=utils-D0v9WKmV.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"utils-D0v9WKmV.js","sources":["../src/components/-private/utils.ts"],"sourcesContent":["/**\n * If the user provides an onChange or similar function, use that,\n * otherwise fallback to the uncontrolled toggle\n */\nexport function toggleWithFallback(\n uncontrolledToggle: (...args: unknown[]) => void,\n\n controlledToggle?: (...args: any[]) => void,\n ...args: unknown[]\n) {\n if (controlledToggle) {\n return controlledToggle(...args);\n }\n\n uncontrolledToggle(...args);\n}\n"],"names":["toggleWithFallback","uncontrolledToggle","controlledToggle","args"],"mappings":"AAAA;AACA;AACA;AACA;AACO,SAASA,kBAAkBA,CAChCC,kBAAgD,EAEhDC,gBAA2C,EAC3C,GAAGC,IAAe,EAClB;AACA,EAAA,IAAID,gBAAgB,EAAE;AACpB,IAAA,OAAOA,gBAAgB,CAAC,GAAGC,IAAI,CAAC;AAClC,EAAA;EAEAF,kBAAkB,CAAC,GAAGE,IAAI,CAAC;AAC7B;;;;"}