@astryxdesign/core 0.7.6-canary.f67d5fa → 0.7.6-canary.f899313

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 (33) hide show
  1. package/dist/Badge/Badge.d.ts.map +1 -1
  2. package/dist/Badge/Badge.js +2 -1
  3. package/dist/DateInput/MonthScroller.d.ts.map +1 -1
  4. package/dist/DateInput/MonthScroller.js +17 -18
  5. package/dist/DropdownMenu/DropdownMenuGroup.d.ts.map +1 -1
  6. package/dist/DropdownMenu/DropdownMenuGroup.js +2 -1
  7. package/dist/Field/FieldLabel.d.ts.map +1 -1
  8. package/dist/Field/FieldLabel.js +27 -2
  9. package/dist/FileInput/FileInput.d.ts.map +1 -1
  10. package/dist/FileInput/FileInput.js +33 -22
  11. package/dist/Layer/useTouchTrigger.d.ts +9 -0
  12. package/dist/Layer/useTouchTrigger.d.ts.map +1 -1
  13. package/dist/Layer/useTouchTrigger.js +1 -1
  14. package/dist/NumberInput/NumberInput.d.ts.map +1 -1
  15. package/dist/NumberInput/NumberInput.js +11 -15
  16. package/dist/Slider/Slider.d.ts.map +1 -1
  17. package/dist/Slider/Slider.js +82 -10
  18. package/dist/Typeahead/BaseTypeahead.d.ts.map +1 -1
  19. package/dist/Typeahead/BaseTypeahead.js +10 -3
  20. package/package.json +4 -4
  21. package/src/Badge/Badge.tsx +2 -1
  22. package/src/DateInput/MonthScroller.tsx +15 -17
  23. package/src/DropdownMenu/DropdownMenuGroup.tsx +2 -1
  24. package/src/Field/Field.doc.mjs +2 -1
  25. package/src/Field/FieldLabel.doc.mjs +4 -2
  26. package/src/Field/FieldLabel.spec.md +30 -21
  27. package/src/Field/FieldLabel.tsx +37 -3
  28. package/src/FileInput/FileInput.tsx +39 -23
  29. package/src/Layer/useTouchTrigger.ts +1 -1
  30. package/src/NumberInput/NumberInput.tsx +11 -18
  31. package/src/Slider/Slider.spec.md +18 -16
  32. package/src/Slider/Slider.tsx +101 -9
  33. package/src/Typeahead/BaseTypeahead.tsx +18 -2
@@ -1 +1 @@
1
- {"version":3,"file":"Badge.d.ts","sourceRoot":"","sources":["../../src/Badge/Badge.tsx"],"names":[],"mappings":"AAEA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,OAAO,CAAC;AACrC,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAW5C,OAAO,KAAK,EAAC,eAAe,EAAC,MAAM,SAAS,CAAC;AAwJ7C;;;GAGG;AACH,MAAM,MAAM,YAAY,GAAG,MAAM,eAAe,CAAC;AAEjD,MAAM,WAAW,UAAW,SAAQ,SAAS,CAAC,eAAe,CAAC;IAC5D,wCAAwC;IACxC,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;IACjC;;;OAGG;IACH,OAAO,CAAC,EAAE,YAAY,CAAC;IACvB;;OAEG;IACH,KAAK,EAAE,SAAS,CAAC;IAEjB;;OAEG;IACH,IAAI,CAAC,EAAE,SAAS,CAAC;CAClB;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,KAAK,CAAC,EACpB,OAAmB,EACnB,KAAK,EACL,IAAI,EACJ,MAAM,EACN,SAAS,EACT,KAAK,EACL,GAAG,EACH,GAAG,KAAK,EACT,EAAE,UAAU,+BA6CZ;yBAtDe,KAAK"}
1
+ {"version":3,"file":"Badge.d.ts","sourceRoot":"","sources":["../../src/Badge/Badge.tsx"],"names":[],"mappings":"AAEA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,OAAO,CAAC;AACrC,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAY5C,OAAO,KAAK,EAAC,eAAe,EAAC,MAAM,SAAS,CAAC;AAwJ7C;;;GAGG;AACH,MAAM,MAAM,YAAY,GAAG,MAAM,eAAe,CAAC;AAEjD,MAAM,WAAW,UAAW,SAAQ,SAAS,CAAC,eAAe,CAAC;IAC5D,wCAAwC;IACxC,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;IACjC;;;OAGG;IACH,OAAO,CAAC,EAAE,YAAY,CAAC;IACvB;;OAEG;IACH,KAAK,EAAE,SAAS,CAAC;IAEjB;;OAEG;IACH,IAAI,CAAC,EAAE,SAAS,CAAC;CAClB;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,KAAK,CAAC,EACpB,OAAmB,EACnB,KAAK,EACL,IAAI,EACJ,MAAM,EACN,SAAS,EACT,KAAK,EACL,GAAG,EACH,GAAG,KAAK,EACT,EAAE,UAAU,+BA6CZ;yBAtDe,KAAK"}
@@ -19,6 +19,7 @@ import "../theme/tokens.stylex.js";
19
19
  import { colorVars, spacingVars, radiusVars, fontWeightVars, typeScaleVars } from "../theme/tokens.stylex.js";
20
20
  import { mergeProps } from "../utils/index.js";
21
21
  import { themeProps } from "../utils/themeProps.js";
22
+ import { isRenderable } from "../utils/isRenderable.js";
22
23
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
23
24
  /**
24
25
  * Base badge styles
@@ -187,7 +188,7 @@ export function Badge({
187
188
  // a client component, so it is tracked in #5585.
188
189
  const labelTitle = typeof label === 'number' ? String(label) : typeof label === 'string' && label.length > 0 ? label : undefined;
189
190
  // Whether the label renders anything, which is when the badge grows with it.
190
- const hasLabel = label !== '' && label != null && typeof label !== 'boolean';
191
+ const hasLabel = isRenderable(label);
191
192
  return /*#__PURE__*/_jsxs("span", {
192
193
  ref: ref,
193
194
  ...mergeProps(themeProps('badge', {
@@ -1 +1 @@
1
- {"version":3,"file":"MonthScroller.d.ts","sourceRoot":"","sources":["../../src/DateInput/MonthScroller.tsx"],"names":[],"mappings":"AAoDA,OAAO,EACL,KAAK,SAAS,EACd,KAAK,aAAa,EAClB,KAAK,SAAS,EAQf,MAAM,UAAU,CAAC;AAqNlB,MAAM,WAAW,mBAAmB;IAClC,0DAA0D;IAC1D,aAAa,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,cAAc,KAAK,IAAI,CAAC;CACxE;AAED,MAAM,WAAW,kBAAkB;IACjC,yEAAyE;IACzE,SAAS,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,mBAAmB,GAAG,IAAI,CAAC,CAAC;IACxD,+CAA+C;IAC/C,aAAa,EAAE,MAAM,CAAC;IACtB,8CAA8C;IAC9C,aAAa,EAAE,MAAM,CAAC;IACtB,iCAAiC;IACjC,iBAAiB,EAAE,MAAM,CAAC;IAC1B,+DAA+D;IAC/D,oBAAoB,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,IAAI,CAAC;IACnD,+BAA+B;IAC/B,YAAY,EAAE,SAAS,GAAG,IAAI,CAAC;IAC/B,4CAA4C;IAC5C,KAAK,EAAE,SAAS,CAAC;IACjB,2DAA2D;IAC3D,cAAc,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,OAAO,CAAC;IAC7C,gCAAgC;IAChC,YAAY,EAAE,SAAS,CAAC;IACxB,kCAAkC;IAClC,QAAQ,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC;CAC1C;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,EAC5B,SAAS,EACT,aAAa,EACb,aAAa,EACb,iBAAiB,EACjB,oBAAoB,EACpB,YAAY,EACZ,KAAK,EACL,cAAc,EACd,YAAY,EACZ,QAAQ,GACT,EAAE,kBAAkB,+BAufpB;yBAlgBe,aAAa"}
1
+ {"version":3,"file":"MonthScroller.d.ts","sourceRoot":"","sources":["../../src/DateInput/MonthScroller.tsx"],"names":[],"mappings":"AAoDA,OAAO,EACL,KAAK,SAAS,EACd,KAAK,aAAa,EAClB,KAAK,SAAS,EAQf,MAAM,UAAU,CAAC;AAgNlB,MAAM,WAAW,mBAAmB;IAClC,0DAA0D;IAC1D,aAAa,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,cAAc,KAAK,IAAI,CAAC;CACxE;AAED,MAAM,WAAW,kBAAkB;IACjC,yEAAyE;IACzE,SAAS,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,mBAAmB,GAAG,IAAI,CAAC,CAAC;IACxD,+CAA+C;IAC/C,aAAa,EAAE,MAAM,CAAC;IACtB,8CAA8C;IAC9C,aAAa,EAAE,MAAM,CAAC;IACtB,iCAAiC;IACjC,iBAAiB,EAAE,MAAM,CAAC;IAC1B,+DAA+D;IAC/D,oBAAoB,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,IAAI,CAAC;IACnD,+BAA+B;IAC/B,YAAY,EAAE,SAAS,GAAG,IAAI,CAAC;IAC/B,4CAA4C;IAC5C,KAAK,EAAE,SAAS,CAAC;IACjB,2DAA2D;IAC3D,cAAc,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,OAAO,CAAC;IAC7C,gCAAgC;IAChC,YAAY,EAAE,SAAS,CAAC;IACxB,kCAAkC;IAClC,QAAQ,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC;CAC1C;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,EAC5B,SAAS,EACT,aAAa,EACb,aAAa,EACb,iBAAiB,EACjB,oBAAoB,EACpB,YAAY,EACZ,KAAK,EACL,cAAc,EACd,YAAY,EACZ,QAAQ,GACT,EAAE,kBAAkB,+BA0fpB;yBArgBe,aAAa"}
@@ -54,8 +54,10 @@ const DAY_SIZE = dateInputTouchSizes.daySize;
54
54
  */
55
55
  const OVERSCAN = 3;
56
56
 
57
- /** Input on the scroller that ends a steer: the user's from here. */
58
- const USER_INPUT_EVENTS = ['touchstart', 'wheel', 'pointerdown', 'keydown'];
57
+ /** Every listener on the scroller is passive; one options object serves all. */
58
+ const PASSIVE = {
59
+ passive: true
60
+ };
59
61
  const styles = {
60
62
  spacer: {
61
63
  kVAEAm: "x1n2onr6",
@@ -483,23 +485,20 @@ export function MonthScroller({
483
485
  onVisibleMonthChangeRef.current(minMonthIndex + row);
484
486
  });
485
487
  };
486
- scroller.addEventListener('scroll', onScroll, {
487
- passive: true
488
- });
489
- for (const type of USER_INPUT_EVENTS) {
490
- scroller.addEventListener(type, endSteer, {
491
- passive: true
492
- });
493
- }
494
- scroller.addEventListener('touchstart', onTouchStart, {
495
- passive: true
496
- });
488
+ scroller.addEventListener('scroll', onScroll, PASSIVE);
489
+ // The user's input on the scroller ends a steer: from here, it's theirs.
490
+ scroller.addEventListener('touchstart', endSteer, PASSIVE);
491
+ scroller.addEventListener('wheel', endSteer, PASSIVE);
492
+ scroller.addEventListener('pointerdown', endSteer, PASSIVE);
493
+ scroller.addEventListener('keydown', endSteer, PASSIVE);
494
+ scroller.addEventListener('touchstart', onTouchStart, PASSIVE);
497
495
  return () => {
498
- scroller.removeEventListener('scroll', onScroll);
499
- for (const type of USER_INPUT_EVENTS) {
500
- scroller.removeEventListener(type, endSteer);
501
- }
502
- scroller.removeEventListener('touchstart', onTouchStart);
496
+ scroller.removeEventListener('scroll', onScroll, PASSIVE);
497
+ scroller.removeEventListener('touchstart', endSteer, PASSIVE);
498
+ scroller.removeEventListener('wheel', endSteer, PASSIVE);
499
+ scroller.removeEventListener('pointerdown', endSteer, PASSIVE);
500
+ scroller.removeEventListener('keydown', endSteer, PASSIVE);
501
+ scroller.removeEventListener('touchstart', onTouchStart, PASSIVE);
503
502
  if (frameRef.current != null) {
504
503
  cancelAnimationFrame(frameRef.current);
505
504
  frameRef.current = undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"DropdownMenuGroup.d.ts","sourceRoot":"","sources":["../../src/DropdownMenu/DropdownMenuGroup.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,EAAQ,KAAK,SAAS,EAAC,MAAM,OAAO,CAAC;AAQ5C,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAgB5C,MAAM,WAAW,sBAAuB,SAAQ,IAAI,CAClD,SAAS,CAAC,cAAc,CAAC,EACzB,MAAM,CACP;IACC;;;;OAIG;IACH,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,sEAAsE;IACtE,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,mDAAmD;IACnD,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;CACjC;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,iBAAiB,CAAC,EAChC,KAAK,EACL,QAAQ,EACR,MAAM,EACN,SAAS,EACT,KAAK,EACL,GAAG,EACH,iBAAiB,EAAE,cAAc,EACjC,GAAG,IAAI,EACR,EAAE,sBAAsB,+BAwBxB;yBAjCe,iBAAiB"}
1
+ {"version":3,"file":"DropdownMenuGroup.d.ts","sourceRoot":"","sources":["../../src/DropdownMenu/DropdownMenuGroup.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,EAAQ,KAAK,SAAS,EAAC,MAAM,OAAO,CAAC;AAQ5C,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAiB5C,MAAM,WAAW,sBAAuB,SAAQ,IAAI,CAClD,SAAS,CAAC,cAAc,CAAC,EACzB,MAAM,CACP;IACC;;;;OAIG;IACH,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,sEAAsE;IACtE,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,mDAAmD;IACnD,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;CACjC;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,iBAAiB,CAAC,EAChC,KAAK,EACL,QAAQ,EACR,MAAM,EACN,SAAS,EACT,KAAK,EACL,GAAG,EACH,iBAAiB,EAAE,cAAc,EACjC,GAAG,IAAI,EACR,EAAE,sBAAsB,+BAwBxB;yBAjCe,iBAAiB"}
@@ -29,6 +29,7 @@ import "../theme/tokens.stylex.js";
29
29
  import { colorVars, spacingVars, typographyVars, typeScaleVars } from "../theme/tokens.stylex.js";
30
30
  import { mergeProps } from "../utils/index.js";
31
31
  import { themeProps } from "../utils/themeProps.js";
32
+ import { isRenderable } from "../utils/isRenderable.js";
32
33
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
33
34
  /**
34
35
  * A titled group of menu rows.
@@ -64,7 +65,7 @@ export function DropdownMenuGroup({
64
65
  ...rest
65
66
  }) {
66
67
  const headingId = useId();
67
- const hasTitle = title != null && title !== '' && title !== false;
68
+ const hasTitle = isRenderable(title);
68
69
  return /*#__PURE__*/_jsxs("div", {
69
70
  ...rest,
70
71
  ref: ref,
@@ -1 +1 @@
1
- {"version":3,"file":"FieldLabel.d.ts","sourceRoot":"","sources":["../../src/Field/FieldLabel.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAuB,KAAK,SAAS,EAAiB,MAAM,OAAO,CAAC;AAE3E,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAW5C,OAAO,KAAK,EAAC,QAAQ,EAAC,MAAM,SAAS,CAAC;AAgFtC,MAAM,WAAW,eAAgB,SAAQ,SAAS,CAAC,gBAAgB,CAAC;IAClE,wCAAwC;IACxC,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;IAClC;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IACd;;;;OAIG;IACH,OAAO,EAAE,MAAM,CAAC;IAChB;;;;;OAKG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;;;;;;OAQG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB;;;;;OAKG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;OAEG;IACH,SAAS,CAAC,EAAE,SAAS,GAAG,QAAQ,CAAC;IACjC;;OAEG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;OAGG;IACH,WAAW,CAAC,EAAE,SAAS,CAAC;IACxB;;OAEG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,UAAU,CAAC,EACzB,KAAK,EACL,OAAO,EACP,OAAO,EACP,YAAoB,EACpB,aAAqB,EACrB,UAAkB,EAClB,UAAkB,EAClB,UAAkB,EAClB,SAAS,EACT,YAAY,EACZ,WAAW,EACX,aAAa,EACb,SAAS,EACT,KAAK,EACL,MAAM,EACN,GAAG,EACH,GAAG,IAAI,EACR,EAAE,eAAe,+BAyIjB;yBA3Je,UAAU"}
1
+ {"version":3,"file":"FieldLabel.d.ts","sourceRoot":"","sources":["../../src/Field/FieldLabel.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAML,KAAK,SAAS,EAEf,MAAM,OAAO,CAAC;AAEf,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAW5C,OAAO,KAAK,EAAC,QAAQ,EAAC,MAAM,SAAS,CAAC;AAiFtC,MAAM,WAAW,eAAgB,SAAQ,SAAS,CAAC,gBAAgB,CAAC;IAClE,wCAAwC;IACxC,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;IAClC;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IACd;;;;OAIG;IACH,OAAO,EAAE,MAAM,CAAC;IAChB;;;;;OAKG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;;;;;;OAQG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB;;;;;OAKG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;OAEG;IACH,SAAS,CAAC,EAAE,SAAS,GAAG,QAAQ,CAAC;IACjC;;OAEG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;OAGG;IACH,WAAW,CAAC,EAAE,SAAS,CAAC;IACxB;;OAEG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,UAAU,CAAC,EACzB,KAAK,EACL,OAAO,EACP,OAAO,EACP,YAAoB,EACpB,aAAqB,EACrB,UAAkB,EAClB,UAAkB,EAClB,UAAkB,EAClB,SAAS,EACT,YAAY,EACZ,WAAW,EACX,aAAa,EACb,SAAS,EACT,KAAK,EACL,MAAM,EACN,GAAG,EACH,GAAG,IAAI,EACR,EAAE,eAAe,+BAkKjB;yBApLe,UAAU"}
@@ -22,6 +22,7 @@ import "../theme/tokens.stylex.js";
22
22
  import { colorVars, fontWeightVars, spacingVars, typographyVars, typeScaleVars } from "../theme/tokens.stylex.js";
23
23
  import { Icon, renderIconSlot } from "../Icon/Icon.js";
24
24
  import { Tooltip } from "../Tooltip/Tooltip.js";
25
+ import { TOUCH_POINTER_TYPES } from "../Layer/useTouchTrigger.js";
25
26
  import { useTranslator } from "../i18n/useTranslator.js";
26
27
  import { themeProps } from "../utils/themeProps.js";
27
28
  import { useInputContainer } from "../hooks/useInputContainer.js";
@@ -136,6 +137,22 @@ export function FieldLabel({
136
137
  // a ref-shaped object, since FieldLabel points at the control by id rather
137
138
  // than holding a ref to it.
138
139
  const descriptionRef = useRef(null);
140
+ // A tap on the info icon asks for the help, so it stops there: it does not
141
+ // go on to activate the label's control, as a press anywhere else on the
142
+ // label would (focus the field, toggle a switch). A mouse click on the icon
143
+ // keeps that native activation, and hover shows the help.
144
+ const iconPressIsTapRef = useRef(false);
145
+ const handleIconPointerDown = event => {
146
+ // A finger or a pen: the pointers whose tap the shared touch trigger
147
+ // answers, so the ones whose tap opens or closes the help.
148
+ iconPressIsTapRef.current = TOUCH_POINTER_TYPES.has(event.pointerType);
149
+ };
150
+ const handleIconClick = event => {
151
+ if (iconPressIsTapRef.current) {
152
+ event.preventDefault();
153
+ }
154
+ iconPressIsTapRef.current = false;
155
+ };
139
156
  const controlRef = useMemo(() => ({
140
157
  get current() {
141
158
  return inputID == null ? null : descriptionRef.current?.ownerDocument.getElementById(inputID) ?? null;
@@ -159,13 +176,21 @@ export function FieldLabel({
159
176
  "aria-hidden": "true",
160
177
  children: " \u2219 "
161
178
  }), statusText]
162
- }), labelTooltip && /*#__PURE__*/_jsx(Tooltip, {
179
+ }), labelTooltip &&
180
+ /*#__PURE__*/
181
+ // The icon's one job is to reveal the help, so a tap on it opens or
182
+ // closes the help (`touchTrigger="tap"`), although it sits inside a
183
+ // `<label>`.
184
+ _jsx(Tooltip, {
163
185
  content: labelTooltip,
164
186
  placement: "above",
187
+ touchTrigger: "tap",
165
188
  children: /*#__PURE__*/_jsx(Icon, {
166
189
  icon: "info",
167
190
  size: "sm",
168
- color: "inherit"
191
+ color: "inherit",
192
+ onPointerDown: handleIconPointerDown,
193
+ onClick: handleIconClick
169
194
  })
170
195
  })]
171
196
  });
@@ -1 +1 @@
1
- {"version":3,"file":"FileInput.d.ts","sourceRoot":"","sources":["../../src/FileInput/FileInput.tsx"],"names":[],"mappings":"AAuCA,OAAO,EAGL,KAAK,WAAW,EAChB,KAAK,kBAAkB,EACxB,MAAM,UAAU,CAAC;AAUlB,YAAY,EACV,WAAW,IAAI,eAAe,EAC9B,eAAe,IAAI,mBAAmB,GACvC,MAAM,UAAU,CAAC;AAGlB,OAAO,EACL,KAAK,mBAAmB,EAEzB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,gBAAgB,CAAC;AAuP9C,MAAM,WAAW,cAAe,SAAQ,IAAI,CAC1C,mBAAmB,EACnB,UAAU,GAAG,cAAc,GAAG,OAAO,CACtC;IACC;;OAEG;IACH,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;IAClC;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IACd;;;OAGG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB;;OAEG;IACH,KAAK,EAAE,IAAI,GAAG,IAAI,EAAE,GAAG,IAAI,CAAC;IAC5B;;OAEG;IACH,QAAQ,EAAE,CAAC,KAAK,EAAE,IAAI,GAAG,IAAI,EAAE,GAAG,IAAI,KAAK,IAAI,CAAC;IAChD;;;OAGG;IACH,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE,IAAI,GAAG,IAAI,EAAE,GAAG,IAAI,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9D;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;OAIG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;;;;;;;;;;;;;;;;;OAmBG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;OAGG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;;OAEG;IACH,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB;;;;;;OAMG;IACH,aAAa,CAAC,EAAE,kBAAkB,CAAC;IACnC;;OAEG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;;OAKG;IACH,IAAI,CAAC,EAAE,UAAU,GAAG,OAAO,CAAC;IAC5B;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;;OAIG;IACH,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB;;OAEG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;;;;;;GAOG;AACH,wBAAgB,SAAS,CAAC,EACxB,KAAK,EACL,aAAqB,EACrB,KAAK,EACL,QAAQ,EACR,YAAY,EACZ,MAAM,EACN,UAAkB,EAClB,OAAO,EACP,QAAQ,EACR,UAAkB,EAClB,eAAe,EACf,UAAkB,EAClB,SAAiB,EACjB,MAAM,EAAE,UAAU,EAClB,aAA0B,EAC1B,WAAW,EACX,WAAW,EACX,IAAc,EACd,UAAkB,EAClB,YAAY,EACZ,KAAK,EACL,eAAe,EACf,kBAAkB,EAClB,cAAc,EACd,aAAa,EACb,gBAAgB,EAChB,YAAY,EACZ,GAAG,EACH,EAAE,EAAE,MAAM,EACV,GAAG,SAAS,EACb,EAAE,cAAc,+BA8ehB;yBA7gBe,SAAS"}
1
+ {"version":3,"file":"FileInput.d.ts","sourceRoot":"","sources":["../../src/FileInput/FileInput.tsx"],"names":[],"mappings":"AAuCA,OAAO,EAGL,KAAK,WAAW,EAChB,KAAK,kBAAkB,EACxB,MAAM,UAAU,CAAC;AAUlB,YAAY,EACV,WAAW,IAAI,eAAe,EAC9B,eAAe,IAAI,mBAAmB,GACvC,MAAM,UAAU,CAAC;AAGlB,OAAO,EACL,KAAK,mBAAmB,EAEzB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,gBAAgB,CAAC;AA2P9C,MAAM,WAAW,cAAe,SAAQ,IAAI,CAC1C,mBAAmB,EACnB,UAAU,GAAG,cAAc,GAAG,OAAO,CACtC;IACC;;OAEG;IACH,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;IAClC;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IACd;;;OAGG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB;;OAEG;IACH,KAAK,EAAE,IAAI,GAAG,IAAI,EAAE,GAAG,IAAI,CAAC;IAC5B;;OAEG;IACH,QAAQ,EAAE,CAAC,KAAK,EAAE,IAAI,GAAG,IAAI,EAAE,GAAG,IAAI,KAAK,IAAI,CAAC;IAChD;;;OAGG;IACH,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE,IAAI,GAAG,IAAI,EAAE,GAAG,IAAI,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9D;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;OAIG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;;;;;;;;;;;;;;;;;OAmBG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;OAGG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;;OAEG;IACH,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB;;;;;;OAMG;IACH,aAAa,CAAC,EAAE,kBAAkB,CAAC;IACnC;;OAEG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;;OAKG;IACH,IAAI,CAAC,EAAE,UAAU,GAAG,OAAO,CAAC;IAC5B;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;;OAIG;IACH,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB;;OAEG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;;;;;;GAOG;AACH,wBAAgB,SAAS,CAAC,EACxB,KAAK,EACL,aAAqB,EACrB,KAAK,EACL,QAAQ,EACR,YAAY,EACZ,MAAM,EACN,UAAkB,EAClB,OAAO,EACP,QAAQ,EACR,UAAkB,EAClB,eAAe,EACf,UAAkB,EAClB,SAAiB,EACjB,MAAM,EAAE,UAAU,EAClB,aAA0B,EAC1B,WAAW,EACX,WAAW,EACX,IAAc,EACd,UAAkB,EAClB,YAAY,EACZ,KAAK,EACL,eAAe,EACf,kBAAkB,EAClB,cAAc,EACd,aAAa,EACb,gBAAgB,EAChB,YAAY,EACZ,GAAG,EACH,EAAE,EAAE,MAAM,EACV,GAAG,SAAS,EACb,EAAE,cAAc,+BA0fhB;yBAzhBe,SAAS"}
@@ -164,6 +164,11 @@ const styles = {
164
164
  kSiTet: "xbyyjgo",
165
165
  kVAM5u: "xvy26l8 x6q1khz",
166
166
  $$css: true
167
+ },
168
+ busy: {
169
+ kkrTdU: "xt0e3qv",
170
+ kGVxlE: "x1gnnqk1",
171
+ $$css: true
167
172
  }
168
173
  };
169
174
  const statusBorderStyles = {
@@ -243,6 +248,10 @@ export function FileInput({
243
248
  const [, startTransition] = useTransition();
244
249
  const [optimisticValue, setOptimisticValue] = useOptimistic(value);
245
250
  const isBusy = isLoading || optimisticValue !== value;
251
+ const isSelectionDisabled = isDisabled || isBusy;
252
+ if (isDragOver && isSelectionDisabled) {
253
+ setIsDragOver(false);
254
+ }
246
255
  // A pick is one user action, already announced as "file selected"; a busy
247
256
  // period it starts (changeAction, or a caller setting isLoading from
248
257
  // onChange) adds no second message (spec:AST-086 FR6). The mark lasts until
@@ -301,7 +310,7 @@ export function FileInput({
301
310
  const defaultPlaceholder = isMultiple ? t('@astryx.fileInput.placeholderMultiple') : t('@astryx.fileInput.placeholder');
302
311
  const displayPlaceholder = placeholder ?? defaultPlaceholder;
303
312
  const handleFiles = useCallback(fileList => {
304
- if (isDisabled) {
313
+ if (isSelectionDisabled) {
305
314
  return;
306
315
  }
307
316
  const {
@@ -340,7 +349,7 @@ export function FileInput({
340
349
  await changeAction(result);
341
350
  });
342
351
  }
343
- }, [accept, isDisabled, isMultiple, maxFiles, maxSize, onChange, changeAction, startTransition, setOptimisticValue, announce, t, formatList]);
352
+ }, [accept, isSelectionDisabled, isMultiple, maxFiles, maxSize, onChange, changeAction, startTransition, setOptimisticValue, announce, t, formatList]);
344
353
  const handleInputChange = useCallback(e => {
345
354
  const fileList = Array.from(e.target.files ?? []);
346
355
  handleFiles(fileList);
@@ -377,20 +386,22 @@ export function FileInput({
377
386
  }
378
387
  }, [onChange, changeAction, startTransition, setOptimisticValue]);
379
388
  const handleClick = useCallback(() => {
380
- if (!isDisabled) {
389
+ if (!isSelectionDisabled) {
381
390
  inputRef.current?.click();
382
391
  }
383
- }, [isDisabled]);
392
+ }, [isSelectionDisabled]);
384
393
 
385
394
  // Explicit keyboard activation so Enter/Space open the picker even where a
386
- // synthetic keydown does not raise a native click. The isDisabled guard
387
- // blocks activation while focusable-disabled.
395
+ // synthetic keydown does not raise a native click. Disabled and busy triggers
396
+ // also cancel the default activation while remaining focusable.
388
397
  const handleKeyDown = useCallback(e => {
389
- if ((e.key === 'Enter' || e.key === ' ') && !isDisabled) {
398
+ if (e.key === 'Enter' || e.key === ' ') {
390
399
  e.preventDefault();
391
- inputRef.current?.click();
400
+ if (!isSelectionDisabled) {
401
+ inputRef.current?.click();
402
+ }
392
403
  }
393
- }, [isDisabled]);
404
+ }, [isSelectionDisabled]);
394
405
 
395
406
  // Make the surface clickable without giving it an interactive role. Clicks on
396
407
  // the nested clear/status controls are ignored by the hook, so those buttons
@@ -401,22 +412,22 @@ export function FileInput({
401
412
  } = useClickableContainer({
402
413
  containerRef,
403
414
  onClick: handleClick,
404
- disabled: isDisabled
415
+ disabled: isSelectionDisabled
405
416
  });
406
417
  const handleDragEnter = useCallback(e => {
407
418
  e.preventDefault();
408
419
  e.stopPropagation();
409
- if (!isDisabled && mode === 'dropzone') {
420
+ if (!isSelectionDisabled && mode === 'dropzone') {
410
421
  setIsDragOver(true);
411
422
  }
412
- }, [isDisabled, mode]);
423
+ }, [isSelectionDisabled, mode]);
413
424
  const handleDragOver = useCallback(e => {
414
425
  e.preventDefault();
415
426
  e.stopPropagation();
416
- if (!isDisabled && mode === 'dropzone') {
427
+ if (!isSelectionDisabled && mode === 'dropzone') {
417
428
  setIsDragOver(true);
418
429
  }
419
- }, [isDisabled, mode]);
430
+ }, [isSelectionDisabled, mode]);
420
431
  const handleDragLeave = useCallback(e => {
421
432
  e.preventDefault();
422
433
  e.stopPropagation();
@@ -432,14 +443,14 @@ export function FileInput({
432
443
  e.preventDefault();
433
444
  e.stopPropagation();
434
445
  setIsDragOver(false);
435
- if (isDisabled || mode !== 'dropzone') {
446
+ if (isSelectionDisabled || mode !== 'dropzone') {
436
447
  return;
437
448
  }
438
449
  const fileList = Array.from(e.dataTransfer.files);
439
450
  if (fileList.length > 0) {
440
451
  handleFiles(fileList);
441
452
  }
442
- }, [isDisabled, mode, handleFiles]);
453
+ }, [isSelectionDisabled, mode, handleFiles]);
443
454
  const hasFiles = optimisticValue != null && (Array.isArray(optimisticValue) ? optimisticValue.length > 0 : true);
444
455
  const fileNames = hasFiles ? Array.isArray(optimisticValue) ? optimisticValue.map(f => f.name).join(', ') : optimisticValue?.name ?? '' : null;
445
456
 
@@ -560,13 +571,13 @@ export function FileInput({
560
571
  // keyboard focus. Handlers are gated internally by isEnabled.
561
572
  disabledMessageTooltip.ref(el);
562
573
  },
563
- onClick: !isDisabled ? onContainerClick : undefined,
564
- onMouseUp: !isDisabled ? onContainerMouseUp : undefined,
574
+ onClick: !isSelectionDisabled ? onContainerClick : undefined,
575
+ onMouseUp: !isSelectionDisabled ? onContainerMouseUp : undefined,
565
576
  ...dragDropProps,
566
577
  ...mergeProps(themeProps('file-input', {
567
578
  mode,
568
579
  status: status?.type ?? null
569
- }), stylex.props(isDropzone ? styles.dropzone : styles.compact, isDropzone && !isDisabled && styles.dropzoneHover, isDropzone && isDragOver && styles.dropzoneActive, isDropzone && isDisabled && styles.dropzoneDisabled, !isDropzone && isDisabled && styles.compactDisabled, status && statusBorderStyles[status.type], controlXstyle), controlClassName, controlStyle),
580
+ }), stylex.props(isDropzone ? styles.dropzone : styles.compact, isDropzone && !isSelectionDisabled && styles.dropzoneHover, isDropzone && !isSelectionDisabled && isDragOver && styles.dropzoneActive, isDropzone && isDisabled && styles.dropzoneDisabled, !isDropzone && isDisabled && styles.compactDisabled, isBusy && styles.busy, status && statusBorderStyles[status.type], controlXstyle), controlClassName, controlStyle),
570
581
  children: [/*#__PURE__*/_jsx(VisuallyHidden, {
571
582
  children: /*#__PURE__*/_jsx("button", {
572
583
  ref: triggerRef,
@@ -574,7 +585,7 @@ export function FileInput({
574
585
  // A disabled trigger keeps its Tab stop (spec:AST-085 FR1).
575
586
  ,
576
587
  tabIndex: 0,
577
- "aria-disabled": isDisabled ? 'true' : undefined,
588
+ "aria-disabled": isSelectionDisabled ? 'true' : undefined,
578
589
  onClick: handleClick,
579
590
  onKeyDown: handleKeyDown
580
591
  // aria-label suppresses child content from the accessible name, so
@@ -602,9 +613,9 @@ export function FileInput({
602
613
  ,
603
614
  form: isDisabled ? '' : undefined
604
615
  // A label or description click activates this input directly; cancel
605
- // it so a disabled input never opens the picker (FR2).
616
+ // it so a disabled or busy input never opens the picker (FR2).
606
617
  ,
607
- onClick: isDisabled ? event => event.preventDefault() : rest.onClick,
618
+ onClick: isSelectionDisabled ? event => event.preventDefault() : rest.onClick,
608
619
  onChange: handleInputChange
609
620
  // The visually-hidden native input is never focused (tabIndex={-1});
610
621
  // its describedby/required/invalid live on the trigger button.
@@ -41,6 +41,15 @@ import { type RefObject } from 'react';
41
41
  * - `none`: never open on touch
42
42
  */
43
43
  export type LayerTouchTrigger = 'auto' | 'tap' | 'none';
44
+ /**
45
+ * Pointer types whose *press* is a tap rather than a click.
46
+ *
47
+ * A pen belongs here but not in the arrival path: in detection range it hovers
48
+ * — firing `pointerenter`/`pointermove` with no contact, exactly as a mouse
49
+ * does, on a device where `(hover: hover)` matches — and only becomes a tap
50
+ * once it lands. See `handlePointerEnter`.
51
+ */
52
+ export declare const TOUCH_POINTER_TYPES: Set<string>;
44
53
  /**
45
54
  * Whether activating this element does something other than reveal the layer.
46
55
  *
@@ -1 +1 @@
1
- {"version":3,"file":"useTouchTrigger.d.ts","sourceRoot":"","sources":["../../src/Layer/useTouchTrigger.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAEH,OAAO,EAAiC,KAAK,SAAS,EAAC,MAAM,OAAO,CAAC;AAOrE;;;;;;GAMG;AACH,MAAM,MAAM,iBAAiB,GAAG,MAAM,GAAG,KAAK,GAAG,MAAM,CAAC;AAmCxD;;;;;;;;;;;GAWG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAoB7D;AAeD,MAAM,WAAW,sBAAsB;IACrC,sDAAsD;IACtD,YAAY,EAAE,iBAAiB,CAAC;IAEhC,oDAAoD;IACpD,SAAS,EAAE,OAAO,CAAC;IAEnB;;;OAGG;IACH,YAAY,EAAE,OAAO,CAAC;IAEtB,2CAA2C;IAC3C,MAAM,EAAE,OAAO,CAAC;IAEhB,0EAA0E;IAC1E,OAAO,EAAE,MAAM,CAAC;IAEhB,oDAAoD;IACpD,UAAU,EAAE,SAAS,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC;IAE1C,uDAAuD;IACvD,IAAI,EAAE,MAAM,IAAI,CAAC;IAEjB,mCAAmC;IACnC,IAAI,EAAE,MAAM,IAAI,CAAC;CAClB;AAED,MAAM,WAAW,qBAAqB;IACpC;;;;OAIG;IACH,iBAAiB,EAAE,SAAS,CAAC,OAAO,CAAC,CAAC;IAEtC;;;;OAIG;IACH,kBAAkB,EAAE,MAAM,OAAO,CAAC;IAElC;;;;OAIG;IACH,kBAAkB,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,IAAI,CAAC;IAElD;;;;;;OAMG;IACH,iBAAiB,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,OAAO,CAAC;IAEpD,gFAAgF;IAChF,YAAY,EAAE,MAAM,IAAI,CAAC;CAC1B;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,eAAe,CAC7B,OAAO,EAAE,sBAAsB,GAC9B,qBAAqB,CAuMvB"}
1
+ {"version":3,"file":"useTouchTrigger.d.ts","sourceRoot":"","sources":["../../src/Layer/useTouchTrigger.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAEH,OAAO,EAAiC,KAAK,SAAS,EAAC,MAAM,OAAO,CAAC;AAOrE;;;;;;GAMG;AACH,MAAM,MAAM,iBAAiB,GAAG,MAAM,GAAG,KAAK,GAAG,MAAM,CAAC;AAExD;;;;;;;GAOG;AACH,eAAO,MAAM,mBAAmB,aAA4B,CAAC;AAyB7D;;;;;;;;;;;GAWG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAoB7D;AAeD,MAAM,WAAW,sBAAsB;IACrC,sDAAsD;IACtD,YAAY,EAAE,iBAAiB,CAAC;IAEhC,oDAAoD;IACpD,SAAS,EAAE,OAAO,CAAC;IAEnB;;;OAGG;IACH,YAAY,EAAE,OAAO,CAAC;IAEtB,2CAA2C;IAC3C,MAAM,EAAE,OAAO,CAAC;IAEhB,0EAA0E;IAC1E,OAAO,EAAE,MAAM,CAAC;IAEhB,oDAAoD;IACpD,UAAU,EAAE,SAAS,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC;IAE1C,uDAAuD;IACvD,IAAI,EAAE,MAAM,IAAI,CAAC;IAEjB,mCAAmC;IACnC,IAAI,EAAE,MAAM,IAAI,CAAC;CAClB;AAED,MAAM,WAAW,qBAAqB;IACpC;;;;OAIG;IACH,iBAAiB,EAAE,SAAS,CAAC,OAAO,CAAC,CAAC;IAEtC;;;;OAIG;IACH,kBAAkB,EAAE,MAAM,OAAO,CAAC;IAElC;;;;OAIG;IACH,kBAAkB,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,IAAI,CAAC;IAElD;;;;;;OAMG;IACH,iBAAiB,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,OAAO,CAAC;IAEpD,gFAAgF;IAChF,YAAY,EAAE,MAAM,IAAI,CAAC;CAC1B;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,eAAe,CAC7B,OAAO,EAAE,sBAAsB,GAC9B,qBAAqB,CAuMvB"}
@@ -56,7 +56,7 @@ import { getInteractionModality, useInteractionModalityTracking } from "../utils
56
56
  * does, on a device where `(hover: hover)` matches — and only becomes a tap
57
57
  * once it lands. See `handlePointerEnter`.
58
58
  */
59
- const TOUCH_POINTER_TYPES = new Set(['touch', 'pen']);
59
+ export const TOUCH_POINTER_TYPES = new Set(['touch', 'pen']);
60
60
 
61
61
  /**
62
62
  * ARIA roles that make an element do something when activated. An explicit
@@ -1 +1 @@
1
- {"version":3,"file":"NumberInput.d.ts","sourceRoot":"","sources":["../../src/NumberInput/NumberInput.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"NumberInput.d.ts","sourceRoot":"","sources":["../../src/NumberInput/NumberInput.tsx"],"names":[],"mappings":"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"}
@@ -17,7 +17,8 @@
17
17
  * - /apps/storybook/stories/NumberInput.stories.tsx (storybook stories)
18
18
  * - /packages/cli/assets/templates/blocks/components/NumberInput/ (showcase blocks)
19
19
  */
20
- import { use, useId, useState, useMemo, useCallback, useLayoutEffect, useRef } from 'react';
20
+ import { use, useId, useState, useMemo, useCallback, useRef } from 'react';
21
+ import { flushSync } from 'react-dom';
21
22
  import * as stylex from '@stylexjs/stylex';
22
23
  import "../theme/tokens.stylex.js";
23
24
  import { colorVars, sizeVars, spacingVars, typographyVars, typeScaleVars, borderVars } from "../theme/tokens.stylex.js";
@@ -367,27 +368,22 @@ export function NumberInput({
367
368
  // `formatValue` the text at rest differs from the editable text, and putting
368
369
  // the editable text in the input after focus collapses that selection to the
369
370
  // end, so typing would append. When focus arrives with the text selected,
370
- // select the swapped-in text too.
371
- const reselectOnFocusRef = useRef(false);
371
+ // the focus handler commits the swap and selects the swapped-in text itself:
372
+ // the work one event causes stays in its handler
373
+ // (architecture:react-component-runtime/INV2).
372
374
  const handleFocus = useCallback(e => {
373
375
  const input = e.currentTarget;
374
- // Only when focusing swaps the text: otherwise no render follows to
375
- // consume the flag, and the first keystroke would.
376
376
  const editableText = pendingInput ?? (value == null ? '' : formatEditableNumber(value, locale));
377
- reselectOnFocusRef.current = input.value.length > 0 && input.value !== editableText && input.selectionStart === 0 && input.selectionEnd === input.value.length;
377
+ const shouldReselect = input.value.length > 0 && input.value !== editableText && input.selectionStart === 0 && input.selectionEnd === input.value.length;
378
378
  setIsFocused(true);
379
379
  onFocus?.(e);
380
- }, [onFocus, pendingInput, value, locale]);
381
- useLayoutEffect(() => {
382
- if (!reselectOnFocusRef.current) {
383
- return;
384
- }
385
- reselectOnFocusRef.current = false;
386
- const input = inputRef.current;
387
- if (input != null && input === document.activeElement) {
380
+ if (shouldReselect) {
381
+ // Commit the swap now, so the editable text is in the input to select.
382
+ // eslint-disable-next-line @eslint-react/dom-no-flush-sync -- the editable text must be in the input before the focus event selects it
383
+ flushSync(() => {});
388
384
  input.setSelectionRange(0, input.value.length);
389
385
  }
390
- }, [displayValue]);
386
+ }, [onFocus, pendingInput, value, locale]);
391
387
  const commitPendingInput = useCallback(trigger => {
392
388
  if (pendingInput === null) {
393
389
  return;
@@ -1 +1 @@
1
- {"version":3,"file":"Slider.d.ts","sourceRoot":"","sources":["../../src/Slider/Slider.tsx"],"names":[],"mappings":"AA2CA,OAAO,KAAK,EAAC,WAAW,EAAC,MAAM,gBAAgB,CAAC;AAShD,OAAO,EACL,KAAK,mBAAmB,EAEzB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,gBAAgB,CAAC;AAU9C,MAAM,WAAW,eAAgB,SAAQ,IAAI,CAC3C,mBAAmB,CAAC,cAAc,CAAC,EACnC,UAAU,CACX;IACC,mDAAmD;IACnD,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IAChC,qEAAqE;IACrE,KAAK,EAAE,MAAM,CAAC;IACd,8FAA8F;IAC9F,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,kDAAkD;IAClD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,qDAAqD;IACrD,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;;;;;;;;;;;;;;;;;OAmBG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,oDAAoD;IACpD,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,oDAAoD;IACpD,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,uCAAuC;IACvC,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB;;;;OAIG;IACH,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,uEAAuE;IACvE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,gCAAgC;IAChC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,kCAAkC;IAClC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,iCAAiC;IACjC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,uDAAuD;IACvD,WAAW,CAAC,EAAE,YAAY,GAAG,UAAU,CAAC;IACxC,uEAAuE;IACvE,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;IACxC,6DAA6D;IAC7D,YAAY,CAAC,EAAE,SAAS,GAAG,MAAM,GAAG,MAAM,CAAC;IAC3C,8DAA8D;IAC9D,KAAK,CAAC,EAAE;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAC,EAAE,CAAC;IAC1C;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,oCAAoC;IACpC,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,iBAAkB,SAAQ,eAAe;IACxD,yCAAyC;IACzC,KAAK,EAAE,MAAM,CAAC;IACd,kDAAkD;IAClD,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACnC,iEAAiE;IACjE,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CACvC;AAED,MAAM,WAAW,gBAAiB,SAAQ,eAAe;IACvD,8CAA8C;IAC9C,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACxB,kDAAkD;IAClD,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,KAAK,IAAI,CAAC;IAC7C,iEAAiE;IACjE,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,KAAK,IAAI,CAAC;IAChD,8CAA8C;IAC9C,qBAAqB,CAAC,EAAE,MAAM,CAAC;CAChC;AAED,MAAM,MAAM,WAAW,GAAG,iBAAiB,GAAG,gBAAgB,CAAC;AAmT/D;;;;;;;;GAQG;AACH,wBAAgB,MAAM,CAAC,EAAC,GAAG,EAAE,GAAG,KAAK,EAAC,EAAE,WAAW,+BA6zBlD;yBA7zBe,MAAM"}
1
+ {"version":3,"file":"Slider.d.ts","sourceRoot":"","sources":["../../src/Slider/Slider.tsx"],"names":[],"mappings":"AA2CA,OAAO,KAAK,EAAC,WAAW,EAAC,MAAM,gBAAgB,CAAC;AAShD,OAAO,EACL,KAAK,mBAAmB,EAEzB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,gBAAgB,CAAC;AAU9C,MAAM,WAAW,eAAgB,SAAQ,IAAI,CAC3C,mBAAmB,CAAC,cAAc,CAAC,EACnC,UAAU,CACX;IACC,mDAAmD;IACnD,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IAChC,qEAAqE;IACrE,KAAK,EAAE,MAAM,CAAC;IACd,8FAA8F;IAC9F,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,kDAAkD;IAClD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,qDAAqD;IACrD,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;;;;;;;;;;;;;;;;;OAmBG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,oDAAoD;IACpD,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,oDAAoD;IACpD,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,uCAAuC;IACvC,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB;;;;OAIG;IACH,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,uEAAuE;IACvE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,gCAAgC;IAChC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,kCAAkC;IAClC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,iCAAiC;IACjC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,uDAAuD;IACvD,WAAW,CAAC,EAAE,YAAY,GAAG,UAAU,CAAC;IACxC,uEAAuE;IACvE,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;IACxC,6DAA6D;IAC7D,YAAY,CAAC,EAAE,SAAS,GAAG,MAAM,GAAG,MAAM,CAAC;IAC3C,8DAA8D;IAC9D,KAAK,CAAC,EAAE;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAC,EAAE,CAAC;IAC1C;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,oCAAoC;IACpC,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,iBAAkB,SAAQ,eAAe;IACxD,yCAAyC;IACzC,KAAK,EAAE,MAAM,CAAC;IACd,kDAAkD;IAClD,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACnC,iEAAiE;IACjE,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CACvC;AAED,MAAM,WAAW,gBAAiB,SAAQ,eAAe;IACvD,8CAA8C;IAC9C,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACxB,kDAAkD;IAClD,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,KAAK,IAAI,CAAC;IAC7C,iEAAiE;IACjE,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,KAAK,IAAI,CAAC;IAChD,8CAA8C;IAC9C,qBAAqB,CAAC,EAAE,MAAM,CAAC;CAChC;AAED,MAAM,MAAM,WAAW,GAAG,iBAAiB,GAAG,gBAAgB,CAAC;AAmT/D;;;;;;;;GAQG;AACH,wBAAgB,MAAM,CAAC,EAAC,GAAG,EAAE,GAAG,KAAK,EAAC,EAAE,WAAW,+BAy5BlD;yBAz5Be,MAAM"}
@@ -5,7 +5,7 @@
5
5
  /**
6
6
  * @file Slider.tsx
7
7
  * @input Uses React, useId, useRef, useCallback, useEffect, Field, Tooltip, useTooltip, VisuallyHidden
8
- * @output Exports Slider and its props; unfilled marks share the track token; modifier-only key presses do not restore the thumb focus ring; a drag belongs to the pointer that started it
8
+ * @output Exports Slider and its props; unfilled marks share the track token; modifier-only key presses do not restore the thumb focus ring; a drag belongs to the pointer that started it; two coincident range thumbs separate toward the press or the first movement
9
9
  * @position Core implementation; consumed by index.ts, tested by Slider.test.tsx
10
10
  *
11
11
  * SYNC: When modified, update these files to stay in sync:
@@ -422,7 +422,19 @@ export function Slider({
422
422
  // Prefer the lower thumb if equidistant
423
423
  return d0 <= d1 ? 0 : 1;
424
424
  }, [isRange, values]);
425
- const updateValue = useCallback((thumbIndex, newVal, snap = true) => {
425
+
426
+ // The pointer's value at a press on two coincident thumbs, while no
427
+ // movement has said which way the drag goes; the first value off it picks
428
+ // the thumb that can travel that way (see handlePointerMove).
429
+ const coincidentDragRef = useRef(null);
430
+ // Whether the drag in progress began on two coincident thumbs: such a drag
431
+ // can always follow the pointer, so when the dragged thumb is held against
432
+ // the other one and the pointer passes it, the other thumb takes the drag.
433
+ const coincidentOriginRef = useRef(false);
434
+ const updateValue = useCallback((thumbIndex, newVal, snap = true,
435
+ // The other thumb's values to start from, when one event moves both
436
+ // (a drag handed from one coincident thumb to the other).
437
+ from = values) => {
426
438
  if (isDisabled) {
427
439
  return;
428
440
  }
@@ -431,7 +443,7 @@ export function Slider({
431
443
  // grid (max 100 with step 3 snapped End to 99, not 100).
432
444
  const clamped = clamp(snap ? snapToStep(newVal, min, step) : newVal, min, max);
433
445
  if (isRange) {
434
- const currentValues = [...values];
446
+ const currentValues = [...from];
435
447
  currentValues[thumbIndex] = clamped;
436
448
 
437
449
  // Enforce minStepsBetweenThumbs
@@ -479,6 +491,8 @@ export function Slider({
479
491
  detachLostCaptureRef.current = null;
480
492
  draggingThumbRef.current = null;
481
493
  dragPointerRef.current = null;
494
+ coincidentDragRef.current = null;
495
+ coincidentOriginRef.current = false;
482
496
  setDraggingThumb(null);
483
497
  fireChangeEnd();
484
498
  }
@@ -505,12 +519,29 @@ export function Slider({
505
519
  const thumbs = track?.querySelectorAll('[role="slider"]');
506
520
  const pressedThumb = e.target.closest('[role="slider"]');
507
521
  const pressedThumbIndex = pressedThumb == null || thumbs == null ? -1 : Array.from(thumbs).indexOf(pressedThumb);
508
- // A direct thumb press owns that thumb even when range values coincide.
509
- // Track and mark presses still choose the nearest value.
510
- const thumbIndex = pressedThumbIndex >= 0 ? pressedThumbIndex : getClosestThumb(newVal);
522
+ // A direct thumb press owns that thumb; track and mark presses choose
523
+ // the nearest value. Two thumbs on one value are the exception: only
524
+ // one of them can travel toward where the pointer goes. A track press
525
+ // beside them picks the thumb on its side. A press on the thumbs
526
+ // themselves (or on their shared value) moves nothing: the pressed
527
+ // thumb holds the press until the pointer moves, and the direction of
528
+ // that first movement from the press picks the thumb.
529
+ const isCoincident = isRange && values[0] === values[1];
530
+ let thumbIndex = pressedThumbIndex >= 0 ? pressedThumbIndex : getClosestThumb(newVal);
531
+ const parks = isCoincident && (pressedThumbIndex >= 0 || newVal === values[0]);
532
+ // The first movement is measured from the pointer itself, not from a
533
+ // mark it pressed (a wide label sits away from its mark's value).
534
+ coincidentDragRef.current = parks ? getValueFromPosition(e.clientX, e.clientY) : null;
535
+ // Only a drag that began on the shared thumbs, the press that waited for
536
+ // the first movement, hands itself to the other thumb (FR6); a track
537
+ // press beside them already picked its thumb.
538
+ coincidentOriginRef.current = parks;
539
+ if (isCoincident && !parks) {
540
+ thumbIndex = newVal > values[0] ? 1 : 0;
541
+ }
511
542
  draggingThumbRef.current = thumbIndex;
512
543
  setDraggingThumb(thumbIndex);
513
- updateValue(thumbIndex, newVal);
544
+ updateValue(thumbIndex, parks ? values[thumbIndex] : newVal);
514
545
 
515
546
  // Focus the thumb that owns this drag.
516
547
  thumbs?.[thumbIndex]?.focus();
@@ -533,12 +564,50 @@ export function Slider({
533
564
  if (typeof e.currentTarget.setPointerCapture === 'function') {
534
565
  e.currentTarget.setPointerCapture(e.pointerId);
535
566
  }
536
- }, [isDisabled, getValueFromPosition, getClosestThumb, updateValue, endDrag]);
567
+ }, [isDisabled, isRange, values, getValueFromPosition, getClosestThumb, updateValue, endDrag]);
537
568
  const handlePointerMove = useCallback(e => {
538
569
  if (draggingThumbRef.current === null || e.pointerId !== dragPointerRef.current || isDisabled) {
539
570
  return;
540
571
  }
541
572
  const newVal = getValueFromPosition(e.clientX, e.clientY);
573
+ // Hands the drag to a thumb, with its focus and pressed paint.
574
+ const handTo = thumbIndex => {
575
+ if (thumbIndex === draggingThumbRef.current) {
576
+ return;
577
+ }
578
+ draggingThumbRef.current = thumbIndex;
579
+ setDraggingThumb(thumbIndex);
580
+ const thumbs = trackRef.current?.querySelectorAll('[role="slider"]');
581
+ thumbs?.[thumbIndex]?.focus();
582
+ setKeyboardFocusThumb(null);
583
+ };
584
+ const pressValue = coincidentDragRef.current;
585
+ if (pressValue !== null) {
586
+ if (newVal === pressValue) {
587
+ return;
588
+ }
589
+ // The first movement from a press on coincident thumbs hands the
590
+ // drag to the thumb that can travel that way.
591
+ coincidentDragRef.current = null;
592
+ handTo(newVal > pressValue ? 1 : 0);
593
+ } else if (coincidentOriginRef.current) {
594
+ // A drag that began on coincident thumbs follows the pointer either
595
+ // way: once the pointer passes the other thumb, the dragged one stops
596
+ // against it and the other takes the drag (a first step that drifted
597
+ // the wrong way never sticks the drag).
598
+ const current = valuesRef.current;
599
+ const dragging = draggingThumbRef.current;
600
+ const other = dragging === 0 ? 1 : 0;
601
+ if (dragging === 0 && newVal > current[1] || dragging === 1 && newVal < current[0]) {
602
+ // The dragged thumb ends against the other one, as if it had
603
+ // followed the pointer there, and the other follows the pointer on.
604
+ const from = [...current];
605
+ from[dragging] = current[other];
606
+ handTo(other);
607
+ updateValue(other, newVal, true, from);
608
+ return;
609
+ }
610
+ }
542
611
  updateValue(draggingThumbRef.current, newVal);
543
612
  }, [isDisabled, getValueFromPosition, updateValue]);
544
613
  const handlePointerUp = useCallback(e => endDrag(e.pointerId), [endDrag]);
@@ -685,8 +754,11 @@ export function Slider({
685
754
  content: displayValue(val),
686
755
  placement: tooltipPlacement,
687
756
  delay: 0,
688
- focusTrigger: "always",
689
- isOpen: draggingThumb === thumbIndex ? true : undefined,
757
+ focusTrigger: "always"
758
+ // A drag keeps its own thumb's value showing and closes the other
759
+ // thumb's, which a drag handed over from it may have forced open.
760
+ ,
761
+ isOpen: draggingThumb === null ? undefined : draggingThumb === thumbIndex,
690
762
  children: thumbElement
691
763
  }, thumbIndex);
692
764
  }
@@ -1 +1 @@
1
- {"version":3,"file":"BaseTypeahead.d.ts","sourceRoot":"","sources":["../../src/Typeahead/BaseTypeahead.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,EAMZ,KAAK,SAAS,EACd,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAIf,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,kBAAkB,CAAC;AA2BnD,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAC5C,OAAO,KAAK,EAAC,cAAc,EAAE,YAAY,EAAC,MAAM,SAAS,CAAC;AAY1D,MAAM,WAAW,kBAAkB,CAAC,CAAC,SAAS,cAAc,CAAE,SAAQ,IAAI,CACxE,SAAS,CAAC,WAAW,CAAC,EACtB,UAAU,CACX;IACC,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;IAClC;;OAEG;IACH,YAAY,EAAE,YAAY,CAAC,CAAC,CAAC,CAAC;IAE9B;;OAEG;IACH,KAAK,EAAE,CAAC,GAAG,IAAI,CAAC;IAEhB;;OAEG;IACH,QAAQ,EAAE,CAAC,IAAI,EAAE,CAAC,GAAG,IAAI,KAAK,IAAI,CAAC;IAEnC;;OAEG;IACH,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,SAAS,CAAC;IAEpC;;OAEG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB;;;OAGG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAE5B;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB,mEAAmE;IACnE,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;;;;;;;;;OAUG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB;;;;;;;;;;;;;OAaG;IACH,eAAe,CAAC,EAAE,SAAS,CAAC;IAE5B;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IAErB;;;;;;;;;OASG;IACH,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAE9B;;;OAGG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;IAEvB;;OAEG;IACH,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAExC;;OAEG;IACH,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,IAAI,CAAC;IAEzC;;;;;;;;;;;;;;;;;;;OAmBG;IACH,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,EAAE,KAAK,CAAC,EAAE,CAAC;IAEtD;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB;;;OAGG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IAEzB;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB;;OAEG;IACH,WAAW,CAAC,EAAE,YAAY,CAAC;IAE3B;;;;;;;;OAQG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IAEvB;;;;OAIG;IACH,SAAS,CAAC,EAAE,SAAS,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC;IAE1C;;;OAGG;IACH,SAAS,CAAC,EAAE,CAAC,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC,gBAAgB,CAAC,KAAK,IAAI,CAAC;IAE/D;;;;OAIG;IACH,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;CAC3B;AAoKD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,aAAa,EAi7BrB,CAAC,CAAC,SAAS,cAAc,EAC5B,KAAK,EAAE,kBAAkB,CAAC,CAAC,CAAC,KACzB,KAAK,CAAC,YAAY,CAAC"}
1
+ {"version":3,"file":"BaseTypeahead.d.ts","sourceRoot":"","sources":["../../src/Typeahead/BaseTypeahead.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,EAMZ,KAAK,SAAS,EACd,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAIf,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,kBAAkB,CAAC;AA2BnD,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAC5C,OAAO,KAAK,EAAC,cAAc,EAAE,YAAY,EAAC,MAAM,SAAS,CAAC;AAY1D,MAAM,WAAW,kBAAkB,CAAC,CAAC,SAAS,cAAc,CAAE,SAAQ,IAAI,CACxE,SAAS,CAAC,WAAW,CAAC,EACtB,UAAU,CACX;IACC,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;IAClC;;OAEG;IACH,YAAY,EAAE,YAAY,CAAC,CAAC,CAAC,CAAC;IAE9B;;OAEG;IACH,KAAK,EAAE,CAAC,GAAG,IAAI,CAAC;IAEhB;;OAEG;IACH,QAAQ,EAAE,CAAC,IAAI,EAAE,CAAC,GAAG,IAAI,KAAK,IAAI,CAAC;IAEnC;;OAEG;IACH,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,SAAS,CAAC;IAEpC;;OAEG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB;;;OAGG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAE5B;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB,mEAAmE;IACnE,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;;;;;;;;;OAUG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB;;;;;;;;;;;;;OAaG;IACH,eAAe,CAAC,EAAE,SAAS,CAAC;IAE5B;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IAErB;;;;;;;;;OASG;IACH,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAE9B;;;OAGG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;IAEvB;;OAEG;IACH,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAExC;;OAEG;IACH,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,IAAI,CAAC;IAEzC;;;;;;;;;;;;;;;;;;;OAmBG;IACH,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,EAAE,KAAK,CAAC,EAAE,CAAC;IAEtD;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB;;;OAGG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IAEzB;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB;;OAEG;IACH,WAAW,CAAC,EAAE,YAAY,CAAC;IAE3B;;;;;;;;OAQG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IAEvB;;;;OAIG;IACH,SAAS,CAAC,EAAE,SAAS,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC;IAE1C;;;OAGG;IACH,SAAS,CAAC,EAAE,CAAC,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC,gBAAgB,CAAC,KAAK,IAAI,CAAC;IAE/D;;;;OAIG;IACH,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;CAC3B;AAoKD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,aAAa,EAi8BrB,CAAC,CAAC,SAAS,cAAc,EAC5B,KAAK,EAAE,kBAAkB,CAAC,CAAC,CAAC,KACzB,KAAK,CAAC,YAAY,CAAC"}