ember-primitives 0.36.0 → 0.38.0

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.
Files changed (48) hide show
  1. package/declarations/components/portal.d.ts +27 -1
  2. package/declarations/store.d.ts +39 -0
  3. package/declarations/test-support/rating.d.ts +1 -1
  4. package/declarations/type-utils.d.ts +3 -0
  5. package/declarations/utils.d.ts +1 -0
  6. package/dist/color-scheme.js.map +1 -1
  7. package/dist/components/-private/utils.js.map +1 -1
  8. package/dist/components/accordion.js.map +1 -1
  9. package/dist/components/dialog.js.map +1 -1
  10. package/dist/components/keys.js.map +1 -1
  11. package/dist/components/menu.js.map +1 -1
  12. package/dist/components/one-time-password/input.js.map +1 -1
  13. package/dist/components/one-time-password/otp.js.map +1 -1
  14. package/dist/components/one-time-password/utils.js.map +1 -1
  15. package/dist/components/popover.js.map +1 -1
  16. package/dist/components/portal-targets.js.map +1 -1
  17. package/dist/components/portal.js +35 -2
  18. package/dist/components/portal.js.map +1 -1
  19. package/dist/components/progress.js.map +1 -1
  20. package/dist/components/rating/index.js.map +1 -1
  21. package/dist/components/rating/state.js.map +1 -1
  22. package/dist/components/scroller.js.map +1 -1
  23. package/dist/components/shadowed.js.map +1 -1
  24. package/dist/components/toggle-group.js.map +1 -1
  25. package/dist/components/zoetrope/index.js.map +1 -1
  26. package/dist/floating-ui/component.js.map +1 -1
  27. package/dist/floating-ui/middleware.js.map +1 -1
  28. package/dist/floating-ui/modifier.js.map +1 -1
  29. package/dist/helpers/body-class.js.map +1 -1
  30. package/dist/helpers/link.js.map +1 -1
  31. package/dist/helpers/service.js.map +1 -1
  32. package/dist/item-D6pwWzMs.js.map +1 -1
  33. package/dist/on-resize.js.map +1 -1
  34. package/dist/proper-links.js.map +1 -1
  35. package/dist/qp.js.map +1 -1
  36. package/dist/store.js +63 -0
  37. package/dist/store.js.map +1 -0
  38. package/dist/tabster.js.map +1 -1
  39. package/dist/test-support/a11y.js.map +1 -1
  40. package/dist/test-support/otp.js.map +1 -1
  41. package/dist/test-support/rating.js.map +1 -1
  42. package/dist/test-support/routing.js.map +1 -1
  43. package/dist/test-support/zoetrope.js.map +1 -1
  44. package/dist/type-utils.js +2 -0
  45. package/dist/type-utils.js.map +1 -0
  46. package/dist/utils.js +5 -1
  47. package/dist/utils.js.map +1 -1
  48. package/package.json +2 -2
@@ -7,8 +7,16 @@ export interface Signature {
7
7
  * The name of the PortalTarget to render in to.
8
8
  * This is the value of the `data-portal-name` attribute
9
9
  * of the element you wish to render in to.
10
+ *
11
+ * This can also be an Element which pairs nicely with query-utilities such as `wormhole`, or the platform-native `querySelector`
10
12
  */
11
- to: Targets | (string & {});
13
+ to: (Targets | (string & {})) | Element;
14
+ /**
15
+ * Set to true to append to the portal instead of replace
16
+ *
17
+ * Default: false
18
+ */
19
+ append?: boolean;
12
20
  };
13
21
  Blocks: {
14
22
  /**
@@ -17,5 +25,23 @@ export interface Signature {
17
25
  default: [];
18
26
  };
19
27
  }
28
+ /**
29
+ * Polyfill for ember-wormhole behavior
30
+ *
31
+ * Example usage:
32
+ * ```gjs
33
+ * import { wormhole, Portal } from 'ember-primitives/components/portal';
34
+ *
35
+ * <template>
36
+ * <div id="the-portal"></div>
37
+ *
38
+ * <Portal @to={{wormhole "the-portal"}}>
39
+ * content renders in the above div
40
+ * </Portal>
41
+ * </template>
42
+ *
43
+ * ```
44
+ */
45
+ export declare function wormhole(query: string | null | undefined | Element): Element;
20
46
  export declare const Portal: TOC<Signature>;
21
47
  export default Portal;
@@ -0,0 +1,39 @@
1
+ import type { Newable } from './type-utils.ts';
2
+ /**
3
+ * Creates a singleton for the given context and links the lifetime of the created class to the passed context
4
+ *
5
+ * Note that this function is _not_ lazy. Calling `createStore` will create an instance of the passed class.
6
+ * When combined with a getter though, creation becomes lazy.
7
+ *
8
+ * In this example, `MyState` is created once per instance of the component.
9
+ * repeat accesses to `this.foo` return a stable reference _as if_ `@cached` were used.
10
+ * ```js
11
+ * class MyState {}
12
+ *
13
+ * class Demo extends Component {
14
+ * // this is a stable reference
15
+ * get foo() {
16
+ * return createStore(this, MyState);
17
+ * }
18
+ *
19
+ * // or
20
+ * bar = createStore(this, MyState);
21
+ *
22
+ * // or
23
+ * three = createStore(this, () => new MyState(1, 2));
24
+ * }
25
+ * ```
26
+ *
27
+ * If arguments need to be configured during construction, the second argument may also be a function
28
+ * ```js
29
+ * class MyState {}
30
+ *
31
+ * class Demo extends Component {
32
+ * // this is a stable reference
33
+ * get foo() {
34
+ * return createStore(this, MyState);
35
+ * }
36
+ * }
37
+ * ```
38
+ */
39
+ export declare function createStore<Instance extends object>(context: object, theClass: Newable<Instance> | (() => Instance)): Instance;
@@ -11,7 +11,7 @@ export declare function rating(selector?: string): RatingPageObject;
11
11
  declare class RatingPageObject {
12
12
  #private;
13
13
  constructor(root: string);
14
- get label(): string | undefined;
14
+ get label(): string;
15
15
  get stars(): string;
16
16
  get starTexts(): string;
17
17
  get value(): number;
@@ -0,0 +1,3 @@
1
+ export type Newable<T extends object = object> = {
2
+ new (...args: any[]): T;
3
+ };
@@ -1 +1,2 @@
1
1
  export declare function uniqueId(): string;
2
+ export declare function isNewable(x: any): x is new (...args: unknown[]) => NonNullable<object>;
@@ -1 +1 @@
1
- {"version":3,"file":"color-scheme.js","sources":["../src/color-scheme.ts"],"sourcesContent":["import { waitForPromise } from '@ember/test-waiters';\n\nimport { cell } from 'ember-resources';\n\nconst _colorScheme = cell<string | undefined>();\n\nlet callbacks: Set<(colorScheme: string) => void> = new Set();\n\nasync function runCallbacks(theme: string) {\n await Promise.resolve();\n\n for (const callback of callbacks.values()) {\n callback(theme);\n }\n}\n\n/**\n * Object for managing the color scheme\n */\nexport const colorScheme = {\n /**\n * Set's the current color scheme to the passed value\n */\n update: (value: string) => {\n colorScheme.current = value;\n\n void waitForPromise(runCallbacks(value));\n },\n\n on: {\n /**\n * register a function to be called when the color scheme changes.\n */\n update: (callback: (colorScheme: string) => void) => {\n callbacks.add(callback);\n },\n },\n off: {\n /**\n * unregister a function that would have been called when the color scheme changes.\n */\n update: (callback: (colorScheme: string) => void) => {\n callbacks.delete(callback);\n },\n },\n\n /**\n * the current valuel of the \"color scheme\"\n */\n get current(): string | undefined {\n return _colorScheme.current;\n },\n set current(value: string | undefined) {\n _colorScheme.current = value;\n\n if (!value) {\n localPreference.delete();\n\n return;\n }\n\n localPreference.update(value);\n setColorScheme(value);\n },\n};\n\n/**\n * Synchronizes state of `colorScheme` with the users preferences as well as reconciles with previously set theme in local storage.\n *\n * This may only be called once per app.\n */\nexport function sync() {\n /**\n * reset the callbacks\n */\n callbacks = new Set();\n\n /**\n * If local prefs are set, then we don't care what prefers-color-scheme is\n */\n if (localPreference.isSet()) {\n const pref = localPreference.read();\n\n if (pref === 'dark') {\n setColorScheme('dark');\n\n _colorScheme.current = 'dark';\n\n return;\n }\n\n setColorScheme('light');\n _colorScheme.current = 'light';\n\n return;\n }\n\n if (prefers.dark()) {\n setColorScheme('dark');\n _colorScheme.current = 'dark';\n } else if (prefers.light()) {\n setColorScheme('light');\n _colorScheme.current = 'light';\n }\n}\n\n/**\n * Helper methods to determining what the user's preferred color scheme is\n */\nexport const prefers = {\n dark: () => window.matchMedia('(prefers-color-scheme: dark)').matches,\n light: () => window.matchMedia('(prefers-color-scheme: light)').matches,\n custom: (name: string) => window.matchMedia(`(prefers-color-scheme: ${name})`).matches,\n none: () => window.matchMedia('(prefers-color-scheme: no-preference)').matches,\n};\n\nconst LOCAL_PREF_KEY = 'ember-primitives/color-scheme#local-preference';\n\n/**\n * Helper methods for working with the color scheme preference in local storage\n */\nexport const localPreference = {\n isSet: () => Boolean(localPreference.read()),\n read: () => localStorage.getItem(LOCAL_PREF_KEY),\n update: (value: string) => localStorage.setItem(LOCAL_PREF_KEY, value),\n delete: () => localStorage.removeItem(LOCAL_PREF_KEY),\n};\n\n/**\n * For the given element, returns the `color-scheme` of that element.\n */\nexport function getColorScheme(element?: HTMLElement) {\n const style = styleOf(element);\n\n return style.getPropertyValue('color-scheme');\n}\n\nexport function setColorScheme(element: HTMLElement, value: string): void;\nexport function setColorScheme(value: string): void;\n\nexport function setColorScheme(...args: [string] | [HTMLElement, string]): void {\n if (typeof args[0] === 'string') {\n styleOf().setProperty('color-scheme', args[0]);\n\n return;\n }\n\n if (typeof args[1] === 'string') {\n styleOf(args[0]).setProperty('color-scheme', args[1]);\n\n return;\n }\n\n throw new Error(`Invalid arity, expected up to 2 args, received ${args.length}`);\n}\n\n/**\n * Removes the `color-scheme` from the given element\n */\nexport function removeColorScheme(element?: HTMLElement) {\n const style = styleOf(element);\n\n style.removeProperty('color-scheme');\n}\n\nfunction styleOf(element?: HTMLElement) {\n if (element) {\n return element.style;\n }\n\n return document.documentElement.style;\n}\n"],"names":["_colorScheme","cell","callbacks","Set","runCallbacks","theme","Promise","resolve","callback","values","colorScheme","update","value","current","waitForPromise","on","add","off","delete","localPreference","setColorScheme","sync","isSet","pref","read","prefers","dark","light","window","matchMedia","matches","custom","name","none","LOCAL_PREF_KEY","Boolean","localStorage","getItem","setItem","removeItem","getColorScheme","element","style","styleOf","getPropertyValue","args","setProperty","Error","length","removeColorScheme","removeProperty","document","documentElement"],"mappings":"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"}
1
+ {"version":3,"file":"color-scheme.js","sources":["../src/color-scheme.ts"],"sourcesContent":["import { waitForPromise } from '@ember/test-waiters';\n\nimport { cell } from 'ember-resources';\n\nconst _colorScheme = cell<string | undefined>();\n\nlet callbacks: Set<(colorScheme: string) => void> = new Set();\n\nasync function runCallbacks(theme: string) {\n await Promise.resolve();\n\n for (const callback of callbacks.values()) {\n callback(theme);\n }\n}\n\n/**\n * Object for managing the color scheme\n */\nexport const colorScheme = {\n /**\n * Set's the current color scheme to the passed value\n */\n update: (value: string) => {\n colorScheme.current = value;\n\n void waitForPromise(runCallbacks(value));\n },\n\n on: {\n /**\n * register a function to be called when the color scheme changes.\n */\n update: (callback: (colorScheme: string) => void) => {\n callbacks.add(callback);\n },\n },\n off: {\n /**\n * unregister a function that would have been called when the color scheme changes.\n */\n update: (callback: (colorScheme: string) => void) => {\n callbacks.delete(callback);\n },\n },\n\n /**\n * the current valuel of the \"color scheme\"\n */\n get current(): string | undefined {\n return _colorScheme.current;\n },\n set current(value: string | undefined) {\n _colorScheme.current = value;\n\n if (!value) {\n localPreference.delete();\n\n return;\n }\n\n localPreference.update(value);\n setColorScheme(value);\n },\n};\n\n/**\n * Synchronizes state of `colorScheme` with the users preferences as well as reconciles with previously set theme in local storage.\n *\n * This may only be called once per app.\n */\nexport function sync() {\n /**\n * reset the callbacks\n */\n callbacks = new Set();\n\n /**\n * If local prefs are set, then we don't care what prefers-color-scheme is\n */\n if (localPreference.isSet()) {\n const pref = localPreference.read();\n\n if (pref === 'dark') {\n setColorScheme('dark');\n\n _colorScheme.current = 'dark';\n\n return;\n }\n\n setColorScheme('light');\n _colorScheme.current = 'light';\n\n return;\n }\n\n if (prefers.dark()) {\n setColorScheme('dark');\n _colorScheme.current = 'dark';\n } else if (prefers.light()) {\n setColorScheme('light');\n _colorScheme.current = 'light';\n }\n}\n\n/**\n * Helper methods to determining what the user's preferred color scheme is\n */\nexport const prefers = {\n dark: () => window.matchMedia('(prefers-color-scheme: dark)').matches,\n light: () => window.matchMedia('(prefers-color-scheme: light)').matches,\n custom: (name: string) => window.matchMedia(`(prefers-color-scheme: ${name})`).matches,\n none: () => window.matchMedia('(prefers-color-scheme: no-preference)').matches,\n};\n\nconst LOCAL_PREF_KEY = 'ember-primitives/color-scheme#local-preference';\n\n/**\n * Helper methods for working with the color scheme preference in local storage\n */\nexport const localPreference = {\n isSet: () => Boolean(localPreference.read()),\n read: () => localStorage.getItem(LOCAL_PREF_KEY),\n update: (value: string) => localStorage.setItem(LOCAL_PREF_KEY, value),\n delete: () => localStorage.removeItem(LOCAL_PREF_KEY),\n};\n\n/**\n * For the given element, returns the `color-scheme` of that element.\n */\nexport function getColorScheme(element?: HTMLElement) {\n const style = styleOf(element);\n\n return style.getPropertyValue('color-scheme');\n}\n\nexport function setColorScheme(element: HTMLElement, value: string): void;\nexport function setColorScheme(value: string): void;\n\nexport function setColorScheme(...args: [string] | [HTMLElement, string]): void {\n if (typeof args[0] === 'string') {\n styleOf().setProperty('color-scheme', args[0]);\n\n return;\n }\n\n if (typeof args[1] === 'string') {\n styleOf(args[0]).setProperty('color-scheme', args[1]);\n\n return;\n }\n\n throw new Error(`Invalid arity, expected up to 2 args, received ${args.length}`);\n}\n\n/**\n * Removes the `color-scheme` from the given element\n */\nexport function removeColorScheme(element?: HTMLElement) {\n const style = styleOf(element);\n\n style.removeProperty('color-scheme');\n}\n\nfunction styleOf(element?: HTMLElement) {\n if (element) {\n return element.style;\n }\n\n return document.documentElement.style;\n}\n"],"names":["_colorScheme","cell","callbacks","Set","runCallbacks","theme","Promise","resolve","callback","values","colorScheme","update","value","current","waitForPromise","on","add","off","delete","localPreference","setColorScheme","sync","isSet","pref","read","prefers","dark","light","window","matchMedia","matches","custom","name","none","LOCAL_PREF_KEY","Boolean","localStorage","getItem","setItem","removeItem","getColorScheme","element","style","styleOf","getPropertyValue","args","setProperty","Error","length","removeColorScheme","removeProperty","document","documentElement"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"utils.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;EAEAF,kBAAkB,CAAC,GAAGE,IAAI,CAAC;AAC7B;;;;"}
1
+ {"version":3,"file":"utils.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;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"accordion.js","sources":["../../src/components/accordion.gts"],"sourcesContent":["import Component from \"@glimmer/component\";\nimport { assert } from \"@ember/debug\";\nimport { hash } from \"@ember/helper\";\n\n// temp\n// https://github.com/tracked-tools/tracked-toolbox/issues/38\n// eslint-disable-next-line @typescript-eslint/ban-ts-comment\n// @ts-ignore\nimport { localCopy } from \"tracked-toolbox\";\n\nimport AccordionItem from \"./accordion/item.gts\";\n\nimport type { WithBoundArgs } from \"@glint/template\";\n\ntype AccordionSingleArgs = {\n /**\n * The type of accordion. If `single`, only one item can be selected at a time. If `multiple`, multiple items can be selected at a time.\n */\n type: \"single\";\n /**\n * Whether the accordion is disabled. When `true`, all items cannot be expanded or collapsed.\n */\n disabled?: boolean;\n /**\n * When type is `single`, whether the accordion is collapsible. When `true`, the selected item can be collapsed by clicking its trigger.\n */\n collapsible?: boolean;\n} & (\n | {\n /**\n * The currently selected value. To be used in a controlled fashion in conjunction with `onValueChange`.\n */\n value: string;\n /**\n * A callback that is called when the selected value changes. To be used in a controlled fashion in conjunction with `value`.\n */\n onValueChange: (value: string | undefined) => void;\n /**\n * Not available in a controlled fashion.\n */\n defaultValue?: never;\n }\n | {\n /**\n * Not available in an uncontrolled fashion.\n */\n value?: never;\n /**\n * Not available in an uncontrolled fashion.\n */\n onValueChange?: never;\n /**\n * The default value of the accordion. To be used in an uncontrolled fashion.\n */\n defaultValue?: string;\n }\n);\n\ntype AccordionMultipleArgs = {\n /**\n * The type of accordion. If `single`, only one item can be selected at a time. If `multiple`, multiple items can be selected at a time.\n */\n type: \"multiple\";\n /**\n * Whether the accordion is disabled. When `true`, all items cannot be expanded or collapsed.\n */\n disabled?: boolean;\n} & (\n | {\n /**\n * The currently selected values. To be used in a controlled fashion in conjunction with `onValueChange`.\n */\n value: string[];\n /**\n * A callback that is called when the selected values change. To be used in a controlled fashion in conjunction with `value`.\n */\n onValueChange: (value?: string[]) => void;\n /**\n * Not available in a controlled fashion.\n */\n defaultValue?: never;\n }\n | {\n /**\n * Not available in an uncontrolled fashion.\n */\n value?: never;\n /**\n * Not available in an uncontrolled fashion.\n */\n onValueChange?: never;\n /**\n * The default values of the accordion. To be used in an uncontrolled fashion.\n */\n defaultValue?: string[];\n }\n);\n\nexport class Accordion extends Component<{\n Element: HTMLDivElement;\n Args: AccordionSingleArgs | AccordionMultipleArgs;\n Blocks: {\n default: [\n {\n /**\n * The AccordionItem component.\n */\n Item: WithBoundArgs<typeof AccordionItem, \"selectedValue\" | \"toggleItem\" | \"disabled\">;\n },\n ];\n };\n}> {\n <template>\n <div data-disabled={{@disabled}} ...attributes>\n {{yield\n (hash\n Item=(component\n AccordionItem\n selectedValue=this.selectedValue\n toggleItem=this.toggleItem\n disabled=@disabled\n )\n )\n }}\n </div>\n </template>\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-call\n @localCopy(\"args.defaultValue\") declare _internallyManagedValue?: string | string[];\n\n get selectedValue() {\n return this.args.value ?? this._internallyManagedValue;\n }\n\n toggleItem = (value: string) => {\n if (this.args.disabled) {\n return;\n }\n\n if (this.args.type === \"single\") {\n this.toggleItemSingle(value);\n } else if (this.args.type === \"multiple\") {\n this.toggleItemMultiple(value);\n }\n };\n\n toggleItemSingle = (value: string) => {\n assert(\"Cannot call `toggleItemSingle` when `disabled` is true.\", !this.args.disabled);\n assert(\n \"Cannot call `toggleItemSingle` when `type` is not `single`.\",\n this.args.type === \"single\",\n );\n\n if (value === this.selectedValue && !this.args.collapsible) {\n return;\n }\n\n const newValue = value === this.selectedValue ? undefined : value;\n\n if (this.args.onValueChange) {\n this.args.onValueChange(newValue);\n } else {\n this._internallyManagedValue = newValue;\n }\n };\n\n toggleItemMultiple = (value: string) => {\n assert(\"Cannot call `toggleItemMultiple` when `disabled` is true.\", !this.args.disabled);\n assert(\n \"Cannot call `toggleItemMultiple` when `type` is not `multiple`.\",\n this.args.type === \"multiple\",\n );\n\n const currentValues = (this.selectedValue as string[] | undefined) ?? [];\n const indexOfValue = currentValues.indexOf(value);\n let newValue: string[];\n\n if (indexOfValue === -1) {\n newValue = [...currentValues, value];\n } else {\n newValue = [\n ...currentValues.slice(0, indexOfValue),\n ...currentValues.slice(indexOfValue + 1),\n ];\n }\n\n if (this.args.onValueChange) {\n this.args.onValueChange(newValue);\n } else {\n this._internallyManagedValue = newValue;\n }\n };\n}\n\nexport default Accordion;\n"],"names":["Accordion","Component","setComponentTemplate","precompileTemplate","strictMode","scope","hash","AccordionItem","g","prototype","localCopy","i","void 0","selectedValue","args","value","_internallyManagedValue","toggleItem","disabled","type","toggleItemSingle","toggleItemMultiple","assert","collapsible","newValue","undefined","onValueChange","currentValues","indexOfValue","indexOf","slice"],"mappings":";;;;;;;;;AAkGO,MAAMA,SAAA,SAAkBC,SAAA;AAc7B,EAAA;IAAAC,oBAAA,CAAAC,kBAAA,CAAA,6MAAA,EAaA;MAAAC,UAAA,EAAA,IAAA;AAAAC,MAAAA,KAAA,EAAAA,OAAA;QAAAC,IAAA;AAAAC,QAAAA;AAAA,OAAA;KAAU,CAAA,EAAV,IAAW,CAAA;AAAD;AAEV;AAAA,EAAA;AAAAC,IAAAA,CAAA,MAAAC,SAAA,EAAA,yBAAA,EAAA,CACCC,SAAA,CAAU,mBAAA,CAAA,CAAA,CAAA;AAAA;AAAA,EAAA,wBAAA,IAAAC,CAAA,CAAA,IAAA,EAAA,yBAAA,CAAA,EAAAC,MAAA;EAEX,IAAIC,aAAAA,GAAgB;IAClB,OAAO,IAAI,CAACC,IAAI,CAACC,KAAK,IAAI,IAAI,CAACC,uBAAuB;AACxD;EAEAC,UAAA,GAAcF,KAAa,IAAA;AACzB,IAAA,IAAI,IAAI,CAACD,IAAI,CAACI,QAAQ,EAAE;AACtB,MAAA;AACF;AAEA,IAAA,IAAI,IAAI,CAACJ,IAAI,CAACK,IAAI,KAAK,QAAA,EAAU;AAC/B,MAAA,IAAI,CAACC,gBAAgB,CAACL,KAAA,CAAA;KACxB,MAAO,IAAI,IAAI,CAACD,IAAI,CAACK,IAAI,KAAK,UAAA,EAAY;AACxC,MAAA,IAAI,CAACE,kBAAkB,CAACN,KAAA,CAAA;AAC1B;GACF;EAEAK,gBAAA,GAAoBL,KAAa,IAAA;IAC/BO,MAAA,CAAO,2DAA2D,CAAC,IAAI,CAACR,IAAI,CAACI,QAAQ,CAAA;IACrFI,MAAA,CACE,+DACA,IAAI,CAACR,IAAI,CAACK,IAAI,KAAK,QAAA,CAAA;AAGrB,IAAA,IAAIJ,KAAA,KAAU,IAAI,CAACF,aAAa,IAAI,CAAC,IAAI,CAACC,IAAI,CAACS,WAAW,EAAE;AAC1D,MAAA;AACF;IAEA,MAAMC,WAAWT,KAAA,KAAU,IAAI,CAACF,aAAa,GAAGY,SAAA,GAAYV,KAAA;AAE5D,IAAA,IAAI,IAAI,CAACD,IAAI,CAACY,aAAa,EAAE;AAC3B,MAAA,IAAI,CAACZ,IAAI,CAACY,aAAa,CAACF,QAAA,CAAA;AAC1B,KAAA,MAAO;MACL,IAAI,CAACR,uBAAuB,GAAGQ,QAAA;AACjC;GACF;EAEAH,kBAAA,GAAsBN,KAAa,IAAA;IACjCO,MAAA,CAAO,6DAA6D,CAAC,IAAI,CAACR,IAAI,CAACI,QAAQ,CAAA;IACvFI,MAAA,CACE,mEACA,IAAI,CAACR,IAAI,CAACK,IAAI,KAAK,UAAA,CAAA;AAGrB,IAAA,MAAMQ,aAAA,GAAiB,IAAI,CAACd,aAAa,IAA6B,EAAE;AACxE,IAAA,MAAMe,YAAA,GAAeD,aAAA,CAAcE,OAAO,CAACd,KAAA,CAAA;AAC3C,IAAA,IAAIS,QAAgB;AAEpB,IAAA,IAAII,YAAA,KAAiB,EAAC,EAAG;AACvBJ,MAAAA,QAAA,GAAW,CAAI,GAAAG,aAAA,EAAeZ,KAAA,CAAM;AACtC,KAAA,MAAO;MACLS,QAAA,GAAW,IACNG,aAAA,CAAcG,KAAK,CAAC,CAAA,EAAGF,YAAA,CAAA,KACvBD,aAAA,CAAcG,KAAK,CAACF,YAAA,GAAe,CAAA,CAAA,CACvC;AACH;AAEA,IAAA,IAAI,IAAI,CAACd,IAAI,CAACY,aAAa,EAAE;AAC3B,MAAA,IAAI,CAACZ,IAAI,CAACY,aAAa,CAACF,QAAA,CAAA;AAC1B,KAAA,MAAO;MACL,IAAI,CAACR,uBAAuB,GAAGQ,QAAA;AACjC;GACF;AACF;;;;"}
1
+ {"version":3,"file":"accordion.js","sources":["../../src/components/accordion.gts"],"sourcesContent":["import Component from \"@glimmer/component\";\nimport { assert } from \"@ember/debug\";\nimport { hash } from \"@ember/helper\";\n\n// temp\n// https://github.com/tracked-tools/tracked-toolbox/issues/38\n// eslint-disable-next-line @typescript-eslint/ban-ts-comment\n// @ts-ignore\nimport { localCopy } from \"tracked-toolbox\";\n\nimport AccordionItem from \"./accordion/item.gts\";\n\nimport type { WithBoundArgs } from \"@glint/template\";\n\ntype AccordionSingleArgs = {\n /**\n * The type of accordion. If `single`, only one item can be selected at a time. If `multiple`, multiple items can be selected at a time.\n */\n type: \"single\";\n /**\n * Whether the accordion is disabled. When `true`, all items cannot be expanded or collapsed.\n */\n disabled?: boolean;\n /**\n * When type is `single`, whether the accordion is collapsible. When `true`, the selected item can be collapsed by clicking its trigger.\n */\n collapsible?: boolean;\n} & (\n | {\n /**\n * The currently selected value. To be used in a controlled fashion in conjunction with `onValueChange`.\n */\n value: string;\n /**\n * A callback that is called when the selected value changes. To be used in a controlled fashion in conjunction with `value`.\n */\n onValueChange: (value: string | undefined) => void;\n /**\n * Not available in a controlled fashion.\n */\n defaultValue?: never;\n }\n | {\n /**\n * Not available in an uncontrolled fashion.\n */\n value?: never;\n /**\n * Not available in an uncontrolled fashion.\n */\n onValueChange?: never;\n /**\n * The default value of the accordion. To be used in an uncontrolled fashion.\n */\n defaultValue?: string;\n }\n);\n\ntype AccordionMultipleArgs = {\n /**\n * The type of accordion. If `single`, only one item can be selected at a time. If `multiple`, multiple items can be selected at a time.\n */\n type: \"multiple\";\n /**\n * Whether the accordion is disabled. When `true`, all items cannot be expanded or collapsed.\n */\n disabled?: boolean;\n} & (\n | {\n /**\n * The currently selected values. To be used in a controlled fashion in conjunction with `onValueChange`.\n */\n value: string[];\n /**\n * A callback that is called when the selected values change. To be used in a controlled fashion in conjunction with `value`.\n */\n onValueChange: (value?: string[]) => void;\n /**\n * Not available in a controlled fashion.\n */\n defaultValue?: never;\n }\n | {\n /**\n * Not available in an uncontrolled fashion.\n */\n value?: never;\n /**\n * Not available in an uncontrolled fashion.\n */\n onValueChange?: never;\n /**\n * The default values of the accordion. To be used in an uncontrolled fashion.\n */\n defaultValue?: string[];\n }\n);\n\nexport class Accordion extends Component<{\n Element: HTMLDivElement;\n Args: AccordionSingleArgs | AccordionMultipleArgs;\n Blocks: {\n default: [\n {\n /**\n * The AccordionItem component.\n */\n Item: WithBoundArgs<typeof AccordionItem, \"selectedValue\" | \"toggleItem\" | \"disabled\">;\n },\n ];\n };\n}> {\n <template>\n <div data-disabled={{@disabled}} ...attributes>\n {{yield\n (hash\n Item=(component\n AccordionItem\n selectedValue=this.selectedValue\n toggleItem=this.toggleItem\n disabled=@disabled\n )\n )\n }}\n </div>\n </template>\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-call\n @localCopy(\"args.defaultValue\") declare _internallyManagedValue?: string | string[];\n\n get selectedValue() {\n return this.args.value ?? this._internallyManagedValue;\n }\n\n toggleItem = (value: string) => {\n if (this.args.disabled) {\n return;\n }\n\n if (this.args.type === \"single\") {\n this.toggleItemSingle(value);\n } else if (this.args.type === \"multiple\") {\n this.toggleItemMultiple(value);\n }\n };\n\n toggleItemSingle = (value: string) => {\n assert(\"Cannot call `toggleItemSingle` when `disabled` is true.\", !this.args.disabled);\n assert(\n \"Cannot call `toggleItemSingle` when `type` is not `single`.\",\n this.args.type === \"single\",\n );\n\n if (value === this.selectedValue && !this.args.collapsible) {\n return;\n }\n\n const newValue = value === this.selectedValue ? undefined : value;\n\n if (this.args.onValueChange) {\n this.args.onValueChange(newValue);\n } else {\n this._internallyManagedValue = newValue;\n }\n };\n\n toggleItemMultiple = (value: string) => {\n assert(\"Cannot call `toggleItemMultiple` when `disabled` is true.\", !this.args.disabled);\n assert(\n \"Cannot call `toggleItemMultiple` when `type` is not `multiple`.\",\n this.args.type === \"multiple\",\n );\n\n const currentValues = (this.selectedValue as string[] | undefined) ?? [];\n const indexOfValue = currentValues.indexOf(value);\n let newValue: string[];\n\n if (indexOfValue === -1) {\n newValue = [...currentValues, value];\n } else {\n newValue = [\n ...currentValues.slice(0, indexOfValue),\n ...currentValues.slice(indexOfValue + 1),\n ];\n }\n\n if (this.args.onValueChange) {\n this.args.onValueChange(newValue);\n } else {\n this._internallyManagedValue = newValue;\n }\n };\n}\n\nexport default Accordion;\n"],"names":["Accordion","Component","setComponentTemplate","precompileTemplate","strictMode","scope","hash","AccordionItem","g","prototype","localCopy","i","void 0","selectedValue","args","value","_internallyManagedValue","toggleItem","disabled","type","toggleItemSingle","toggleItemMultiple","assert","collapsible","newValue","undefined","onValueChange","currentValues","indexOfValue","indexOf","slice"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"dialog.js","sources":["../../src/components/dialog.gts"],"sourcesContent":["import Component from \"@glimmer/component\";\nimport { tracked } from \"@glimmer/tracking\";\nimport { assert } from \"@ember/debug\";\nimport { hash } from \"@ember/helper\";\nimport { on } from \"@ember/modifier\";\n\nimport { modifier as eModifier } from \"ember-modifier\";\n// temp\n// https://github.com/tracked-tools/tracked-toolbox/issues/38\n// eslint-disable-next-line @typescript-eslint/ban-ts-comment\n// @ts-expect-error\nimport { localCopy } from \"tracked-toolbox\";\n\nimport type { TOC } from \"@ember/component/template-only\";\nimport type { ModifierLike, WithBoundArgs } from \"@glint/template\";\n\nconst DialogElement: TOC<{\n Element: HTMLDialogElement;\n Args: {\n /**\n * @internal\n */\n open: boolean | undefined;\n /**\n * @internal\n */\n onClose: () => void;\n\n /**\n * @internal\n */\n register: ModifierLike<{ Element: HTMLDialogElement }>;\n };\n Blocks: { default: [] };\n}> = <template>\n <dialog ...attributes open={{@open}} {{on \"close\" @onClose}} {{@register}}>\n {{yield}}\n </dialog>\n</template>;\n\nexport interface Signature {\n Args: {\n /**\n * Optionally set the open state of the `<dialog>`\n * The state will still be managed internally,\n * so this does not need to be a maintained value, but whenever it changes,\n * the dialog element will reflect that change accordingly.\n */\n open?: boolean;\n /**\n * When the `<dialog>` is closed, this function will be called\n * and the `<dialog>`'s `returnValue` will be passed.\n *\n * This can be used to determine which button was clicked to close the modal\n *\n * Note though that this value is only populated when using\n * `<form method='dialog'>`\n */\n onClose?: (returnValue: string) => void;\n };\n Blocks: {\n default: [\n {\n /**\n * Represents the open state of the `<dialog>` element.\n */\n isOpen: boolean;\n\n /**\n * Closes the `<dialog>` element\n * Will throw an error if `Dialog` is not rendered.\n */\n close: () => void;\n\n /**\n * Opens the `<dialog>` element.\n * Will throw an error if `Dialog` is not rendered.\n */\n open: () => void;\n\n /**\n * This modifier should be applied to the button that opens the Dialog so that it can be re-focused when the dialog closes.\n *\n * Example:\n *\n * ```gjs\n * <template>\n * <Modal as |m|>\n * <button {{m.focusOnClose}} {{on \"click\" m.open}}>Open</button>\n *\n * <m.Dialog>...</m.Dialog>\n * </Modal>\n * </template>\n * ```\n */\n focusOnClose: ModifierLike<{ Element: HTMLElement }>;\n\n /**\n * This is the `<dialog>` element (with some defaults pre-wired).\n * This is required to be rendered.\n */\n Dialog: WithBoundArgs<typeof DialogElement, \"onClose\" | \"register\" | \"open\">;\n },\n ];\n };\n}\n\nclass ModalDialog extends Component<Signature> {\n <template>\n {{yield\n (hash\n isOpen=this.isOpen\n open=this.open\n close=this.close\n focusOnClose=this.refocus\n Dialog=(component DialogElement open=@open onClose=this.handleClose register=this.register)\n )\n }}\n </template>\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-call\n @localCopy(\"args.open\") declare _isOpen: boolean;\n\n get isOpen() {\n /**\n * Always fallback to false (closed)\n */\n return this._isOpen ?? false;\n }\n set isOpen(val: boolean) {\n this._isOpen = val;\n }\n\n #lastIsOpen = false;\n refocus = eModifier((element) => {\n assert(`focusOnClose is only valid on a HTMLElement`, element instanceof HTMLElement);\n\n if (!this.isOpen && this.#lastIsOpen) {\n element.focus();\n }\n\n this.#lastIsOpen = this.isOpen;\n });\n\n @tracked declare dialogElement: HTMLDialogElement | undefined;\n\n register = eModifier((element: HTMLDialogElement) => {\n /**\n * This is very sad.\n *\n * But we need the element to be 'root state'\n * so that when we read things like \"isOpen\",\n * when the dialog is finally rendered, all the\n * downstream properties render.\n *\n * This has to be an async / delayed a bit, so that\n * the tracking frame can exit, and we don't infinite loop\n */\n void (async () => {\n await Promise.resolve();\n\n this.dialogElement = element;\n })();\n });\n\n /**\n * Closes the dialog -- this will throw an error in development if the dialog element was not rendered\n */\n close = () => {\n assert(\n \"Cannot call `close` on <Dialog> without rendering the dialog element.\",\n this.dialogElement,\n );\n\n /**\n * If the element is already closed, don't run all this again\n */\n if (!this.dialogElement.hasAttribute(\"open\")) {\n return;\n }\n\n /**\n * removes the `open` attribute\n * handleClose will be called because the dialog has bound the `close` event.\n */\n this.dialogElement.close();\n };\n\n /**\n * @internal\n *\n * handles the <dialog> element's native close behavior.\n * listened to via addEventListener('close', ...);\n */\n handleClose = () => {\n assert(\n \"Cannot call `handleDialogClose` on <Dialog> without rendering the dialog element. This is likely a bug in ember-primitives. Please open an issue <3\",\n this.dialogElement,\n );\n\n this.isOpen = false;\n this.args.onClose?.(this.dialogElement.returnValue);\n // the return value ends up staying... which is annoying\n this.dialogElement.returnValue = \"\";\n };\n\n /**\n * Opens the dialog -- this will throw an error in development if the dialog element was not rendered\n */\n open = () => {\n assert(\n \"Cannot call `open` on <Dialog> without rendering the dialog element.\",\n this.dialogElement,\n );\n\n /**\n * If the element is already open, don't run all this again\n */\n if (this.dialogElement.hasAttribute(\"open\")) {\n return;\n }\n\n /**\n * adds the `open` attribute\n */\n this.dialogElement.showModal();\n this.isOpen = true;\n };\n}\n\nexport const Modal = ModalDialog;\nexport const Dialog = ModalDialog;\n\nexport default ModalDialog;\n"],"names":["DialogElement","setComponentTemplate","precompileTemplate","strictMode","scope","on","templateOnly","ModalDialog","Component","hash","g","prototype","localCopy","i","void 0","isOpen","_isOpen","val","refocus","eModifier","element","assert","HTMLElement","focus","tracked","register","Promise","resolve","dialogElement","close","hasAttribute","handleClose","args","onClose","returnValue","open","showModal","Modal","Dialog"],"mappings":"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"}
1
+ {"version":3,"file":"dialog.js","sources":["../../src/components/dialog.gts"],"sourcesContent":["import Component from \"@glimmer/component\";\nimport { tracked } from \"@glimmer/tracking\";\nimport { assert } from \"@ember/debug\";\nimport { hash } from \"@ember/helper\";\nimport { on } from \"@ember/modifier\";\n\nimport { modifier as eModifier } from \"ember-modifier\";\n// temp\n// https://github.com/tracked-tools/tracked-toolbox/issues/38\n// eslint-disable-next-line @typescript-eslint/ban-ts-comment\n// @ts-expect-error\nimport { localCopy } from \"tracked-toolbox\";\n\nimport type { TOC } from \"@ember/component/template-only\";\nimport type { ModifierLike, WithBoundArgs } from \"@glint/template\";\n\nconst DialogElement: TOC<{\n Element: HTMLDialogElement;\n Args: {\n /**\n * @internal\n */\n open: boolean | undefined;\n /**\n * @internal\n */\n onClose: () => void;\n\n /**\n * @internal\n */\n register: ModifierLike<{ Element: HTMLDialogElement }>;\n };\n Blocks: { default: [] };\n}> = <template>\n <dialog ...attributes open={{@open}} {{on \"close\" @onClose}} {{@register}}>\n {{yield}}\n </dialog>\n</template>;\n\nexport interface Signature {\n Args: {\n /**\n * Optionally set the open state of the `<dialog>`\n * The state will still be managed internally,\n * so this does not need to be a maintained value, but whenever it changes,\n * the dialog element will reflect that change accordingly.\n */\n open?: boolean;\n /**\n * When the `<dialog>` is closed, this function will be called\n * and the `<dialog>`'s `returnValue` will be passed.\n *\n * This can be used to determine which button was clicked to close the modal\n *\n * Note though that this value is only populated when using\n * `<form method='dialog'>`\n */\n onClose?: (returnValue: string) => void;\n };\n Blocks: {\n default: [\n {\n /**\n * Represents the open state of the `<dialog>` element.\n */\n isOpen: boolean;\n\n /**\n * Closes the `<dialog>` element\n * Will throw an error if `Dialog` is not rendered.\n */\n close: () => void;\n\n /**\n * Opens the `<dialog>` element.\n * Will throw an error if `Dialog` is not rendered.\n */\n open: () => void;\n\n /**\n * This modifier should be applied to the button that opens the Dialog so that it can be re-focused when the dialog closes.\n *\n * Example:\n *\n * ```gjs\n * <template>\n * <Modal as |m|>\n * <button {{m.focusOnClose}} {{on \"click\" m.open}}>Open</button>\n *\n * <m.Dialog>...</m.Dialog>\n * </Modal>\n * </template>\n * ```\n */\n focusOnClose: ModifierLike<{ Element: HTMLElement }>;\n\n /**\n * This is the `<dialog>` element (with some defaults pre-wired).\n * This is required to be rendered.\n */\n Dialog: WithBoundArgs<typeof DialogElement, \"onClose\" | \"register\" | \"open\">;\n },\n ];\n };\n}\n\nclass ModalDialog extends Component<Signature> {\n <template>\n {{yield\n (hash\n isOpen=this.isOpen\n open=this.open\n close=this.close\n focusOnClose=this.refocus\n Dialog=(component DialogElement open=@open onClose=this.handleClose register=this.register)\n )\n }}\n </template>\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-call\n @localCopy(\"args.open\") declare _isOpen: boolean;\n\n get isOpen() {\n /**\n * Always fallback to false (closed)\n */\n return this._isOpen ?? false;\n }\n set isOpen(val: boolean) {\n this._isOpen = val;\n }\n\n #lastIsOpen = false;\n refocus = eModifier((element) => {\n assert(`focusOnClose is only valid on a HTMLElement`, element instanceof HTMLElement);\n\n if (!this.isOpen && this.#lastIsOpen) {\n element.focus();\n }\n\n this.#lastIsOpen = this.isOpen;\n });\n\n @tracked declare dialogElement: HTMLDialogElement | undefined;\n\n register = eModifier((element: HTMLDialogElement) => {\n /**\n * This is very sad.\n *\n * But we need the element to be 'root state'\n * so that when we read things like \"isOpen\",\n * when the dialog is finally rendered, all the\n * downstream properties render.\n *\n * This has to be an async / delayed a bit, so that\n * the tracking frame can exit, and we don't infinite loop\n */\n void (async () => {\n await Promise.resolve();\n\n this.dialogElement = element;\n })();\n });\n\n /**\n * Closes the dialog -- this will throw an error in development if the dialog element was not rendered\n */\n close = () => {\n assert(\n \"Cannot call `close` on <Dialog> without rendering the dialog element.\",\n this.dialogElement,\n );\n\n /**\n * If the element is already closed, don't run all this again\n */\n if (!this.dialogElement.hasAttribute(\"open\")) {\n return;\n }\n\n /**\n * removes the `open` attribute\n * handleClose will be called because the dialog has bound the `close` event.\n */\n this.dialogElement.close();\n };\n\n /**\n * @internal\n *\n * handles the <dialog> element's native close behavior.\n * listened to via addEventListener('close', ...);\n */\n handleClose = () => {\n assert(\n \"Cannot call `handleDialogClose` on <Dialog> without rendering the dialog element. This is likely a bug in ember-primitives. Please open an issue <3\",\n this.dialogElement,\n );\n\n this.isOpen = false;\n this.args.onClose?.(this.dialogElement.returnValue);\n // the return value ends up staying... which is annoying\n this.dialogElement.returnValue = \"\";\n };\n\n /**\n * Opens the dialog -- this will throw an error in development if the dialog element was not rendered\n */\n open = () => {\n assert(\n \"Cannot call `open` on <Dialog> without rendering the dialog element.\",\n this.dialogElement,\n );\n\n /**\n * If the element is already open, don't run all this again\n */\n if (this.dialogElement.hasAttribute(\"open\")) {\n return;\n }\n\n /**\n * adds the `open` attribute\n */\n this.dialogElement.showModal();\n this.isOpen = true;\n };\n}\n\nexport const Modal = ModalDialog;\nexport const Dialog = ModalDialog;\n\nexport default ModalDialog;\n"],"names":["DialogElement","setComponentTemplate","precompileTemplate","strictMode","scope","on","templateOnly","ModalDialog","Component","hash","g","prototype","localCopy","i","void 0","isOpen","_isOpen","val","refocus","eModifier","element","assert","HTMLElement","focus","tracked","register","Promise","resolve","dialogElement","close","hasAttribute","handleClose","args","onClose","returnValue","open","showModal","Modal","Dialog"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"keys.js","sources":["../../src/components/keys.gts"],"sourcesContent":["import type { TOC } from \"@ember/component/template-only\";\n\nconst isLast = (collection: unknown[], index: number) => index === collection.length - 1;\nconst isNotLast = (collection: unknown[], index: number) => !isLast(collection, index);\nconst isMac = navigator.userAgent.indexOf(\"Mac OS\") >= 0;\n\nfunction split(str: string) {\n const keys = str.split(\"+\").map((x) => x.trim());\n\n return keys;\n}\n\nfunction getKeys(keys: string[] | string, mac?: string[] | string) {\n const normalKeys = Array.isArray(keys) ? keys : split(keys);\n\n if (!mac) {\n return normalKeys;\n }\n\n const normalMac = Array.isArray(mac) ? mac : split(mac);\n\n return isMac ? normalMac : normalKeys;\n}\n\nexport interface KeyComboSignature {\n Element: HTMLElement;\n Args: {\n keys: string[] | string;\n mac?: string[] | string;\n };\n}\n\nexport const KeyCombo: TOC<KeyComboSignature> = <template>\n <span class=\"ember-primitives__key-combination\" ...attributes>\n {{#let (getKeys @keys @mac) as |keys|}}\n {{#each keys as |key i|}}\n <Key>{{key}}</Key>\n {{#if (isNotLast keys i)}}\n <span class=\"ember-primitives__key-combination__separator\">+</span>\n {{/if}}\n {{/each}}\n {{/let}}\n </span>\n</template>;\n\nexport interface KeySignature {\n Element: HTMLElement;\n Blocks: { default?: [] };\n}\n\nexport const Key: TOC<KeySignature> = <template>\n <kbd class=\"ember-primitives__key\" ...attributes>{{yield}}</kbd>\n</template>;\n"],"names":["isLast","collection","index","length","isNotLast","isMac","navigator","userAgent","indexOf","split","str","keys","map","x","trim","getKeys","mac","normalKeys","Array","isArray","normalMac","KeyCombo","setComponentTemplate","precompileTemplate","strictMode","scope","Key","templateOnly"],"mappings":";;;;AAEA,MAAMA,MAAA,GAASA,CAACC,UAAmB,EAAIC,KAAa,KAAKA,KAAA,KAAUD,UAAA,CAAWE,MAAM,GAAG,CAAA;AACvF,MAAMC,SAAA,GAAYA,CAACH,UAAmB,EAAIC,KAAa,KAAK,CAACF,MAAA,CAAOC,UAAA,EAAYC,KAAA,CAAA;AAChF,MAAMG,QAAQC,SAAA,CAAUC,SAAS,CAACC,OAAO,CAAC,QAAA,CAAA,IAAa,CAAA;AAEvD,SAASC,KAAAA,CAAMC,GAAW,EAAA;AACxB,EAAA,MAAMC,IAAA,GAAOD,GAAA,CAAID,KAAK,CAAC,GAAA,CAAA,CAAKG,GAAG,CAAEC,CAAA,IAAMA,CAAA,CAAEC,IAAI,EAAA,CAAA;AAE7C,EAAA,OAAOH,IAAA;AACT;AAEA,SAASI,OAAAA,CAAQJ,IAAuB,EAAEK,GAAuB,EAAA;AAC/D,EAAA,MAAMC,aAAaC,KAAA,CAAMC,OAAO,CAACR,IAAA,CAAA,GAAQA,OAAOF,KAAA,CAAME,IAAA,CAAA;EAEtD,IAAI,CAACK,GAAA,EAAK;AACR,IAAA,OAAOC,UAAA;AACT;AAEA,EAAA,MAAMG,YAAYF,KAAA,CAAMC,OAAO,CAACH,GAAA,CAAA,GAAOA,MAAMP,KAAA,CAAMO,GAAA,CAAA;AAEnD,EAAA,OAAOX,QAAQe,SAAA,GAAYH,UAAA;AAC7B;MAUaI,QAAc,GAAAC,oBAAA,CAAqBC,kBAAA,CAAA,kWAAA,EAWhD;EAAAC,UAAA,EAAA,IAAA;AAAAC,EAAAA,KAAA,EAAAA,OAAA;IAAAV,OAAA;IAAAW,GAAA;AAAAtB,IAAAA;AAAA,GAAA;AAAU,CAAA,CAAA,EAAAuB,YAAA,EAAA;MAOGD,GAAS,GAAAJ,oBAAA,CAAgBC,kBAAA,CAAA,0EAAA,EAEtC;EAAAC,UAAA,EAAA;AAAU,CAAA,CAAA,EAAAG,YAAA,EAAA;;;;"}
1
+ {"version":3,"file":"keys.js","sources":["../../src/components/keys.gts"],"sourcesContent":["import type { TOC } from \"@ember/component/template-only\";\n\nconst isLast = (collection: unknown[], index: number) => index === collection.length - 1;\nconst isNotLast = (collection: unknown[], index: number) => !isLast(collection, index);\nconst isMac = navigator.userAgent.indexOf(\"Mac OS\") >= 0;\n\nfunction split(str: string) {\n const keys = str.split(\"+\").map((x) => x.trim());\n\n return keys;\n}\n\nfunction getKeys(keys: string[] | string, mac?: string[] | string) {\n const normalKeys = Array.isArray(keys) ? keys : split(keys);\n\n if (!mac) {\n return normalKeys;\n }\n\n const normalMac = Array.isArray(mac) ? mac : split(mac);\n\n return isMac ? normalMac : normalKeys;\n}\n\nexport interface KeyComboSignature {\n Element: HTMLElement;\n Args: {\n keys: string[] | string;\n mac?: string[] | string;\n };\n}\n\nexport const KeyCombo: TOC<KeyComboSignature> = <template>\n <span class=\"ember-primitives__key-combination\" ...attributes>\n {{#let (getKeys @keys @mac) as |keys|}}\n {{#each keys as |key i|}}\n <Key>{{key}}</Key>\n {{#if (isNotLast keys i)}}\n <span class=\"ember-primitives__key-combination__separator\">+</span>\n {{/if}}\n {{/each}}\n {{/let}}\n </span>\n</template>;\n\nexport interface KeySignature {\n Element: HTMLElement;\n Blocks: { default?: [] };\n}\n\nexport const Key: TOC<KeySignature> = <template>\n <kbd class=\"ember-primitives__key\" ...attributes>{{yield}}</kbd>\n</template>;\n"],"names":["isLast","collection","index","length","isNotLast","isMac","navigator","userAgent","indexOf","split","str","keys","map","x","trim","getKeys","mac","normalKeys","Array","isArray","normalMac","KeyCombo","setComponentTemplate","precompileTemplate","strictMode","scope","Key","templateOnly"],"mappings":";;;;AAEA,MAAMA,MAAA,GAASA,CAACC,UAAmB,EAAIC,KAAa,KAAKA,KAAA,KAAUD,UAAA,CAAWE,MAAM,GAAG,CAAA;AACvF,MAAMC,SAAA,GAAYA,CAACH,UAAmB,EAAIC,KAAa,KAAK,CAACF,MAAA,CAAOC,UAAA,EAAYC,KAAA,CAAA;AAChF,MAAMG,QAAQC,SAAA,CAAUC,SAAS,CAACC,OAAO,CAAC,QAAA,CAAA,IAAa,CAAA;AAEvD,SAASC,KAAAA,CAAMC,GAAW,EAAA;AACxB,EAAA,MAAMC,IAAA,GAAOD,GAAA,CAAID,KAAK,CAAC,GAAA,CAAA,CAAKG,GAAG,CAAEC,CAAA,IAAMA,CAAA,CAAEC,IAAI,EAAA,CAAA;AAE7C,EAAA,OAAOH,IAAA;AACT;AAEA,SAASI,OAAAA,CAAQJ,IAAuB,EAAEK,GAAuB,EAAA;AAC/D,EAAA,MAAMC,aAAaC,KAAA,CAAMC,OAAO,CAACR,IAAA,CAAA,GAAQA,OAAOF,KAAA,CAAME,IAAA,CAAA;EAEtD,IAAI,CAACK,GAAA,EAAK;AACR,IAAA,OAAOC,UAAA;AACT,EAAA;AAEA,EAAA,MAAMG,YAAYF,KAAA,CAAMC,OAAO,CAACH,GAAA,CAAA,GAAOA,MAAMP,KAAA,CAAMO,GAAA,CAAA;AAEnD,EAAA,OAAOX,QAAQe,SAAA,GAAYH,UAAA;AAC7B;MAUaI,QAAc,GAAAC,oBAAA,CAAqBC,kBAAA,CAAA,kWAAA,EAWhD;EAAAC,UAAA,EAAA,IAAA;AAAAC,EAAAA,KAAA,EAAAA,OAAA;IAAAV,OAAA;IAAAW,GAAA;AAAAtB,IAAAA;AAAA,GAAA;AAAU,CAAA,CAAA,EAAAuB,YAAA,EAAA;MAOGD,GAAS,GAAAJ,oBAAA,CAAgBC,kBAAA,CAAA,0EAAA,EAEtC;EAAAC,UAAA,EAAA;AAAU,CAAA,CAAA,EAAAG,YAAA,EAAA;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"menu.js","sources":["../../src/components/menu.gts"],"sourcesContent":["import Component from \"@glimmer/component\";\nimport { hash } from \"@ember/helper\";\nimport { on } from \"@ember/modifier\";\nimport { guidFor } from \"@ember/object/internals\";\n\nimport { modifier as eModifier } from \"ember-modifier\";\nimport { cell } from \"ember-resources\";\nimport { getTabster, getTabsterAttribute, MoverDirections, setTabsterAttribute } from \"tabster\";\n\nimport { Popover, type Signature as PopoverSignature } from \"./popover.gts\";\n\nimport type { TOC } from \"@ember/component/template-only\";\nimport type { WithBoundArgs } from \"@glint/template\";\n\ntype Cell<V> = ReturnType<typeof cell<V>>;\ntype PopoverArgs = PopoverSignature[\"Args\"];\ntype PopoverBlockParams = PopoverSignature[\"Blocks\"][\"default\"][0];\n\nconst TABSTER_CONFIG_CONTENT = getTabsterAttribute(\n {\n mover: {\n direction: MoverDirections.Both,\n cyclic: true,\n },\n deloser: {},\n },\n true,\n);\n\nconst TABSTER_CONFIG_TRIGGER = {\n deloser: {},\n};\n\nexport interface Signature {\n Args: PopoverArgs;\n Blocks: {\n default: [\n {\n arrow: PopoverBlockParams[\"arrow\"];\n trigger: WithBoundArgs<\n typeof trigger,\n \"triggerElement\" | \"contentId\" | \"isOpen\" | \"setReference\"\n >;\n Trigger: WithBoundArgs<typeof Trigger, \"triggerModifier\">;\n Content: WithBoundArgs<\n typeof Content,\n \"triggerElement\" | \"contentId\" | \"isOpen\" | \"PopoverContent\"\n >;\n isOpen: boolean;\n },\n ];\n };\n}\n\nexport interface SeparatorSignature {\n Element: HTMLDivElement;\n Blocks: { default: [] };\n}\n\nconst Separator: TOC<SeparatorSignature> = <template>\n <div role=\"separator\" ...attributes>\n {{yield}}\n </div>\n</template>;\n\n/**\n * We focus items on `pointerMove` to achieve the following:\n *\n * - Mouse over an item (it focuses)\n * - Leave mouse where it is and use keyboard to focus a different item\n * - Wiggle mouse without it leaving previously focused item\n * - Previously focused item should re-focus\n *\n * If we used `mouseOver`/`mouseEnter` it would not re-focus when the mouse\n * wiggles. This is to match native menu implementation.\n */\nfunction focusOnHover(e: PointerEvent) {\n const item = e.currentTarget;\n\n if (item instanceof HTMLElement) {\n item?.focus();\n }\n}\n\nexport interface ItemSignature {\n Element: HTMLButtonElement;\n Args: { onSelect?: (event: Event) => void };\n Blocks: { default: [] };\n}\n\nconst Item: TOC<ItemSignature> = <template>\n {{! @glint-expect-error }}\n {{#let (if @onSelect (modifier on \"click\" @onSelect)) as |maybeClick|}}\n <button\n type=\"button\"\n role=\"menuitem\"\n {{! @glint-expect-error }}\n {{maybeClick}}\n {{on \"pointermove\" focusOnHover}}\n ...attributes\n >\n {{yield}}\n </button>\n {{/let}}\n</template>;\n\nconst installContent = eModifier<{\n Element: HTMLElement;\n Args: {\n Named: {\n isOpen: Cell<boolean>;\n triggerElement: Cell<HTMLElement>;\n };\n };\n}>((element, _: [], { isOpen, triggerElement }) => {\n // focus first focusable element on the content\n const tabster = getTabster(window);\n const firstFocusable = tabster?.focusable.findFirst({\n container: element,\n });\n\n firstFocusable?.focus();\n\n // listen for \"outside\" clicks\n function onDocumentClick(e: MouseEvent) {\n if (\n isOpen.current &&\n e.target &&\n !element.contains(e.target as HTMLElement) &&\n !triggerElement.current?.contains(e.target as HTMLElement)\n ) {\n isOpen.current = false;\n }\n }\n\n // listen for the escape key\n function onDocumentKeydown(e: KeyboardEvent) {\n if (isOpen.current && e.key === \"Escape\") {\n isOpen.current = false;\n }\n }\n\n document.addEventListener(\"click\", onDocumentClick);\n document.addEventListener(\"keydown\", onDocumentKeydown);\n\n return () => {\n document.removeEventListener(\"click\", onDocumentClick);\n document.removeEventListener(\"keydown\", onDocumentKeydown);\n };\n});\n\ninterface PrivateContentSignature {\n Element: HTMLDivElement;\n Args: {\n triggerElement: Cell<HTMLElement>;\n contentId: string;\n isOpen: Cell<boolean>;\n PopoverContent: PopoverBlockParams[\"Content\"];\n };\n Blocks: { default: [{ Item: typeof Item; Separator: typeof Separator }] };\n}\n\nexport interface ContentSignature {\n Element: PrivateContentSignature[\"Element\"];\n Blocks: PrivateContentSignature[\"Blocks\"];\n}\n\nconst Content: TOC<PrivateContentSignature> = <template>\n {{#if @isOpen.current}}\n <@PopoverContent\n id={{@contentId}}\n role=\"menu\"\n data-tabster={{TABSTER_CONFIG_CONTENT}}\n tabindex=\"0\"\n {{installContent isOpen=@isOpen triggerElement=@triggerElement}}\n {{on \"click\" @isOpen.toggle}}\n ...attributes\n >\n {{yield (hash Item=Item Separator=Separator)}}\n </@PopoverContent>\n {{/if}}\n</template>;\n\ninterface PrivateTriggerModifierSignature {\n Element: HTMLElement;\n Args: {\n Named: {\n triggerElement: Cell<HTMLElement>;\n isOpen: Cell<boolean>;\n contentId: string;\n setReference: PopoverBlockParams[\"setReference\"];\n stopPropagation?: boolean;\n preventDefault?: boolean;\n };\n };\n}\n\nexport interface TriggerModifierSignature {\n Element: PrivateTriggerModifierSignature[\"Element\"];\n}\n\nconst trigger = eModifier<PrivateTriggerModifierSignature>(\n (\n element,\n _: [],\n { triggerElement, isOpen, contentId, setReference, stopPropagation, preventDefault },\n ) => {\n element.setAttribute(\"aria-haspopup\", \"menu\");\n\n if (isOpen.current) {\n element.setAttribute(\"aria-controls\", contentId);\n element.setAttribute(\"aria-expanded\", \"true\");\n } else {\n element.removeAttribute(\"aria-controls\");\n element.setAttribute(\"aria-expanded\", \"false\");\n }\n\n setTabsterAttribute(element, TABSTER_CONFIG_TRIGGER);\n\n const onTriggerClick = (event: MouseEvent) => {\n if (stopPropagation) {\n event.stopPropagation();\n }\n\n if (preventDefault) {\n event.preventDefault();\n }\n\n isOpen.toggle();\n };\n\n element.addEventListener(\"click\", onTriggerClick);\n\n triggerElement.current = element;\n // eslint-disable-next-line @typescript-eslint/no-unsafe-call\n setReference(element);\n\n return () => {\n element.removeEventListener(\"click\", onTriggerClick);\n };\n },\n);\n\ninterface PrivateTriggerSignature {\n Element: HTMLButtonElement;\n Args: {\n triggerModifier: WithBoundArgs<\n typeof trigger,\n \"triggerElement\" | \"contentId\" | \"isOpen\" | \"setReference\"\n >;\n stopPropagation?: boolean;\n preventDefault?: boolean;\n };\n Blocks: { default: [] };\n}\n\nexport interface TriggerSignature {\n Element: PrivateTriggerSignature[\"Element\"];\n Blocks: PrivateTriggerSignature[\"Blocks\"];\n}\n\nconst Trigger: TOC<PrivateTriggerSignature> = <template>\n <button\n type=\"button\"\n {{@triggerModifier stopPropagation=@stopPropagation preventDefault=@preventDefault}}\n ...attributes\n >\n {{yield}}\n </button>\n</template>;\n\nconst IsOpen = () => cell<boolean>(false);\nconst TriggerElement = () => cell<HTMLElement>();\n\nexport class Menu extends Component<Signature> {\n contentId = guidFor(this);\n\n <template>\n {{#let (IsOpen) (TriggerElement) as |isOpen triggerEl|}}\n <Popover\n @flipOptions={{@flipOptions}}\n @middleware={{@middleware}}\n @offsetOptions={{@offsetOptions}}\n @placement={{@placement}}\n @shiftOptions={{@shiftOptions}}\n @strategy={{@strategy}}\n @inline={{@inline}}\n as |p|\n >\n {{#let\n (modifier\n trigger\n triggerElement=triggerEl\n isOpen=isOpen\n contentId=this.contentId\n setReference=p.setReference\n )\n as |triggerModifier|\n }}\n {{yield\n (hash\n trigger=triggerModifier\n Trigger=(component Trigger triggerModifier=triggerModifier)\n Content=(component\n Content\n PopoverContent=p.Content\n isOpen=isOpen\n triggerElement=triggerEl\n contentId=this.contentId\n )\n arrow=p.arrow\n isOpen=isOpen.current\n )\n }}\n {{/let}}\n </Popover>\n {{/let}}\n </template>\n}\n\nexport default Menu;\n"],"names":["TABSTER_CONFIG_CONTENT","getTabsterAttribute","mover","direction","MoverDirections","Both","cyclic","deloser","TABSTER_CONFIG_TRIGGER","Separator","setComponentTemplate","precompileTemplate","strictMode","templateOnly","focusOnHover","e","item","currentTarget","HTMLElement","focus","Item","scope","on","installContent","eModifier","element","_","isOpen","triggerElement","tabster","getTabster","window","firstFocusable","focusable","findFirst","container","onDocumentClick","current","target","contains","onDocumentKeydown","key","document","addEventListener","removeEventListener","Content","hash","trigger","contentId","setReference","stopPropagation","preventDefault","setAttribute","removeAttribute","setTabsterAttribute","onTriggerClick","event","toggle","Trigger","IsOpen","cell","TriggerElement","Menu","Component","guidFor","Popover"],"mappings":"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"}
1
+ {"version":3,"file":"menu.js","sources":["../../src/components/menu.gts"],"sourcesContent":["import Component from \"@glimmer/component\";\nimport { hash } from \"@ember/helper\";\nimport { on } from \"@ember/modifier\";\nimport { guidFor } from \"@ember/object/internals\";\n\nimport { modifier as eModifier } from \"ember-modifier\";\nimport { cell } from \"ember-resources\";\nimport { getTabster, getTabsterAttribute, MoverDirections, setTabsterAttribute } from \"tabster\";\n\nimport { Popover, type Signature as PopoverSignature } from \"./popover.gts\";\n\nimport type { TOC } from \"@ember/component/template-only\";\nimport type { WithBoundArgs } from \"@glint/template\";\n\ntype Cell<V> = ReturnType<typeof cell<V>>;\ntype PopoverArgs = PopoverSignature[\"Args\"];\ntype PopoverBlockParams = PopoverSignature[\"Blocks\"][\"default\"][0];\n\nconst TABSTER_CONFIG_CONTENT = getTabsterAttribute(\n {\n mover: {\n direction: MoverDirections.Both,\n cyclic: true,\n },\n deloser: {},\n },\n true,\n);\n\nconst TABSTER_CONFIG_TRIGGER = {\n deloser: {},\n};\n\nexport interface Signature {\n Args: PopoverArgs;\n Blocks: {\n default: [\n {\n arrow: PopoverBlockParams[\"arrow\"];\n trigger: WithBoundArgs<\n typeof trigger,\n \"triggerElement\" | \"contentId\" | \"isOpen\" | \"setReference\"\n >;\n Trigger: WithBoundArgs<typeof Trigger, \"triggerModifier\">;\n Content: WithBoundArgs<\n typeof Content,\n \"triggerElement\" | \"contentId\" | \"isOpen\" | \"PopoverContent\"\n >;\n isOpen: boolean;\n },\n ];\n };\n}\n\nexport interface SeparatorSignature {\n Element: HTMLDivElement;\n Blocks: { default: [] };\n}\n\nconst Separator: TOC<SeparatorSignature> = <template>\n <div role=\"separator\" ...attributes>\n {{yield}}\n </div>\n</template>;\n\n/**\n * We focus items on `pointerMove` to achieve the following:\n *\n * - Mouse over an item (it focuses)\n * - Leave mouse where it is and use keyboard to focus a different item\n * - Wiggle mouse without it leaving previously focused item\n * - Previously focused item should re-focus\n *\n * If we used `mouseOver`/`mouseEnter` it would not re-focus when the mouse\n * wiggles. This is to match native menu implementation.\n */\nfunction focusOnHover(e: PointerEvent) {\n const item = e.currentTarget;\n\n if (item instanceof HTMLElement) {\n item?.focus();\n }\n}\n\nexport interface ItemSignature {\n Element: HTMLButtonElement;\n Args: { onSelect?: (event: Event) => void };\n Blocks: { default: [] };\n}\n\nconst Item: TOC<ItemSignature> = <template>\n {{! @glint-expect-error }}\n {{#let (if @onSelect (modifier on \"click\" @onSelect)) as |maybeClick|}}\n <button\n type=\"button\"\n role=\"menuitem\"\n {{! @glint-expect-error }}\n {{maybeClick}}\n {{on \"pointermove\" focusOnHover}}\n ...attributes\n >\n {{yield}}\n </button>\n {{/let}}\n</template>;\n\nconst installContent = eModifier<{\n Element: HTMLElement;\n Args: {\n Named: {\n isOpen: Cell<boolean>;\n triggerElement: Cell<HTMLElement>;\n };\n };\n}>((element, _: [], { isOpen, triggerElement }) => {\n // focus first focusable element on the content\n const tabster = getTabster(window);\n const firstFocusable = tabster?.focusable.findFirst({\n container: element,\n });\n\n firstFocusable?.focus();\n\n // listen for \"outside\" clicks\n function onDocumentClick(e: MouseEvent) {\n if (\n isOpen.current &&\n e.target &&\n !element.contains(e.target as HTMLElement) &&\n !triggerElement.current?.contains(e.target as HTMLElement)\n ) {\n isOpen.current = false;\n }\n }\n\n // listen for the escape key\n function onDocumentKeydown(e: KeyboardEvent) {\n if (isOpen.current && e.key === \"Escape\") {\n isOpen.current = false;\n }\n }\n\n document.addEventListener(\"click\", onDocumentClick);\n document.addEventListener(\"keydown\", onDocumentKeydown);\n\n return () => {\n document.removeEventListener(\"click\", onDocumentClick);\n document.removeEventListener(\"keydown\", onDocumentKeydown);\n };\n});\n\ninterface PrivateContentSignature {\n Element: HTMLDivElement;\n Args: {\n triggerElement: Cell<HTMLElement>;\n contentId: string;\n isOpen: Cell<boolean>;\n PopoverContent: PopoverBlockParams[\"Content\"];\n };\n Blocks: { default: [{ Item: typeof Item; Separator: typeof Separator }] };\n}\n\nexport interface ContentSignature {\n Element: PrivateContentSignature[\"Element\"];\n Blocks: PrivateContentSignature[\"Blocks\"];\n}\n\nconst Content: TOC<PrivateContentSignature> = <template>\n {{#if @isOpen.current}}\n <@PopoverContent\n id={{@contentId}}\n role=\"menu\"\n data-tabster={{TABSTER_CONFIG_CONTENT}}\n tabindex=\"0\"\n {{installContent isOpen=@isOpen triggerElement=@triggerElement}}\n {{on \"click\" @isOpen.toggle}}\n ...attributes\n >\n {{yield (hash Item=Item Separator=Separator)}}\n </@PopoverContent>\n {{/if}}\n</template>;\n\ninterface PrivateTriggerModifierSignature {\n Element: HTMLElement;\n Args: {\n Named: {\n triggerElement: Cell<HTMLElement>;\n isOpen: Cell<boolean>;\n contentId: string;\n setReference: PopoverBlockParams[\"setReference\"];\n stopPropagation?: boolean;\n preventDefault?: boolean;\n };\n };\n}\n\nexport interface TriggerModifierSignature {\n Element: PrivateTriggerModifierSignature[\"Element\"];\n}\n\nconst trigger = eModifier<PrivateTriggerModifierSignature>(\n (\n element,\n _: [],\n { triggerElement, isOpen, contentId, setReference, stopPropagation, preventDefault },\n ) => {\n element.setAttribute(\"aria-haspopup\", \"menu\");\n\n if (isOpen.current) {\n element.setAttribute(\"aria-controls\", contentId);\n element.setAttribute(\"aria-expanded\", \"true\");\n } else {\n element.removeAttribute(\"aria-controls\");\n element.setAttribute(\"aria-expanded\", \"false\");\n }\n\n setTabsterAttribute(element, TABSTER_CONFIG_TRIGGER);\n\n const onTriggerClick = (event: MouseEvent) => {\n if (stopPropagation) {\n event.stopPropagation();\n }\n\n if (preventDefault) {\n event.preventDefault();\n }\n\n isOpen.toggle();\n };\n\n element.addEventListener(\"click\", onTriggerClick);\n\n triggerElement.current = element;\n // eslint-disable-next-line @typescript-eslint/no-unsafe-call\n setReference(element);\n\n return () => {\n element.removeEventListener(\"click\", onTriggerClick);\n };\n },\n);\n\ninterface PrivateTriggerSignature {\n Element: HTMLButtonElement;\n Args: {\n triggerModifier: WithBoundArgs<\n typeof trigger,\n \"triggerElement\" | \"contentId\" | \"isOpen\" | \"setReference\"\n >;\n stopPropagation?: boolean;\n preventDefault?: boolean;\n };\n Blocks: { default: [] };\n}\n\nexport interface TriggerSignature {\n Element: PrivateTriggerSignature[\"Element\"];\n Blocks: PrivateTriggerSignature[\"Blocks\"];\n}\n\nconst Trigger: TOC<PrivateTriggerSignature> = <template>\n <button\n type=\"button\"\n {{@triggerModifier stopPropagation=@stopPropagation preventDefault=@preventDefault}}\n ...attributes\n >\n {{yield}}\n </button>\n</template>;\n\nconst IsOpen = () => cell<boolean>(false);\nconst TriggerElement = () => cell<HTMLElement>();\n\nexport class Menu extends Component<Signature> {\n contentId = guidFor(this);\n\n <template>\n {{#let (IsOpen) (TriggerElement) as |isOpen triggerEl|}}\n <Popover\n @flipOptions={{@flipOptions}}\n @middleware={{@middleware}}\n @offsetOptions={{@offsetOptions}}\n @placement={{@placement}}\n @shiftOptions={{@shiftOptions}}\n @strategy={{@strategy}}\n @inline={{@inline}}\n as |p|\n >\n {{#let\n (modifier\n trigger\n triggerElement=triggerEl\n isOpen=isOpen\n contentId=this.contentId\n setReference=p.setReference\n )\n as |triggerModifier|\n }}\n {{yield\n (hash\n trigger=triggerModifier\n Trigger=(component Trigger triggerModifier=triggerModifier)\n Content=(component\n Content\n PopoverContent=p.Content\n isOpen=isOpen\n triggerElement=triggerEl\n contentId=this.contentId\n )\n arrow=p.arrow\n isOpen=isOpen.current\n )\n }}\n {{/let}}\n </Popover>\n {{/let}}\n </template>\n}\n\nexport default Menu;\n"],"names":["TABSTER_CONFIG_CONTENT","getTabsterAttribute","mover","direction","MoverDirections","Both","cyclic","deloser","TABSTER_CONFIG_TRIGGER","Separator","setComponentTemplate","precompileTemplate","strictMode","templateOnly","focusOnHover","e","item","currentTarget","HTMLElement","focus","Item","scope","on","installContent","eModifier","element","_","isOpen","triggerElement","tabster","getTabster","window","firstFocusable","focusable","findFirst","container","onDocumentClick","current","target","contains","onDocumentKeydown","key","document","addEventListener","removeEventListener","Content","hash","trigger","contentId","setReference","stopPropagation","preventDefault","setAttribute","removeAttribute","setTabsterAttribute","onTriggerClick","event","toggle","Trigger","IsOpen","cell","TriggerElement","Menu","Component","guidFor","Popover"],"mappings":";;;;;;;;;;;;AAkBA,MAAMA,yBAAyBC,mBAAA,CAC7B;AACEC,EAAAA,KAAA,EAAO;IACLC,SAAA,EAAWC,gBAAgBC,IAAI;AAC/BC,IAAAA,MAAA,EAAQ;GACV;AACAC,EAAAA,OAAA,EAAS;AACX,CAAA,EACA,IAAA,CAAA;AAGF,MAAMC,sBAAA,GAAyB;AAC7BD,EAAAA,OAAA,EAAS;AACX,CAAA;AA4BA,MAAME,SAAe,GAAAC,oBAAA,CAAsBC,kBAAA,CAAA,uEAAA,EAI3C;EAAAC,UAAA,EAAA;AAAU,CAAA,CAAA,EAAAC,YAAA,EAAA,CAAA;AAEV;;;;;;;;;;;AAWA,SAASC,YAAAA,CAAaC,CAAe,EAAA;AACnC,EAAA,MAAMC,IAAA,GAAOD,EAAEE,aAAa;EAE5B,IAAID,gBAAgBE,WAAA,EAAa;IAC/BF,IAAA,EAAMG,KAAA,EAAA;AACR,EAAA;AACF;AAQA,MAAMC,IAAU,GAAAV,oBAAA,CAAiBC,kBAAA,CAAA,+SAAA,EAcjC;EAAAC,UAAA,EAAA,IAAA;AAAAS,EAAAA,KAAA,EAAAA,OAAA;IAAAC,EAAA;AAAAR,IAAAA;AAAA,GAAA;AAAU,CAAA,CAAA,EAAAD,YAAA,EAAA,CAAA;AAEV,MAAMU,cAAA,GAAiBC,QAAA,CAQpB,CAACC,SAASC,CAAA,EAAO;EAAEC,MAAM;AAAEC,EAAAA;AAAc,CAAE,KAAA;AAC5C;AACA,EAAA,MAAMC,UAAUC,UAAA,CAAWC,MAAA,CAAA;AAC3B,EAAA,MAAMC,cAAA,GAAiBH,OAAA,EAASI,SAAA,CAAUC,SAAA,CAAU;AAClDC,IAAAA,SAAA,EAAWV;AACb,GAAA,CAAA;EAEAO,cAAA,EAAgBb,KAAA,EAAA;AAEhB;EACA,SAASiB,eAAAA,CAAgBrB,CAAa,EAAA;AACpC,IAAA,IACEY,MAAA,CAAOU,OAAO,IACdtB,CAAA,CAAEuB,MAAM,IACR,CAACb,OAAA,CAAQc,QAAQ,CAACxB,CAAA,CAAEuB,MAAU,CAAA,IAC9B,CAACV,cAAA,CAAeS,OAAO,EAAEE,QAAA,CAASxB,CAAA,CAAEuB,MAAU,CAAA,EAC9C;MACAX,MAAA,CAAOU,OAAO,GAAG,KAAA;AACnB,IAAA;AACF,EAAA;AAEA;EACA,SAASG,iBAAAA,CAAkBzB,CAAgB,EAAA;IACzC,IAAIY,OAAOU,OAAO,IAAItB,CAAA,CAAE0B,GAAG,KAAK,QAAA,EAAU;MACxCd,MAAA,CAAOU,OAAO,GAAG,KAAA;AACnB,IAAA;AACF,EAAA;AAEAK,EAAAA,QAAA,CAASC,gBAAgB,CAAC,OAAA,EAASP,eAAA,CAAA;AACnCM,EAAAA,QAAA,CAASC,gBAAgB,CAAC,SAAA,EAAWH,iBAAA,CAAA;AAErC,EAAA,OAAO,MAAA;AACLE,IAAAA,QAAA,CAASE,mBAAmB,CAAC,OAAA,EAASR,eAAA,CAAA;AACtCM,IAAAA,QAAA,CAASE,mBAAmB,CAAC,SAAA,EAAWJ,iBAAA,CAAA;EAC1C,CAAA;AACF,CAAA,CAAA;AAkBA,MAAMK,OAAa,GAAAnC,oBAAA,CAA2BC,kBAAA,CAAA,qVAAA,EAc9C;EAAAC,UAAA,EAAA,IAAA;AAAAS,EAAAA,KAAA,EAAAA,OAAA;IAAArB,sBAAA;IAAAuB,cAAA;IAAAD,EAAA;IAAAwB,IAAA;IAAA1B,IAAA;AAAAX,IAAAA;AAAA,GAAA;AAAU,CAAA,CAAA,EAAAI,YAAA,EAAA,CAAA;AAoBV,MAAMkC,UAAUvB,QAAA,CACd,CACEC,OAAA,EACAC,CAAA,EACA;EAAEE,cAAc;EAAED,MAAM;EAAEqB,SAAS;EAAEC,YAAY;EAAEC,eAAe;AAAEC,EAAAA;AAAc,CAAE,KAAA;AAEpF1B,EAAAA,OAAA,CAAQ2B,YAAY,CAAC,eAAA,EAAiB,MAAA,CAAA;EAEtC,IAAIzB,MAAA,CAAOU,OAAO,EAAE;AAClBZ,IAAAA,OAAA,CAAQ2B,YAAY,CAAC,eAAA,EAAiBJ,SAAA,CAAA;AACtCvB,IAAAA,OAAA,CAAQ2B,YAAY,CAAC,eAAA,EAAiB,MAAA,CAAA;AACxC,EAAA,CAAA,MAAO;AACL3B,IAAAA,OAAA,CAAQ4B,eAAe,CAAC,eAAA,CAAA;AACxB5B,IAAAA,OAAA,CAAQ2B,YAAY,CAAC,eAAA,EAAiB,OAAA,CAAA;AACxC,EAAA;AAEAE,EAAAA,mBAAA,CAAoB7B,OAAA,EAASjB,sBAAA,CAAA;EAE7B,MAAM+C,cAAA,GAAkBC,KAAO,IAAA;AAC7B,IAAA,IAAIN,eAAA,EAAiB;MACnBM,KAAA,CAAMN,eAAe,EAAA;AACvB,IAAA;AAEA,IAAA,IAAIC,cAAA,EAAgB;MAClBK,KAAA,CAAML,cAAc,EAAA;AACtB,IAAA;IAEAxB,MAAA,CAAO8B,MAAM,EAAA;EACf,CAAA;AAEAhC,EAAAA,OAAA,CAAQkB,gBAAgB,CAAC,OAAA,EAASY,cAAA,CAAA;EAElC3B,cAAA,CAAeS,OAAO,GAAGZ,OAAA;AACzB;EACAwB,YAAA,CAAaxB,OAAA,CAAA;AAEb,EAAA,OAAO,MAAA;AACLA,IAAAA,OAAA,CAAQmB,mBAAmB,CAAC,OAAA,EAASW,cAAA,CAAA;EACvC,CAAA;AACF,CAAA,CAAA;AAqBF,MAAMG,OAAa,GAAAhD,oBAAA,CAA2BC,kBAAA,CAAA,+JAAA,EAQ9C;EAAAC,UAAA,EAAA;AAAU,CAAA,CAAA,EAAAC,YAAA,EAAA,CAAA;AAEV,MAAM8C,MAAA,GAASA,MAAMC,IAAA,CAAc,KAAA,CAAA;AACnC,MAAMC,cAAA,GAAiBA,MAAMD,IAAA,EAAK;AAE3B,MAAME,aAAaC,SAAA,CAAU;AAClCf,EAAAA,SAAA,GAAYgB,OAAA,CAAQ,IAAI,CAAA;AAExB,EAAA;IAAAtD,oBAAA,CAAAC,kBAAA,CAAA,+uBAAA,EAwCA;MAAAC,UAAA,EAAA,IAAA;AAAAS,MAAAA,KAAA,EAAAA,OAAA;QAAAsC,MAAA;QAAAE,cAAA;QAAAI,OAAA;QAAAlB,OAAA;QAAAD,IAAA;QAAAY,OAAA;AAAAb,QAAAA;AAAA,OAAA;KAAU,CAAA,EAAV,IAAW,CAAA;AAAD;AACZ;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"input.js","sources":["../../../src/components/one-time-password/input.gts"],"sourcesContent":["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"],"names":["DEFAULT_LENGTH","labelFor","inputIndex","labelFn","waiter","buildWaiter","Fields","setComponentTemplate","precompileTemplate","strictMode","scope","on","selectAll","handlePaste","autoAdvance","handleNavigation","templateOnly","OTPInput","Component","handleChange","event","args","onChange","beginAsync","cancelAnimationFrame","requestAnimationFrame","endAsync","isDestroyed","isDestroying","value","getCollectiveValue","target","length","undefined","warn","id","code","complete","fields","Array"],"mappings":";;;;;;;;;;AAiBA,MAAMA,cAAA,GAAiB,CAAA;AAEvB,SAASC,QAAAA,CAASC,UAAkB,EAAEC,OAAgD,EAAA;AACpF,EAAA,IAAIA,OAAA,EAAS;IACX,OAAOA,OAAA,CAAQD,UAAA,CAAA;AACjB;AAEA,EAAA,OAAO,CAAA,2BAAA,EAA8BA,UAAA,GAAa,GAAG;AACvD;AAEA,MAAME,SAASC,WAAA,CAAY,wCAAA,CAAA;AAE3B,MAAMC,MAUD,GAAAC,oBAAA,CAAAC,kBAAA,CAAA,kaAAA,EAkBL;EAAAC,UAAA,EAAA,IAAA;AAAAC,EAAAA,KAAA,EAAAA,OAAA;IAAAT,QAAA;IAAAU,EAAA;IAAAC,SAAA;IAAAC,WAAA;IAAAC,WAAA;AAAAC,IAAAA;AAAA,GAAA;AAAU,CAAA,CAAA,EAAAC,YAAA,EAAA,CAAA;AAEH,MAAMC,QAAA,SAAiBC,SAAA;AAsD5B;;;;;EAKAC,YAAA,GAAgBC,KAAO,IAAA;AACrB,IAAA,IAAI,CAAC,IAAI,CAACC,IAAI,CAACC,QAAQ,EAAE;AAEzB,IAAA,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE;MAChB,IAAI,CAAC,MAAM,GAAGlB,OAAOmB,UAAU,EAAA;AACjC;AAEA,IAAA,IAAI,IAAI,CAAC,MAAM,EAAE;AACfC,MAAAA,oBAAA,CAAqB,IAAI,CAAC,MAAM,CAAA;AAClC;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,IAAA,IAAI,CAAC,MAAM,GAAGC,qBAAA,CAAsB,MAAA;AAClCrB,MAAAA,MAAA,CAAOsB,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAA;MAE3B,IAAIC,WAAA,CAAY,IAAI,CAAA,IAAKC,YAAA,CAAa,IAAI,CAAA,EAAG;AAC7C,MAAA,IAAI,CAAC,IAAI,CAACP,IAAI,CAACC,QAAQ,EAAE;MAEzB,MAAMO,QAAQC,kBAAA,CAAmBV,KAAA,CAAMW,MAAM,EAAE,IAAI,CAACC,MAAM,CAAA;MAE1D,IAAIH,UAAUI,SAAA,EAAW;QACvBC,IAAA,CAAK,+EAA+E,EAAE;AACpFC,UAAAA,EAAA,EAAI;AACN,SAAA,CAAA;AAEA,QAAA;AACF;AAEA,MAAA,IAAI,CAACd,IAAI,CAACC,QAAQ,CAAC;AAAEc,QAAAA,IAAA,EAAMP,KAAA;AAAOQ,QAAAA,QAAA,EAAUR,KAAA,CAAMG,MAAM,KAAK,IAAI,CAACA;OAAO,EAAGZ,KAAA,CAAA;AAC9E,KAAA,CAAA;GACF;AAEA,EAAA,MAAM;AACN,EAAA,MAAM;EAEN,IAAIY,MAAAA,GAAS;AACX,IAAA,OAAO,IAAI,CAACX,IAAI,CAACW,MAAM,IAAIhC,cAAA;AAC7B;EAEA,IAAIsC,MAAAA,GAAS;AACX;AACA;AACA;AACA,IAAA,OAAO,IAAIC,KAAA,CAAiB,IAAI,CAACP,MAAM,CAAA;AACzC;AAEA,EAAA;IAAAzB,oBAAA,CAAAC,kBAAA,CAAA,0oBAAA,EA2BA;MAAAC,UAAA,EAAA,IAAA;AAAAC,MAAAA,KAAA,EAAAA,OAAA;AAAAJ,QAAAA;AAAA,OAAA;KAAU,CAAA,EAAV,IAAW,CAAA;AAAD;AACZ;;;;"}
1
+ {"version":3,"file":"input.js","sources":["../../../src/components/one-time-password/input.gts"],"sourcesContent":["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"],"names":["DEFAULT_LENGTH","labelFor","inputIndex","labelFn","waiter","buildWaiter","Fields","setComponentTemplate","precompileTemplate","strictMode","scope","on","selectAll","handlePaste","autoAdvance","handleNavigation","templateOnly","OTPInput","Component","handleChange","event","args","onChange","beginAsync","cancelAnimationFrame","requestAnimationFrame","endAsync","isDestroyed","isDestroying","value","getCollectiveValue","target","length","undefined","warn","id","code","complete","fields","Array"],"mappings":";;;;;;;;;;AAiBA,MAAMA,cAAA,GAAiB,CAAA;AAEvB,SAASC,QAAAA,CAASC,UAAkB,EAAEC,OAAgD,EAAA;AACpF,EAAA,IAAIA,OAAA,EAAS;IACX,OAAOA,OAAA,CAAQD,UAAA,CAAA;AACjB,EAAA;AAEA,EAAA,OAAO,CAAA,2BAAA,EAA8BA,UAAA,GAAa,GAAG;AACvD;AAEA,MAAME,SAASC,WAAA,CAAY,wCAAA,CAAA;AAE3B,MAAMC,MAUD,GAAAC,oBAAA,CAAAC,kBAAA,CAAA,kaAAA,EAkBL;EAAAC,UAAA,EAAA,IAAA;AAAAC,EAAAA,KAAA,EAAAA,OAAA;IAAAT,QAAA;IAAAU,EAAA;IAAAC,SAAA;IAAAC,WAAA;IAAAC,WAAA;AAAAC,IAAAA;AAAA,GAAA;AAAU,CAAA,CAAA,EAAAC,YAAA,EAAA,CAAA;AAEH,MAAMC,QAAA,SAAiBC,SAAA;AAsD5B;;;;;EAKAC,YAAA,GAAgBC,KAAO,IAAA;AACrB,IAAA,IAAI,CAAC,IAAI,CAACC,IAAI,CAACC,QAAQ,EAAE;AAEzB,IAAA,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE;MAChB,IAAI,CAAC,MAAM,GAAGlB,OAAOmB,UAAU,EAAA;AACjC,IAAA;AAEA,IAAA,IAAI,IAAI,CAAC,MAAM,EAAE;AACfC,MAAAA,oBAAA,CAAqB,IAAI,CAAC,MAAM,CAAA;AAClC,IAAA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,IAAA,IAAI,CAAC,MAAM,GAAGC,qBAAA,CAAsB,MAAA;AAClCrB,MAAAA,MAAA,CAAOsB,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAA;MAE3B,IAAIC,WAAA,CAAY,IAAI,CAAA,IAAKC,YAAA,CAAa,IAAI,CAAA,EAAG;AAC7C,MAAA,IAAI,CAAC,IAAI,CAACP,IAAI,CAACC,QAAQ,EAAE;MAEzB,MAAMO,QAAQC,kBAAA,CAAmBV,KAAA,CAAMW,MAAM,EAAE,IAAI,CAACC,MAAM,CAAA;MAE1D,IAAIH,UAAUI,SAAA,EAAW;QACvBC,IAAA,CAAK,+EAA+E,EAAE;AACpFC,UAAAA,EAAA,EAAI;AACN,SAAA,CAAA;AAEA,QAAA;AACF,MAAA;AAEA,MAAA,IAAI,CAACd,IAAI,CAACC,QAAQ,CAAC;AAAEc,QAAAA,IAAA,EAAMP,KAAA;AAAOQ,QAAAA,QAAA,EAAUR,KAAA,CAAMG,MAAM,KAAK,IAAI,CAACA;OAAO,EAAGZ,KAAA,CAAA;AAC9E,IAAA,CAAA,CAAA;EACF,CAAA;AAEA,EAAA,MAAM;AACN,EAAA,MAAM;EAEN,IAAIY,MAAAA,GAAS;AACX,IAAA,OAAO,IAAI,CAACX,IAAI,CAACW,MAAM,IAAIhC,cAAA;AAC7B,EAAA;EAEA,IAAIsC,MAAAA,GAAS;AACX;AACA;AACA;AACA,IAAA,OAAO,IAAIC,KAAA,CAAiB,IAAI,CAACP,MAAM,CAAA;AACzC,EAAA;AAEA,EAAA;IAAAzB,oBAAA,CAAAC,kBAAA,CAAA,0oBAAA,EA2BA;MAAAC,UAAA,EAAA,IAAA;AAAAC,MAAAA,KAAA,EAAAA,OAAA;AAAAJ,QAAAA;AAAA,OAAA;KAAU,CAAA,EAAV,IAAW,CAAA;AAAD;AACZ;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"otp.js","sources":["../../../src/components/one-time-password/otp.gts"],"sourcesContent":["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":["waiter","buildWaiter","handleFormSubmit","submit","event","preventDefault","assert","currentTarget","HTMLFormElement","formData","FormData","code","key","value","entries","startsWith","handleChange","autoSubmit","data","complete","target","HTMLElement","SVGElement","form","closest","token","beginAsync","finished","endAsync","removeEventListener","addEventListener","requestSubmit","OTP","setComponentTemplate","precompileTemplate","strictMode","scope","on","fn","hash","OTPInput","Submit","Reset","templateOnly"],"mappings":";;;;;;;;;;AAWA,MAAMA,SAASC,WAAA,CAAY,8CAAA,CAAA;AAE3B,MAAMC,gBAAA,GAAmBA,CAACC,MAAwC,EAAEC,KAAO,KAAA;EACzEA,KAAA,CAAMC,cAAc,EAAA;EAEpBC,MAAA,CACE,2EAAA,EACAF,KAAA,CAAMG,aAAa,YAAYC,eAAA,CAAA;EAGjC,MAAMC,QAAA,GAAW,IAAIC,QAAA,CAASN,KAAA,CAAMG,aAAa,CAAA;EAEjD,IAAII,IAAA,GAAO,EAAA;AAEX,EAAA,KAAK,MAAM,CAACC,GAAA,EAAKC,MAAM,IAAIJ,QAAA,CAASK,OAAO,EAAA,EAAI;AAC7C,IAAA,IAAIF,GAAA,CAAIG,UAAU,CAAC,MAAA,CAAA,EAAS;AAC1B;AACAJ,MAAAA,IAAA,IAAQE,KAAA;AACV;AACF;AAEAV,EAAAA,MAAA,CAAO;AACLQ,IAAAA;AACF,GAAA,CAAA;AACF,CAAA;AAEA,SAASK,YAAAA,CACPC,UAA+B,EAC/BC,IAAyC,EACzCd,KAAY,EAAA;EAEZ,IAAI,CAACa,UAAA,EAAY;AACjB,EAAA,IAAI,CAACC,IAAA,CAAKC,QAAQ,EAAE;AAEpBb,EAAAA,MAAA,CACE,mDACAF,KAAA,CAAMgB,MAAM,YAAYC,WAAA,IAAejB,KAAA,CAAMgB,MAAM,YAAYE,UAAA,CAAA;EAGjE,MAAMC,IAAA,GAAOnB,KAAA,CAAMgB,MAAM,CAACI,OAAO,CAAC,MAAA,CAAA;AAElClB,EAAAA,MAAA,CAAO,mFAAA,EAAqFiB,IAAA,CAAA;AAE5F,EAAA,MAAME,KAAA,GAAQzB,OAAO0B,UAAU,EAAA;EAC/B,MAAMC,QAAA,GAAWA,MAAA;AACf3B,IAAAA,MAAA,CAAO4B,QAAQ,CAACH,KAAA,CAAA;AAChBF,IAAAA,IAAA,CAAKM,mBAAmB,CAAC,QAAA,EAAUF,QAAA,CAAA;GACrC;AAEAJ,EAAAA,IAAA,CAAKO,gBAAgB,CAAC,QAAA,EAAUH,QAAA,CAAA;AAEhC;EACAJ,IAAA,CAAKQ,aAAa,EAAA;AACpB;MAEaC,GAmDR,GAAAC,oBAAA,CAAAC,kBAAA,CAAA,2OAAA,EAYL;EAAAC,UAAA,EAAA,IAAA;AAAAC,EAAAA,KAAA,EAAAA,OAAA;IAAAC,EAAA;IAAAC,EAAA;IAAApC,gBAAA;IAAAqC,IAAA;IAAAC,QAAA;IAAAxB,YAAA;IAAAyB,MAAA;AAAAC,IAAAA;AAAA,GAAA;AAAU,CAAA,CAAA,EAAAC,YAAA,EAAA;;;;"}
1
+ {"version":3,"file":"otp.js","sources":["../../../src/components/one-time-password/otp.gts"],"sourcesContent":["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":["waiter","buildWaiter","handleFormSubmit","submit","event","preventDefault","assert","currentTarget","HTMLFormElement","formData","FormData","code","key","value","entries","startsWith","handleChange","autoSubmit","data","complete","target","HTMLElement","SVGElement","form","closest","token","beginAsync","finished","endAsync","removeEventListener","addEventListener","requestSubmit","OTP","setComponentTemplate","precompileTemplate","strictMode","scope","on","fn","hash","OTPInput","Submit","Reset","templateOnly"],"mappings":";;;;;;;;;;AAWA,MAAMA,SAASC,WAAA,CAAY,8CAAA,CAAA;AAE3B,MAAMC,gBAAA,GAAmBA,CAACC,MAAwC,EAAEC,KAAO,KAAA;EACzEA,KAAA,CAAMC,cAAc,EAAA;EAEpBC,MAAA,CACE,2EAAA,EACAF,KAAA,CAAMG,aAAa,YAAYC,eAAA,CAAA;EAGjC,MAAMC,QAAA,GAAW,IAAIC,QAAA,CAASN,KAAA,CAAMG,aAAa,CAAA;EAEjD,IAAII,IAAA,GAAO,EAAA;AAEX,EAAA,KAAK,MAAM,CAACC,GAAA,EAAKC,MAAM,IAAIJ,QAAA,CAASK,OAAO,EAAA,EAAI;AAC7C,IAAA,IAAIF,GAAA,CAAIG,UAAU,CAAC,MAAA,CAAA,EAAS;AAC1B;AACAJ,MAAAA,IAAA,IAAQE,KAAA;AACV,IAAA;AACF,EAAA;AAEAV,EAAAA,MAAA,CAAO;AACLQ,IAAAA;AACF,GAAA,CAAA;AACF,CAAA;AAEA,SAASK,YAAAA,CACPC,UAA+B,EAC/BC,IAAyC,EACzCd,KAAY,EAAA;EAEZ,IAAI,CAACa,UAAA,EAAY;AACjB,EAAA,IAAI,CAACC,IAAA,CAAKC,QAAQ,EAAE;AAEpBb,EAAAA,MAAA,CACE,mDACAF,KAAA,CAAMgB,MAAM,YAAYC,WAAA,IAAejB,KAAA,CAAMgB,MAAM,YAAYE,UAAA,CAAA;EAGjE,MAAMC,IAAA,GAAOnB,KAAA,CAAMgB,MAAM,CAACI,OAAO,CAAC,MAAA,CAAA;AAElClB,EAAAA,MAAA,CAAO,mFAAA,EAAqFiB,IAAA,CAAA;AAE5F,EAAA,MAAME,KAAA,GAAQzB,OAAO0B,UAAU,EAAA;EAC/B,MAAMC,QAAA,GAAWA,MAAA;AACf3B,IAAAA,MAAA,CAAO4B,QAAQ,CAACH,KAAA,CAAA;AAChBF,IAAAA,IAAA,CAAKM,mBAAmB,CAAC,QAAA,EAAUF,QAAA,CAAA;EACrC,CAAA;AAEAJ,EAAAA,IAAA,CAAKO,gBAAgB,CAAC,QAAA,EAAUH,QAAA,CAAA;AAEhC;EACAJ,IAAA,CAAKQ,aAAa,EAAA;AACpB;MAEaC,GAmDR,GAAAC,oBAAA,CAAAC,kBAAA,CAAA,2OAAA,EAYL;EAAAC,UAAA,EAAA,IAAA;AAAAC,EAAAA,KAAA,EAAAA,OAAA;IAAAC,EAAA;IAAAC,EAAA;IAAApC,gBAAA;IAAAqC,IAAA;IAAAC,QAAA;IAAAxB,YAAA;IAAAyB,MAAA;AAAAC,IAAAA;AAAA,GAAA;AAAU,CAAA,CAAA,EAAAC,YAAA,EAAA;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"utils.js","sources":["../../../src/components/one-time-password/utils.ts"],"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"],"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"],"mappings":"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"}
1
+ {"version":3,"file":"utils.js","sources":["../../../src/components/one-time-password/utils.ts"],"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"],"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"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"popover.js","sources":["../../src/components/popover.gts"],"sourcesContent":["import { hash } from \"@ember/helper\";\n\nimport { arrow } from \"@floating-ui/dom\";\nimport { element } from \"ember-element-helper\";\nimport { modifier as eModifier } from \"ember-modifier\";\nimport { cell } from \"ember-resources\";\n\nimport { FloatingUI } from \"../floating-ui.ts\";\nimport { Portal } from \"./portal.gts\";\nimport { TARGETS } from \"./portal-targets.gts\";\n\nimport type { Signature as FloatingUiComponentSignature } from \"../floating-ui/component.ts\";\nimport type { Signature as HookSignature } from \"../floating-ui/modifier.ts\";\nimport type { TOC } from \"@ember/component/template-only\";\nimport type { ElementContext, Middleware } from \"@floating-ui/dom\";\nimport type { ModifierLike, WithBoundArgs } from \"@glint/template\";\n\nexport interface Signature {\n Args: {\n /**\n * See the Floating UI's [flip docs](https://floating-ui.com/docs/flip) for possible values.\n *\n * This argument is forwarded to the `<FloatingUI>` component.\n */\n flipOptions?: HookSignature[\"Args\"][\"Named\"][\"flipOptions\"];\n /**\n * Array of one or more objects to add to Floating UI's list of [middleware](https://floating-ui.com/docs/middleware)\n *\n * This argument is forwarded to the `<FloatingUI>` component.\n */\n middleware?: HookSignature[\"Args\"][\"Named\"][\"middleware\"];\n /**\n * See the Floating UI's [offset docs](https://floating-ui.com/docs/offset) for possible values.\n *\n * This argument is forwarded to the `<FloatingUI>` component.\n */\n offsetOptions?: HookSignature[\"Args\"][\"Named\"][\"offsetOptions\"];\n /**\n * One of the possible [`placements`](https://floating-ui.com/docs/computeposition#placement). The default is 'bottom'.\n *\n * Possible values are\n * - top\n * - bottom\n * - right\n * - left\n *\n * And may optionally have `-start` or `-end` added to adjust position along the side.\n *\n * This argument is forwarded to the `<FloatingUI>` component.\n */\n placement?: `${\"top\" | \"bottom\" | \"left\" | \"right\"}${\"\" | \"-start\" | \"-end\"}`;\n /**\n * See the Floating UI's [shift docs](https://floating-ui.com/docs/shift) for possible values.\n *\n * This argument is forwarded to the `<FloatingUI>` component.\n */\n shiftOptions?: HookSignature[\"Args\"][\"Named\"][\"shiftOptions\"];\n /**\n * CSS position property, either `fixed` or `absolute`.\n *\n * Pros and cons of each strategy are explained on [Floating UI's Docs](https://floating-ui.com/docs/computePosition#strategy)\n *\n * This argument is forwarded to the `<FloatingUI>` component.\n */\n strategy?: HookSignature[\"Args\"][\"Named\"][\"strategy\"];\n\n /**\n * By default, the popover is portaled.\n * If you don't control your CSS, and the positioning of the popover content\n * is misbehaving, you may pass \"@inline={{true}}\" to opt out of portalling.\n *\n * Inline may also be useful in nested menus, where you know exactly how the nesting occurs\n */\n inline?: boolean;\n };\n Blocks: {\n default: [\n {\n reference: FloatingUiComponentSignature[\"Blocks\"][\"default\"][0];\n setReference: FloatingUiComponentSignature[\"Blocks\"][\"default\"][2][\"setReference\"];\n Content: WithBoundArgs<typeof Content, \"floating\">;\n data: FloatingUiComponentSignature[\"Blocks\"][\"default\"][2][\"data\"];\n arrow: ModifierLike<{ Element: HTMLElement }>;\n },\n ];\n };\n}\n\nfunction getElementTag(tagName: undefined | string) {\n return tagName || \"div\";\n}\n\n/**\n * Allows lazy evaluation of the portal target (do nothing until rendered)\n * This is useful because the algorithm for finding the portal target isn't cheap.\n */\nconst Content: TOC<{\n Element: HTMLDivElement;\n Args: {\n floating: ModifierLike<{ Element: HTMLElement }>;\n inline?: boolean;\n /**\n * By default the popover content is wrapped in a div.\n * You may change this by supplying the name of an element here.\n *\n * For example:\n * ```gjs\n * <Popover as |p|>\n * <p.Content @as=\"dialog\">\n * this is now focus trapped\n * </p.Content>\n * </Popover>\n * ```\n */\n as?: string;\n };\n Blocks: { default: [] };\n}> = <template>\n {{#let (element (getElementTag @as)) as |El|}}\n {{#if @inline}}\n {{! @glint-ignore\n https://github.com/tildeio/ember-element-helper/issues/91\n https://github.com/typed-ember/glint/issues/610\n }}\n <El {{@floating}} ...attributes>\n {{yield}}\n </El>\n {{else}}\n <Portal @to={{TARGETS.popover}}>\n {{! @glint-ignore\n https://github.com/tildeio/ember-element-helper/issues/91\n https://github.com/typed-ember/glint/issues/610\n }}\n <El {{@floating}} ...attributes>\n {{yield}}\n </El>\n </Portal>\n {{/if}}\n {{/let}}\n</template>;\n\ninterface AttachArrowSignature {\n Element: HTMLElement;\n Args: {\n Named: {\n arrowElement: ReturnType<typeof ArrowElement>;\n data:\n | undefined\n | {\n placement: string;\n middlewareData?: {\n arrow?: { x?: number; y?: number };\n };\n };\n };\n };\n}\n\nconst arrowSides = {\n top: \"bottom\",\n right: \"left\",\n bottom: \"top\",\n left: \"right\",\n};\n\ntype Direction = \"top\" | \"bottom\" | \"left\" | \"right\";\ntype Placement = `${Direction}${\"\" | \"-start\" | \"-end\"}`;\n\nconst attachArrow: ModifierLike<AttachArrowSignature> = eModifier<AttachArrowSignature>(\n (element, _: [], named) => {\n if (element === named.arrowElement.current) {\n if (!named.data) return;\n if (!named.data.middlewareData) return;\n\n const { arrow } = named.data.middlewareData;\n const { placement } = named.data;\n\n if (!arrow) return;\n if (!placement) return;\n\n const { x: arrowX, y: arrowY } = arrow;\n const otherSide = (placement as Placement).split(\"-\")[0] as Direction;\n const staticSide = arrowSides[otherSide];\n\n Object.assign(named.arrowElement.current.style, {\n left: arrowX != null ? `${arrowX}px` : \"\",\n top: arrowY != null ? `${arrowY}px` : \"\",\n right: \"\",\n bottom: \"\",\n [staticSide]: \"-4px\",\n });\n\n return;\n }\n\n void (async () => {\n await Promise.resolve();\n named.arrowElement.set(element);\n })();\n },\n);\n\nconst ArrowElement: () => ReturnType<typeof cell<HTMLElement>> = () => cell<HTMLElement>();\n\nfunction maybeAddArrow(middleware: Middleware[] | undefined, element: Element | undefined) {\n const result = [...(middleware || [])];\n\n if (element) {\n result.push(arrow({ element }));\n }\n\n return result;\n}\n\nfunction flipOptions(options: HookSignature[\"Args\"][\"Named\"][\"flipOptions\"]) {\n return {\n elementContext: \"reference\" as ElementContext,\n ...options,\n };\n}\n\nexport const Popover: TOC<Signature> = <template>\n {{#let (ArrowElement) as |arrowElement|}}\n <FloatingUI\n @placement={{@placement}}\n @strategy={{@strategy}}\n @middleware={{maybeAddArrow @middleware arrowElement.current}}\n @flipOptions={{flipOptions @flipOptions}}\n @shiftOptions={{@shiftOptions}}\n @offsetOptions={{@offsetOptions}}\n as |reference floating extra|\n >\n {{#let (modifier attachArrow arrowElement=arrowElement data=extra.data) as |arrow|}}\n {{yield\n (hash\n reference=reference\n setReference=extra.setReference\n Content=(component Content floating=floating inline=@inline)\n data=extra.data\n arrow=arrow\n )\n }}\n {{/let}}\n </FloatingUI>\n {{/let}}\n</template>;\n\nexport default Popover;\n"],"names":["getElementTag","tagName","Content","setComponentTemplate","precompileTemplate","strictMode","scope","element","Portal","TARGETS","templateOnly","arrowSides","top","right","bottom","left","attachArrow","eModifier","_","named","arrowElement","current","data","middlewareData","arrow","placement","x","arrowX","y","arrowY","otherSide","split","staticSide","Object","assign","style","Promise","resolve","set","ArrowElement","cell","maybeAddArrow","middleware","result","push","flipOptions","options","elementContext","Popover","FloatingUI","hash"],"mappings":"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"}
1
+ {"version":3,"file":"popover.js","sources":["../../src/components/popover.gts"],"sourcesContent":["import { hash } from \"@ember/helper\";\n\nimport { arrow } from \"@floating-ui/dom\";\nimport { element } from \"ember-element-helper\";\nimport { modifier as eModifier } from \"ember-modifier\";\nimport { cell } from \"ember-resources\";\n\nimport { FloatingUI } from \"../floating-ui.ts\";\nimport { Portal } from \"./portal.gts\";\nimport { TARGETS } from \"./portal-targets.gts\";\n\nimport type { Signature as FloatingUiComponentSignature } from \"../floating-ui/component.ts\";\nimport type { Signature as HookSignature } from \"../floating-ui/modifier.ts\";\nimport type { TOC } from \"@ember/component/template-only\";\nimport type { ElementContext, Middleware } from \"@floating-ui/dom\";\nimport type { ModifierLike, WithBoundArgs } from \"@glint/template\";\n\nexport interface Signature {\n Args: {\n /**\n * See the Floating UI's [flip docs](https://floating-ui.com/docs/flip) for possible values.\n *\n * This argument is forwarded to the `<FloatingUI>` component.\n */\n flipOptions?: HookSignature[\"Args\"][\"Named\"][\"flipOptions\"];\n /**\n * Array of one or more objects to add to Floating UI's list of [middleware](https://floating-ui.com/docs/middleware)\n *\n * This argument is forwarded to the `<FloatingUI>` component.\n */\n middleware?: HookSignature[\"Args\"][\"Named\"][\"middleware\"];\n /**\n * See the Floating UI's [offset docs](https://floating-ui.com/docs/offset) for possible values.\n *\n * This argument is forwarded to the `<FloatingUI>` component.\n */\n offsetOptions?: HookSignature[\"Args\"][\"Named\"][\"offsetOptions\"];\n /**\n * One of the possible [`placements`](https://floating-ui.com/docs/computeposition#placement). The default is 'bottom'.\n *\n * Possible values are\n * - top\n * - bottom\n * - right\n * - left\n *\n * And may optionally have `-start` or `-end` added to adjust position along the side.\n *\n * This argument is forwarded to the `<FloatingUI>` component.\n */\n placement?: `${\"top\" | \"bottom\" | \"left\" | \"right\"}${\"\" | \"-start\" | \"-end\"}`;\n /**\n * See the Floating UI's [shift docs](https://floating-ui.com/docs/shift) for possible values.\n *\n * This argument is forwarded to the `<FloatingUI>` component.\n */\n shiftOptions?: HookSignature[\"Args\"][\"Named\"][\"shiftOptions\"];\n /**\n * CSS position property, either `fixed` or `absolute`.\n *\n * Pros and cons of each strategy are explained on [Floating UI's Docs](https://floating-ui.com/docs/computePosition#strategy)\n *\n * This argument is forwarded to the `<FloatingUI>` component.\n */\n strategy?: HookSignature[\"Args\"][\"Named\"][\"strategy\"];\n\n /**\n * By default, the popover is portaled.\n * If you don't control your CSS, and the positioning of the popover content\n * is misbehaving, you may pass \"@inline={{true}}\" to opt out of portalling.\n *\n * Inline may also be useful in nested menus, where you know exactly how the nesting occurs\n */\n inline?: boolean;\n };\n Blocks: {\n default: [\n {\n reference: FloatingUiComponentSignature[\"Blocks\"][\"default\"][0];\n setReference: FloatingUiComponentSignature[\"Blocks\"][\"default\"][2][\"setReference\"];\n Content: WithBoundArgs<typeof Content, \"floating\">;\n data: FloatingUiComponentSignature[\"Blocks\"][\"default\"][2][\"data\"];\n arrow: ModifierLike<{ Element: HTMLElement }>;\n },\n ];\n };\n}\n\nfunction getElementTag(tagName: undefined | string) {\n return tagName || \"div\";\n}\n\n/**\n * Allows lazy evaluation of the portal target (do nothing until rendered)\n * This is useful because the algorithm for finding the portal target isn't cheap.\n */\nconst Content: TOC<{\n Element: HTMLDivElement;\n Args: {\n floating: ModifierLike<{ Element: HTMLElement }>;\n inline?: boolean;\n /**\n * By default the popover content is wrapped in a div.\n * You may change this by supplying the name of an element here.\n *\n * For example:\n * ```gjs\n * <Popover as |p|>\n * <p.Content @as=\"dialog\">\n * this is now focus trapped\n * </p.Content>\n * </Popover>\n * ```\n */\n as?: string;\n };\n Blocks: { default: [] };\n}> = <template>\n {{#let (element (getElementTag @as)) as |El|}}\n {{#if @inline}}\n {{! @glint-ignore\n https://github.com/tildeio/ember-element-helper/issues/91\n https://github.com/typed-ember/glint/issues/610\n }}\n <El {{@floating}} ...attributes>\n {{yield}}\n </El>\n {{else}}\n <Portal @to={{TARGETS.popover}}>\n {{! @glint-ignore\n https://github.com/tildeio/ember-element-helper/issues/91\n https://github.com/typed-ember/glint/issues/610\n }}\n <El {{@floating}} ...attributes>\n {{yield}}\n </El>\n </Portal>\n {{/if}}\n {{/let}}\n</template>;\n\ninterface AttachArrowSignature {\n Element: HTMLElement;\n Args: {\n Named: {\n arrowElement: ReturnType<typeof ArrowElement>;\n data:\n | undefined\n | {\n placement: string;\n middlewareData?: {\n arrow?: { x?: number; y?: number };\n };\n };\n };\n };\n}\n\nconst arrowSides = {\n top: \"bottom\",\n right: \"left\",\n bottom: \"top\",\n left: \"right\",\n};\n\ntype Direction = \"top\" | \"bottom\" | \"left\" | \"right\";\ntype Placement = `${Direction}${\"\" | \"-start\" | \"-end\"}`;\n\nconst attachArrow: ModifierLike<AttachArrowSignature> = eModifier<AttachArrowSignature>(\n (element, _: [], named) => {\n if (element === named.arrowElement.current) {\n if (!named.data) return;\n if (!named.data.middlewareData) return;\n\n const { arrow } = named.data.middlewareData;\n const { placement } = named.data;\n\n if (!arrow) return;\n if (!placement) return;\n\n const { x: arrowX, y: arrowY } = arrow;\n const otherSide = (placement as Placement).split(\"-\")[0] as Direction;\n const staticSide = arrowSides[otherSide];\n\n Object.assign(named.arrowElement.current.style, {\n left: arrowX != null ? `${arrowX}px` : \"\",\n top: arrowY != null ? `${arrowY}px` : \"\",\n right: \"\",\n bottom: \"\",\n [staticSide]: \"-4px\",\n });\n\n return;\n }\n\n void (async () => {\n await Promise.resolve();\n named.arrowElement.set(element);\n })();\n },\n);\n\nconst ArrowElement: () => ReturnType<typeof cell<HTMLElement>> = () => cell<HTMLElement>();\n\nfunction maybeAddArrow(middleware: Middleware[] | undefined, element: Element | undefined) {\n const result = [...(middleware || [])];\n\n if (element) {\n result.push(arrow({ element }));\n }\n\n return result;\n}\n\nfunction flipOptions(options: HookSignature[\"Args\"][\"Named\"][\"flipOptions\"]) {\n return {\n elementContext: \"reference\" as ElementContext,\n ...options,\n };\n}\n\nexport const Popover: TOC<Signature> = <template>\n {{#let (ArrowElement) as |arrowElement|}}\n <FloatingUI\n @placement={{@placement}}\n @strategy={{@strategy}}\n @middleware={{maybeAddArrow @middleware arrowElement.current}}\n @flipOptions={{flipOptions @flipOptions}}\n @shiftOptions={{@shiftOptions}}\n @offsetOptions={{@offsetOptions}}\n as |reference floating extra|\n >\n {{#let (modifier attachArrow arrowElement=arrowElement data=extra.data) as |arrow|}}\n {{yield\n (hash\n reference=reference\n setReference=extra.setReference\n Content=(component Content floating=floating inline=@inline)\n data=extra.data\n arrow=arrow\n )\n }}\n {{/let}}\n </FloatingUI>\n {{/let}}\n</template>;\n\nexport default Popover;\n"],"names":["getElementTag","tagName","Content","setComponentTemplate","precompileTemplate","strictMode","scope","element","Portal","TARGETS","templateOnly","arrowSides","top","right","bottom","left","attachArrow","eModifier","_","named","arrowElement","current","data","middlewareData","arrow","placement","x","arrowX","y","arrowY","otherSide","split","staticSide","Object","assign","style","Promise","resolve","set","ArrowElement","cell","maybeAddArrow","middleware","result","push","flipOptions","options","elementContext","Popover","FloatingUI","hash"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"portal-targets.js","sources":["../../src/components/portal-targets.gts"],"sourcesContent":["import { assert } from \"@ember/debug\";\nimport { isDevelopingApp, macroCondition } from \"@embroider/macros\";\n\nimport type { TOC } from \"@ember/component/template-only\";\n\nexport const TARGETS = Object.freeze({\n popover: \"ember-primitives__portal-targets__popover\",\n tooltip: \"ember-primitives__portal-targets__tooltip\",\n modal: \"ember-primitives__portal-targets__modal\",\n});\n\nexport function findNearestTarget(origin: Element, name: string) {\n assert(`first argument to \\`findNearestTarget\\` must be an element`, origin instanceof Element);\n assert(`second argument to \\`findNearestTarget\\` must be a string`, typeof name === `string`);\n\n let element: Element | null = null;\n\n let parent = origin.parentNode;\n\n while (!element && parent) {\n element = parent.querySelector(`[data-portal-name=${name}]`);\n if (element) break;\n parent = parent.parentNode;\n }\n\n if (macroCondition(isDevelopingApp())) {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n (window as any).prime0 = origin;\n }\n\n assert(\n `Could not find element by the given name: \\`${name}\\`.` +\n ` The known names are ` +\n `${Object.values(TARGETS).join(\", \")} ` +\n `-- but any name will work as long as it is set to the \\`data-portal-name\\` attribute. ` +\n `Double check that the element you're wanting to portal to is rendered. ` +\n `The element passed to \\`findNearestTarget\\` is stored on \\`window.prime0\\` ` +\n `You can debug in your browser's console via ` +\n `\\`document.querySelector('[data-portal-name=\"${name}\"]')\\``,\n element,\n );\n\n return element;\n}\n\nexport interface Signature {\n Element: null;\n}\n\nexport const PortalTargets: TOC<Signature> = <template>\n <div data-portal-name={{TARGETS.popover}}></div>\n <div data-portal-name={{TARGETS.tooltip}}></div>\n <div data-portal-name={{TARGETS.modal}}></div>\n</template>;\n\nexport default PortalTargets;\n"],"names":["TARGETS","Object","freeze","popover","tooltip","modal","findNearestTarget","origin","name","assert","Element","element","parent","parentNode","querySelector","macroCondition","isDevelopingApp","window","prime0","values","join","PortalTargets","setComponentTemplate","precompileTemplate","strictMode","scope","templateOnly"],"mappings":";;;;;;MAKaA,OAAA,GAAUC,MAAA,CAAOC,MAAM,CAAC;AACnCC,EAAAA,OAAA,EAAS,2CAAA;AACTC,EAAAA,OAAA,EAAS,2CAAA;AACTC,EAAAA,KAAA,EAAO;AACT,CAAA;AAEO,SAASC,iBAAAA,CAAkBC,MAAe,EAAEC,IAAY,EAAA;AAC7DC,EAAAA,MAAA,CAAO,CAAA,0DAAA,CAA4D,EAAEF,MAAA,YAAkBG,OAAA,CAAA;AACvFD,EAAAA,MAAA,CAAO,CAAA,yDAAA,CAA2D,EAAE,OAAOD,IAAA,KAAS,QAAQ,CAAA;EAE5F,IAAIG,OAAuB,GAAG,IAAA;AAE9B,EAAA,IAAIC,MAAA,GAASL,OAAOM,UAAU;AAE9B,EAAA,OAAO,CAACF,WAAWC,MAAA,EAAQ;IACzBD,OAAA,GAAUC,MAAA,CAAOE,aAAa,CAAC,CAAA,kBAAA,EAAqBN,IAAA,GAAO,CAAA;AAC3D,IAAA,IAAIG,OAAA,EAAS;IACbC,MAAA,GAASA,OAAOC,UAAU;AAC5B;AAEA,EAAA,IAAIE,eAAeC,eAAA,EAAA,CAAA,EAAoB;AACrC;IACCC,MAAA,CAAeC,MAAM,GAAGX,MAAA;AAC3B;AAEAE,EAAAA,MAAA,CACE,CAAA,4CAAA,EAA+CD,IAAA,CAAA,GAAA,CAAS,GACtD,CAAA,qBAAA,CAAuB,GACvB,CAAA,EAAGP,OAAOkB,MAAM,CAACnB,SAASoB,IAAI,CAAC,QAAQ,GACvC,CAAA,sFAAA,CAAwF,GACxF,yEAAyE,GACzE,CAAA,2EAAA,CAA6E,GAC7E,CAAA,4CAAA,CAA8C,GAC9C,CAAA,6CAAA,EAAgDZ,IAAA,CAAA,MAAA,CAAY,EAC9DG,OAAA,CAAA;AAGF,EAAA,OAAOA,OAAA;AACT;MAMaU,aAAmB,GAAAC,oBAAA,CAAaC,kBAAA,CAAA,8JAAA,EAI7C;EAAAC,UAAA,EAAA,IAAA;AAAAC,EAAAA,KAAA,EAAAA,OAAA;AAAAzB,IAAAA;AAAA,GAAA;AAAU,CAAA,CAAA,EAAA0B,YAAA,EAAA;;;;"}
1
+ {"version":3,"file":"portal-targets.js","sources":["../../src/components/portal-targets.gts"],"sourcesContent":["import { assert } from \"@ember/debug\";\nimport { isDevelopingApp, macroCondition } from \"@embroider/macros\";\n\nimport type { TOC } from \"@ember/component/template-only\";\n\nexport const TARGETS = Object.freeze({\n popover: \"ember-primitives__portal-targets__popover\",\n tooltip: \"ember-primitives__portal-targets__tooltip\",\n modal: \"ember-primitives__portal-targets__modal\",\n});\n\nexport function findNearestTarget(origin: Element, name: string) {\n assert(`first argument to \\`findNearestTarget\\` must be an element`, origin instanceof Element);\n assert(`second argument to \\`findNearestTarget\\` must be a string`, typeof name === `string`);\n\n let element: Element | null = null;\n\n let parent = origin.parentNode;\n\n while (!element && parent) {\n element = parent.querySelector(`[data-portal-name=${name}]`);\n if (element) break;\n parent = parent.parentNode;\n }\n\n if (macroCondition(isDevelopingApp())) {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n (window as any).prime0 = origin;\n }\n\n assert(\n `Could not find element by the given name: \\`${name}\\`.` +\n ` The known names are ` +\n `${Object.values(TARGETS).join(\", \")} ` +\n `-- but any name will work as long as it is set to the \\`data-portal-name\\` attribute. ` +\n `Double check that the element you're wanting to portal to is rendered. ` +\n `The element passed to \\`findNearestTarget\\` is stored on \\`window.prime0\\` ` +\n `You can debug in your browser's console via ` +\n `\\`document.querySelector('[data-portal-name=\"${name}\"]')\\``,\n element,\n );\n\n return element;\n}\n\nexport interface Signature {\n Element: null;\n}\n\nexport const PortalTargets: TOC<Signature> = <template>\n <div data-portal-name={{TARGETS.popover}}></div>\n <div data-portal-name={{TARGETS.tooltip}}></div>\n <div data-portal-name={{TARGETS.modal}}></div>\n</template>;\n\nexport default PortalTargets;\n"],"names":["TARGETS","Object","freeze","popover","tooltip","modal","findNearestTarget","origin","name","assert","Element","element","parent","parentNode","querySelector","macroCondition","isDevelopingApp","window","prime0","values","join","PortalTargets","setComponentTemplate","precompileTemplate","strictMode","scope","templateOnly"],"mappings":";;;;;;MAKaA,OAAA,GAAUC,MAAA,CAAOC,MAAM,CAAC;AACnCC,EAAAA,OAAA,EAAS,2CAAA;AACTC,EAAAA,OAAA,EAAS,2CAAA;AACTC,EAAAA,KAAA,EAAO;AACT,CAAA;AAEO,SAASC,iBAAAA,CAAkBC,MAAe,EAAEC,IAAY,EAAA;AAC7DC,EAAAA,MAAA,CAAO,CAAA,0DAAA,CAA4D,EAAEF,MAAA,YAAkBG,OAAA,CAAA;AACvFD,EAAAA,MAAA,CAAO,CAAA,yDAAA,CAA2D,EAAE,OAAOD,IAAA,KAAS,QAAQ,CAAA;EAE5F,IAAIG,OAAuB,GAAG,IAAA;AAE9B,EAAA,IAAIC,MAAA,GAASL,OAAOM,UAAU;AAE9B,EAAA,OAAO,CAACF,WAAWC,MAAA,EAAQ;IACzBD,OAAA,GAAUC,MAAA,CAAOE,aAAa,CAAC,CAAA,kBAAA,EAAqBN,IAAA,GAAO,CAAA;AAC3D,IAAA,IAAIG,OAAA,EAAS;IACbC,MAAA,GAASA,OAAOC,UAAU;AAC5B,EAAA;AAEA,EAAA,IAAIE,eAAeC,eAAA,EAAA,CAAA,EAAoB;AACrC;IACCC,MAAA,CAAeC,MAAM,GAAGX,MAAA;AAC3B,EAAA;AAEAE,EAAAA,MAAA,CACE,CAAA,4CAAA,EAA+CD,IAAA,CAAA,GAAA,CAAS,GACtD,CAAA,qBAAA,CAAuB,GACvB,CAAA,EAAGP,OAAOkB,MAAM,CAACnB,SAASoB,IAAI,CAAC,QAAQ,GACvC,CAAA,sFAAA,CAAwF,GACxF,yEAAyE,GACzE,CAAA,2EAAA,CAA6E,GAC7E,CAAA,4CAAA,CAA8C,GAC9C,CAAA,6CAAA,EAAgDZ,IAAA,CAAA,MAAA,CAAY,EAC9DG,OAAA,CAAA;AAGF,EAAA,OAAOA,OAAA;AACT;MAMaU,aAAmB,GAAAC,oBAAA,CAAaC,kBAAA,CAAA,8JAAA,EAI7C;EAAAC,UAAA,EAAA,IAAA;AAAAC,EAAAA,KAAA,EAAAA,OAAA;AAAAzB,IAAAA;AAAA,GAAA;AAAU,CAAA,CAAA,EAAA0B,YAAA,EAAA;;;;"}