@particle-academy/react-fancy 5.65.0 → 5.67.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 (106) hide show
  1. package/CHANGELOG.md +74 -0
  2. package/dist/{PastePills.types-CDyotkUb.d.cts → PastePills.types-CpXzsuwJ.d.cts} +2 -0
  3. package/dist/{PastePills.types-CDyotkUb.d.ts → PastePills.types-CpXzsuwJ.d.ts} +2 -0
  4. package/dist/{PastedFilesInput-CrgNoEBd.d.ts → PastedFilesInput-Bt3KSTVN.d.ts} +1 -1
  5. package/dist/{PastedFilesInput-DQ1eZaHk.d.cts → PastedFilesInput-CUQeOeOA.d.cts} +1 -1
  6. package/dist/button.cjs +3 -4
  7. package/dist/button.js +1 -2
  8. package/dist/{chunk-COXHFZR6.js → chunk-23AVEYUP.js} +14 -8
  9. package/dist/chunk-23AVEYUP.js.map +1 -0
  10. package/dist/{chunk-C5YX5XVL.cjs → chunk-3U7PUZLI.cjs} +214 -4
  11. package/dist/chunk-3U7PUZLI.cjs.map +1 -0
  12. package/dist/{chunk-ATIDUWY6.cjs → chunk-4S5DFN5N.cjs} +12 -12
  13. package/dist/{chunk-ATIDUWY6.cjs.map → chunk-4S5DFN5N.cjs.map} +1 -1
  14. package/dist/{chunk-CMC2TOEQ.cjs → chunk-6CAXLP7D.cjs} +6 -6
  15. package/dist/{chunk-CMC2TOEQ.cjs.map → chunk-6CAXLP7D.cjs.map} +1 -1
  16. package/dist/{chunk-TQGRXJ74.cjs → chunk-7FYRFNPX.cjs} +9 -9
  17. package/dist/{chunk-TQGRXJ74.cjs.map → chunk-7FYRFNPX.cjs.map} +1 -1
  18. package/dist/{chunk-MVVHUTXA.js → chunk-B4LVQ4QI.js} +3 -3
  19. package/dist/{chunk-MVVHUTXA.js.map → chunk-B4LVQ4QI.js.map} +1 -1
  20. package/dist/{chunk-QP35Z2WB.js → chunk-BL5IKSB3.js} +3 -3
  21. package/dist/{chunk-QP35Z2WB.js.map → chunk-BL5IKSB3.js.map} +1 -1
  22. package/dist/{chunk-SZH7TFME.js → chunk-DCAD2JPP.js} +4 -4
  23. package/dist/{chunk-SZH7TFME.js.map → chunk-DCAD2JPP.js.map} +1 -1
  24. package/dist/{chunk-MCQJFMDP.cjs → chunk-E5UU666U.cjs} +478 -36
  25. package/dist/chunk-E5UU666U.cjs.map +1 -0
  26. package/dist/{chunk-L24LUSEE.js → chunk-FXOT4P4P.js} +478 -36
  27. package/dist/chunk-FXOT4P4P.js.map +1 -0
  28. package/dist/{chunk-CAUEKGMR.js → chunk-HEY4SMS2.js} +4 -4
  29. package/dist/{chunk-CAUEKGMR.js.map → chunk-HEY4SMS2.js.map} +1 -1
  30. package/dist/{chunk-QNQNGARW.cjs → chunk-HFK5SBNM.cjs} +27 -9
  31. package/dist/chunk-HFK5SBNM.cjs.map +1 -0
  32. package/dist/{chunk-TLRRMYNV.js → chunk-OXERDFFF.js} +212 -4
  33. package/dist/chunk-OXERDFFF.js.map +1 -0
  34. package/dist/{chunk-ELFTEJBT.js → chunk-QSGAFKK2.js} +3 -3
  35. package/dist/{chunk-ELFTEJBT.js.map → chunk-QSGAFKK2.js.map} +1 -1
  36. package/dist/{chunk-SYEHWUM5.cjs → chunk-RALJMI7C.cjs} +4 -4
  37. package/dist/{chunk-SYEHWUM5.cjs.map → chunk-RALJMI7C.cjs.map} +1 -1
  38. package/dist/{chunk-UM4JXBRZ.cjs → chunk-S3NB6LDV.cjs} +4 -4
  39. package/dist/{chunk-UM4JXBRZ.cjs.map → chunk-S3NB6LDV.cjs.map} +1 -1
  40. package/dist/{chunk-C463C4MM.cjs → chunk-SAG6DHQK.cjs} +22 -16
  41. package/dist/chunk-SAG6DHQK.cjs.map +1 -0
  42. package/dist/{chunk-4XHG6Q42.cjs → chunk-U5LKNGHU.cjs} +21 -21
  43. package/dist/{chunk-4XHG6Q42.cjs.map → chunk-U5LKNGHU.cjs.map} +1 -1
  44. package/dist/{chunk-M52S3TFI.js → chunk-WFR7HKJL.js} +3 -3
  45. package/dist/{chunk-M52S3TFI.js.map → chunk-WFR7HKJL.js.map} +1 -1
  46. package/dist/{chunk-NILA2LZY.js → chunk-YIKXJWO4.js} +27 -9
  47. package/dist/chunk-YIKXJWO4.js.map +1 -0
  48. package/dist/composer.cjs +4 -4
  49. package/dist/composer.d.cts +2 -2
  50. package/dist/composer.d.ts +2 -2
  51. package/dist/composer.js +2 -2
  52. package/dist/content-renderer.cjs +7 -5
  53. package/dist/content-renderer.d.cts +56 -4
  54. package/dist/content-renderer.d.ts +56 -4
  55. package/dist/content-renderer.js +4 -2
  56. package/dist/editor.cjs +6 -5
  57. package/dist/editor.d.cts +1 -1
  58. package/dist/editor.d.ts +1 -1
  59. package/dist/editor.js +4 -3
  60. package/dist/{extensions-6PVd3-vB.d.cts → extensions-DiByZIpD.d.cts} +26 -3
  61. package/dist/{extensions-6PVd3-vB.d.ts → extensions-DiByZIpD.d.ts} +26 -3
  62. package/dist/{index-CCJVT9Hu.d.cts → index-DWtSViJ3.d.cts} +7 -1
  63. package/dist/{index-DRlltbdV.d.ts → index-XR5t8bTq.d.ts} +7 -1
  64. package/dist/index.cjs +47 -48
  65. package/dist/index.cjs.map +1 -1
  66. package/dist/index.d.cts +5 -5
  67. package/dist/index.d.ts +5 -5
  68. package/dist/index.js +10 -11
  69. package/dist/index.js.map +1 -1
  70. package/dist/input.cjs +3 -3
  71. package/dist/input.d.cts +1 -1
  72. package/dist/input.d.ts +1 -1
  73. package/dist/input.js +2 -2
  74. package/dist/inputs.cjs +3 -3
  75. package/dist/inputs.d.cts +1 -1
  76. package/dist/inputs.d.ts +1 -1
  77. package/dist/inputs.js +2 -2
  78. package/dist/json-editor.cjs +15 -16
  79. package/dist/json-editor.js +4 -5
  80. package/dist/magic-wand.cjs +3 -4
  81. package/dist/magic-wand.js +2 -3
  82. package/dist/paste-pills.cjs +14 -14
  83. package/dist/paste-pills.d.cts +3 -3
  84. package/dist/paste-pills.d.ts +3 -3
  85. package/dist/paste-pills.js +1 -1
  86. package/dist/prompt-input.cjs +6 -7
  87. package/dist/prompt-input.d.cts +2 -2
  88. package/dist/prompt-input.d.ts +2 -2
  89. package/dist/prompt-input.js +3 -4
  90. package/dist/reason-tag.cjs +3 -4
  91. package/dist/reason-tag.js +2 -3
  92. package/docs/ContentRenderer.md +138 -3
  93. package/docs/PromptInput.md +24 -1
  94. package/package.json +1 -1
  95. package/dist/chunk-6TBRBN7H.js +0 -212
  96. package/dist/chunk-6TBRBN7H.js.map +0 -1
  97. package/dist/chunk-C463C4MM.cjs.map +0 -1
  98. package/dist/chunk-C5YX5XVL.cjs.map +0 -1
  99. package/dist/chunk-COXHFZR6.js.map +0 -1
  100. package/dist/chunk-L24LUSEE.js.map +0 -1
  101. package/dist/chunk-MCQJFMDP.cjs.map +0 -1
  102. package/dist/chunk-NILA2LZY.js.map +0 -1
  103. package/dist/chunk-QNQNGARW.cjs.map +0 -1
  104. package/dist/chunk-TLRRMYNV.js.map +0 -1
  105. package/dist/chunk-X2FC7ODX.cjs +0 -215
  106. package/dist/chunk-X2FC7ODX.cjs.map +0 -1
@@ -4,7 +4,7 @@ var chunkMRZXTL46_cjs = require('./chunk-MRZXTL46.cjs');
4
4
  var chunkP53432AK_cjs = require('./chunk-P53432AK.cjs');
5
5
  var chunkQF7CD4JH_cjs = require('./chunk-QF7CD4JH.cjs');
6
6
  var chunkO3F6DYWR_cjs = require('./chunk-O3F6DYWR.cjs');
7
- var chunkQNQNGARW_cjs = require('./chunk-QNQNGARW.cjs');
7
+ var chunkHFK5SBNM_cjs = require('./chunk-HFK5SBNM.cjs');
8
8
  var chunkKJ22KE56_cjs = require('./chunk-KJ22KE56.cjs');
9
9
  var chunkL3V3BYVS_cjs = require('./chunk-L3V3BYVS.cjs');
10
10
  var chunkSNHU2AI4_cjs = require('./chunk-SNHU2AI4.cjs');
@@ -82,7 +82,7 @@ var Input = react.forwardRef(
82
82
  const pasting = pasteThreshold !== void 0 || pasteImages;
83
83
  const editorRef = react.useRef(null);
84
84
  const hiddenRef = react.useRef(null);
85
- const paste = chunkQNQNGARW_cjs.useInlinePaste({
85
+ const paste = chunkHFK5SBNM_cjs.useInlinePaste({
86
86
  pasteThreshold,
87
87
  pasteImages,
88
88
  previewChars,
@@ -136,7 +136,7 @@ var Input = react.forwardRef(
136
136
  ),
137
137
  pasting ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
138
138
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "min-w-0 flex-1", children: /* @__PURE__ */ jsxRuntime.jsx(
139
- chunkQNQNGARW_cjs.InlinePasteEditor,
139
+ chunkHFK5SBNM_cjs.InlinePasteEditor,
140
140
  {
141
141
  ref: editorRef,
142
142
  id: inputId,
@@ -188,7 +188,7 @@ var Input = react.forwardRef(
188
188
  value: paste.expand(pasteValue)
189
189
  }
190
190
  ),
191
- pasteImages && filesName && /* @__PURE__ */ jsxRuntime.jsx(chunkQNQNGARW_cjs.PastedFilesInput, { name: filesName, files: pastedFiles, form: props.form })
191
+ pasteImages && filesName && /* @__PURE__ */ jsxRuntime.jsx(chunkHFK5SBNM_cjs.PastedFilesInput, { name: filesName, files: pastedFiles, form: props.form })
192
192
  ] }) : /* @__PURE__ */ jsxRuntime.jsx(
193
193
  "input",
194
194
  {
@@ -300,5 +300,5 @@ function EyeOffIcon() {
300
300
  }
301
301
 
302
302
  exports.Input = Input;
303
- //# sourceMappingURL=chunk-CMC2TOEQ.cjs.map
304
- //# sourceMappingURL=chunk-CMC2TOEQ.cjs.map
303
+ //# sourceMappingURL=chunk-6CAXLP7D.cjs.map
304
+ //# sourceMappingURL=chunk-6CAXLP7D.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/hooks/use-adornment-width.ts","../src/components/inputs/Input/Input.tsx"],"names":["useState","useCallback","useEffect","forwardRef","useId","useFieldMode","useInlineEdit","useControllableState","useRef","useInlinePaste","useMemo","jsx","DisplayValue","InputWrapper","jsxs","Fragment","InlinePasteEditor","cn","inputBaseClasses","inputSizeClasses","dirtyClasses","errorClasses","PastedFilesInput","Field"],"mappings":";;;;;;;;;;;;;;AA0BO,SAAS,iBAAA,GAAkE;AAChF,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAIA,eAAS,CAAC,CAAA;AACpC,EAAA,MAAM,CAAC,IAAA,EAAM,OAAO,CAAA,GAAIA,eAA6B,IAAI,CAAA;AAEzD,EAAA,MAAM,GAAA,GAAMC,kBAAY,CAAC,CAAA,KAA0B,QAAQ,CAAC,CAAA,EAAG,EAAE,CAAA;AAEjE,EAAAC,eAAA,CAAU,MAAM;AACd,IAAA,IAAI,CAAC,IAAA,EAAM;AACT,MAAA,QAAA,CAAS,CAAC,CAAA;AAEV,MAAA;AAAA,IACF;AAEA,IAAA,MAAM,OAAO,MAAM,QAAA,CAAS,IAAA,CAAK,qBAAA,GAAwB,KAAK,CAAA;AAC9D,IAAA,IAAA,EAAK;AAEL,IAAA,IAAI,OAAO,mBAAmB,WAAA,EAAa;AAE3C,IAAA,MAAM,QAAA,GAAW,IAAI,cAAA,CAAe,IAAI,CAAA;AACxC,IAAA,QAAA,CAAS,QAAQ,IAAI,CAAA;AAErB,IAAA,OAAO,MAAM,SAAS,UAAA,EAAW;AAAA,EACnC,CAAA,EAAG,CAAC,IAAI,CAAC,CAAA;AAET,EAAA,OAAO,CAAC,KAAK,KAAK,CAAA;AACpB;AC5BO,IAAM,KAAA,GAAQC,gBAAA;AAAA,EACnB,CACE;AAAA,IACE,IAAA,GAAO,MAAA;AAAA,IACP,IAAA,GAAO,IAAA;AAAA,IACP,KAAA;AAAA,IACA,KAAA;AAAA,IACA,KAAA;AAAA,IACA,WAAA;AAAA,IACA,WAAA;AAAA,IACA,QAAA;AAAA,IACA,QAAA;AAAA,IACA,SAAA;AAAA,IACA,EAAA;AAAA,IACA,OAAA;AAAA,IACA,QAAA;AAAA,IACA,MAAA;AAAA,IACA,MAAA;AAAA,IACA,cAAA;AAAA,IACA,cAAA;AAAA,IACA,IAAA;AAAA,IACA,aAAA;AAAA,IACA,QAAA;AAAA,IACA,MAAA;AAAA,IACA,QAAA;AAAA,IACA,gBAAA;AAAA,IACA,WAAA,GAAc,eAAA;AAAA,IACd,SAAA,GAAY,eAAA;AAAA,IACZ,cAAA;AAAA,IACA,WAAA,GAAc,KAAA;AAAA,IACd,cAAA;AAAA,IACA,YAAA,GAAe,EAAA;AAAA,IACf,kBAAA;AAAA,IACA,eAAA;AAAA,IACA,UAAA;AAAA,IACA,kBAAA;AAAA,IACA,UAAA;AAAA,IACA,kBAAA;AAAA,IACA,GAAG;AAAA,KAEL,GAAA,KACG;AACH,IAAA,MAAM,SAASC,WAAA,EAAM;AACrB,IAAA,MAAM,UAAU,EAAA,IAAM,MAAA;AACtB,IAAA,MAAM,YAAA,GAAeC,+BAAa,IAAI,CAAA;AACtC,IAAA,MAAM,EAAE,aAAa,WAAA,EAAa,SAAA,EAAW,UAAS,GAAIC,+BAAA,CAAc,cAAc,QAAQ,CAAA;AAK9F,IAAA,MAAM,CAAC,UAAA,EAAY,YAAY,CAAA,GAAI,iBAAA,EAAkB;AACrD,IAAA,MAAM,CAAC,WAAA,EAAa,aAAa,CAAA,GAAI,iBAAA,EAAkB;AAIvD,IAAA,MAAM,SAAA,GAAY,MAAA,KAAW,IAAA,IAAQ,IAAA,KAAS,UAAA;AAC9C,IAAA,MAAM,CAAC,UAAA,EAAY,WAAW,IAAIC,sCAAA,CAAqB,QAAA,EAAU,OAAO,gBAAgB,CAAA;AACxF,IAAA,MAAM,QAAQ,SAAA,IAAa,UAAA;AAG3B,IAAA,MAAM,YAAA,GAAe,QAAQ,MAAA,GAAS,IAAA;AAOtC,IAAA,MAAM,OAAA,GAAU,mBAAmB,MAAA,IAAa,WAAA;AAChD,IAAA,MAAM,SAAA,GAAYC,aAAgC,IAAI,CAAA;AACtD,IAAA,MAAM,SAAA,GAAYA,aAAgC,IAAI,CAAA;AACtD,IAAA,MAAM,QAAQC,gCAAA,CAAe;AAAA,MAC3B,cAAA;AAAA,MACA,WAAA;AAAA,MACA,YAAA;AAAA,MACA,kBAAA;AAAA,MACA,UAAA,EAAY,eAAA;AAAA,MACZ,UAAU,QAAA,KAAa,IAAA;AAAA,MACvB,UAAA;AAAA,MACA,kBAAA;AAAA,MACA,UAAA;AAAA,MACA,kBAAA;AAAA,MACA,SAAA;AAAA,MACA,SAAA,EAAW;AAAA,KACZ,CAAA;AACD,IAAA,MAAM,CAAC,UAAA,EAAY,aAAa,CAAA,GAAIF,sCAAA;AAAA,MAClC,MAAM,KAAA,KAAU,MAAA,GAAY,MAAA,GAAY,MAAA,CAAO,MAAM,KAAK,CAAA;AAAA,MAC1D,MAAM,YAAA,KAAiB,MAAA,GAAY,EAAA,GAAK,MAAA,CAAO,MAAM,YAAY,CAAA;AAAA,MACjE;AAAA,KACF;AACA,IAAA,MAAM,YAAY,cAAA,KAAmB,KAAA,CAAM,OAAO,CAAA,EAAG,KAAA,CAAM,IAAI,CAAA,QAAA,CAAA,GAAa,MAAA,CAAA;AAC5E,IAAA,MAAM,WAAA,GAAcG,aAAA;AAAA,MAClB,MAAO,WAAA,GAAc,KAAA,CAAM,QAAA,CAAS,UAAU,CAAA,CAAE,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,CAAE,IAAI,CAAA,GAAI,EAAC;AAAA,MACtE,CAAC,WAAA,EAAa,KAAA,EAAO,UAAU;AAAA,KACjC;AACA,IAAA,MAAM,OAAA,GAAU,GAAG,OAAO,CAAA,MAAA,CAAA;AAE1B,IAAA,MAAM,KAAA,GAAQ,CAAC,WAAA,mBACbC,cAAA;AAAA,MAACC,8BAAA;AAAA,MAAA;AAAA,QACC,IAAA;AAAA,QACA,WAAA;AAAA,QACA,UAAA,EAAY,SAAA;AAAA,QACZ,SAAS,OAAA,IAAW,MAAA;AAAA,QACpB,UAAU,QAAA,IAAY,MAAA;AAAA,QAErB,mBAAS,UAAA,GAAc,KAAA,CAAM,KAAA,GAAQ,sCAAA,GAAW,KAAO,KAAA,CAAM;AAAA;AAAA,KAChE,mBAEAD,cAAA;AAAA,MAACE,8BAAA;AAAA,MAAA;AAAA,QACC,MAAA;AAAA,QACA,MAAA;AAAA,QACA,cAAA;AAAA,QACA,cAAA;AAAA,QACA,IAAA;AAAA,QAEA,QAAA,kBAAAC,eAAA,CAAC,KAAA,EAAA,EAAI,wBAAA,EAAuB,EAAA,EAAG,WAAU,4BAAA,EACtC,QAAA,EAAA;AAAA,UAAA,OAAA,oBACCH,cAAA;AAAA,YAAC,MAAA;AAAA,YAAA;AAAA,cACC,GAAA,EAAK,UAAA;AAAA,cACL,SAAA,EAAU,qKAAA;AAAA,cAET,QAAA,EAAA;AAAA;AAAA,WACH;AAAA,UAED,0BACCG,eAAA,CAAAC,mBAAA,EAAA,EACE,QAAA,EAAA;AAAA,4BAAAJ,cAAA,CAAC,KAAA,EAAA,EAAI,WAAU,gBAAA,EACb,QAAA,kBAAAA,cAAA;AAAA,cAACK,mCAAA;AAAA,cAAA;AAAA,gBACC,GAAA,EAAK,SAAA;AAAA,gBACL,EAAA,EAAI,OAAA;AAAA,gBACJ,KAAA,EAAO,UAAA;AAAA,gBACP,OAAO,KAAA,CAAM,KAAA;AAAA,gBACb,QAAA,EAAU,CAAC,IAAA,KAAS;AAClB,kBAAA,aAAA,CAAc,IAAI,CAAA;AAClB,kBAAA,KAAA,CAAM,MAAM,IAAI,CAAA;AAAA,gBAClB,CAAA;AAAA,gBAEA,QAAA,EAAU,MAAM,SAAA,CAAU,OAAA,EAAS,MAAM,aAAA,EAAc;AAAA,gBACvD,SAAA,EAAW,KAAA;AAAA,gBACX,SAAS,KAAA,CAAM,WAAA;AAAA,gBACf,eAAe,KAAA,CAAM,aAAA;AAAA,gBACrB,WAAA,EAAa,MAAM,WAAA,IAAe,EAAA;AAAA,gBAClC,UAAU,QAAA,KAAa,IAAA;AAAA,gBACvB,cAAA,EAAgB,KAAA,GAAQ,OAAA,GAAU,KAAA,CAAM,iBAAiB,CAAA;AAAA,gBACzD,WAAA,EAAa,QAAQ,KAAK,CAAA;AAAA,gBAC1B,sBAAsBC,oBAAA,CAAG,uBAAA,CAAwB,IAAI,CAAA,EAAG,OAAA,GAAU,WAAW,MAAS,CAAA;AAAA,gBACtF,KAAA,EAAO;AAAA,kBACL,GAAI,YAAA,GAAe,EAAE,WAAA,EAAa,YAAA,GAAe,IAAG,GAAI,IAAA;AAAA,kBACxD,GAAI,aAAA,GAAgB,EAAE,YAAA,EAAc,aAAA,GAAgB,IAAG,GAAI;AAAA,iBAC7D;AAAA,gBACA,SAAA,EAAWA,oBAAA;AAAA,kBACTC,kCAAA;AAAA,kBACAC,mCAAiB,IAAI,CAAA;AAAA,kBACrBC,+BAAa,KAAK,CAAA;AAAA,kBAClBC,+BAAa,KAAK,CAAA;AAAA;AAAA,kBAElB,4FAAA;AAAA,kBACA,OAAA,IAAW,CAAC,YAAA,IAAgB,MAAA;AAAA,kBAC5B,QAAA,IAAY,CAAC,aAAA,IAAiB,MAAA;AAAA,kBAC9B,SAAA;AAAA,kBACA,eAAA,EAAiB;AAAA;AACnB;AAAA,aACF,EACF,CAAA;AAAA,YACC,KAAA,CAAM,OAAA;AAAA,4BAEPV,cAAA;AAAA,cAAC,OAAA;AAAA,cAAA;AAAA,gBACC,GAAA,EAAK,CAAC,EAAA,KAAO;AACX,kBAAA,SAAA,CAAU,OAAA,GAAU,EAAA;AACpB,kBAAA,IAAI,OAAO,GAAA,KAAQ,UAAA,EAAY,GAAA,CAAI,EAAE,CAAA;AAAA,uBAAA,IAC5B,GAAA,MAAS,OAAA,GAAU,EAAA;AAAA,gBAC9B,CAAA;AAAA,gBACA,IAAA,EAAK,QAAA;AAAA,gBACL,MAAM,KAAA,CAAM,IAAA;AAAA,gBACZ,MAAM,KAAA,CAAM,IAAA;AAAA,gBACZ,KAAA,EAAO,KAAA,CAAM,MAAA,CAAO,UAAU;AAAA;AAAA,aAChC;AAAA,YACC,WAAA,IAAe,SAAA,oBACdA,cAAA,CAACW,kCAAA,EAAA,EAAiB,IAAA,EAAM,WAAW,KAAA,EAAO,WAAA,EAAa,IAAA,EAAM,KAAA,CAAM,IAAA,EAAM;AAAA,WAAA,EAE7E,CAAA,mBAEAX,cAAA;AAAA,YAAC,OAAA;AAAA,YAAA;AAAA,cACC,GAAA;AAAA,cACA,EAAA,EAAI,OAAA;AAAA,cACJ,IAAA,EAAM,YAAA;AAAA,cACN,QAAA;AAAA,cACA,QAAA;AAAA,cACA,SAAA,EAAWM,oBAAA;AAAA,gBACTC,kCAAA;AAAA,gBACAC,mCAAiB,IAAI,CAAA;AAAA,gBACrBC,+BAAa,KAAK,CAAA;AAAA,gBAClBC,+BAAa,KAAK,CAAA;AAAA,gBAClB,QAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,gBAMA,OAAA,IAAW,CAAC,YAAA,IAAgB,MAAA;AAAA,gBAAA,CAC3B,QAAA,IAAY,SAAA,KAAc,CAAC,aAAA,IAAiB,MAAA;AAAA,gBAC7C;AAAA,eACF;AAAA,cACA,KAAA,EAAO;AAAA;AAAA,gBAEL,GAAI,YAAA,GAAe,EAAE,WAAA,EAAa,YAAA,GAAe,IAAG,GAAI,IAAA;AAAA,gBACxD,GAAI,aAAA,GAAgB,EAAE,YAAA,EAAc,aAAA,GAAgB,IAAG,GAAI,IAAA;AAAA,gBAC3D,GAAG,KAAA,CAAM;AAAA,eACX;AAAA,cACA,QAAA,EAAU,CAAC,CAAA,KAAM;AACf,gBAAA,QAAA,GAAW,CAAC,CAAA;AACZ,gBAAA,aAAA,GAAgB,CAAA,CAAE,OAAO,KAAK,CAAA;AAAA,cAChC,CAAA;AAAA,cACC,GAAG,KAAA;AAAA,cAGJ,SAAA,EAAW,eAAe,KAAA,CAAM,SAAA;AAAA,cAChC,MAAA,EAAQ,CAAC,CAAA,KAAM;AACb,gBAAA,KAAA,CAAM,SAAS,CAAC,CAAA;AAChB,gBAAA,IAAI,aAAa,QAAA,EAAS;AAAA,cAC5B;AAAA;AAAA,WACF;AAAA,UAED,SAAA,mBACCV,cAAA;AAAA,YAAC,QAAA;AAAA,YAAA;AAAA,cACC,IAAA,EAAK,QAAA;AAAA,cAGL,EAAA,EAAI,GAAG,OAAO,CAAA,OAAA,CAAA;AAAA,cACd,yBAAA,EAAwB,EAAA;AAAA,cACxB,SAAS,MAAM,WAAA,CAAY,CAAC,CAAA,KAAM,CAAC,CAAC,CAAA;AAAA,cACpC,QAAA;AAAA,cACA,eAAA,EAAe,OAAA;AAAA,cACf,cAAA,EAAc,KAAA;AAAA,cACd,YAAA,EAAY,QAAQ,SAAA,GAAY,WAAA;AAAA,cAChC,KAAA,EAAO,QAAQ,SAAA,GAAY,WAAA;AAAA,cAK3B,QAAA,EAAU,EAAA;AAAA,cACV,SAAA,EAAU,oYAAA;AAAA,cAET,QAAA,EAAA,KAAA,mBAAQA,cAAA,CAAC,UAAA,EAAA,EAAW,CAAA,kCAAM,OAAA,EAAA,EAAQ;AAAA;AAAA,cAGrC,QAAA,oBACEA,cAAA;AAAA,YAAC,MAAA;AAAA,YAAA;AAAA,cACC,GAAA,EAAK,WAAA;AAAA,cACL,SAAA,EAAU,sKAAA;AAAA,cAET,QAAA,EAAA;AAAA;AAAA;AACH,SAAA,EAGN;AAAA;AAAA,KACF;AAGF,IAAA,IAAI,KAAA,IAAS,SAAS,WAAA,EAAa;AACjC,MAAA,uBACEA,cAAA;AAAA,QAACY,uBAAA;AAAA,QAAA;AAAA,UACC,KAAA;AAAA,UACA,OAAA,EAAS,UAAU,OAAA,GAAU,MAAA;AAAA,UAC7B,WAAA;AAAA,UACA,WAAA;AAAA,UACA,KAAA;AAAA,UACA,QAAA;AAAA,UACA,OAAA,EAAS,OAAA;AAAA,UACT,IAAA;AAAA,UAEC,QAAA,EAAA;AAAA;AAAA,OACH;AAAA,IAEJ;AAEA,IAAA,OAAO,KAAA;AAAA,EACT;AACF;AAEA,KAAA,CAAM,WAAA,GAAc,OAAA;AAGpB,IAAM,uBAAA,GAA0B;AAAA,EAC9B,EAAA,EAAI,sBAAA;AAAA,EACJ,EAAA,EAAI,0BAAA;AAAA,EACJ,EAAA,EAAI,sBAAA;AAAA,EACJ,EAAA,EAAI,0BAAA;AAAA,EACJ,EAAA,EAAI;AACN,CAAA;AAOA,SAAS,OAAA,GAAU;AACjB,EAAA,uCACG,KAAA,EAAA,EAAI,KAAA,EAAM,MAAK,MAAA,EAAO,IAAA,EAAK,SAAQ,WAAA,EAAY,IAAA,EAAK,QAAO,MAAA,EAAO,cAAA,EAAe,aAAY,GAAA,EAAI,aAAA,EAAc,SAAQ,cAAA,EAAe,OAAA,EAAQ,eAAY,MAAA,EACzJ,QAAA,EAAA;AAAA,oBAAAZ,cAAA,CAAC,MAAA,EAAA,EAAK,GAAE,uGAAA,EAAwG,CAAA;AAAA,mCAC/G,QAAA,EAAA,EAAO,EAAA,EAAG,MAAK,EAAA,EAAG,IAAA,EAAK,GAAE,GAAA,EAAI;AAAA,GAAA,EAChC,CAAA;AAEJ;AAEA,SAAS,UAAA,GAAa;AACpB,EAAA,uCACG,KAAA,EAAA,EAAI,KAAA,EAAM,MAAK,MAAA,EAAO,IAAA,EAAK,SAAQ,WAAA,EAAY,IAAA,EAAK,QAAO,MAAA,EAAO,cAAA,EAAe,aAAY,GAAA,EAAI,aAAA,EAAc,SAAQ,cAAA,EAAe,OAAA,EAAQ,eAAY,MAAA,EACzJ,QAAA,EAAA;AAAA,oBAAAA,cAAA,CAAC,MAAA,EAAA,EAAK,GAAE,gGAAA,EAAiG,CAAA;AAAA,oBACzGA,cAAA,CAAC,MAAA,EAAA,EAAK,CAAA,EAAE,sCAAA,EAAuC,CAAA;AAAA,oBAC/CA,cAAA,CAAC,MAAA,EAAA,EAAK,CAAA,EAAE,8FAAA,EAA+F,CAAA;AAAA,oBACvGA,cAAA,CAAC,MAAA,EAAA,EAAK,CAAA,EAAE,YAAA,EAAa;AAAA,GAAA,EACvB,CAAA;AAEJ","file":"chunk-CMC2TOEQ.cjs","sourcesContent":["import { useCallback, useEffect, useState } from \"react\";\n\n/**\n * Measure an inline adornment so the input can reserve exactly its width.\n *\n * ## Why this exists\n *\n * `leading` / `trailing` render ABSOLUTELY over the input, so they take no\n * space in flow and the input must be padded by hand to keep text clear of\n * them. That padding used to be a fixed `pl-9` / `pr-9` — 36px, sized for a\n * single icon. Any wider adornment ran straight under the value: `leading =\n * \"https://\"` is roughly 50px, so `https://` and `fancy.app` rendered on top of\n * one another.\n *\n * A fixed padding cannot be right for arbitrary content, and these props accept\n * arbitrary content — a currency code, a unit, a protocol, a short label. So\n * the width is measured rather than assumed.\n *\n * Returns `0` until measured (and on the server), which is the signal to keep\n * the old fixed padding as a fallback: an unmeasured render is then no worse\n * than it was before, rather than unpadded.\n *\n * `ResizeObserver` rather than a one-shot read, because the width changes after\n * first paint for reasons the first paint cannot see — a webfont swapping in,\n * the adornment's own content changing, a container query resizing the text.\n */\nexport function useAdornmentWidth(): [(node: HTMLElement | null) => void, number] {\n const [width, setWidth] = useState(0);\n const [node, setNode] = useState<HTMLElement | null>(null);\n\n const ref = useCallback((n: HTMLElement | null) => setNode(n), []);\n\n useEffect(() => {\n if (!node) {\n setWidth(0);\n\n return;\n }\n\n const read = () => setWidth(node.getBoundingClientRect().width);\n read();\n\n if (typeof ResizeObserver === \"undefined\") return;\n\n const observer = new ResizeObserver(read);\n observer.observe(node);\n\n return () => observer.disconnect();\n }, [node]);\n\n return [ref, width];\n}\n","import { forwardRef, useId, useMemo, useRef } from \"react\";\nimport { cn } from \"../../../utils/cn\";\nimport { useControllableState } from \"../../../hooks/use-controllable-state\";\nimport { useAdornmentWidth } from \"../../../hooks/use-adornment-width\";\nimport { Field } from \"../Field\";\nimport { InputWrapper } from \"../InputWrapper\";\nimport {\n dirtyClasses,\n errorClasses,\n inputBaseClasses,\n inputSizeClasses,\n} from \"../inputs.utils\";\nimport { useFieldMode } from \"../mode/FieldMode.context\";\nimport { DisplayValue } from \"../mode/DisplayValue\";\nimport { useInlineEdit } from \"../mode/useInlineEdit\";\nimport {\n InlinePasteEditor,\n PastedFilesInput,\n useInlinePaste,\n type InlinePasteEditorHandle,\n} from \"../../PastePills\";\nimport type { InputProps } from \"./Input.types\";\n\nexport const Input = forwardRef<HTMLInputElement, InputProps>(\n (\n {\n type = \"text\",\n size = \"md\",\n dirty,\n error,\n label,\n labelHidden,\n description,\n required,\n disabled,\n className,\n id,\n leading,\n trailing,\n prefix,\n suffix,\n prefixPosition,\n suffixPosition,\n mode,\n onValueChange,\n onChange,\n reveal,\n revealed,\n onRevealedChange,\n revealLabel = \"Show password\",\n hideLabel = \"Hide password\",\n pasteThreshold,\n pasteImages = false,\n pasteFilesName,\n previewChars = 20,\n renderPastePreview,\n pasteClassNames,\n heldPastes,\n onHeldPastesChange,\n heldImages,\n onHeldImagesChange,\n ...props\n },\n ref,\n ) => {\n const autoId = useId();\n const inputId = id ?? autoId;\n const resolvedMode = useFieldMode(mode);\n const { showControl, interactive, enterEdit, exitEdit } = useInlineEdit(resolvedMode, disabled);\n\n // Measured, not assumed: `leading`/`trailing` take arbitrary content, and a\n // fixed padding can only ever be right for one width. See\n // `useAdornmentWidth` for what went wrong with the fixed version.\n const [leadingRef, leadingWidth] = useAdornmentWidth();\n const [trailingRef, trailingWidth] = useAdornmentWidth();\n\n // Only meaningful on a password field: a reveal on an already-visible input\n // is a button that does nothing.\n const canReveal = reveal === true && type === \"password\";\n const [isRevealed, setRevealed] = useControllableState(revealed, false, onRevealedChange);\n const shown = canReveal && isRevealed;\n // The rendered type, NOT the declared one — `type` stays \"password\" so the\n // display-mode masking below and any caller reading props are unaffected.\n const renderedType = shown ? \"text\" : type;\n\n /*\n * Paste pills: the same core `Composer` and `PromptInput` use, so the three\n * cannot disagree about what a pill holds or what a send carries. Hooks run\n * whether or not it is on (Rules of Hooks); nothing is rendered unless asked.\n */\n const pasting = pasteThreshold !== undefined || pasteImages;\n const editorRef = useRef<InlinePasteEditorHandle>(null);\n const hiddenRef = useRef<HTMLInputElement | null>(null);\n const paste = useInlinePaste({\n pasteThreshold,\n pasteImages,\n previewChars,\n renderPastePreview,\n classNames: pasteClassNames,\n disabled: disabled === true,\n heldPastes,\n onHeldPastesChange,\n heldImages,\n onHeldImagesChange,\n editorRef,\n blockText: false,\n });\n const [pasteValue, setPasteValue] = useControllableState<string>(\n props.value === undefined ? undefined : String(props.value),\n props.defaultValue === undefined ? \"\" : String(props.defaultValue),\n onValueChange,\n );\n const filesName = pasteFilesName ?? (props.name ? `${props.name}_files[]` : undefined);\n const pastedFiles = useMemo(\n () => (pasteImages ? paste.imagesIn(pasteValue).map((i) => i.file) : []),\n [pasteImages, paste, pasteValue],\n );\n const labelId = `${inputId}-label`;\n\n const input = !showControl ? (\n <DisplayValue\n size={size}\n interactive={interactive}\n onActivate={enterEdit}\n leading={leading ?? prefix}\n trailing={trailing ?? suffix}\n >\n {type === \"password\" ? (props.value ? \"••••••\" : \"\") : (props.value as string | undefined)}\n </DisplayValue>\n ) : (\n <InputWrapper\n prefix={prefix}\n suffix={suffix}\n prefixPosition={prefixPosition}\n suffixPosition={suffixPosition}\n size={size}\n >\n <div data-react-fancy-input=\"\" className=\"relative flex items-center\">\n {leading && (\n <span\n ref={leadingRef}\n className=\"pointer-events-none absolute left-3 text-[color:var(--fancy-text-faint,var(--color-zinc-400))] dark:text-[color:var(--fancy-text-faint-dark,var(--color-zinc-500))]\"\n >\n {leading}\n </span>\n )}\n {pasting ? (\n <>\n <div className=\"min-w-0 flex-1\">\n <InlinePasteEditor\n ref={editorRef}\n id={inputId}\n value={pasteValue}\n known={paste.known}\n onChange={(next) => {\n setPasteValue(next);\n paste.prune(next);\n }}\n // Enter in a text field submits its form; keep that.\n onSubmit={() => hiddenRef.current?.form?.requestSubmit()}\n multiline={false}\n onPaste={paste.decidePaste}\n onHostsChange={paste.onHostsChange}\n placeholder={props.placeholder ?? \"\"}\n disabled={disabled === true}\n ariaLabelledBy={label ? labelId : props[\"aria-labelledby\"]}\n ariaInvalid={Boolean(error)}\n placeholderClassName={cn(pastePlaceholderClasses[size], leading ? \"left-9\" : undefined)}\n style={{\n ...(leadingWidth ? { paddingLeft: leadingWidth + 20 } : null),\n ...(trailingWidth ? { paddingRight: trailingWidth + 20 } : null),\n }}\n className={cn(\n inputBaseClasses,\n inputSizeClasses[size],\n dirtyClasses(dirty),\n errorClasses(error),\n // One line, like the <input> it stands in for.\n \"min-h-0 max-h-none w-full overflow-x-auto overflow-y-hidden whitespace-nowrap break-normal\",\n leading && !leadingWidth && \"pl-9\",\n trailing && !trailingWidth && \"pr-9\",\n className,\n pasteClassNames?.input,\n )}\n />\n </div>\n {paste.portals}\n {/* What a native submit posts: the value with every pill expanded. */}\n <input\n ref={(el) => {\n hiddenRef.current = el;\n if (typeof ref === \"function\") ref(el);\n else if (ref) ref.current = el;\n }}\n type=\"hidden\"\n name={props.name}\n form={props.form}\n value={paste.expand(pasteValue)}\n />\n {pasteImages && filesName && (\n <PastedFilesInput name={filesName} files={pastedFiles} form={props.form} />\n )}\n </>\n ) : (\n <input\n ref={ref}\n id={inputId}\n type={renderedType}\n disabled={disabled}\n required={required}\n className={cn(\n inputBaseClasses,\n inputSizeClasses[size],\n dirtyClasses(dirty),\n errorClasses(error),\n \"w-full\",\n // The fixed classes are the PRE-MEASURE fallback only. Once the\n // adornment is measured, the inline style below overrides them\n // with its real width -- a fixed 36px is correct for one icon and\n // wrong for anything wider, which is how `https://` came to\n // render on top of the value.\n leading && !leadingWidth && \"pl-9\",\n (trailing || canReveal) && !trailingWidth && \"pr-9\",\n className,\n )}\n style={{\n // 12px clears `left-3`/`right-3`; 8px is the gap to the text.\n ...(leadingWidth ? { paddingLeft: leadingWidth + 20 } : null),\n ...(trailingWidth ? { paddingRight: trailingWidth + 20 } : null),\n ...props.style,\n }}\n onChange={(e) => {\n onChange?.(e);\n onValueChange?.(e.target.value);\n }}\n {...props}\n // Inline click-to-edit: focus on entering edit, return to the display\n // (and run the host's onBlur) when focus leaves.\n autoFocus={interactive || props.autoFocus}\n onBlur={(e) => {\n props.onBlur?.(e);\n if (interactive) exitEdit();\n }}\n />\n )}\n {canReveal ? (\n <button\n type=\"button\"\n // type=\"button\" is load-bearing: the default is \"submit\", so a\n // reveal inside a login form would submit it on every click.\n id={`${inputId}-reveal`}\n data-react-fancy-reveal=\"\"\n onClick={() => setRevealed((v) => !v)}\n disabled={disabled}\n aria-controls={inputId}\n aria-pressed={shown}\n aria-label={shown ? hideLabel : revealLabel}\n title={shown ? hideLabel : revealLabel}\n // Not focusable by tab: the field and the submit button are the\n // path through a login form, and a reveal in between is a stop\n // most people do not want. Still reachable by click and by\n // screen readers.\n tabIndex={-1}\n className=\"absolute right-2 inline-flex items-center justify-center rounded p-1 text-[color:var(--fancy-text-faint,var(--color-zinc-400))] transition-colors hover:text-zinc-600 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-blue-500/40 disabled:cursor-not-allowed disabled:opacity-50 dark:text-[color:var(--fancy-text-faint-dark,var(--color-zinc-500))] dark:hover:text-zinc-300\"\n >\n {shown ? <EyeOffIcon /> : <EyeIcon />}\n </button>\n ) : (\n trailing && (\n <span\n ref={trailingRef}\n className=\"pointer-events-none absolute right-3 text-[color:var(--fancy-text-faint,var(--color-zinc-400))] dark:text-[color:var(--fancy-text-faint-dark,var(--color-zinc-500))]\"\n >\n {trailing}\n </span>\n )\n )}\n </div>\n </InputWrapper>\n );\n\n if (label || error || description) {\n return (\n <Field\n label={label}\n labelId={pasting ? labelId : undefined}\n labelHidden={labelHidden}\n description={description}\n error={error}\n required={required}\n htmlFor={inputId}\n size={size}\n >\n {input}\n </Field>\n );\n }\n\n return input;\n },\n);\n\nInput.displayName = \"Input\";\n\n/** Where the placeholder sits over the paste editor, matching `inputSizeClasses`. */\nconst pastePlaceholderClasses = {\n xs: \"left-2 top-1 text-xs\",\n sm: \"left-2.5 top-1.5 text-sm\",\n md: \"left-3 top-2 text-sm\",\n lg: \"left-4 top-2.5 text-base\",\n xl: \"left-5 top-3 text-lg\",\n} as const;\n\n/**\n * Inline SVGs rather than the Icon component: Input is the most-installed\n * primitive in the kit, and routing it through the icon registry would make\n * every consumer's password field depend on an icon set being configured.\n */\nfunction EyeIcon() {\n return (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden=\"true\">\n <path d=\"M2.062 12.348a1 1 0 0 1 0-.696 10.75 10.75 0 0 1 19.876 0 1 1 0 0 1 0 .696 10.75 10.75 0 0 1-19.876 0\" />\n <circle cx=\"12\" cy=\"12\" r=\"3\" />\n </svg>\n );\n}\n\nfunction EyeOffIcon() {\n return (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden=\"true\">\n <path d=\"M10.733 5.076a10.744 10.744 0 0 1 11.205 6.575 1 1 0 0 1 0 .696 10.747 10.747 0 0 1-1.444 2.49\" />\n <path d=\"M14.084 14.158a3 3 0 0 1-4.242-4.242\" />\n <path d=\"M17.479 17.499a10.75 10.75 0 0 1-15.417-5.151 1 1 0 0 1 0-.696 10.75 10.75 0 0 1 4.446-5.143\" />\n <path d=\"m2 2 20 20\" />\n </svg>\n );\n}\n"]}
1
+ {"version":3,"sources":["../src/hooks/use-adornment-width.ts","../src/components/inputs/Input/Input.tsx"],"names":["useState","useCallback","useEffect","forwardRef","useId","useFieldMode","useInlineEdit","useControllableState","useRef","useInlinePaste","useMemo","jsx","DisplayValue","InputWrapper","jsxs","Fragment","InlinePasteEditor","cn","inputBaseClasses","inputSizeClasses","dirtyClasses","errorClasses","PastedFilesInput","Field"],"mappings":"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","file":"chunk-6CAXLP7D.cjs","sourcesContent":["import { useCallback, useEffect, useState } from \"react\";\n\n/**\n * Measure an inline adornment so the input can reserve exactly its width.\n *\n * ## Why this exists\n *\n * `leading` / `trailing` render ABSOLUTELY over the input, so they take no\n * space in flow and the input must be padded by hand to keep text clear of\n * them. That padding used to be a fixed `pl-9` / `pr-9` — 36px, sized for a\n * single icon. Any wider adornment ran straight under the value: `leading =\n * \"https://\"` is roughly 50px, so `https://` and `fancy.app` rendered on top of\n * one another.\n *\n * A fixed padding cannot be right for arbitrary content, and these props accept\n * arbitrary content — a currency code, a unit, a protocol, a short label. So\n * the width is measured rather than assumed.\n *\n * Returns `0` until measured (and on the server), which is the signal to keep\n * the old fixed padding as a fallback: an unmeasured render is then no worse\n * than it was before, rather than unpadded.\n *\n * `ResizeObserver` rather than a one-shot read, because the width changes after\n * first paint for reasons the first paint cannot see — a webfont swapping in,\n * the adornment's own content changing, a container query resizing the text.\n */\nexport function useAdornmentWidth(): [(node: HTMLElement | null) => void, number] {\n const [width, setWidth] = useState(0);\n const [node, setNode] = useState<HTMLElement | null>(null);\n\n const ref = useCallback((n: HTMLElement | null) => setNode(n), []);\n\n useEffect(() => {\n if (!node) {\n setWidth(0);\n\n return;\n }\n\n const read = () => setWidth(node.getBoundingClientRect().width);\n read();\n\n if (typeof ResizeObserver === \"undefined\") return;\n\n const observer = new ResizeObserver(read);\n observer.observe(node);\n\n return () => observer.disconnect();\n }, [node]);\n\n return [ref, width];\n}\n","import { forwardRef, useId, useMemo, useRef } from \"react\";\nimport { cn } from \"../../../utils/cn\";\nimport { useControllableState } from \"../../../hooks/use-controllable-state\";\nimport { useAdornmentWidth } from \"../../../hooks/use-adornment-width\";\nimport { Field } from \"../Field\";\nimport { InputWrapper } from \"../InputWrapper\";\nimport {\n dirtyClasses,\n errorClasses,\n inputBaseClasses,\n inputSizeClasses,\n} from \"../inputs.utils\";\nimport { useFieldMode } from \"../mode/FieldMode.context\";\nimport { DisplayValue } from \"../mode/DisplayValue\";\nimport { useInlineEdit } from \"../mode/useInlineEdit\";\nimport {\n InlinePasteEditor,\n PastedFilesInput,\n useInlinePaste,\n type InlinePasteEditorHandle,\n} from \"../../PastePills\";\nimport type { InputProps } from \"./Input.types\";\n\nexport const Input = forwardRef<HTMLInputElement, InputProps>(\n (\n {\n type = \"text\",\n size = \"md\",\n dirty,\n error,\n label,\n labelHidden,\n description,\n required,\n disabled,\n className,\n id,\n leading,\n trailing,\n prefix,\n suffix,\n prefixPosition,\n suffixPosition,\n mode,\n onValueChange,\n onChange,\n reveal,\n revealed,\n onRevealedChange,\n revealLabel = \"Show password\",\n hideLabel = \"Hide password\",\n pasteThreshold,\n pasteImages = false,\n pasteFilesName,\n previewChars = 20,\n renderPastePreview,\n pasteClassNames,\n heldPastes,\n onHeldPastesChange,\n heldImages,\n onHeldImagesChange,\n ...props\n },\n ref,\n ) => {\n const autoId = useId();\n const inputId = id ?? autoId;\n const resolvedMode = useFieldMode(mode);\n const { showControl, interactive, enterEdit, exitEdit } = useInlineEdit(resolvedMode, disabled);\n\n // Measured, not assumed: `leading`/`trailing` take arbitrary content, and a\n // fixed padding can only ever be right for one width. See\n // `useAdornmentWidth` for what went wrong with the fixed version.\n const [leadingRef, leadingWidth] = useAdornmentWidth();\n const [trailingRef, trailingWidth] = useAdornmentWidth();\n\n // Only meaningful on a password field: a reveal on an already-visible input\n // is a button that does nothing.\n const canReveal = reveal === true && type === \"password\";\n const [isRevealed, setRevealed] = useControllableState(revealed, false, onRevealedChange);\n const shown = canReveal && isRevealed;\n // The rendered type, NOT the declared one — `type` stays \"password\" so the\n // display-mode masking below and any caller reading props are unaffected.\n const renderedType = shown ? \"text\" : type;\n\n /*\n * Paste pills: the same core `Composer` and `PromptInput` use, so the three\n * cannot disagree about what a pill holds or what a send carries. Hooks run\n * whether or not it is on (Rules of Hooks); nothing is rendered unless asked.\n */\n const pasting = pasteThreshold !== undefined || pasteImages;\n const editorRef = useRef<InlinePasteEditorHandle>(null);\n const hiddenRef = useRef<HTMLInputElement | null>(null);\n const paste = useInlinePaste({\n pasteThreshold,\n pasteImages,\n previewChars,\n renderPastePreview,\n classNames: pasteClassNames,\n disabled: disabled === true,\n heldPastes,\n onHeldPastesChange,\n heldImages,\n onHeldImagesChange,\n editorRef,\n blockText: false,\n });\n const [pasteValue, setPasteValue] = useControllableState<string>(\n props.value === undefined ? undefined : String(props.value),\n props.defaultValue === undefined ? \"\" : String(props.defaultValue),\n onValueChange,\n );\n const filesName = pasteFilesName ?? (props.name ? `${props.name}_files[]` : undefined);\n const pastedFiles = useMemo(\n () => (pasteImages ? paste.imagesIn(pasteValue).map((i) => i.file) : []),\n [pasteImages, paste, pasteValue],\n );\n const labelId = `${inputId}-label`;\n\n const input = !showControl ? (\n <DisplayValue\n size={size}\n interactive={interactive}\n onActivate={enterEdit}\n leading={leading ?? prefix}\n trailing={trailing ?? suffix}\n >\n {type === \"password\" ? (props.value ? \"••••••\" : \"\") : (props.value as string | undefined)}\n </DisplayValue>\n ) : (\n <InputWrapper\n prefix={prefix}\n suffix={suffix}\n prefixPosition={prefixPosition}\n suffixPosition={suffixPosition}\n size={size}\n >\n <div data-react-fancy-input=\"\" className=\"relative flex items-center\">\n {leading && (\n <span\n ref={leadingRef}\n className=\"pointer-events-none absolute left-3 text-[color:var(--fancy-text-faint,var(--color-zinc-400))] dark:text-[color:var(--fancy-text-faint-dark,var(--color-zinc-500))]\"\n >\n {leading}\n </span>\n )}\n {pasting ? (\n <>\n <div className=\"min-w-0 flex-1\">\n <InlinePasteEditor\n ref={editorRef}\n id={inputId}\n value={pasteValue}\n known={paste.known}\n onChange={(next) => {\n setPasteValue(next);\n paste.prune(next);\n }}\n // Enter in a text field submits its form; keep that.\n onSubmit={() => hiddenRef.current?.form?.requestSubmit()}\n multiline={false}\n onPaste={paste.decidePaste}\n onHostsChange={paste.onHostsChange}\n placeholder={props.placeholder ?? \"\"}\n disabled={disabled === true}\n ariaLabelledBy={label ? labelId : props[\"aria-labelledby\"]}\n ariaInvalid={Boolean(error)}\n placeholderClassName={cn(pastePlaceholderClasses[size], leading ? \"left-9\" : undefined)}\n style={{\n ...(leadingWidth ? { paddingLeft: leadingWidth + 20 } : null),\n ...(trailingWidth ? { paddingRight: trailingWidth + 20 } : null),\n }}\n className={cn(\n inputBaseClasses,\n inputSizeClasses[size],\n dirtyClasses(dirty),\n errorClasses(error),\n // One line, like the <input> it stands in for.\n \"min-h-0 max-h-none w-full overflow-x-auto overflow-y-hidden whitespace-nowrap break-normal\",\n leading && !leadingWidth && \"pl-9\",\n trailing && !trailingWidth && \"pr-9\",\n className,\n pasteClassNames?.input,\n )}\n />\n </div>\n {paste.portals}\n {/* What a native submit posts: the value with every pill expanded. */}\n <input\n ref={(el) => {\n hiddenRef.current = el;\n if (typeof ref === \"function\") ref(el);\n else if (ref) ref.current = el;\n }}\n type=\"hidden\"\n name={props.name}\n form={props.form}\n value={paste.expand(pasteValue)}\n />\n {pasteImages && filesName && (\n <PastedFilesInput name={filesName} files={pastedFiles} form={props.form} />\n )}\n </>\n ) : (\n <input\n ref={ref}\n id={inputId}\n type={renderedType}\n disabled={disabled}\n required={required}\n className={cn(\n inputBaseClasses,\n inputSizeClasses[size],\n dirtyClasses(dirty),\n errorClasses(error),\n \"w-full\",\n // The fixed classes are the PRE-MEASURE fallback only. Once the\n // adornment is measured, the inline style below overrides them\n // with its real width -- a fixed 36px is correct for one icon and\n // wrong for anything wider, which is how `https://` came to\n // render on top of the value.\n leading && !leadingWidth && \"pl-9\",\n (trailing || canReveal) && !trailingWidth && \"pr-9\",\n className,\n )}\n style={{\n // 12px clears `left-3`/`right-3`; 8px is the gap to the text.\n ...(leadingWidth ? { paddingLeft: leadingWidth + 20 } : null),\n ...(trailingWidth ? { paddingRight: trailingWidth + 20 } : null),\n ...props.style,\n }}\n onChange={(e) => {\n onChange?.(e);\n onValueChange?.(e.target.value);\n }}\n {...props}\n // Inline click-to-edit: focus on entering edit, return to the display\n // (and run the host's onBlur) when focus leaves.\n autoFocus={interactive || props.autoFocus}\n onBlur={(e) => {\n props.onBlur?.(e);\n if (interactive) exitEdit();\n }}\n />\n )}\n {canReveal ? (\n <button\n type=\"button\"\n // type=\"button\" is load-bearing: the default is \"submit\", so a\n // reveal inside a login form would submit it on every click.\n id={`${inputId}-reveal`}\n data-react-fancy-reveal=\"\"\n onClick={() => setRevealed((v) => !v)}\n disabled={disabled}\n aria-controls={inputId}\n aria-pressed={shown}\n aria-label={shown ? hideLabel : revealLabel}\n title={shown ? hideLabel : revealLabel}\n // Not focusable by tab: the field and the submit button are the\n // path through a login form, and a reveal in between is a stop\n // most people do not want. Still reachable by click and by\n // screen readers.\n tabIndex={-1}\n className=\"absolute right-2 inline-flex items-center justify-center rounded p-1 text-[color:var(--fancy-text-faint,var(--color-zinc-400))] transition-colors hover:text-zinc-600 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-blue-500/40 disabled:cursor-not-allowed disabled:opacity-50 dark:text-[color:var(--fancy-text-faint-dark,var(--color-zinc-500))] dark:hover:text-zinc-300\"\n >\n {shown ? <EyeOffIcon /> : <EyeIcon />}\n </button>\n ) : (\n trailing && (\n <span\n ref={trailingRef}\n className=\"pointer-events-none absolute right-3 text-[color:var(--fancy-text-faint,var(--color-zinc-400))] dark:text-[color:var(--fancy-text-faint-dark,var(--color-zinc-500))]\"\n >\n {trailing}\n </span>\n )\n )}\n </div>\n </InputWrapper>\n );\n\n if (label || error || description) {\n return (\n <Field\n label={label}\n labelId={pasting ? labelId : undefined}\n labelHidden={labelHidden}\n description={description}\n error={error}\n required={required}\n htmlFor={inputId}\n size={size}\n >\n {input}\n </Field>\n );\n }\n\n return input;\n },\n);\n\nInput.displayName = \"Input\";\n\n/** Where the placeholder sits over the paste editor, matching `inputSizeClasses`. */\nconst pastePlaceholderClasses = {\n xs: \"left-2 top-1 text-xs\",\n sm: \"left-2.5 top-1.5 text-sm\",\n md: \"left-3 top-2 text-sm\",\n lg: \"left-4 top-2.5 text-base\",\n xl: \"left-5 top-3 text-lg\",\n} as const;\n\n/**\n * Inline SVGs rather than the Icon component: Input is the most-installed\n * primitive in the kit, and routing it through the icon registry would make\n * every consumer's password field depend on an icon set being configured.\n */\nfunction EyeIcon() {\n return (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden=\"true\">\n <path d=\"M2.062 12.348a1 1 0 0 1 0-.696 10.75 10.75 0 0 1 19.876 0 1 1 0 0 1 0 .696 10.75 10.75 0 0 1-19.876 0\" />\n <circle cx=\"12\" cy=\"12\" r=\"3\" />\n </svg>\n );\n}\n\nfunction EyeOffIcon() {\n return (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden=\"true\">\n <path d=\"M10.733 5.076a10.744 10.744 0 0 1 11.205 6.575 1 1 0 0 1 0 .696 10.747 10.747 0 0 1-1.444 2.49\" />\n <path d=\"M14.084 14.158a3 3 0 0 1-4.242-4.242\" />\n <path d=\"M17.479 17.499a10.75 10.75 0 0 1-15.417-5.151 1 1 0 0 1 0-.696 10.75 10.75 0 0 1 4.446-5.143\" />\n <path d=\"m2 2 20 20\" />\n </svg>\n );\n}\n"]}
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var chunkQNQNGARW_cjs = require('./chunk-QNQNGARW.cjs');
3
+ var chunkHFK5SBNM_cjs = require('./chunk-HFK5SBNM.cjs');
4
4
  var chunkSNHU2AI4_cjs = require('./chunk-SNHU2AI4.cjs');
5
5
  var chunkZU5Q77OT_cjs = require('./chunk-ZU5Q77OT.cjs');
6
6
  var react = require('react');
@@ -37,7 +37,7 @@ var Composer = react.forwardRef(
37
37
  );
38
38
  const textareaRef = react.useRef(null);
39
39
  const editorRef = react.useRef(null);
40
- const paste = chunkQNQNGARW_cjs.useInlinePaste({
40
+ const paste = chunkHFK5SBNM_cjs.useInlinePaste({
41
41
  pasteThreshold,
42
42
  pasteImages,
43
43
  previewChars,
@@ -131,7 +131,7 @@ ${text}` : text);
131
131
  "data-react-fancy-composer-paste-pill": paste2.id,
132
132
  onClick: () => insertPaste(paste2),
133
133
  disabled,
134
- "aria-label": `Insert this pasted text, ${chunkQNQNGARW_cjs.withSeparators(paste2.text.length)} characters`,
134
+ "aria-label": `Insert this pasted text, ${chunkHFK5SBNM_cjs.withSeparators(paste2.text.length)} characters`,
135
135
  "aria-describedby": `${paste2.id}-preview`,
136
136
  className: chunkZU5Q77OT_cjs.cn(
137
137
  "inline-flex items-center gap-1.5 rounded-full border border-[color:var(--fancy-border,var(--color-zinc-200))] bg-zinc-50 py-1 pl-2.5 pr-7 text-xs text-zinc-700 transition-colors hover:bg-zinc-100 dark:border-[color:var(--fancy-border-dark,var(--color-zinc-700))] dark:bg-zinc-800 dark:text-zinc-200 dark:hover:bg-zinc-700",
@@ -140,7 +140,7 @@ ${text}` : text);
140
140
  ),
141
141
  children: /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
142
142
  "Pasted text \xB7 ",
143
- chunkQNQNGARW_cjs.withSeparators(paste2.text.length),
143
+ chunkHFK5SBNM_cjs.withSeparators(paste2.text.length),
144
144
  " characters"
145
145
  ] })
146
146
  }
@@ -170,7 +170,7 @@ ${text}` : text);
170
170
  "pointer-events-none absolute bottom-full left-0 z-10 mb-1 hidden max-w-xs whitespace-pre-wrap break-all rounded-md bg-zinc-900 px-2 py-1 text-xs text-white group-hover:block dark:bg-zinc-100 dark:text-zinc-900",
171
171
  classNames?.preview
172
172
  ),
173
- children: renderPastePreview?.({ kind: "text", paste: paste2 }) ?? chunkQNQNGARW_cjs.endsOf(paste2.text, previewChars)
173
+ children: renderPastePreview?.({ kind: "text", paste: paste2 }) ?? chunkHFK5SBNM_cjs.endsOf(paste2.text, previewChars)
174
174
  }
175
175
  )
176
176
  ] }, paste2.id)
@@ -179,7 +179,7 @@ ${text}` : text);
179
179
  ),
180
180
  inline ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
181
181
  /* @__PURE__ */ jsxRuntime.jsx(
182
- chunkQNQNGARW_cjs.InlinePasteEditor,
182
+ chunkHFK5SBNM_cjs.InlinePasteEditor,
183
183
  {
184
184
  ref: editorRef,
185
185
  value,
@@ -194,7 +194,7 @@ ${text}` : text);
194
194
  }
195
195
  ),
196
196
  paste.portals,
197
- pasteImages && pasteFilesName && /* @__PURE__ */ jsxRuntime.jsx(chunkQNQNGARW_cjs.PastedFilesInput, { name: pasteFilesName, files: pastedFiles })
197
+ pasteImages && pasteFilesName && /* @__PURE__ */ jsxRuntime.jsx(chunkHFK5SBNM_cjs.PastedFilesInput, { name: pasteFilesName, files: pastedFiles })
198
198
  ] }) : /* @__PURE__ */ jsxRuntime.jsx(
199
199
  "textarea",
200
200
  {
@@ -233,5 +233,5 @@ ${text}` : text);
233
233
  Composer.displayName = "Composer";
234
234
 
235
235
  exports.Composer = Composer;
236
- //# sourceMappingURL=chunk-TQGRXJ74.cjs.map
237
- //# sourceMappingURL=chunk-TQGRXJ74.cjs.map
236
+ //# sourceMappingURL=chunk-7FYRFNPX.cjs.map
237
+ //# sourceMappingURL=chunk-7FYRFNPX.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/components/Composer/Composer.tsx"],"names":["forwardRef","Composer","useControllableState","useRef","useInlinePaste","useMemo","useCallback","jsxs","cn","jsx","paste","withSeparators","endsOf","Fragment","InlinePasteEditor","PastedFilesInput"],"mappings":"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","file":"chunk-TQGRXJ74.cjs","sourcesContent":["import { forwardRef, useCallback, useMemo, useRef } from \"react\";\nimport { cn } from \"../../utils/cn\";\nimport { useControllableState } from \"../../hooks/use-controllable-state\";\nimport {\n endsOf,\n InlinePasteEditor,\n PastedFilesInput,\n useInlinePaste,\n withSeparators,\n type HeldPaste,\n type InlinePasteEditorHandle,\n} from \"../PastePills\";\nimport type { ComposerProps } from \"./Composer.types\";\n\n/** Characters of a held paste shown at each end of the hover preview, unless `previewChars` says otherwise. */\nconst PREVIEW_CHARS = 20;\n\nexport const Composer = forwardRef<HTMLDivElement, ComposerProps>(\n function Composer(\n {\n value: controlledValue,\n defaultValue = \"\",\n onChange,\n onSubmit,\n placeholder = \"Type a message...\",\n actions,\n disabled = false,\n className,\n pasteThreshold,\n pastePlacement = \"above\",\n pasteImages = false,\n previewChars = PREVIEW_CHARS,\n renderPastePreview,\n classNames,\n heldPastes: controlledHeldPastes,\n onHeldPastesChange,\n heldImages: controlledHeldImages,\n onHeldImagesChange,\n pasteFilesName,\n },\n ref,\n ) {\n const inline = pastePlacement === \"inline\";\n const [value, setValue] = useControllableState(\n controlledValue,\n defaultValue,\n onChange,\n );\n const textareaRef = useRef<HTMLTextAreaElement>(null);\n const editorRef = useRef<InlinePasteEditorHandle>(null);\n /*\n * The holding logic lives in `usePastePills`, wrapped by `useInlinePaste` for\n * the inline placement — which `PromptInput` shares, so the two components\n * cannot disagree about what a pill means. The rule that must not drift is\n * the one below: a send with pills still closed carries the text.\n */\n const paste = useInlinePaste({\n pasteThreshold,\n pasteImages,\n previewChars,\n renderPastePreview,\n classNames,\n disabled,\n heldPastes: controlledHeldPastes,\n onHeldPastesChange,\n heldImages: controlledHeldImages,\n onHeldImagesChange,\n editorRef,\n });\n const pills = paste.pills;\n const heldPastes = paste.heldPastes;\n const pastedFiles = useMemo(\n () => (inline && pasteImages ? paste.imagesIn(value).map((i) => i.file) : []),\n [inline, pasteImages, paste, value],\n );\n\n const handlePaste = useCallback(\n (e: React.ClipboardEvent<HTMLTextAreaElement>) => {\n // Composable by design, so this reads as a question rather than a handover.\n // Nothing else here wants the paste, so the answer is simply ignored.\n pills.handlePaste(e);\n },\n [pills],\n );\n\n const handleInlineChange = useCallback(\n (next: string) => {\n setValue(next);\n paste.prune(next);\n },\n [setValue, paste],\n );\n\n /** Everything the person believes they are sending, in the order they built it. */\n const composeOutgoing = useCallback(() => {\n if (inline) return paste.expand(value);\n\n return [value, ...heldPastes.map((p) => p.text)].filter(Boolean).join(\"\\n\\n\");\n }, [inline, value, heldPastes, paste]);\n\n const hasContent = value.trim().length > 0 || (!inline && heldPastes.length > 0);\n\n const focusInput = useCallback(() => {\n if (inline) editorRef.current?.focus();\n else textareaRef.current?.focus();\n }, [inline]);\n\n const handleSubmit = useCallback(() => {\n if (!hasContent || disabled) return;\n\n /*\n * THE DANGEROUS STATE, and the reason this feature needed a spec rather than\n * a guess. A pill reads as \"your paste is attached\" — so a send that drops it\n * means asking a question about a document without the document, and nobody\n * can tell: the sender believes it went, the receiver sees a question about\n * nothing.\n *\n * Above the input, held pastes go out in arrival order after what was typed,\n * because people type the question BEFORE pasting the thing it is about.\n * Inline, every pill goes out exactly where it sits.\n */\n const images = inline ? paste.imagesIn(value) : [];\n\n onSubmit?.(composeOutgoing(), { images });\n setValue(\"\");\n paste.clear();\n focusInput();\n }, [hasContent, disabled, value, inline, paste, onSubmit, composeOutgoing, setValue, focusInput]);\n\n const handleKeyDown = (e: React.KeyboardEvent<HTMLTextAreaElement>) => {\n if (e.key === \"Enter\" && !e.shiftKey) {\n e.preventDefault();\n handleSubmit();\n }\n };\n\n /** Above the input: click a pill to dump it in, APPENDED to what is already typed. */\n const insertPaste = useCallback(\n (held: HeldPaste) => {\n // `expand` removes it and hands back the text; inserting is this\n // component's job because the hook owns no DOM.\n const text = pills.expand(held.id);\n\n if (text === undefined) return;\n\n setValue((current) => (current ? `${current}\\n\\n${text}` : text));\n textareaRef.current?.focus();\n },\n [pills, setValue],\n );\n\n return (\n <div\n data-react-fancy-composer=\"\"\n ref={ref}\n className={cn(\n \"rounded-xl border border-[color:var(--fancy-border,var(--color-zinc-200))] bg-[color:var(--fancy-surface,var(--color-white))] dark:border-[color:var(--fancy-border-dark,var(--color-zinc-700))] dark:bg-[color:var(--fancy-surface-dark,var(--color-zinc-900))]\",\n disabled && \"opacity-50\",\n className,\n )}\n >\n {!inline && heldPastes.length > 0 && (\n <div\n data-react-fancy-composer-paste-pills=\"\"\n className=\"flex flex-wrap gap-1.5 px-3 pt-3\"\n >\n {heldPastes.map((paste) => (\n // `group` + `group-hover` rather than hover state: the preview is\n // presentation, and a useState for it would be one more thing an\n // agent could desynchronise.\n <span key={paste.id} className=\"group relative inline-flex\">\n <button\n type=\"button\"\n data-react-fancy-composer-paste-pill={paste.id}\n onClick={() => insertPaste(paste)}\n disabled={disabled}\n // No `title`. A native tooltip plus the hover preview below\n // renders TWO tooltips on the same hover, at different delays.\n // The label says what clicking does; the preview says what the\n // text is, and it is linked rather than merely adjacent so a\n // screen reader reaches it too.\n aria-label={`Insert this pasted text, ${withSeparators(paste.text.length)} characters`}\n aria-describedby={`${paste.id}-preview`}\n // `pr-7` leaves room for the absolutely-positioned × that sits\n // over this button's right edge. With a smaller right padding the\n // × lands on top of the label.\n className={cn(\n \"inline-flex items-center gap-1.5 rounded-full border border-[color:var(--fancy-border,var(--color-zinc-200))] bg-zinc-50 py-1 pl-2.5 pr-7 text-xs text-zinc-700 transition-colors hover:bg-zinc-100 dark:border-[color:var(--fancy-border-dark,var(--color-zinc-700))] dark:bg-zinc-800 dark:text-zinc-200 dark:hover:bg-zinc-700\",\n classNames?.pill,\n classNames?.textPill,\n )}\n >\n <span>\n Pasted text · {withSeparators(paste.text.length)} characters\n </span>\n </button>\n\n <button\n type=\"button\"\n data-react-fancy-composer-paste-pill-remove={paste.id}\n onClick={() => pills.remove(paste.id)}\n disabled={disabled}\n aria-label=\"Discard this pasted text\"\n className={cn(\n \"absolute right-1 top-1/2 -translate-y-1/2 rounded-full px-1 text-xs text-zinc-400 transition-colors hover:text-zinc-700 dark:hover:text-zinc-100\",\n classNames?.remove,\n )}\n >\n ×\n </button>\n\n <span\n id={`${paste.id}-preview`}\n data-react-fancy-composer-paste-pill-preview={paste.id}\n role=\"tooltip\"\n className={cn(\n \"pointer-events-none absolute bottom-full left-0 z-10 mb-1 hidden max-w-xs whitespace-pre-wrap break-all rounded-md bg-zinc-900 px-2 py-1 text-xs text-white group-hover:block dark:bg-zinc-100 dark:text-zinc-900\",\n classNames?.preview,\n )}\n >\n {renderPastePreview?.({ kind: \"text\", paste }) ??\n endsOf(paste.text, previewChars)}\n </span>\n </span>\n ))}\n </div>\n )}\n\n {inline ? (\n <>\n <InlinePasteEditor\n ref={editorRef}\n value={value}\n known={paste.known}\n onChange={handleInlineChange}\n onSubmit={handleSubmit}\n onPaste={paste.decidePaste}\n onHostsChange={paste.onHostsChange}\n placeholder={placeholder}\n disabled={disabled}\n className={classNames?.input}\n />\n {paste.portals}\n {pasteImages && pasteFilesName && (\n <PastedFilesInput name={pasteFilesName} files={pastedFiles} />\n )}\n </>\n ) : (\n <textarea\n ref={textareaRef}\n value={value}\n onChange={(e) => setValue(e.target.value)}\n onKeyDown={handleKeyDown}\n onPaste={handlePaste}\n placeholder={placeholder}\n disabled={disabled}\n rows={3}\n className={cn(\n \"w-full resize-none bg-transparent px-4 pt-3 text-sm outline-none placeholder:text-zinc-400\",\n classNames?.input,\n )}\n />\n )}\n <div className=\"flex items-center justify-between border-t border-zinc-100 px-3 py-2 dark:border-zinc-800\">\n <div className=\"flex items-center gap-1\">{actions}</div>\n <button\n type=\"button\"\n onClick={handleSubmit}\n disabled={disabled || !hasContent}\n className=\"rounded-lg bg-zinc-900 px-3 py-1.5 text-sm font-medium text-white transition-colors hover:bg-zinc-800 disabled:opacity-50 dark:bg-white dark:text-zinc-900 dark:hover:bg-zinc-100\"\n >\n Send\n </button>\n </div>\n </div>\n );\n },\n);\n\nComposer.displayName = \"Composer\";\n"]}
1
+ {"version":3,"sources":["../src/components/Composer/Composer.tsx"],"names":["forwardRef","Composer","useControllableState","useRef","useInlinePaste","useMemo","useCallback","jsxs","cn","jsx","paste","withSeparators","endsOf","Fragment","InlinePasteEditor","PastedFilesInput"],"mappings":"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","file":"chunk-7FYRFNPX.cjs","sourcesContent":["import { forwardRef, useCallback, useMemo, useRef } from \"react\";\nimport { cn } from \"../../utils/cn\";\nimport { useControllableState } from \"../../hooks/use-controllable-state\";\nimport {\n endsOf,\n InlinePasteEditor,\n PastedFilesInput,\n useInlinePaste,\n withSeparators,\n type HeldPaste,\n type InlinePasteEditorHandle,\n} from \"../PastePills\";\nimport type { ComposerProps } from \"./Composer.types\";\n\n/** Characters of a held paste shown at each end of the hover preview, unless `previewChars` says otherwise. */\nconst PREVIEW_CHARS = 20;\n\nexport const Composer = forwardRef<HTMLDivElement, ComposerProps>(\n function Composer(\n {\n value: controlledValue,\n defaultValue = \"\",\n onChange,\n onSubmit,\n placeholder = \"Type a message...\",\n actions,\n disabled = false,\n className,\n pasteThreshold,\n pastePlacement = \"above\",\n pasteImages = false,\n previewChars = PREVIEW_CHARS,\n renderPastePreview,\n classNames,\n heldPastes: controlledHeldPastes,\n onHeldPastesChange,\n heldImages: controlledHeldImages,\n onHeldImagesChange,\n pasteFilesName,\n },\n ref,\n ) {\n const inline = pastePlacement === \"inline\";\n const [value, setValue] = useControllableState(\n controlledValue,\n defaultValue,\n onChange,\n );\n const textareaRef = useRef<HTMLTextAreaElement>(null);\n const editorRef = useRef<InlinePasteEditorHandle>(null);\n /*\n * The holding logic lives in `usePastePills`, wrapped by `useInlinePaste` for\n * the inline placement — which `PromptInput` shares, so the two components\n * cannot disagree about what a pill means. The rule that must not drift is\n * the one below: a send with pills still closed carries the text.\n */\n const paste = useInlinePaste({\n pasteThreshold,\n pasteImages,\n previewChars,\n renderPastePreview,\n classNames,\n disabled,\n heldPastes: controlledHeldPastes,\n onHeldPastesChange,\n heldImages: controlledHeldImages,\n onHeldImagesChange,\n editorRef,\n });\n const pills = paste.pills;\n const heldPastes = paste.heldPastes;\n const pastedFiles = useMemo(\n () => (inline && pasteImages ? paste.imagesIn(value).map((i) => i.file) : []),\n [inline, pasteImages, paste, value],\n );\n\n const handlePaste = useCallback(\n (e: React.ClipboardEvent<HTMLTextAreaElement>) => {\n // Composable by design, so this reads as a question rather than a handover.\n // Nothing else here wants the paste, so the answer is simply ignored.\n pills.handlePaste(e);\n },\n [pills],\n );\n\n const handleInlineChange = useCallback(\n (next: string) => {\n setValue(next);\n paste.prune(next);\n },\n [setValue, paste],\n );\n\n /** Everything the person believes they are sending, in the order they built it. */\n const composeOutgoing = useCallback(() => {\n if (inline) return paste.expand(value);\n\n return [value, ...heldPastes.map((p) => p.text)].filter(Boolean).join(\"\\n\\n\");\n }, [inline, value, heldPastes, paste]);\n\n const hasContent = value.trim().length > 0 || (!inline && heldPastes.length > 0);\n\n const focusInput = useCallback(() => {\n if (inline) editorRef.current?.focus();\n else textareaRef.current?.focus();\n }, [inline]);\n\n const handleSubmit = useCallback(() => {\n if (!hasContent || disabled) return;\n\n /*\n * THE DANGEROUS STATE, and the reason this feature needed a spec rather than\n * a guess. A pill reads as \"your paste is attached\" — so a send that drops it\n * means asking a question about a document without the document, and nobody\n * can tell: the sender believes it went, the receiver sees a question about\n * nothing.\n *\n * Above the input, held pastes go out in arrival order after what was typed,\n * because people type the question BEFORE pasting the thing it is about.\n * Inline, every pill goes out exactly where it sits.\n */\n const images = inline ? paste.imagesIn(value) : [];\n\n onSubmit?.(composeOutgoing(), { images });\n setValue(\"\");\n paste.clear();\n focusInput();\n }, [hasContent, disabled, value, inline, paste, onSubmit, composeOutgoing, setValue, focusInput]);\n\n const handleKeyDown = (e: React.KeyboardEvent<HTMLTextAreaElement>) => {\n if (e.key === \"Enter\" && !e.shiftKey) {\n e.preventDefault();\n handleSubmit();\n }\n };\n\n /** Above the input: click a pill to dump it in, APPENDED to what is already typed. */\n const insertPaste = useCallback(\n (held: HeldPaste) => {\n // `expand` removes it and hands back the text; inserting is this\n // component's job because the hook owns no DOM.\n const text = pills.expand(held.id);\n\n if (text === undefined) return;\n\n setValue((current) => (current ? `${current}\\n\\n${text}` : text));\n textareaRef.current?.focus();\n },\n [pills, setValue],\n );\n\n return (\n <div\n data-react-fancy-composer=\"\"\n ref={ref}\n className={cn(\n \"rounded-xl border border-[color:var(--fancy-border,var(--color-zinc-200))] bg-[color:var(--fancy-surface,var(--color-white))] dark:border-[color:var(--fancy-border-dark,var(--color-zinc-700))] dark:bg-[color:var(--fancy-surface-dark,var(--color-zinc-900))]\",\n disabled && \"opacity-50\",\n className,\n )}\n >\n {!inline && heldPastes.length > 0 && (\n <div\n data-react-fancy-composer-paste-pills=\"\"\n className=\"flex flex-wrap gap-1.5 px-3 pt-3\"\n >\n {heldPastes.map((paste) => (\n // `group` + `group-hover` rather than hover state: the preview is\n // presentation, and a useState for it would be one more thing an\n // agent could desynchronise.\n <span key={paste.id} className=\"group relative inline-flex\">\n <button\n type=\"button\"\n data-react-fancy-composer-paste-pill={paste.id}\n onClick={() => insertPaste(paste)}\n disabled={disabled}\n // No `title`. A native tooltip plus the hover preview below\n // renders TWO tooltips on the same hover, at different delays.\n // The label says what clicking does; the preview says what the\n // text is, and it is linked rather than merely adjacent so a\n // screen reader reaches it too.\n aria-label={`Insert this pasted text, ${withSeparators(paste.text.length)} characters`}\n aria-describedby={`${paste.id}-preview`}\n // `pr-7` leaves room for the absolutely-positioned × that sits\n // over this button's right edge. With a smaller right padding the\n // × lands on top of the label.\n className={cn(\n \"inline-flex items-center gap-1.5 rounded-full border border-[color:var(--fancy-border,var(--color-zinc-200))] bg-zinc-50 py-1 pl-2.5 pr-7 text-xs text-zinc-700 transition-colors hover:bg-zinc-100 dark:border-[color:var(--fancy-border-dark,var(--color-zinc-700))] dark:bg-zinc-800 dark:text-zinc-200 dark:hover:bg-zinc-700\",\n classNames?.pill,\n classNames?.textPill,\n )}\n >\n <span>\n Pasted text · {withSeparators(paste.text.length)} characters\n </span>\n </button>\n\n <button\n type=\"button\"\n data-react-fancy-composer-paste-pill-remove={paste.id}\n onClick={() => pills.remove(paste.id)}\n disabled={disabled}\n aria-label=\"Discard this pasted text\"\n className={cn(\n \"absolute right-1 top-1/2 -translate-y-1/2 rounded-full px-1 text-xs text-zinc-400 transition-colors hover:text-zinc-700 dark:hover:text-zinc-100\",\n classNames?.remove,\n )}\n >\n ×\n </button>\n\n <span\n id={`${paste.id}-preview`}\n data-react-fancy-composer-paste-pill-preview={paste.id}\n role=\"tooltip\"\n className={cn(\n \"pointer-events-none absolute bottom-full left-0 z-10 mb-1 hidden max-w-xs whitespace-pre-wrap break-all rounded-md bg-zinc-900 px-2 py-1 text-xs text-white group-hover:block dark:bg-zinc-100 dark:text-zinc-900\",\n classNames?.preview,\n )}\n >\n {renderPastePreview?.({ kind: \"text\", paste }) ??\n endsOf(paste.text, previewChars)}\n </span>\n </span>\n ))}\n </div>\n )}\n\n {inline ? (\n <>\n <InlinePasteEditor\n ref={editorRef}\n value={value}\n known={paste.known}\n onChange={handleInlineChange}\n onSubmit={handleSubmit}\n onPaste={paste.decidePaste}\n onHostsChange={paste.onHostsChange}\n placeholder={placeholder}\n disabled={disabled}\n className={classNames?.input}\n />\n {paste.portals}\n {pasteImages && pasteFilesName && (\n <PastedFilesInput name={pasteFilesName} files={pastedFiles} />\n )}\n </>\n ) : (\n <textarea\n ref={textareaRef}\n value={value}\n onChange={(e) => setValue(e.target.value)}\n onKeyDown={handleKeyDown}\n onPaste={handlePaste}\n placeholder={placeholder}\n disabled={disabled}\n rows={3}\n className={cn(\n \"w-full resize-none bg-transparent px-4 pt-3 text-sm outline-none placeholder:text-zinc-400\",\n classNames?.input,\n )}\n />\n )}\n <div className=\"flex items-center justify-between border-t border-zinc-100 px-3 py-2 dark:border-zinc-800\">\n <div className=\"flex items-center gap-1\">{actions}</div>\n <button\n type=\"button\"\n onClick={handleSubmit}\n disabled={disabled || !hasContent}\n className=\"rounded-lg bg-zinc-900 px-3 py-1.5 text-sm font-medium text-white transition-colors hover:bg-zinc-800 disabled:opacity-50 dark:bg-white dark:text-zinc-900 dark:hover:bg-zinc-100\"\n >\n Send\n </button>\n </div>\n </div>\n );\n },\n);\n\nComposer.displayName = \"Composer\";\n"]}
@@ -2,7 +2,7 @@ import { InputWrapper } from './chunk-KXYMMNNV.js';
2
2
  import { DisplayValue } from './chunk-WX5XYDVN.js';
3
3
  import { Field } from './chunk-5WQ6FPSP.js';
4
4
  import { inputBaseClasses, inputSizeClasses, dirtyClasses, errorClasses } from './chunk-USWQAMI3.js';
5
- import { useInlinePaste, InlinePasteEditor, PastedFilesInput } from './chunk-NILA2LZY.js';
5
+ import { useInlinePaste, InlinePasteEditor, PastedFilesInput } from './chunk-YIKXJWO4.js';
6
6
  import { useInlineEdit } from './chunk-OL53XYHF.js';
7
7
  import { useFieldMode } from './chunk-NRXK42LO.js';
8
8
  import { useControllableState } from './chunk-EDYAXGUM.js';
@@ -298,5 +298,5 @@ function EyeOffIcon() {
298
298
  }
299
299
 
300
300
  export { Input };
301
- //# sourceMappingURL=chunk-MVVHUTXA.js.map
302
- //# sourceMappingURL=chunk-MVVHUTXA.js.map
301
+ //# sourceMappingURL=chunk-B4LVQ4QI.js.map
302
+ //# sourceMappingURL=chunk-B4LVQ4QI.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/hooks/use-adornment-width.ts","../src/components/inputs/Input/Input.tsx"],"names":[],"mappings":"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","file":"chunk-MVVHUTXA.js","sourcesContent":["import { useCallback, useEffect, useState } from \"react\";\n\n/**\n * Measure an inline adornment so the input can reserve exactly its width.\n *\n * ## Why this exists\n *\n * `leading` / `trailing` render ABSOLUTELY over the input, so they take no\n * space in flow and the input must be padded by hand to keep text clear of\n * them. That padding used to be a fixed `pl-9` / `pr-9` — 36px, sized for a\n * single icon. Any wider adornment ran straight under the value: `leading =\n * \"https://\"` is roughly 50px, so `https://` and `fancy.app` rendered on top of\n * one another.\n *\n * A fixed padding cannot be right for arbitrary content, and these props accept\n * arbitrary content — a currency code, a unit, a protocol, a short label. So\n * the width is measured rather than assumed.\n *\n * Returns `0` until measured (and on the server), which is the signal to keep\n * the old fixed padding as a fallback: an unmeasured render is then no worse\n * than it was before, rather than unpadded.\n *\n * `ResizeObserver` rather than a one-shot read, because the width changes after\n * first paint for reasons the first paint cannot see — a webfont swapping in,\n * the adornment's own content changing, a container query resizing the text.\n */\nexport function useAdornmentWidth(): [(node: HTMLElement | null) => void, number] {\n const [width, setWidth] = useState(0);\n const [node, setNode] = useState<HTMLElement | null>(null);\n\n const ref = useCallback((n: HTMLElement | null) => setNode(n), []);\n\n useEffect(() => {\n if (!node) {\n setWidth(0);\n\n return;\n }\n\n const read = () => setWidth(node.getBoundingClientRect().width);\n read();\n\n if (typeof ResizeObserver === \"undefined\") return;\n\n const observer = new ResizeObserver(read);\n observer.observe(node);\n\n return () => observer.disconnect();\n }, [node]);\n\n return [ref, width];\n}\n","import { forwardRef, useId, useMemo, useRef } from \"react\";\nimport { cn } from \"../../../utils/cn\";\nimport { useControllableState } from \"../../../hooks/use-controllable-state\";\nimport { useAdornmentWidth } from \"../../../hooks/use-adornment-width\";\nimport { Field } from \"../Field\";\nimport { InputWrapper } from \"../InputWrapper\";\nimport {\n dirtyClasses,\n errorClasses,\n inputBaseClasses,\n inputSizeClasses,\n} from \"../inputs.utils\";\nimport { useFieldMode } from \"../mode/FieldMode.context\";\nimport { DisplayValue } from \"../mode/DisplayValue\";\nimport { useInlineEdit } from \"../mode/useInlineEdit\";\nimport {\n InlinePasteEditor,\n PastedFilesInput,\n useInlinePaste,\n type InlinePasteEditorHandle,\n} from \"../../PastePills\";\nimport type { InputProps } from \"./Input.types\";\n\nexport const Input = forwardRef<HTMLInputElement, InputProps>(\n (\n {\n type = \"text\",\n size = \"md\",\n dirty,\n error,\n label,\n labelHidden,\n description,\n required,\n disabled,\n className,\n id,\n leading,\n trailing,\n prefix,\n suffix,\n prefixPosition,\n suffixPosition,\n mode,\n onValueChange,\n onChange,\n reveal,\n revealed,\n onRevealedChange,\n revealLabel = \"Show password\",\n hideLabel = \"Hide password\",\n pasteThreshold,\n pasteImages = false,\n pasteFilesName,\n previewChars = 20,\n renderPastePreview,\n pasteClassNames,\n heldPastes,\n onHeldPastesChange,\n heldImages,\n onHeldImagesChange,\n ...props\n },\n ref,\n ) => {\n const autoId = useId();\n const inputId = id ?? autoId;\n const resolvedMode = useFieldMode(mode);\n const { showControl, interactive, enterEdit, exitEdit } = useInlineEdit(resolvedMode, disabled);\n\n // Measured, not assumed: `leading`/`trailing` take arbitrary content, and a\n // fixed padding can only ever be right for one width. See\n // `useAdornmentWidth` for what went wrong with the fixed version.\n const [leadingRef, leadingWidth] = useAdornmentWidth();\n const [trailingRef, trailingWidth] = useAdornmentWidth();\n\n // Only meaningful on a password field: a reveal on an already-visible input\n // is a button that does nothing.\n const canReveal = reveal === true && type === \"password\";\n const [isRevealed, setRevealed] = useControllableState(revealed, false, onRevealedChange);\n const shown = canReveal && isRevealed;\n // The rendered type, NOT the declared one — `type` stays \"password\" so the\n // display-mode masking below and any caller reading props are unaffected.\n const renderedType = shown ? \"text\" : type;\n\n /*\n * Paste pills: the same core `Composer` and `PromptInput` use, so the three\n * cannot disagree about what a pill holds or what a send carries. Hooks run\n * whether or not it is on (Rules of Hooks); nothing is rendered unless asked.\n */\n const pasting = pasteThreshold !== undefined || pasteImages;\n const editorRef = useRef<InlinePasteEditorHandle>(null);\n const hiddenRef = useRef<HTMLInputElement | null>(null);\n const paste = useInlinePaste({\n pasteThreshold,\n pasteImages,\n previewChars,\n renderPastePreview,\n classNames: pasteClassNames,\n disabled: disabled === true,\n heldPastes,\n onHeldPastesChange,\n heldImages,\n onHeldImagesChange,\n editorRef,\n blockText: false,\n });\n const [pasteValue, setPasteValue] = useControllableState<string>(\n props.value === undefined ? undefined : String(props.value),\n props.defaultValue === undefined ? \"\" : String(props.defaultValue),\n onValueChange,\n );\n const filesName = pasteFilesName ?? (props.name ? `${props.name}_files[]` : undefined);\n const pastedFiles = useMemo(\n () => (pasteImages ? paste.imagesIn(pasteValue).map((i) => i.file) : []),\n [pasteImages, paste, pasteValue],\n );\n const labelId = `${inputId}-label`;\n\n const input = !showControl ? (\n <DisplayValue\n size={size}\n interactive={interactive}\n onActivate={enterEdit}\n leading={leading ?? prefix}\n trailing={trailing ?? suffix}\n >\n {type === \"password\" ? (props.value ? \"••••••\" : \"\") : (props.value as string | undefined)}\n </DisplayValue>\n ) : (\n <InputWrapper\n prefix={prefix}\n suffix={suffix}\n prefixPosition={prefixPosition}\n suffixPosition={suffixPosition}\n size={size}\n >\n <div data-react-fancy-input=\"\" className=\"relative flex items-center\">\n {leading && (\n <span\n ref={leadingRef}\n className=\"pointer-events-none absolute left-3 text-[color:var(--fancy-text-faint,var(--color-zinc-400))] dark:text-[color:var(--fancy-text-faint-dark,var(--color-zinc-500))]\"\n >\n {leading}\n </span>\n )}\n {pasting ? (\n <>\n <div className=\"min-w-0 flex-1\">\n <InlinePasteEditor\n ref={editorRef}\n id={inputId}\n value={pasteValue}\n known={paste.known}\n onChange={(next) => {\n setPasteValue(next);\n paste.prune(next);\n }}\n // Enter in a text field submits its form; keep that.\n onSubmit={() => hiddenRef.current?.form?.requestSubmit()}\n multiline={false}\n onPaste={paste.decidePaste}\n onHostsChange={paste.onHostsChange}\n placeholder={props.placeholder ?? \"\"}\n disabled={disabled === true}\n ariaLabelledBy={label ? labelId : props[\"aria-labelledby\"]}\n ariaInvalid={Boolean(error)}\n placeholderClassName={cn(pastePlaceholderClasses[size], leading ? \"left-9\" : undefined)}\n style={{\n ...(leadingWidth ? { paddingLeft: leadingWidth + 20 } : null),\n ...(trailingWidth ? { paddingRight: trailingWidth + 20 } : null),\n }}\n className={cn(\n inputBaseClasses,\n inputSizeClasses[size],\n dirtyClasses(dirty),\n errorClasses(error),\n // One line, like the <input> it stands in for.\n \"min-h-0 max-h-none w-full overflow-x-auto overflow-y-hidden whitespace-nowrap break-normal\",\n leading && !leadingWidth && \"pl-9\",\n trailing && !trailingWidth && \"pr-9\",\n className,\n pasteClassNames?.input,\n )}\n />\n </div>\n {paste.portals}\n {/* What a native submit posts: the value with every pill expanded. */}\n <input\n ref={(el) => {\n hiddenRef.current = el;\n if (typeof ref === \"function\") ref(el);\n else if (ref) ref.current = el;\n }}\n type=\"hidden\"\n name={props.name}\n form={props.form}\n value={paste.expand(pasteValue)}\n />\n {pasteImages && filesName && (\n <PastedFilesInput name={filesName} files={pastedFiles} form={props.form} />\n )}\n </>\n ) : (\n <input\n ref={ref}\n id={inputId}\n type={renderedType}\n disabled={disabled}\n required={required}\n className={cn(\n inputBaseClasses,\n inputSizeClasses[size],\n dirtyClasses(dirty),\n errorClasses(error),\n \"w-full\",\n // The fixed classes are the PRE-MEASURE fallback only. Once the\n // adornment is measured, the inline style below overrides them\n // with its real width -- a fixed 36px is correct for one icon and\n // wrong for anything wider, which is how `https://` came to\n // render on top of the value.\n leading && !leadingWidth && \"pl-9\",\n (trailing || canReveal) && !trailingWidth && \"pr-9\",\n className,\n )}\n style={{\n // 12px clears `left-3`/`right-3`; 8px is the gap to the text.\n ...(leadingWidth ? { paddingLeft: leadingWidth + 20 } : null),\n ...(trailingWidth ? { paddingRight: trailingWidth + 20 } : null),\n ...props.style,\n }}\n onChange={(e) => {\n onChange?.(e);\n onValueChange?.(e.target.value);\n }}\n {...props}\n // Inline click-to-edit: focus on entering edit, return to the display\n // (and run the host's onBlur) when focus leaves.\n autoFocus={interactive || props.autoFocus}\n onBlur={(e) => {\n props.onBlur?.(e);\n if (interactive) exitEdit();\n }}\n />\n )}\n {canReveal ? (\n <button\n type=\"button\"\n // type=\"button\" is load-bearing: the default is \"submit\", so a\n // reveal inside a login form would submit it on every click.\n id={`${inputId}-reveal`}\n data-react-fancy-reveal=\"\"\n onClick={() => setRevealed((v) => !v)}\n disabled={disabled}\n aria-controls={inputId}\n aria-pressed={shown}\n aria-label={shown ? hideLabel : revealLabel}\n title={shown ? hideLabel : revealLabel}\n // Not focusable by tab: the field and the submit button are the\n // path through a login form, and a reveal in between is a stop\n // most people do not want. Still reachable by click and by\n // screen readers.\n tabIndex={-1}\n className=\"absolute right-2 inline-flex items-center justify-center rounded p-1 text-[color:var(--fancy-text-faint,var(--color-zinc-400))] transition-colors hover:text-zinc-600 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-blue-500/40 disabled:cursor-not-allowed disabled:opacity-50 dark:text-[color:var(--fancy-text-faint-dark,var(--color-zinc-500))] dark:hover:text-zinc-300\"\n >\n {shown ? <EyeOffIcon /> : <EyeIcon />}\n </button>\n ) : (\n trailing && (\n <span\n ref={trailingRef}\n className=\"pointer-events-none absolute right-3 text-[color:var(--fancy-text-faint,var(--color-zinc-400))] dark:text-[color:var(--fancy-text-faint-dark,var(--color-zinc-500))]\"\n >\n {trailing}\n </span>\n )\n )}\n </div>\n </InputWrapper>\n );\n\n if (label || error || description) {\n return (\n <Field\n label={label}\n labelId={pasting ? labelId : undefined}\n labelHidden={labelHidden}\n description={description}\n error={error}\n required={required}\n htmlFor={inputId}\n size={size}\n >\n {input}\n </Field>\n );\n }\n\n return input;\n },\n);\n\nInput.displayName = \"Input\";\n\n/** Where the placeholder sits over the paste editor, matching `inputSizeClasses`. */\nconst pastePlaceholderClasses = {\n xs: \"left-2 top-1 text-xs\",\n sm: \"left-2.5 top-1.5 text-sm\",\n md: \"left-3 top-2 text-sm\",\n lg: \"left-4 top-2.5 text-base\",\n xl: \"left-5 top-3 text-lg\",\n} as const;\n\n/**\n * Inline SVGs rather than the Icon component: Input is the most-installed\n * primitive in the kit, and routing it through the icon registry would make\n * every consumer's password field depend on an icon set being configured.\n */\nfunction EyeIcon() {\n return (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden=\"true\">\n <path d=\"M2.062 12.348a1 1 0 0 1 0-.696 10.75 10.75 0 0 1 19.876 0 1 1 0 0 1 0 .696 10.75 10.75 0 0 1-19.876 0\" />\n <circle cx=\"12\" cy=\"12\" r=\"3\" />\n </svg>\n );\n}\n\nfunction EyeOffIcon() {\n return (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden=\"true\">\n <path d=\"M10.733 5.076a10.744 10.744 0 0 1 11.205 6.575 1 1 0 0 1 0 .696 10.747 10.747 0 0 1-1.444 2.49\" />\n <path d=\"M14.084 14.158a3 3 0 0 1-4.242-4.242\" />\n <path d=\"M17.479 17.499a10.75 10.75 0 0 1-15.417-5.151 1 1 0 0 1 0-.696 10.75 10.75 0 0 1 4.446-5.143\" />\n <path d=\"m2 2 20 20\" />\n </svg>\n );\n}\n"]}
1
+ {"version":3,"sources":["../src/hooks/use-adornment-width.ts","../src/components/inputs/Input/Input.tsx"],"names":[],"mappings":"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","file":"chunk-B4LVQ4QI.js","sourcesContent":["import { useCallback, useEffect, useState } from \"react\";\n\n/**\n * Measure an inline adornment so the input can reserve exactly its width.\n *\n * ## Why this exists\n *\n * `leading` / `trailing` render ABSOLUTELY over the input, so they take no\n * space in flow and the input must be padded by hand to keep text clear of\n * them. That padding used to be a fixed `pl-9` / `pr-9` — 36px, sized for a\n * single icon. Any wider adornment ran straight under the value: `leading =\n * \"https://\"` is roughly 50px, so `https://` and `fancy.app` rendered on top of\n * one another.\n *\n * A fixed padding cannot be right for arbitrary content, and these props accept\n * arbitrary content — a currency code, a unit, a protocol, a short label. So\n * the width is measured rather than assumed.\n *\n * Returns `0` until measured (and on the server), which is the signal to keep\n * the old fixed padding as a fallback: an unmeasured render is then no worse\n * than it was before, rather than unpadded.\n *\n * `ResizeObserver` rather than a one-shot read, because the width changes after\n * first paint for reasons the first paint cannot see — a webfont swapping in,\n * the adornment's own content changing, a container query resizing the text.\n */\nexport function useAdornmentWidth(): [(node: HTMLElement | null) => void, number] {\n const [width, setWidth] = useState(0);\n const [node, setNode] = useState<HTMLElement | null>(null);\n\n const ref = useCallback((n: HTMLElement | null) => setNode(n), []);\n\n useEffect(() => {\n if (!node) {\n setWidth(0);\n\n return;\n }\n\n const read = () => setWidth(node.getBoundingClientRect().width);\n read();\n\n if (typeof ResizeObserver === \"undefined\") return;\n\n const observer = new ResizeObserver(read);\n observer.observe(node);\n\n return () => observer.disconnect();\n }, [node]);\n\n return [ref, width];\n}\n","import { forwardRef, useId, useMemo, useRef } from \"react\";\nimport { cn } from \"../../../utils/cn\";\nimport { useControllableState } from \"../../../hooks/use-controllable-state\";\nimport { useAdornmentWidth } from \"../../../hooks/use-adornment-width\";\nimport { Field } from \"../Field\";\nimport { InputWrapper } from \"../InputWrapper\";\nimport {\n dirtyClasses,\n errorClasses,\n inputBaseClasses,\n inputSizeClasses,\n} from \"../inputs.utils\";\nimport { useFieldMode } from \"../mode/FieldMode.context\";\nimport { DisplayValue } from \"../mode/DisplayValue\";\nimport { useInlineEdit } from \"../mode/useInlineEdit\";\nimport {\n InlinePasteEditor,\n PastedFilesInput,\n useInlinePaste,\n type InlinePasteEditorHandle,\n} from \"../../PastePills\";\nimport type { InputProps } from \"./Input.types\";\n\nexport const Input = forwardRef<HTMLInputElement, InputProps>(\n (\n {\n type = \"text\",\n size = \"md\",\n dirty,\n error,\n label,\n labelHidden,\n description,\n required,\n disabled,\n className,\n id,\n leading,\n trailing,\n prefix,\n suffix,\n prefixPosition,\n suffixPosition,\n mode,\n onValueChange,\n onChange,\n reveal,\n revealed,\n onRevealedChange,\n revealLabel = \"Show password\",\n hideLabel = \"Hide password\",\n pasteThreshold,\n pasteImages = false,\n pasteFilesName,\n previewChars = 20,\n renderPastePreview,\n pasteClassNames,\n heldPastes,\n onHeldPastesChange,\n heldImages,\n onHeldImagesChange,\n ...props\n },\n ref,\n ) => {\n const autoId = useId();\n const inputId = id ?? autoId;\n const resolvedMode = useFieldMode(mode);\n const { showControl, interactive, enterEdit, exitEdit } = useInlineEdit(resolvedMode, disabled);\n\n // Measured, not assumed: `leading`/`trailing` take arbitrary content, and a\n // fixed padding can only ever be right for one width. See\n // `useAdornmentWidth` for what went wrong with the fixed version.\n const [leadingRef, leadingWidth] = useAdornmentWidth();\n const [trailingRef, trailingWidth] = useAdornmentWidth();\n\n // Only meaningful on a password field: a reveal on an already-visible input\n // is a button that does nothing.\n const canReveal = reveal === true && type === \"password\";\n const [isRevealed, setRevealed] = useControllableState(revealed, false, onRevealedChange);\n const shown = canReveal && isRevealed;\n // The rendered type, NOT the declared one — `type` stays \"password\" so the\n // display-mode masking below and any caller reading props are unaffected.\n const renderedType = shown ? \"text\" : type;\n\n /*\n * Paste pills: the same core `Composer` and `PromptInput` use, so the three\n * cannot disagree about what a pill holds or what a send carries. Hooks run\n * whether or not it is on (Rules of Hooks); nothing is rendered unless asked.\n */\n const pasting = pasteThreshold !== undefined || pasteImages;\n const editorRef = useRef<InlinePasteEditorHandle>(null);\n const hiddenRef = useRef<HTMLInputElement | null>(null);\n const paste = useInlinePaste({\n pasteThreshold,\n pasteImages,\n previewChars,\n renderPastePreview,\n classNames: pasteClassNames,\n disabled: disabled === true,\n heldPastes,\n onHeldPastesChange,\n heldImages,\n onHeldImagesChange,\n editorRef,\n blockText: false,\n });\n const [pasteValue, setPasteValue] = useControllableState<string>(\n props.value === undefined ? undefined : String(props.value),\n props.defaultValue === undefined ? \"\" : String(props.defaultValue),\n onValueChange,\n );\n const filesName = pasteFilesName ?? (props.name ? `${props.name}_files[]` : undefined);\n const pastedFiles = useMemo(\n () => (pasteImages ? paste.imagesIn(pasteValue).map((i) => i.file) : []),\n [pasteImages, paste, pasteValue],\n );\n const labelId = `${inputId}-label`;\n\n const input = !showControl ? (\n <DisplayValue\n size={size}\n interactive={interactive}\n onActivate={enterEdit}\n leading={leading ?? prefix}\n trailing={trailing ?? suffix}\n >\n {type === \"password\" ? (props.value ? \"••••••\" : \"\") : (props.value as string | undefined)}\n </DisplayValue>\n ) : (\n <InputWrapper\n prefix={prefix}\n suffix={suffix}\n prefixPosition={prefixPosition}\n suffixPosition={suffixPosition}\n size={size}\n >\n <div data-react-fancy-input=\"\" className=\"relative flex items-center\">\n {leading && (\n <span\n ref={leadingRef}\n className=\"pointer-events-none absolute left-3 text-[color:var(--fancy-text-faint,var(--color-zinc-400))] dark:text-[color:var(--fancy-text-faint-dark,var(--color-zinc-500))]\"\n >\n {leading}\n </span>\n )}\n {pasting ? (\n <>\n <div className=\"min-w-0 flex-1\">\n <InlinePasteEditor\n ref={editorRef}\n id={inputId}\n value={pasteValue}\n known={paste.known}\n onChange={(next) => {\n setPasteValue(next);\n paste.prune(next);\n }}\n // Enter in a text field submits its form; keep that.\n onSubmit={() => hiddenRef.current?.form?.requestSubmit()}\n multiline={false}\n onPaste={paste.decidePaste}\n onHostsChange={paste.onHostsChange}\n placeholder={props.placeholder ?? \"\"}\n disabled={disabled === true}\n ariaLabelledBy={label ? labelId : props[\"aria-labelledby\"]}\n ariaInvalid={Boolean(error)}\n placeholderClassName={cn(pastePlaceholderClasses[size], leading ? \"left-9\" : undefined)}\n style={{\n ...(leadingWidth ? { paddingLeft: leadingWidth + 20 } : null),\n ...(trailingWidth ? { paddingRight: trailingWidth + 20 } : null),\n }}\n className={cn(\n inputBaseClasses,\n inputSizeClasses[size],\n dirtyClasses(dirty),\n errorClasses(error),\n // One line, like the <input> it stands in for.\n \"min-h-0 max-h-none w-full overflow-x-auto overflow-y-hidden whitespace-nowrap break-normal\",\n leading && !leadingWidth && \"pl-9\",\n trailing && !trailingWidth && \"pr-9\",\n className,\n pasteClassNames?.input,\n )}\n />\n </div>\n {paste.portals}\n {/* What a native submit posts: the value with every pill expanded. */}\n <input\n ref={(el) => {\n hiddenRef.current = el;\n if (typeof ref === \"function\") ref(el);\n else if (ref) ref.current = el;\n }}\n type=\"hidden\"\n name={props.name}\n form={props.form}\n value={paste.expand(pasteValue)}\n />\n {pasteImages && filesName && (\n <PastedFilesInput name={filesName} files={pastedFiles} form={props.form} />\n )}\n </>\n ) : (\n <input\n ref={ref}\n id={inputId}\n type={renderedType}\n disabled={disabled}\n required={required}\n className={cn(\n inputBaseClasses,\n inputSizeClasses[size],\n dirtyClasses(dirty),\n errorClasses(error),\n \"w-full\",\n // The fixed classes are the PRE-MEASURE fallback only. Once the\n // adornment is measured, the inline style below overrides them\n // with its real width -- a fixed 36px is correct for one icon and\n // wrong for anything wider, which is how `https://` came to\n // render on top of the value.\n leading && !leadingWidth && \"pl-9\",\n (trailing || canReveal) && !trailingWidth && \"pr-9\",\n className,\n )}\n style={{\n // 12px clears `left-3`/`right-3`; 8px is the gap to the text.\n ...(leadingWidth ? { paddingLeft: leadingWidth + 20 } : null),\n ...(trailingWidth ? { paddingRight: trailingWidth + 20 } : null),\n ...props.style,\n }}\n onChange={(e) => {\n onChange?.(e);\n onValueChange?.(e.target.value);\n }}\n {...props}\n // Inline click-to-edit: focus on entering edit, return to the display\n // (and run the host's onBlur) when focus leaves.\n autoFocus={interactive || props.autoFocus}\n onBlur={(e) => {\n props.onBlur?.(e);\n if (interactive) exitEdit();\n }}\n />\n )}\n {canReveal ? (\n <button\n type=\"button\"\n // type=\"button\" is load-bearing: the default is \"submit\", so a\n // reveal inside a login form would submit it on every click.\n id={`${inputId}-reveal`}\n data-react-fancy-reveal=\"\"\n onClick={() => setRevealed((v) => !v)}\n disabled={disabled}\n aria-controls={inputId}\n aria-pressed={shown}\n aria-label={shown ? hideLabel : revealLabel}\n title={shown ? hideLabel : revealLabel}\n // Not focusable by tab: the field and the submit button are the\n // path through a login form, and a reveal in between is a stop\n // most people do not want. Still reachable by click and by\n // screen readers.\n tabIndex={-1}\n className=\"absolute right-2 inline-flex items-center justify-center rounded p-1 text-[color:var(--fancy-text-faint,var(--color-zinc-400))] transition-colors hover:text-zinc-600 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-blue-500/40 disabled:cursor-not-allowed disabled:opacity-50 dark:text-[color:var(--fancy-text-faint-dark,var(--color-zinc-500))] dark:hover:text-zinc-300\"\n >\n {shown ? <EyeOffIcon /> : <EyeIcon />}\n </button>\n ) : (\n trailing && (\n <span\n ref={trailingRef}\n className=\"pointer-events-none absolute right-3 text-[color:var(--fancy-text-faint,var(--color-zinc-400))] dark:text-[color:var(--fancy-text-faint-dark,var(--color-zinc-500))]\"\n >\n {trailing}\n </span>\n )\n )}\n </div>\n </InputWrapper>\n );\n\n if (label || error || description) {\n return (\n <Field\n label={label}\n labelId={pasting ? labelId : undefined}\n labelHidden={labelHidden}\n description={description}\n error={error}\n required={required}\n htmlFor={inputId}\n size={size}\n >\n {input}\n </Field>\n );\n }\n\n return input;\n },\n);\n\nInput.displayName = \"Input\";\n\n/** Where the placeholder sits over the paste editor, matching `inputSizeClasses`. */\nconst pastePlaceholderClasses = {\n xs: \"left-2 top-1 text-xs\",\n sm: \"left-2.5 top-1.5 text-sm\",\n md: \"left-3 top-2 text-sm\",\n lg: \"left-4 top-2.5 text-base\",\n xl: \"left-5 top-3 text-lg\",\n} as const;\n\n/**\n * Inline SVGs rather than the Icon component: Input is the most-installed\n * primitive in the kit, and routing it through the icon registry would make\n * every consumer's password field depend on an icon set being configured.\n */\nfunction EyeIcon() {\n return (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden=\"true\">\n <path d=\"M2.062 12.348a1 1 0 0 1 0-.696 10.75 10.75 0 0 1 19.876 0 1 1 0 0 1 0 .696 10.75 10.75 0 0 1-19.876 0\" />\n <circle cx=\"12\" cy=\"12\" r=\"3\" />\n </svg>\n );\n}\n\nfunction EyeOffIcon() {\n return (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden=\"true\">\n <path d=\"M10.733 5.076a10.744 10.744 0 0 1 11.205 6.575 1 1 0 0 1 0 .696 10.747 10.747 0 0 1-1.444 2.49\" />\n <path d=\"M14.084 14.158a3 3 0 0 1-4.242-4.242\" />\n <path d=\"M17.479 17.499a10.75 10.75 0 0 1-15.417-5.151 1 1 0 0 1 0-.696 10.75 10.75 0 0 1 4.446-5.143\" />\n <path d=\"m2 2 20 20\" />\n </svg>\n );\n}\n"]}
@@ -1,5 +1,5 @@
1
1
  import { Popover } from './chunk-QTS4Q2NK.js';
2
- import { Button } from './chunk-TLRRMYNV.js';
2
+ import { Button } from './chunk-OXERDFFF.js';
3
3
  import { jsxs, jsx } from 'react/jsx-runtime';
4
4
 
5
5
  var CONFIDENCE_TIERS = [
@@ -113,5 +113,5 @@ function ReasonTag({
113
113
  }
114
114
 
115
115
  export { ReasonTag };
116
- //# sourceMappingURL=chunk-QP35Z2WB.js.map
117
- //# sourceMappingURL=chunk-QP35Z2WB.js.map
116
+ //# sourceMappingURL=chunk-BL5IKSB3.js.map
117
+ //# sourceMappingURL=chunk-BL5IKSB3.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/components/ReasonTag/ReasonTag.tsx"],"names":[],"mappings":"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","file":"chunk-QP35Z2WB.js","sourcesContent":["import { Popover } from \"../Popover\";\nimport { Button } from \"../Button\";\n\n/**\n * ReasonTag — wraps any value with a small affordance that reveals the\n * agent's reasoning, sources, and confidence on hover or click.\n *\n * <ReasonTag\n * value=\"$1.4M\"\n * reason=\"Projected Q3 ARR after stacking renewals.\"\n * confidence={0.91}\n * sources={[{ label: \"Q2 actuals · CRM export\" }]}\n * by=\"Forecaster\"\n * />\n *\n * Three visual styles:\n * • \"dot\" — value with a tiny coloured dot (default, subtle)\n * • \"underline\" — dotted underline + trailing \"?\"\n * • \"chip\" — full coloured pill (loud)\n *\n * Confidence drives the colour via three tiers (high / medium / low),\n * so a quick visual scan tells the human which suggestions deserve a\n * second look without opening any tooltips.\n *\n * `pinned` swaps the popover for an inline annotation slot — useful\n * when explainability should always be visible, not buried in a hover.\n */\nexport type ReasonTagSource = { label: string; href?: string };\n\nexport type ReasonTagTheme = \"dot\" | \"underline\" | \"chip\";\n\nexport interface ReasonTagProps {\n /** The value the tag wraps — usually a number, label, or short phrase. */\n value: React.ReactNode;\n /** Free-text rationale shown in the popover / inline annotation. */\n reason: string;\n /** 0..1 confidence. Drives the tier colour. Defaults to 1. */\n confidence?: number;\n /** Optional list of sources (label + optional href). */\n sources?: ReasonTagSource[];\n /** Optional author / agent name shown in the popover header. */\n by?: string;\n /** Visual treatment for the trigger. */\n theme?: ReasonTagTheme;\n /**\n * When true, the popover is replaced with an always-visible inline\n * annotation below the value.\n */\n pinned?: boolean;\n /** Called when the user hits the \"ask follow-up\" action. */\n onFollowUp?: () => void;\n /** Optional className applied to the trigger element. */\n className?: string;\n}\n\nconst CONFIDENCE_TIERS: Array<{ min: number; color: string; label: string }> = [\n { min: 0.85, color: \"#10b981\", label: \"high\" },\n { min: 0.6, color: \"#f59e0b\", label: \"medium\" },\n { min: 0, color: \"#ef4444\", label: \"low\" },\n];\n\nfunction tier(c: number) {\n return CONFIDENCE_TIERS.find((t) => c >= t.min) ?? CONFIDENCE_TIERS[2];\n}\n\nexport function ReasonTag({\n value,\n reason,\n confidence = 1,\n sources = [],\n by,\n theme = \"dot\",\n pinned = false,\n onFollowUp,\n className,\n}: ReasonTagProps) {\n const t = tier(confidence);\n\n const trigger =\n theme === \"chip\" ? (\n <span\n className={`inline-flex cursor-help items-center gap-1 rounded-full px-2 py-0.5 text-[12px] font-medium ${className ?? \"\"}`}\n style={{ backgroundColor: t.color + \"22\", color: t.color }}\n >\n <span\n className=\"h-1.5 w-1.5 rounded-full\"\n style={{ backgroundColor: t.color }}\n />\n {value}\n <span className=\"text-[10px] opacity-70\">?</span>\n </span>\n ) : theme === \"underline\" ? (\n <span\n className={`cursor-help underline decoration-dotted underline-offset-2 ${className ?? \"\"}`}\n style={{ textDecorationColor: t.color }}\n >\n {value}\n <span\n className=\"ml-0.5 font-mono text-[10px]\"\n style={{ color: t.color }}\n >\n ?\n </span>\n </span>\n ) : (\n <span className={`inline-flex cursor-help items-baseline gap-1 ${className ?? \"\"}`}>\n <span className=\"font-medium\">{value}</span>\n <span\n className=\"inline-block h-1.5 w-1.5 rounded-full align-middle\"\n style={{ backgroundColor: t.color }}\n title=\"reason available\"\n />\n </span>\n );\n\n if (pinned) {\n return (\n <span className=\"inline-flex flex-col items-start gap-0.5 align-top\">\n {trigger}\n <span\n className=\"block max-w-[280px] rounded border-l-2 pl-2 text-[11px] leading-snug text-zinc-600 dark:text-zinc-300\"\n style={{ borderColor: t.color }}\n >\n {reason}\n </span>\n </span>\n );\n }\n\n return (\n <Popover hover>\n <Popover.Trigger>{trigger}</Popover.Trigger>\n <Popover.Content>\n <div className=\"w-72 space-y-2 text-sm\">\n <div className=\"flex items-baseline gap-2\">\n <span\n className=\"text-[10px] font-semibold uppercase tracking-wider\"\n style={{ color: t.color }}\n >\n {t.label} confidence · {(confidence * 100).toFixed(0)}%\n </span>\n {by && (\n <span className=\"ml-auto font-mono text-[10px] text-zinc-400\">\n @{by}\n </span>\n )}\n </div>\n <p className=\"text-[13px] leading-snug text-zinc-700 dark:text-zinc-200\">\n {reason}\n </p>\n {sources.length > 0 && (\n <div>\n <div className=\"text-[10px] uppercase tracking-wider text-zinc-400\">\n sources\n </div>\n <ul className=\"mt-0.5 space-y-0.5 text-[12px]\">\n {sources.map((s, i) => (\n <li key={i}>\n {s.href ? (\n <a className=\"text-violet-600 hover:underline\" href={s.href}>\n {s.label}\n </a>\n ) : (\n <span className=\"text-zinc-600 dark:text-zinc-300\">\n {s.label}\n </span>\n )}\n </li>\n ))}\n </ul>\n </div>\n )}\n {onFollowUp && (\n <div className=\"flex justify-end pt-1\">\n <Button size=\"sm\" variant=\"ghost\" onClick={onFollowUp}>\n ask follow-up\n </Button>\n </div>\n )}\n </div>\n </Popover.Content>\n </Popover>\n );\n}\n"]}
1
+ {"version":3,"sources":["../src/components/ReasonTag/ReasonTag.tsx"],"names":[],"mappings":"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","file":"chunk-BL5IKSB3.js","sourcesContent":["import { Popover } from \"../Popover\";\nimport { Button } from \"../Button\";\n\n/**\n * ReasonTag — wraps any value with a small affordance that reveals the\n * agent's reasoning, sources, and confidence on hover or click.\n *\n * <ReasonTag\n * value=\"$1.4M\"\n * reason=\"Projected Q3 ARR after stacking renewals.\"\n * confidence={0.91}\n * sources={[{ label: \"Q2 actuals · CRM export\" }]}\n * by=\"Forecaster\"\n * />\n *\n * Three visual styles:\n * • \"dot\" — value with a tiny coloured dot (default, subtle)\n * • \"underline\" — dotted underline + trailing \"?\"\n * • \"chip\" — full coloured pill (loud)\n *\n * Confidence drives the colour via three tiers (high / medium / low),\n * so a quick visual scan tells the human which suggestions deserve a\n * second look without opening any tooltips.\n *\n * `pinned` swaps the popover for an inline annotation slot — useful\n * when explainability should always be visible, not buried in a hover.\n */\nexport type ReasonTagSource = { label: string; href?: string };\n\nexport type ReasonTagTheme = \"dot\" | \"underline\" | \"chip\";\n\nexport interface ReasonTagProps {\n /** The value the tag wraps — usually a number, label, or short phrase. */\n value: React.ReactNode;\n /** Free-text rationale shown in the popover / inline annotation. */\n reason: string;\n /** 0..1 confidence. Drives the tier colour. Defaults to 1. */\n confidence?: number;\n /** Optional list of sources (label + optional href). */\n sources?: ReasonTagSource[];\n /** Optional author / agent name shown in the popover header. */\n by?: string;\n /** Visual treatment for the trigger. */\n theme?: ReasonTagTheme;\n /**\n * When true, the popover is replaced with an always-visible inline\n * annotation below the value.\n */\n pinned?: boolean;\n /** Called when the user hits the \"ask follow-up\" action. */\n onFollowUp?: () => void;\n /** Optional className applied to the trigger element. */\n className?: string;\n}\n\nconst CONFIDENCE_TIERS: Array<{ min: number; color: string; label: string }> = [\n { min: 0.85, color: \"#10b981\", label: \"high\" },\n { min: 0.6, color: \"#f59e0b\", label: \"medium\" },\n { min: 0, color: \"#ef4444\", label: \"low\" },\n];\n\nfunction tier(c: number) {\n return CONFIDENCE_TIERS.find((t) => c >= t.min) ?? CONFIDENCE_TIERS[2];\n}\n\nexport function ReasonTag({\n value,\n reason,\n confidence = 1,\n sources = [],\n by,\n theme = \"dot\",\n pinned = false,\n onFollowUp,\n className,\n}: ReasonTagProps) {\n const t = tier(confidence);\n\n const trigger =\n theme === \"chip\" ? (\n <span\n className={`inline-flex cursor-help items-center gap-1 rounded-full px-2 py-0.5 text-[12px] font-medium ${className ?? \"\"}`}\n style={{ backgroundColor: t.color + \"22\", color: t.color }}\n >\n <span\n className=\"h-1.5 w-1.5 rounded-full\"\n style={{ backgroundColor: t.color }}\n />\n {value}\n <span className=\"text-[10px] opacity-70\">?</span>\n </span>\n ) : theme === \"underline\" ? (\n <span\n className={`cursor-help underline decoration-dotted underline-offset-2 ${className ?? \"\"}`}\n style={{ textDecorationColor: t.color }}\n >\n {value}\n <span\n className=\"ml-0.5 font-mono text-[10px]\"\n style={{ color: t.color }}\n >\n ?\n </span>\n </span>\n ) : (\n <span className={`inline-flex cursor-help items-baseline gap-1 ${className ?? \"\"}`}>\n <span className=\"font-medium\">{value}</span>\n <span\n className=\"inline-block h-1.5 w-1.5 rounded-full align-middle\"\n style={{ backgroundColor: t.color }}\n title=\"reason available\"\n />\n </span>\n );\n\n if (pinned) {\n return (\n <span className=\"inline-flex flex-col items-start gap-0.5 align-top\">\n {trigger}\n <span\n className=\"block max-w-[280px] rounded border-l-2 pl-2 text-[11px] leading-snug text-zinc-600 dark:text-zinc-300\"\n style={{ borderColor: t.color }}\n >\n {reason}\n </span>\n </span>\n );\n }\n\n return (\n <Popover hover>\n <Popover.Trigger>{trigger}</Popover.Trigger>\n <Popover.Content>\n <div className=\"w-72 space-y-2 text-sm\">\n <div className=\"flex items-baseline gap-2\">\n <span\n className=\"text-[10px] font-semibold uppercase tracking-wider\"\n style={{ color: t.color }}\n >\n {t.label} confidence · {(confidence * 100).toFixed(0)}%\n </span>\n {by && (\n <span className=\"ml-auto font-mono text-[10px] text-zinc-400\">\n @{by}\n </span>\n )}\n </div>\n <p className=\"text-[13px] leading-snug text-zinc-700 dark:text-zinc-200\">\n {reason}\n </p>\n {sources.length > 0 && (\n <div>\n <div className=\"text-[10px] uppercase tracking-wider text-zinc-400\">\n sources\n </div>\n <ul className=\"mt-0.5 space-y-0.5 text-[12px]\">\n {sources.map((s, i) => (\n <li key={i}>\n {s.href ? (\n <a className=\"text-violet-600 hover:underline\" href={s.href}>\n {s.label}\n </a>\n ) : (\n <span className=\"text-zinc-600 dark:text-zinc-300\">\n {s.label}\n </span>\n )}\n </li>\n ))}\n </ul>\n </div>\n )}\n {onFollowUp && (\n <div className=\"flex justify-end pt-1\">\n <Button size=\"sm\" variant=\"ghost\" onClick={onFollowUp}>\n ask follow-up\n </Button>\n </div>\n )}\n </div>\n </Popover.Content>\n </Popover>\n );\n}\n"]}
@@ -1,6 +1,6 @@
1
1
  import { Switch } from './chunk-DXZCKDYS.js';
2
2
  import { DatePicker } from './chunk-2UTN3EFK.js';
3
- import { Input } from './chunk-MVVHUTXA.js';
3
+ import { Input } from './chunk-B4LVQ4QI.js';
4
4
  import { Select } from './chunk-FVI4JDLA.js';
5
5
  import { Textarea } from './chunk-UVUBV4VZ.js';
6
6
  import { DisplayValue } from './chunk-WX5XYDVN.js';
@@ -9,7 +9,7 @@ import { Text } from './chunk-XM3V3RSU.js';
9
9
  import { ColorPicker } from './chunk-SVSQXKFL.js';
10
10
  import { useInlineEdit } from './chunk-OL53XYHF.js';
11
11
  import { Badge } from './chunk-6FCQD2KQ.js';
12
- import { Button } from './chunk-TLRRMYNV.js';
12
+ import { Button } from './chunk-OXERDFFF.js';
13
13
  import { Callout } from './chunk-ZXZJYVWP.js';
14
14
  import { cn } from './chunk-MMW2JGKZ.js';
15
15
  import { createContext, forwardRef, useId, useRef, useMemo, useState, useEffect, useCallback, useContext } from 'react';
@@ -1337,5 +1337,5 @@ function buildItems({
1337
1337
  }
1338
1338
 
1339
1339
  export { JSON_FIELD_TYPES, JsonEditor, applyJsonEdit, describeEdit, findJsonConflicts, getAtPath, inferType, parseKeyMap, parsePath, pathToString, resolveKeyRule, typeMatches };
1340
- //# sourceMappingURL=chunk-SZH7TFME.js.map
1341
- //# sourceMappingURL=chunk-SZH7TFME.js.map
1340
+ //# sourceMappingURL=chunk-DCAD2JPP.js.map
1341
+ //# sourceMappingURL=chunk-DCAD2JPP.js.map