@neuronection/assistant-ui 0.19.0 → 0.20.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.
- package/CHANGELOG.md +10 -0
- package/README.md +3 -0
- package/dist/ai-text-transform.d.ts +44 -0
- package/dist/ai-text-transform.js +3 -0
- package/dist/ai-text-transform.js.map +1 -0
- package/dist/chunk-2PR6POP6.js +543 -0
- package/dist/chunk-2PR6POP6.js.map +1 -0
- package/dist/chunk-BKAO7BTU.js +156 -0
- package/dist/chunk-BKAO7BTU.js.map +1 -0
- package/dist/chunk-KAC2DOLH.js +362 -0
- package/dist/chunk-KAC2DOLH.js.map +1 -0
- package/dist/chunk-XUDCCQRN.js +253 -0
- package/dist/chunk-XUDCCQRN.js.map +1 -0
- package/dist/dictation.d.ts +64 -0
- package/dist/dictation.js +3 -0
- package/dist/dictation.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +15 -11
- package/dist/index.js.map +1 -1
- package/dist/rich-text-editor.d.ts +51 -0
- package/dist/rich-text-editor.js +3 -0
- package/dist/rich-text-editor.js.map +1 -0
- package/dist/styles.css +1 -1
- package/dist/text-diff-view.d.ts +61 -0
- package/dist/text-diff-view.js +3 -0
- package/dist/text-diff-view.js.map +1 -0
- package/package.json +24 -2
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/dictation/DictationButton.tsx","../src/components/dictation/useDictation.ts"],"names":["useRef","useEffect"],"mappings":";;;;;;AAOA,IAAM,cAAc,CAAC,IAAA,EAAM,IAAA,EAAM,GAAA,EAAK,MAAM,IAAI,CAAA;AAWzC,SAAS,eAAA,CAAgB;AAAA,EAC9B,MAAA;AAAA,EACA,OAAA;AAAA,EACA,KAAA,GAAQ,SAAA;AAAA,EACR,cAAA;AAAA,EACA;AACF,CAAA,EAAyB;AACvB,EAAA,uBACE,IAAA;AAAA,IAAC,QAAA;AAAA,IAAA;AAAA,MACC,IAAA,EAAK,QAAA;AAAA,MACL,KAAA,EAAO,KAAA;AAAA,MACP,YAAA,EAAY,KAAA;AAAA,MACZ,gBAAc,MAAA,KAAW,WAAA,GAAc,IAAA,GAAO,MAAA,KAAW,iBAAiB,MAAA,GAAY,KAAA;AAAA,MACtF,UAAU,MAAA,KAAW,cAAA;AAAA,MACrB,SAAA,EAAQ,kBAAA;AAAA,MACR,SAAA,EAAW,EAAA;AAAA,QACT,2HAAA;AAAA,QACA,MAAA,KAAW,cACP,gEAAA,GACA,qDAAA;AAAA,QACJ;AAAA,OACF;AAAA,MACA,OAAA,EAAS,OAAA;AAAA,MAET,QAAA,EAAA;AAAA,wBAAA,GAAA,CAAC,GAAA,EAAA,EAAI,SAAA,EAAU,QAAA,EAAS,aAAA,EAAW,IAAA,EAAC,CAAA;AAAA,wBACpC,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,SAAA,EAAW,4BAAkB,KAAA,EAAM;AAAA;AAAA;AAAA,GACrD;AAEJ;AAEA,SAAS,SAAA,CAAU;AAAA,EACjB,QAAA;AAAA,EACA;AACF,CAAA,EAGG;AACD,EAAA,MAAM,OAAA,GAAgB,KAAA,CAAA,MAAA,CAAsC,EAAE,CAAA;AAC9D,EAAM,gBAAU,MAAM;AACpB,IAAA,IAAI,CAAC,MAAA,EAAQ;AACX,MAAA;AAAA,IACF;AACA,IAAA,IAAI,KAAA,GAAQ,qBAAA,CAAsB,SAAS,IAAA,GAAO;AAChD,MAAA,MAAM,QAAQ,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,QAAA,CAAS,WAAW,CAAC,CAAA;AAC/C,MAAA,OAAA,CAAQ,OAAA,CAAQ,OAAA,CAAQ,CAAC,GAAA,EAAK,KAAA,KAAU;AACtC,QAAA,IAAI,QAAQ,IAAA,EAAM;AAChB,UAAA,MAAM,MAAA,GAAS,WAAA,CAAY,KAAK,CAAA,IAAK,CAAA;AACrC,UAAA,MAAM,MAAA,GAAS,KAAK,GAAA,CAAI,IAAA,EAAM,KAAK,GAAA,CAAI,CAAA,EAAG,KAAA,GAAQ,MAAM,CAAC,CAAA;AACzD,UAAA,GAAA,CAAI,KAAA,CAAM,SAAA,GAAY,CAAA,OAAA,EAAU,MAAM,CAAA,CAAA,CAAA;AAAA,QACxC;AAAA,MACF,CAAC,CAAA;AACD,MAAA,KAAA,GAAQ,sBAAsB,IAAI,CAAA;AAAA,IACpC,CAAC,CAAA;AACD,IAAA,OAAO,MAAM,qBAAqB,KAAK,CAAA;AAAA,EACzC,CAAA,EAAG,CAAC,MAAA,EAAQ,QAAQ,CAAC,CAAA;AACrB,EAAA,uBACE,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,4BAAA,EAA6B,aAAA,EAAW,MACrD,QAAA,EAAA,WAAA,CAAY,GAAA,CAAI,CAAC,CAAA,EAAG,KAAA,qBACnB,GAAA;AAAA,IAAC,MAAA;AAAA,IAAA;AAAA,MAEC,GAAA,EAAK,CAAC,OAAA,KAAY;AAChB,QAAA,OAAA,CAAQ,OAAA,CAAQ,KAAK,CAAA,GAAI,OAAA;AAAA,MAC3B,CAAA;AAAA,MACA,SAAA,EAAU;AAAA,KAAA;AAAA,IAJL;AAAA,GAMR,CAAA,EACH,CAAA;AAEJ;AAeA,IAAM,oBAAA,GAAuD;AAAA,EAC3D,SAAA,EAAW,iBAAA;AAAA,EACX,YAAA,EAAc,oBAAA;AAAA,EACd,IAAA,EAAM,MAAA;AAAA,EACN,MAAA,EAAQ,QAAA;AAAA,EACR,YAAA,EAAc,SAAA;AAAA,EACd,WAAA,EAAa,gDAAA;AAAA,EACb,MAAA,EAAQ,+BAAA;AAAA,EACR,UAAA,EAAY,sCAAA;AAAA,EACZ,MAAA,EAAQ;AACV,CAAA;AAcO,SAAS,cAAA,CAAe;AAAA,EAC7B,MAAA;AAAA,EACA,OAAA;AAAA,EACA,QAAA;AAAA,EACA,KAAA;AAAA,EACA,MAAA;AAAA,EACA,MAAA;AAAA,EACA,QAAA;AAAA,EACA,cAAA;AAAA,EACA;AACF,CAAA,EAAwB;AACtB,EAAA,MAAM,MAAA,GAAS,EAAE,GAAG,oBAAA,EAAsB,GAAG,MAAA,EAAO;AACpD,EAAA,MAAM,UAAA,GAAa,CAAC,KAAA,KAAkB;AACpC,IAAA,MAAM,OAAA,GAAU,IAAA,CAAK,KAAA,CAAM,KAAA,GAAQ,EAAE,CAAA;AACrC,IAAA,MAAM,SAAS,MAAA,CAAO,KAAA,GAAQ,EAAE,CAAA,CAAE,QAAA,CAAS,GAAG,GAAG,CAAA;AACjD,IAAA,OAAO,CAAA,EAAG,OAAO,OAAO,CAAA,CAAE,SAAS,CAAA,EAAG,GAAG,CAAC,CAAA,CAAA,EAAI,MAAM,CAAA,CAAA;AAAA,EACtD,CAAA;AACA,EAAA,MAAM,SAAA,GACJ,KAAA,KAAU,IAAA,GACN,EAAA,GACA,KAAA,CAAM,SAAS,aAAA,GACb,MAAA,CAAO,WAAA,GACP,KAAA,CAAM,IAAA,KAAS,QAAA,GACb,OAAO,MAAA,GACP,KAAA,CAAM,IAAA,KAAS,YAAA,GACb,MAAA,CAAO,UAAA,GACP,MAAA,CAAO,MAAA,CAAO,OAAA,CAAQ,UAAA,EAAY,KAAA,CAAM,MAAA,IAAU,EAAE,CAAA;AAChE,EAAA,IAAI,UAAU,IAAA,EAAM;AAClB,IAAA,uBACE,IAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QACC,SAAA,EAAQ,iBAAA;AAAA,QACR,SAAA,EAAW,EAAA;AAAA,UACT,mIAAA;AAAA,UACA;AAAA,SACF;AAAA,QACA,IAAA,EAAK,OAAA;AAAA,QAEL,QAAA,EAAA;AAAA,0BAAA,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,4BAAA,EAA8B,QAAA,EAAA,SAAA,EAAU,CAAA;AAAA,0BACxD,GAAA;AAAA,YAAC,QAAA;AAAA,YAAA;AAAA,cACC,IAAA,EAAK,QAAA;AAAA,cACL,cAAY,MAAA,CAAO,YAAA;AAAA,cACnB,OAAO,MAAA,CAAO,YAAA;AAAA,cACd,SAAA,EAAU,qCAAA;AAAA,cACV,OAAA,EAAS,cAAA;AAAA,cAET,QAAA,kBAAA,GAAA,CAAC,CAAA,EAAA,EAAE,SAAA,EAAU,UAAA,EAAW,eAAW,IAAA,EAAC;AAAA;AAAA;AACtC;AAAA;AAAA,KACF;AAAA,EAEJ;AACA,EAAA,IAAI,WAAW,MAAA,EAAQ;AACrB,IAAA,OAAO,IAAA;AAAA,EACT;AACA,EAAA,uBACE,GAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,SAAA,EAAQ,iBAAA;AAAA,MACR,SAAA,EAAW,EAAA;AAAA,QACT,kHAAA;AAAA,QACA;AAAA,OACF;AAAA,MACA,IAAA,EAAK,QAAA;AAAA,MACL,cAAY,MAAA,CAAO,SAAA;AAAA,MAElB,QAAA,EAAA,MAAA,KAAW,8BACV,IAAA,CAAA,QAAA,EAAA,EACE,QAAA,EAAA;AAAA,wBAAA,GAAA;AAAA,UAAC,MAAA;AAAA,UAAA;AAAA,YACC,SAAA,EAAU,kEAAA;AAAA,YACV,aAAA,EAAW;AAAA;AAAA,SACb;AAAA,4BACC,MAAA,EAAA,EAAK,SAAA,EAAU,8CAAA,EACb,QAAA,EAAA,UAAA,CAAW,OAAO,CAAA,EACrB,CAAA;AAAA,wBACA,GAAA,CAAC,SAAA,EAAA,EAAU,QAAA,EAAoB,MAAA,EAAM,IAAA,EAAC,CAAA;AAAA,wBACtC,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,mDAAA,EACb,iBAAO,SAAA,EACV,CAAA;AAAA,wBACA,GAAA;AAAA,UAAC,QAAA;AAAA,UAAA;AAAA,YACC,IAAA,EAAK,QAAA;AAAA,YACL,cAAY,MAAA,CAAO,MAAA;AAAA,YACnB,OAAO,MAAA,CAAO,MAAA;AAAA,YACd,SAAA,EAAU,iEAAA;AAAA,YACV,OAAA,EAAS,QAAA;AAAA,YAET,QAAA,kBAAA,GAAA,CAAC,CAAA,EAAA,EAAE,SAAA,EAAU,UAAA,EAAW,eAAW,IAAA,EAAC;AAAA;AAAA,SACtC;AAAA,wBACA,IAAA;AAAA,UAAC,QAAA;AAAA,UAAA;AAAA,YACC,IAAA,EAAK,QAAA;AAAA,YACL,OAAO,MAAA,CAAO,IAAA;AAAA,YACd,cAAY,MAAA,CAAO,IAAA;AAAA,YACnB,SAAA,EAAU,6EAAA;AAAA,YACV,OAAA,EAAS,MAAA;AAAA,YAET,QAAA,EAAA;AAAA,8BAAA,GAAA,CAAC,MAAA,EAAA,EAAO,SAAA,EAAU,QAAA,EAAS,aAAA,EAAW,IAAA,EAAC,CAAA;AAAA,cACtC,MAAA,CAAO;AAAA;AAAA;AAAA;AACV,OAAA,EACF,oBAEA,IAAA,CAAA,QAAA,EAAA,EACE,QAAA,EAAA;AAAA,wBAAA,GAAA;AAAA,UAAC,OAAA;AAAA,UAAA;AAAA,YACC,SAAA,EAAU,0DAAA;AAAA,YACV,aAAA,EAAW;AAAA;AAAA,SACb;AAAA,wBACA,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,0CAAA,EACb,iBAAO,YAAA,EACV;AAAA,OAAA,EACF;AAAA;AAAA,GAEJ;AAEJ;ACpNA,IAAM,oBAAA,GAAuB;AAAA,EAC3B,wBAAA;AAAA,EACA,YAAA;AAAA,EACA,uBAAA;AAAA,EACA;AACF,CAAA;AAEA,IAAM,SAAA,GAAY,CAAA;AAClB,IAAM,WAAA,GAAc,CAAA;AACpB,IAAM,WAAA,GAAc,IAAA;AAEpB,SAAS,YAAA,GAA8B;AACrC,EAAA,IAAI,OAAO,kBAAkB,WAAA,EAAa;AACxC,IAAA,OAAO,IAAA;AAAA,EACT;AACA,EAAA,KAAA,MAAW,YAAY,oBAAA,EAAsB;AAC3C,IAAA,IAAI,aAAA,CAAc,eAAA,CAAgB,QAAQ,CAAA,EAAG;AAC3C,MAAA,OAAO,QAAA;AAAA,IACT;AAAA,EACF;AACA,EAAA,OAAO,IAAA;AACT;AAEO,SAAS,aAAa,OAAA,EAA8B;AACzD,EAAA,MAAM,CAAC,MAAA,EAAQ,SAAS,CAAA,GAAI,SAA0B,MAAM,CAAA;AAC5D,EAAA,MAAM,CAAC,OAAA,EAAS,UAAU,CAAA,GAAI,SAAS,CAAC,CAAA;AACxC,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAI,SAAgC,IAAI,CAAA;AAE9D,EAAA,MAAM,UAAA,GAAaA,OAAO,OAAO,CAAA;AACjC,EAAA,UAAA,CAAW,OAAA,GAAU,OAAA;AAErB,EAAA,MAAM,WAAA,GAAcA,OAA6B,IAAI,CAAA;AACrD,EAAA,MAAM,SAAA,GAAYA,OAA2B,IAAI,CAAA;AACjD,EAAA,MAAM,SAAA,GAAYA,MAAAA,CAAmB,EAAE,CAAA;AACvC,EAAA,MAAM,eAAA,GAAkBA,OAA4B,IAAI,CAAA;AACxD,EAAA,MAAM,MAAA,GAASA,OAAsB,IAAI,CAAA;AACzC,EAAA,MAAM,QAAA,GAAWA,OAAsB,IAAI,CAAA;AAC3C,EAAA,MAAM,QAAA,GAAWA,OAAO,CAAC,CAAA;AAEzB,EAAA,MAAM,QAAA,GAAW,YAAY,MAAM;AACjC,IAAA,IAAI,MAAA,CAAO,YAAY,IAAA,EAAM;AAC3B,MAAA,oBAAA,CAAqB,OAAO,OAAO,CAAA;AACnC,MAAA,MAAA,CAAO,OAAA,GAAU,IAAA;AAAA,IACnB;AACA,IAAA,IAAI,QAAA,CAAS,YAAY,IAAA,EAAM;AAC7B,MAAA,MAAA,CAAO,aAAA,CAAc,SAAS,OAAO,CAAA;AACrC,MAAA,QAAA,CAAS,OAAA,GAAU,IAAA;AAAA,IACrB;AACA,IAAA,eAAA,CAAgB,OAAA,EAAS,KAAA,EAAM,CAAE,KAAA,CAAM,MAAM,MAAS,CAAA;AACtD,IAAA,eAAA,CAAgB,OAAA,GAAU,IAAA;AAC1B,IAAA,SAAA,CAAU,OAAA,EAAS,WAAU,CAAE,OAAA,CAAQ,CAAC,KAAA,KAAU,KAAA,CAAM,MAAM,CAAA;AAC9D,IAAA,SAAA,CAAU,OAAA,GAAU,IAAA;AACpB,IAAA,WAAA,CAAY,OAAA,GAAU,IAAA;AACtB,IAAA,QAAA,CAAS,OAAA,GAAU,CAAA;AAAA,EACrB,CAAA,EAAG,EAAE,CAAA;AAEL,EAAA,MAAM,UAAA,GAAa,WAAA,CAAY,CAAC,MAAA,KAAwB;AACtD,IAAA,IAAI,OAAO,iBAAiB,WAAA,EAAa;AACvC,MAAA;AAAA,IACF;AACA,IAAA,MAAM,OAAA,GAAU,IAAI,YAAA,EAAa;AACjC,IAAA,eAAA,CAAgB,OAAA,GAAU,OAAA;AAC1B,IAAA,MAAM,QAAA,GAAW,QAAQ,cAAA,EAAe;AACxC,IAAA,QAAA,CAAS,OAAA,GAAU,GAAA;AACnB,IAAA,OAAA,CAAQ,uBAAA,CAAwB,MAAM,CAAA,CAAE,OAAA,CAAQ,QAAQ,CAAA;AACxD,IAAA,MAAM,MAAA,GAAS,IAAI,UAAA,CAAW,QAAA,CAAS,OAAO,CAAA;AAC9C,IAAA,MAAM,OAAO,MAAM;AACjB,MAAA,QAAA,CAAS,sBAAsB,MAAM,CAAA;AACrC,MAAA,IAAI,GAAA,GAAM,CAAA;AACV,MAAA,KAAA,MAAW,SAAS,MAAA,EAAQ;AAC1B,QAAA,MAAM,QAAA,GAAA,CAAY,QAAQ,GAAA,IAAO,GAAA;AACjC,QAAA,GAAA,IAAO,QAAA,GAAW,QAAA;AAAA,MACpB;AACA,MAAA,MAAM,GAAA,GAAM,IAAA,CAAK,IAAA,CAAK,GAAA,GAAM,OAAO,MAAM,CAAA;AACzC,MAAA,QAAA,CAAS,UAAU,IAAA,CAAK,GAAA;AAAA,QACtB,SAAA;AAAA,QACA,KAAK,GAAA,CAAI,GAAA,GAAM,WAAA,EAAa,QAAA,CAAS,UAAU,WAAW;AAAA,OAC5D;AACA,MAAA,MAAA,CAAO,OAAA,GAAU,sBAAsB,IAAI,CAAA;AAAA,IAC7C,CAAA;AACA,IAAA,MAAA,CAAO,OAAA,GAAU,sBAAsB,IAAI,CAAA;AAAA,EAC7C,CAAA,EAAG,EAAE,CAAA;AAEL,EAAA,MAAM,KAAA,GAAQ,YAAY,YAAY;AACpC,IAAA,IAAI,WAAW,MAAA,EAAQ;AACrB,MAAA;AAAA,IACF;AACA,IAAA,QAAA,CAAS,IAAI,CAAA;AACb,IAAA,IACE,OAAO,cAAc,WAAA,IACrB,CAAC,UAAU,YAAA,EAAc,YAAA,IACzB,OAAO,aAAA,KAAkB,WAAA,EACzB;AACA,MAAA,QAAA,CAAS,EAAE,IAAA,EAAM,aAAA,EAAe,CAAA;AAChC,MAAA;AAAA,IACF;AACA,IAAA,IAAI,MAAA;AACJ,IAAA,IAAI;AACF,MAAA,MAAA,GAAS,MAAM,SAAA,CAAU,YAAA,CAAa,aAAa,EAAE,KAAA,EAAO,MAAM,CAAA;AAAA,IACpE,SAAS,YAAA,EAAc;AACrB,MAAA,MAAM,IAAA,GAAO,YAAA,YAAwB,YAAA,GAAe,YAAA,CAAa,IAAA,GAAO,EAAA;AACxE,MAAA,QAAA;AAAA,QACE,IAAA,KAAS,qBAAqB,IAAA,KAAS,eAAA,IAAmB,SAAS,eAAA,GAC/D,EAAE,IAAA,EAAM,QAAA,EAAS,GACjB;AAAA,UACE,IAAA,EAAM,QAAA;AAAA,UACN,QACE,YAAA,YAAwB,KAAA,GACpB,YAAA,CAAa,OAAA,GACb,OAAO,YAAY;AAAA;AAC3B,OACN;AACA,MAAA;AAAA,IACF;AACA,IAAA,MAAM,WAAW,YAAA,EAAa;AAC9B,IAAA,MAAM,QAAA,GAAW,IAAI,aAAA,CAAc,MAAA,EAAQ,WAAW,EAAE,QAAA,KAAa,MAAS,CAAA;AAC9E,IAAA,MAAM,SAAqB,EAAC;AAC5B,IAAA,QAAA,CAAS,eAAA,GAAkB,CAAC,KAAA,KAAU;AACpC,MAAA,IAAI,KAAA,CAAM,IAAA,CAAK,IAAA,GAAO,CAAA,EAAG;AACvB,QAAA,MAAA,CAAO,IAAA,CAAK,MAAM,IAAI,CAAA;AAAA,MACxB;AAAA,IACF,CAAA;AACA,IAAA,WAAA,CAAY,OAAA,GAAU,QAAA;AACtB,IAAA,SAAA,CAAU,OAAA,GAAU,MAAA;AACpB,IAAA,SAAA,CAAU,OAAA,GAAU,MAAA;AACpB,IAAA,QAAA,CAAS,MAAM,GAAG,CAAA;AAClB,IAAA,UAAA,CAAW,CAAC,CAAA;AACZ,IAAA,SAAA,CAAU,WAAW,CAAA;AACrB,IAAA,UAAA,CAAW,MAAM,CAAA;AACjB,IAAA,QAAA,CAAS,OAAA,GAAU,MAAA,CAAO,WAAA,CAAY,MAAM;AAC1C,MAAA,UAAA,CAAW,CAAC,OAAA,KAAY,OAAA,GAAU,CAAC,CAAA;AAAA,IACrC,GAAG,GAAI,CAAA;AAAA,EACT,CAAA,EAAG,CAAC,UAAA,EAAY,MAAM,CAAC,CAAA;AAEvB,EAAA,MAAM,MAAA,GAAS,YAAY,MAAM;AAC/B,IAAA,MAAM,WAAW,WAAA,CAAY,OAAA;AAC7B,IAAA,IAAI,QAAA,KAAa,IAAA,IAAQ,QAAA,CAAS,KAAA,KAAU,UAAA,EAAY;AACtD,MAAA,QAAA,CAAS,MAAA,GAAS,IAAA;AAClB,MAAA,QAAA,CAAS,IAAA,EAAK;AAAA,IAChB;AACA,IAAA,QAAA,EAAS;AACT,IAAA,UAAA,CAAW,CAAC,CAAA;AACZ,IAAA,SAAA,CAAU,MAAM,CAAA;AAAA,EAClB,CAAA,EAAG,CAAC,QAAQ,CAAC,CAAA;AAEb,EAAA,MAAM,IAAA,GAAO,YAAY,YAAY;AACnC,IAAA,MAAM,WAAW,WAAA,CAAY,OAAA;AAC7B,IAAA,IAAI,QAAA,KAAa,IAAA,IAAQ,QAAA,CAAS,KAAA,KAAU,UAAA,EAAY;AACtD,MAAA;AAAA,IACF;AACA,IAAA,MAAM,QAAA,GAAW,SAAS,QAAA,IAAY,YAAA;AACtC,IAAA,MAAM,SAAS,SAAA,CAAU,OAAA;AACzB,IAAA,MAAM,OAAA,GAAU,IAAI,OAAA,CAAc,CAAC,OAAA,KAAY;AAC7C,MAAA,QAAA,CAAS,MAAA,GAAS,MAAM,OAAA,EAAQ;AAAA,IAClC,CAAC,CAAA;AACD,IAAA,QAAA,CAAS,IAAA,EAAK;AACd,IAAA,MAAM,OAAA;AACN,IAAA,QAAA,EAAS;AACT,IAAA,UAAA,CAAW,CAAC,CAAA;AACZ,IAAA,SAAA,CAAU,cAAc,CAAA;AACxB,IAAA,IAAI;AACF,MAAA,MAAM,OAAO,IAAI,IAAA,CAAK,QAAQ,EAAE,IAAA,EAAM,UAAU,CAAA;AAChD,MAAA,MAAM,MAAA,GAAS,MAAM,UAAA,CAAW,OAAA,CAAQ,WAAW,IAAI,CAAA;AACvD,MAAA,SAAA,CAAU,MAAM,CAAA;AAChB,MAAA,UAAA,CAAW,OAAA,CAAQ,QAAA,GAAW,MAAA,CAAO,IAAI,CAAA;AAAA,IAC3C,SAAS,eAAA,EAAiB;AACxB,MAAA,MAAM,UAAA,GACJ,UAAA,CAAW,OAAA,CAAQ,aAAA,GAAgB,eAAe,CAAA,IACjD;AAAA,QACC,IAAA,EAAM,QAAA;AAAA,QACN,QACE,eAAA,YAA2B,KAAA,GACvB,eAAA,CAAgB,OAAA,GAChB,OAAO,eAAe;AAAA,OAC9B;AACF,MAAA,QAAA,CAAS,UAAU,CAAA;AACnB,MAAA,SAAA,CAAU,MAAM,CAAA;AAAA,IAClB;AAAA,EACF,CAAA,EAAG,CAAC,QAAQ,CAAC,CAAA;AAEb,EAAA,MAAM,YAAA,GAAe,YAAY,MAAM;AACrC,IAAA,QAAA,CAAS,IAAI,CAAA;AAAA,EACf,CAAA,EAAG,EAAE,CAAA;AAEL,EAAAC,SAAAA;AAAA,IACE,MAAM,MAAM;AACV,MAAA,MAAM,WAAW,WAAA,CAAY,OAAA;AAC7B,MAAA,IAAI,QAAA,KAAa,IAAA,IAAQ,QAAA,CAAS,KAAA,KAAU,UAAA,EAAY;AACtD,QAAA,QAAA,CAAS,MAAA,GAAS,IAAA;AAClB,QAAA,QAAA,CAAS,IAAA,EAAK;AAAA,MAChB;AACA,MAAA,QAAA,EAAS;AAAA,IACX,CAAA;AAAA,IACA,CAAC,QAAQ;AAAA,GACX;AAEA,EAAA,OAAO,EAAE,QAAQ,OAAA,EAAS,KAAA,EAAO,UAAU,KAAA,EAAO,IAAA,EAAM,QAAQ,YAAA,EAAa;AAC/E","file":"chunk-KAC2DOLH.js","sourcesContent":["import * as React from 'react'\nimport { Loader2, Mic, Square, X } from 'lucide-react'\n\nimport { cn } from '../../lib/utils'\n\nimport type { DictationError, DictationStatus } from './useDictation'\n\nconst BAR_WEIGHTS = [0.45, 0.62, 0.8, 0.92, 1.05]\n\nexport interface DictationButtonProps {\n status: DictationStatus\n onStart: () => void\n /** Accessible name / tooltip. English default: 'Dictate'. */\n label?: string\n recordingLabel?: string\n className?: string\n}\n\nexport function DictationButton({\n status,\n onStart,\n label = 'Dictate',\n recordingLabel,\n className,\n}: DictationButtonProps) {\n return (\n <button\n type=\"button\"\n title={label}\n aria-label={label}\n aria-pressed={status === 'recording' ? true : status === 'transcribing' ? undefined : false}\n disabled={status === 'transcribing'}\n data-as=\"dictation-button\"\n className={cn(\n 'rounded p-1.5 transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--as-focus-ring)]',\n status === 'recording'\n ? 'animate-pulse bg-[var(--as-danger)]/10 text-[var(--as-danger)]'\n : 'text-[var(--as-muted-fg)] hover:text-[var(--as-fg)]',\n className,\n )}\n onClick={onStart}\n >\n <Mic className=\"size-4\" aria-hidden />\n <span className=\"sr-only\">{recordingLabel ?? label}</span>\n </button>\n )\n}\n\nfunction LevelBars({\n levelRef,\n active,\n}: {\n levelRef: React.RefObject<number>\n active: boolean\n}) {\n const barsRef = React.useRef<Array<HTMLSpanElement | null>>([])\n React.useEffect(() => {\n if (!active) {\n return\n }\n let frame = requestAnimationFrame(function tick() {\n const level = Math.min(1, levelRef.current ?? 0)\n barsRef.current.forEach((bar, index) => {\n if (bar !== null) {\n const weight = BAR_WEIGHTS[index] ?? 1\n const height = Math.max(0.15, Math.min(1, level * weight))\n bar.style.transform = `scaleY(${height})`\n }\n })\n frame = requestAnimationFrame(tick)\n })\n return () => cancelAnimationFrame(frame)\n }, [active, levelRef])\n return (\n <span className=\"flex h-4 items-end gap-0.5\" aria-hidden>\n {BAR_WEIGHTS.map((_, index) => (\n <span\n key={index}\n ref={(element) => {\n barsRef.current[index] = element\n }}\n className=\"h-4 w-1 origin-bottom rounded-full bg-[var(--as-danger)] opacity-40\"\n />\n ))}\n </span>\n )\n}\n\nexport interface DictationStripLabels {\n recording?: string\n transcribing?: string\n stop?: string\n cancel?: string\n dismissError?: string\n unsupported?: string\n denied?: string\n unassigned?: string\n /** `{detail}` is interpolated with the transport error message. */\n failed?: string\n}\n\nconst DEFAULT_STRIP_LABELS: Required<DictationStripLabels> = {\n recording: 'Recording…',\n transcribing: 'Transcribing…',\n stop: 'Stop',\n cancel: 'Cancel',\n dismissError: 'Dismiss',\n unsupported: 'Speech input is not supported in this browser.',\n denied: 'Microphone access was denied.',\n unassigned: 'No speech-to-text model is assigned.',\n failed: 'Transcription failed. {detail}',\n}\n\nexport interface DictationStripProps {\n status: DictationStatus\n seconds: number\n levelRef: React.RefObject<number>\n error: DictationError | null\n labels?: Partial<DictationStripLabels>\n onStop: () => void\n onCancel: () => void\n onDismissError: () => void\n className?: string\n}\n\nexport function DictationStrip({\n status,\n seconds,\n levelRef,\n error,\n labels,\n onStop,\n onCancel,\n onDismissError,\n className,\n}: DictationStripProps) {\n const merged = { ...DEFAULT_STRIP_LABELS, ...labels }\n const formatTime = (total: number) => {\n const minutes = Math.floor(total / 60)\n const padded = String(total % 60).padStart(2, '0')\n return `${String(minutes).padStart(2, '0')}:${padded}`\n }\n const errorText =\n error === null\n ? ''\n : error.kind === 'unsupported'\n ? merged.unsupported\n : error.kind === 'denied'\n ? merged.denied\n : error.kind === 'unassigned'\n ? merged.unassigned\n : merged.failed.replace('{detail}', error.detail ?? '')\n if (error !== null) {\n return (\n <div\n data-as=\"dictation-strip\"\n className={cn(\n 'flex items-center gap-2 rounded-md border border-dashed border-[var(--as-warning)] px-2.5 py-1.5 text-xs text-[var(--as-warning)]',\n className,\n )}\n role=\"alert\"\n >\n <span className=\"min-w-0 flex-1 break-words\">{errorText}</span>\n <button\n type=\"button\"\n aria-label={merged.dismissError}\n title={merged.dismissError}\n className=\"rounded-full p-0.5 hover:opacity-70\"\n onClick={onDismissError}\n >\n <X className=\"size-3.5\" aria-hidden />\n </button>\n </div>\n )\n }\n if (status === 'idle') {\n return null\n }\n return (\n <div\n data-as=\"dictation-strip\"\n className={cn(\n 'flex items-center gap-2 rounded-md border border-[var(--as-border)] bg-[var(--as-surface)] px-2.5 py-1.5 text-xs',\n className,\n )}\n role=\"status\"\n aria-label={merged.recording}\n >\n {status === 'recording' ? (\n <>\n <span\n className=\"size-2 shrink-0 animate-pulse rounded-full bg-[var(--as-danger)]\"\n aria-hidden\n />\n <span className=\"tabular-nums font-medium text-[var(--as-fg)]\">\n {formatTime(seconds)}\n </span>\n <LevelBars levelRef={levelRef} active />\n <span className=\"min-w-0 flex-1 truncate text-[var(--as-muted-fg)]\">\n {merged.recording}\n </span>\n <button\n type=\"button\"\n aria-label={merged.cancel}\n title={merged.cancel}\n className=\"rounded p-1 text-[var(--as-muted-fg)] hover:text-[var(--as-fg)]\"\n onClick={onCancel}\n >\n <X className=\"size-3.5\" aria-hidden />\n </button>\n <button\n type=\"button\"\n title={merged.stop}\n aria-label={merged.stop}\n className=\"flex items-center gap-1 rounded bg-[var(--as-danger)] px-2 py-1 font-medium\"\n onClick={onStop}\n >\n <Square className=\"size-3\" aria-hidden />\n {merged.stop}\n </button>\n </>\n ) : (\n <>\n <Loader2\n className=\"size-3.5 shrink-0 animate-spin text-[var(--as-muted-fg)]\"\n aria-hidden\n />\n <span className=\"min-w-0 flex-1 text-[var(--as-muted-fg)]\">\n {merged.transcribing}\n </span>\n </>\n )}\n </div>\n )\n}\n","import { useCallback, useEffect, useRef, useState } from 'react'\n\nexport type DictationStatus = 'idle' | 'recording' | 'transcribing'\n\nexport interface DictationError {\n kind: 'unsupported' | 'denied' | 'unassigned' | 'failed'\n detail?: string\n}\n\nexport interface DictationResult {\n text: string\n}\n\nexport interface UseDictationOptions {\n /** App-owned transport: upload the blob, resolve with the transcript. */\n transcribe: (audio: Blob) => Promise<DictationResult>\n /** Map a transport failure to a structured error (e.g. 409 → 'unassigned'). */\n classifyError?: (error: unknown) => DictationError\n /** Called with the transcript on success. */\n onResult?: (text: string) => void\n}\n\nconst PREFERRED_MIME_TYPES = [\n 'audio/webm;codecs=opus',\n 'audio/webm',\n 'audio/ogg;codecs=opus',\n 'audio/mp4',\n]\n\nconst MAX_LEVEL = 1\nconst LEVEL_BOOST = 4\nconst LEVEL_DECAY = 0.85\n\nfunction pickMimeType(): string | null {\n if (typeof MediaRecorder === 'undefined') {\n return null\n }\n for (const mimeType of PREFERRED_MIME_TYPES) {\n if (MediaRecorder.isTypeSupported(mimeType)) {\n return mimeType\n }\n }\n return null\n}\n\nexport function useDictation(options: UseDictationOptions) {\n const [status, setStatus] = useState<DictationStatus>('idle')\n const [seconds, setSeconds] = useState(0)\n const [error, setError] = useState<DictationError | null>(null)\n\n const optionsRef = useRef(options)\n optionsRef.current = options\n\n const recorderRef = useRef<MediaRecorder | null>(null)\n const streamRef = useRef<MediaStream | null>(null)\n const chunksRef = useRef<BlobPart[]>([])\n const audioContextRef = useRef<AudioContext | null>(null)\n const rafRef = useRef<number | null>(null)\n const timerRef = useRef<number | null>(null)\n const levelRef = useRef(0)\n\n const teardown = useCallback(() => {\n if (rafRef.current !== null) {\n cancelAnimationFrame(rafRef.current)\n rafRef.current = null\n }\n if (timerRef.current !== null) {\n window.clearInterval(timerRef.current)\n timerRef.current = null\n }\n audioContextRef.current?.close().catch(() => undefined)\n audioContextRef.current = null\n streamRef.current?.getTracks().forEach((track) => track.stop())\n streamRef.current = null\n recorderRef.current = null\n levelRef.current = 0\n }, [])\n\n const startMeter = useCallback((stream: MediaStream) => {\n if (typeof AudioContext === 'undefined') {\n return\n }\n const context = new AudioContext()\n audioContextRef.current = context\n const analyser = context.createAnalyser()\n analyser.fftSize = 512\n context.createMediaStreamSource(stream).connect(analyser)\n const buffer = new Uint8Array(analyser.fftSize)\n const tick = () => {\n analyser.getByteTimeDomainData(buffer)\n let sum = 0\n for (const value of buffer) {\n const centered = (value - 128) / 128\n sum += centered * centered\n }\n const rms = Math.sqrt(sum / buffer.length)\n levelRef.current = Math.min(\n MAX_LEVEL,\n Math.max(rms * LEVEL_BOOST, levelRef.current * LEVEL_DECAY),\n )\n rafRef.current = requestAnimationFrame(tick)\n }\n rafRef.current = requestAnimationFrame(tick)\n }, [])\n\n const start = useCallback(async () => {\n if (status !== 'idle') {\n return\n }\n setError(null)\n if (\n typeof navigator === 'undefined' ||\n !navigator.mediaDevices?.getUserMedia ||\n typeof MediaRecorder === 'undefined'\n ) {\n setError({ kind: 'unsupported' })\n return\n }\n let stream: MediaStream\n try {\n stream = await navigator.mediaDevices.getUserMedia({ audio: true })\n } catch (requestError) {\n const name = requestError instanceof DOMException ? requestError.name : ''\n setError(\n name === 'NotAllowedError' || name === 'SecurityError' || name === 'NotFoundError'\n ? { kind: 'denied' }\n : {\n kind: 'failed',\n detail:\n requestError instanceof Error\n ? requestError.message\n : String(requestError),\n },\n )\n return\n }\n const mimeType = pickMimeType()\n const recorder = new MediaRecorder(stream, mimeType ? { mimeType } : undefined)\n const chunks: BlobPart[] = []\n recorder.ondataavailable = (event) => {\n if (event.data.size > 0) {\n chunks.push(event.data)\n }\n }\n recorderRef.current = recorder\n streamRef.current = stream\n chunksRef.current = chunks\n recorder.start(250)\n setSeconds(0)\n setStatus('recording')\n startMeter(stream)\n timerRef.current = window.setInterval(() => {\n setSeconds((current) => current + 1)\n }, 1000)\n }, [startMeter, status])\n\n const cancel = useCallback(() => {\n const recorder = recorderRef.current\n if (recorder !== null && recorder.state !== 'inactive') {\n recorder.onstop = null\n recorder.stop()\n }\n teardown()\n setSeconds(0)\n setStatus('idle')\n }, [teardown])\n\n const stop = useCallback(async () => {\n const recorder = recorderRef.current\n if (recorder === null || recorder.state === 'inactive') {\n return\n }\n const mimeType = recorder.mimeType || 'audio/webm'\n const chunks = chunksRef.current\n const stopped = new Promise<void>((resolve) => {\n recorder.onstop = () => resolve()\n })\n recorder.stop()\n await stopped\n teardown()\n setSeconds(0)\n setStatus('transcribing')\n try {\n const blob = new Blob(chunks, { type: mimeType })\n const result = await optionsRef.current.transcribe(blob)\n setStatus('idle')\n optionsRef.current.onResult?.(result.text)\n } catch (transcribeError) {\n const classified =\n optionsRef.current.classifyError?.(transcribeError) ??\n ({\n kind: 'failed',\n detail:\n transcribeError instanceof Error\n ? transcribeError.message\n : String(transcribeError),\n } satisfies DictationError)\n setError(classified)\n setStatus('idle')\n }\n }, [teardown])\n\n const dismissError = useCallback(() => {\n setError(null)\n }, [])\n\n useEffect(\n () => () => {\n const recorder = recorderRef.current\n if (recorder !== null && recorder.state !== 'inactive') {\n recorder.onstop = null\n recorder.stop()\n }\n teardown()\n },\n [teardown],\n )\n\n return { status, seconds, error, levelRef, start, stop, cancel, dismissError }\n}\n"]}
|
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
import { cn } from './chunk-BLJWR4ZV.js';
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
import { useEditor, EditorContent } from '@tiptap/react';
|
|
4
|
+
import StarterKit from '@tiptap/starter-kit';
|
|
5
|
+
import { Redo2, Undo2, Quote, ListOrdered, List, Heading2, Code, Strikethrough, Italic, Bold } from 'lucide-react';
|
|
6
|
+
import { Markdown } from 'tiptap-markdown';
|
|
7
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
8
|
+
|
|
9
|
+
var DEFAULT_TOOLBAR = [
|
|
10
|
+
"history",
|
|
11
|
+
"heading",
|
|
12
|
+
"format",
|
|
13
|
+
"list",
|
|
14
|
+
"quote"
|
|
15
|
+
];
|
|
16
|
+
var DEFAULT_LABELS = {
|
|
17
|
+
toolbar: "Formatting",
|
|
18
|
+
bold: "Bold",
|
|
19
|
+
italic: "Italic",
|
|
20
|
+
strike: "Strikethrough",
|
|
21
|
+
code: "Code",
|
|
22
|
+
heading: "Heading",
|
|
23
|
+
bulletList: "Bulleted list",
|
|
24
|
+
orderedList: "Numbered list",
|
|
25
|
+
blockquote: "Quote",
|
|
26
|
+
undo: "Undo",
|
|
27
|
+
redo: "Redo"
|
|
28
|
+
};
|
|
29
|
+
var DEFAULT_ICONS = {
|
|
30
|
+
bold: Bold,
|
|
31
|
+
italic: Italic,
|
|
32
|
+
strike: Strikethrough,
|
|
33
|
+
code: Code,
|
|
34
|
+
heading: Heading2,
|
|
35
|
+
bulletList: List,
|
|
36
|
+
orderedList: ListOrdered,
|
|
37
|
+
blockquote: Quote,
|
|
38
|
+
undo: Undo2,
|
|
39
|
+
redo: Redo2
|
|
40
|
+
};
|
|
41
|
+
function getMarkdown(editor) {
|
|
42
|
+
const storage = editor.storage;
|
|
43
|
+
return storage.markdown?.getMarkdown?.() ?? "";
|
|
44
|
+
}
|
|
45
|
+
function applyExternalValue(editor, markdown) {
|
|
46
|
+
const hadFocus = editor.isFocused;
|
|
47
|
+
const caret = editor.state.selection.head;
|
|
48
|
+
editor.commands.setContent(markdown, { emitUpdate: false });
|
|
49
|
+
if (hadFocus) {
|
|
50
|
+
editor.commands.setTextSelection(Math.min(caret, editor.state.doc.content.size));
|
|
51
|
+
editor.commands.focus();
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
var RichTextEditor = React.forwardRef(
|
|
55
|
+
function RichTextEditor2({
|
|
56
|
+
value,
|
|
57
|
+
onValueChange,
|
|
58
|
+
ariaLabel,
|
|
59
|
+
disabled = false,
|
|
60
|
+
toolbar = DEFAULT_TOOLBAR,
|
|
61
|
+
toolbarExtra,
|
|
62
|
+
extensions,
|
|
63
|
+
parseMarkdown,
|
|
64
|
+
serializeMarkdown,
|
|
65
|
+
labels,
|
|
66
|
+
icons,
|
|
67
|
+
className
|
|
68
|
+
}, ref) {
|
|
69
|
+
const mergedLabels = { ...DEFAULT_LABELS, ...labels };
|
|
70
|
+
const mergedIcons = { ...DEFAULT_ICONS, ...icons };
|
|
71
|
+
const lastEmittedRef = React.useRef(value);
|
|
72
|
+
const onValueChangeRef = React.useRef(onValueChange);
|
|
73
|
+
onValueChangeRef.current = onValueChange;
|
|
74
|
+
const hooksRef = React.useRef({ parseMarkdown, serializeMarkdown });
|
|
75
|
+
hooksRef.current = { parseMarkdown, serializeMarkdown };
|
|
76
|
+
const [, bump] = React.useReducer((count) => count + 1, 0);
|
|
77
|
+
const toDocument = React.useCallback(
|
|
78
|
+
(markdown) => parseMarkdown ? parseMarkdown(markdown) : markdown,
|
|
79
|
+
[parseMarkdown]
|
|
80
|
+
);
|
|
81
|
+
const toApp = React.useCallback(
|
|
82
|
+
(markdown) => serializeMarkdown ? serializeMarkdown(markdown) : markdown,
|
|
83
|
+
[serializeMarkdown]
|
|
84
|
+
);
|
|
85
|
+
const editor = useEditor(
|
|
86
|
+
{
|
|
87
|
+
extensions: React.useMemo(
|
|
88
|
+
() => [StarterKit, Markdown, ...extensions ?? []],
|
|
89
|
+
[extensions]
|
|
90
|
+
),
|
|
91
|
+
content: toDocument(value),
|
|
92
|
+
editable: !disabled,
|
|
93
|
+
immediatelyRender: false,
|
|
94
|
+
editorProps: {
|
|
95
|
+
attributes: {
|
|
96
|
+
"aria-label": ariaLabel,
|
|
97
|
+
class: "as-rich-text-editor__content min-h-24 w-full bg-transparent px-3 py-2 text-sm text-[var(--as-fg)] outline-none"
|
|
98
|
+
}
|
|
99
|
+
},
|
|
100
|
+
onUpdate: ({ editor: current }) => {
|
|
101
|
+
const markdown = toApp(getMarkdown(current));
|
|
102
|
+
lastEmittedRef.current = markdown;
|
|
103
|
+
onValueChangeRef.current(markdown);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
);
|
|
107
|
+
const isMounted = editor !== null;
|
|
108
|
+
React.useEffect(() => {
|
|
109
|
+
if (!isMounted || editor === null) {
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
const handler = () => bump();
|
|
113
|
+
editor.on("transaction", handler);
|
|
114
|
+
editor.on("update", handler);
|
|
115
|
+
return () => {
|
|
116
|
+
editor.off("transaction", handler);
|
|
117
|
+
editor.off("update", handler);
|
|
118
|
+
};
|
|
119
|
+
}, [editor, isMounted]);
|
|
120
|
+
React.useEffect(() => {
|
|
121
|
+
if (editor === null || editor.isDestroyed) {
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
editor.setEditable(!disabled);
|
|
125
|
+
}, [editor, disabled]);
|
|
126
|
+
React.useEffect(() => {
|
|
127
|
+
if (editor === null || editor.isDestroyed) {
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
if (value === lastEmittedRef.current) {
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
const current = toApp(getMarkdown(editor));
|
|
134
|
+
if (value === current) {
|
|
135
|
+
lastEmittedRef.current = value;
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
applyExternalValue(editor, toDocument(value));
|
|
139
|
+
lastEmittedRef.current = value;
|
|
140
|
+
}, [editor, value, toApp, toDocument]);
|
|
141
|
+
const groups = toolbar === false ? [] : toolbar ?? DEFAULT_TOOLBAR;
|
|
142
|
+
const renderButton = (key, group, onClick, active) => {
|
|
143
|
+
const Icon = mergedIcons[key];
|
|
144
|
+
return /* @__PURE__ */ jsx(
|
|
145
|
+
"button",
|
|
146
|
+
{
|
|
147
|
+
type: "button",
|
|
148
|
+
"aria-label": mergedLabels[key],
|
|
149
|
+
"aria-pressed": active,
|
|
150
|
+
title: mergedLabels[key],
|
|
151
|
+
disabled,
|
|
152
|
+
className: cn(
|
|
153
|
+
"rounded p-1.5 text-[var(--as-muted-fg)] transition-colors hover:text-[var(--as-fg)] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--as-focus-ring)] disabled:cursor-not-allowed disabled:opacity-50",
|
|
154
|
+
active && "bg-[var(--as-surface-active)] text-[var(--as-fg)]"
|
|
155
|
+
),
|
|
156
|
+
onClick,
|
|
157
|
+
children: /* @__PURE__ */ jsx(Icon, { className: "size-4", "aria-hidden": true })
|
|
158
|
+
},
|
|
159
|
+
`${group}-${key}`
|
|
160
|
+
);
|
|
161
|
+
};
|
|
162
|
+
return /* @__PURE__ */ jsxs(
|
|
163
|
+
"div",
|
|
164
|
+
{
|
|
165
|
+
ref,
|
|
166
|
+
"data-as": "rich-text-editor",
|
|
167
|
+
className: cn(
|
|
168
|
+
"w-full rounded-[var(--as-radius)] border border-[var(--as-border)] bg-[var(--as-surface)] text-[var(--as-fg)] focus-within:border-[var(--as-focus-ring)]",
|
|
169
|
+
disabled && "opacity-50",
|
|
170
|
+
className
|
|
171
|
+
),
|
|
172
|
+
children: [
|
|
173
|
+
groups.length > 0 || toolbarExtra ? /* @__PURE__ */ jsxs(
|
|
174
|
+
"div",
|
|
175
|
+
{
|
|
176
|
+
role: "toolbar",
|
|
177
|
+
"aria-label": mergedLabels.toolbar,
|
|
178
|
+
className: "flex flex-wrap items-center gap-0.5 border-b border-[var(--as-border)] p-1",
|
|
179
|
+
children: [
|
|
180
|
+
groups.includes("history") ? renderButton(
|
|
181
|
+
"undo",
|
|
182
|
+
"history",
|
|
183
|
+
() => editor?.chain().focus().undo().run(),
|
|
184
|
+
false
|
|
185
|
+
) : null,
|
|
186
|
+
groups.includes("history") ? renderButton(
|
|
187
|
+
"redo",
|
|
188
|
+
"history",
|
|
189
|
+
() => editor?.chain().focus().redo().run(),
|
|
190
|
+
false
|
|
191
|
+
) : null,
|
|
192
|
+
groups.includes("heading") ? renderButton(
|
|
193
|
+
"heading",
|
|
194
|
+
"heading",
|
|
195
|
+
() => editor?.chain().focus().toggleHeading({ level: 2 }).run(),
|
|
196
|
+
editor?.isActive("heading", { level: 2 }) === true
|
|
197
|
+
) : null,
|
|
198
|
+
groups.includes("format") ? renderButton(
|
|
199
|
+
"bold",
|
|
200
|
+
"format",
|
|
201
|
+
() => editor?.chain().focus().toggleBold().run(),
|
|
202
|
+
editor?.isActive("bold") === true
|
|
203
|
+
) : null,
|
|
204
|
+
groups.includes("format") ? renderButton(
|
|
205
|
+
"italic",
|
|
206
|
+
"format",
|
|
207
|
+
() => editor?.chain().focus().toggleItalic().run(),
|
|
208
|
+
editor?.isActive("italic") === true
|
|
209
|
+
) : null,
|
|
210
|
+
groups.includes("format") ? renderButton(
|
|
211
|
+
"strike",
|
|
212
|
+
"format",
|
|
213
|
+
() => editor?.chain().focus().toggleStrike().run(),
|
|
214
|
+
editor?.isActive("strike") === true
|
|
215
|
+
) : null,
|
|
216
|
+
groups.includes("format") ? renderButton(
|
|
217
|
+
"code",
|
|
218
|
+
"format",
|
|
219
|
+
() => editor?.chain().focus().toggleCode().run(),
|
|
220
|
+
editor?.isActive("code") === true
|
|
221
|
+
) : null,
|
|
222
|
+
groups.includes("list") ? renderButton(
|
|
223
|
+
"bulletList",
|
|
224
|
+
"list",
|
|
225
|
+
() => editor?.chain().focus().toggleBulletList().run(),
|
|
226
|
+
editor?.isActive("bulletList") === true
|
|
227
|
+
) : null,
|
|
228
|
+
groups.includes("list") ? renderButton(
|
|
229
|
+
"orderedList",
|
|
230
|
+
"list",
|
|
231
|
+
() => editor?.chain().focus().toggleOrderedList().run(),
|
|
232
|
+
editor?.isActive("orderedList") === true
|
|
233
|
+
) : null,
|
|
234
|
+
groups.includes("quote") ? renderButton(
|
|
235
|
+
"blockquote",
|
|
236
|
+
"quote",
|
|
237
|
+
() => editor?.chain().focus().toggleBlockquote().run(),
|
|
238
|
+
editor?.isActive("blockquote") === true
|
|
239
|
+
) : null,
|
|
240
|
+
typeof toolbarExtra === "function" ? toolbarExtra(editor) : toolbarExtra
|
|
241
|
+
]
|
|
242
|
+
}
|
|
243
|
+
) : null,
|
|
244
|
+
/* @__PURE__ */ jsx(EditorContent, { editor })
|
|
245
|
+
]
|
|
246
|
+
}
|
|
247
|
+
);
|
|
248
|
+
}
|
|
249
|
+
);
|
|
250
|
+
|
|
251
|
+
export { RichTextEditor };
|
|
252
|
+
//# sourceMappingURL=chunk-XUDCCQRN.js.map
|
|
253
|
+
//# sourceMappingURL=chunk-XUDCCQRN.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/rich-text-editor/RichTextEditor.tsx"],"names":["RichTextEditor"],"mappings":"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","file":"chunk-XUDCCQRN.js","sourcesContent":["import * as React from 'react'\nimport { Editor, EditorContent, useEditor, type Extensions } from '@tiptap/react'\nimport StarterKit from '@tiptap/starter-kit'\nimport {\n Bold,\n Code,\n Heading2,\n Italic,\n List,\n ListOrdered,\n Quote,\n Redo2,\n Strikethrough,\n Undo2,\n type LucideIcon,\n} from 'lucide-react'\nimport { Markdown } from 'tiptap-markdown'\n\nimport { cn } from '../../lib/utils'\n\nexport type RichTextToolbarGroup = 'history' | 'heading' | 'format' | 'list' | 'quote'\n\nconst DEFAULT_TOOLBAR: RichTextToolbarGroup[] = [\n 'history',\n 'heading',\n 'format',\n 'list',\n 'quote',\n]\n\nexport interface RichTextEditorLabels {\n toolbar?: string\n bold?: string\n italic?: string\n strike?: string\n code?: string\n heading?: string\n bulletList?: string\n orderedList?: string\n blockquote?: string\n undo?: string\n redo?: string\n}\n\nexport interface RichTextEditorIcons {\n bold?: LucideIcon\n italic?: LucideIcon\n strike?: LucideIcon\n code?: LucideIcon\n heading?: LucideIcon\n bulletList?: LucideIcon\n orderedList?: LucideIcon\n blockquote?: LucideIcon\n undo?: LucideIcon\n redo?: LucideIcon\n}\n\nconst DEFAULT_LABELS: Required<RichTextEditorLabels> = {\n toolbar: 'Formatting',\n bold: 'Bold',\n italic: 'Italic',\n strike: 'Strikethrough',\n code: 'Code',\n heading: 'Heading',\n bulletList: 'Bulleted list',\n orderedList: 'Numbered list',\n blockquote: 'Quote',\n undo: 'Undo',\n redo: 'Redo',\n}\n\nconst DEFAULT_ICONS: Required<RichTextEditorIcons> = {\n bold: Bold,\n italic: Italic,\n strike: Strikethrough,\n code: Code,\n heading: Heading2,\n bulletList: List,\n orderedList: ListOrdered,\n blockquote: Quote,\n undo: Undo2,\n redo: Redo2,\n}\n\nexport interface RichTextEditorProps {\n value: string\n onValueChange: (markdown: string) => void\n ariaLabel: string\n disabled?: boolean\n toolbar?: RichTextToolbarGroup[] | false\n /** App-owned controls at the end of the toolbar; render-prop form receives the editor. */\n toolbarExtra?: React.ReactNode | ((editor: Editor | null) => React.ReactNode)\n /** App extensions merged after the starter kit (math, tables, custom nodes…). */\n extensions?: Extensions\n /** Map incoming app-domain markdown before it reaches the document. */\n parseMarkdown?: (markdown: string) => string\n /** Map the serialized document before it is emitted / echo-compared. */\n serializeMarkdown?: (markdown: string) => string\n labels?: Partial<RichTextEditorLabels>\n icons?: Partial<RichTextEditorIcons>\n className?: string\n}\n\nfunction getMarkdown(editor: Editor): string {\n const storage = editor.storage as { markdown?: { getMarkdown?: () => string } }\n return storage.markdown?.getMarkdown?.() ?? ''\n}\n\nfunction applyExternalValue(editor: Editor, markdown: string): void {\n const hadFocus = editor.isFocused\n const caret = editor.state.selection.head\n editor.commands.setContent(markdown, { emitUpdate: false })\n if (hadFocus) {\n editor.commands.setTextSelection(Math.min(caret, editor.state.doc.content.size))\n editor.commands.focus()\n }\n}\n\nexport const RichTextEditor = React.forwardRef<HTMLDivElement, RichTextEditorProps>(\n function RichTextEditor(\n {\n value,\n onValueChange,\n ariaLabel,\n disabled = false,\n toolbar = DEFAULT_TOOLBAR,\n toolbarExtra,\n extensions,\n parseMarkdown,\n serializeMarkdown,\n labels,\n icons,\n className,\n },\n ref,\n ) {\n const mergedLabels = { ...DEFAULT_LABELS, ...labels }\n const mergedIcons = { ...DEFAULT_ICONS, ...icons }\n const lastEmittedRef = React.useRef<string>(value)\n const onValueChangeRef = React.useRef(onValueChange)\n onValueChangeRef.current = onValueChange\n const hooksRef = React.useRef({ parseMarkdown, serializeMarkdown })\n hooksRef.current = { parseMarkdown, serializeMarkdown }\n const [, bump] = React.useReducer((count: number) => count + 1, 0)\n\n const toDocument = React.useCallback(\n (markdown: string) => (parseMarkdown ? parseMarkdown(markdown) : markdown),\n [parseMarkdown],\n )\n const toApp = React.useCallback(\n (markdown: string) => (serializeMarkdown ? serializeMarkdown(markdown) : markdown),\n [serializeMarkdown],\n )\n\n const editor = useEditor(\n {\n extensions: React.useMemo(\n () => [StarterKit, Markdown, ...(extensions ?? [])],\n [extensions],\n ),\n content: toDocument(value),\n editable: !disabled,\n immediatelyRender: false,\n editorProps: {\n attributes: {\n 'aria-label': ariaLabel,\n class:\n 'as-rich-text-editor__content min-h-24 w-full bg-transparent px-3 py-2 text-sm text-[var(--as-fg)] outline-none',\n },\n },\n onUpdate: ({ editor: current }) => {\n const markdown = toApp(getMarkdown(current))\n lastEmittedRef.current = markdown\n onValueChangeRef.current(markdown)\n },\n },\n )\n\n const isMounted = editor !== null\n\n React.useEffect(() => {\n if (!isMounted || editor === null) {\n return\n }\n const handler = () => bump()\n editor.on('transaction', handler)\n editor.on('update', handler)\n return () => {\n editor.off('transaction', handler)\n editor.off('update', handler)\n }\n }, [editor, isMounted])\n\n React.useEffect(() => {\n if (editor === null || editor.isDestroyed) {\n return\n }\n editor.setEditable(!disabled)\n }, [editor, disabled])\n\n React.useEffect(() => {\n if (editor === null || editor.isDestroyed) {\n return\n }\n if (value === lastEmittedRef.current) {\n return\n }\n const current = toApp(getMarkdown(editor))\n if (value === current) {\n lastEmittedRef.current = value\n return\n }\n applyExternalValue(editor, toDocument(value))\n lastEmittedRef.current = value\n }, [editor, value, toApp, toDocument])\n\n const groups = toolbar === false ? [] : (toolbar ?? DEFAULT_TOOLBAR)\n\n const renderButton = (\n key: Exclude<keyof RichTextEditorLabels, 'toolbar'>,\n group: Exclude<RichTextToolbarGroup, 'history'> | 'history',\n onClick: () => void,\n active: boolean,\n ) => {\n const Icon = mergedIcons[key]\n return (\n <button\n key={`${group}-${key}`}\n type=\"button\"\n aria-label={mergedLabels[key]}\n aria-pressed={active}\n title={mergedLabels[key]}\n disabled={disabled}\n className={cn(\n 'rounded p-1.5 text-[var(--as-muted-fg)] transition-colors hover:text-[var(--as-fg)] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--as-focus-ring)] disabled:cursor-not-allowed disabled:opacity-50',\n active && 'bg-[var(--as-surface-active)] text-[var(--as-fg)]',\n )}\n onClick={onClick}\n >\n <Icon className=\"size-4\" aria-hidden />\n </button>\n )\n }\n\n return (\n <div\n ref={ref}\n data-as=\"rich-text-editor\"\n className={cn(\n 'w-full rounded-[var(--as-radius)] border border-[var(--as-border)] bg-[var(--as-surface)] text-[var(--as-fg)] focus-within:border-[var(--as-focus-ring)]',\n disabled && 'opacity-50',\n className,\n )}\n >\n {groups.length > 0 || toolbarExtra ? (\n <div\n role=\"toolbar\"\n aria-label={mergedLabels.toolbar}\n className=\"flex flex-wrap items-center gap-0.5 border-b border-[var(--as-border)] p-1\"\n >\n {groups.includes('history')\n ? renderButton(\n 'undo',\n 'history',\n () => editor?.chain().focus().undo().run(),\n false,\n )\n : null}\n {groups.includes('history')\n ? renderButton(\n 'redo',\n 'history',\n () => editor?.chain().focus().redo().run(),\n false,\n )\n : null}\n {groups.includes('heading')\n ? renderButton(\n 'heading',\n 'heading',\n () => editor?.chain().focus().toggleHeading({ level: 2 }).run(),\n editor?.isActive('heading', { level: 2 }) === true,\n )\n : null}\n {groups.includes('format')\n ? renderButton(\n 'bold',\n 'format',\n () => editor?.chain().focus().toggleBold().run(),\n editor?.isActive('bold') === true,\n )\n : null}\n {groups.includes('format')\n ? renderButton(\n 'italic',\n 'format',\n () => editor?.chain().focus().toggleItalic().run(),\n editor?.isActive('italic') === true,\n )\n : null}\n {groups.includes('format')\n ? renderButton(\n 'strike',\n 'format',\n () => editor?.chain().focus().toggleStrike().run(),\n editor?.isActive('strike') === true,\n )\n : null}\n {groups.includes('format')\n ? renderButton(\n 'code',\n 'format',\n () => editor?.chain().focus().toggleCode().run(),\n editor?.isActive('code') === true,\n )\n : null}\n {groups.includes('list')\n ? renderButton(\n 'bulletList',\n 'list',\n () => editor?.chain().focus().toggleBulletList().run(),\n editor?.isActive('bulletList') === true,\n )\n : null}\n {groups.includes('list')\n ? renderButton(\n 'orderedList',\n 'list',\n () => editor?.chain().focus().toggleOrderedList().run(),\n editor?.isActive('orderedList') === true,\n )\n : null}\n {groups.includes('quote')\n ? renderButton(\n 'blockquote',\n 'quote',\n () => editor?.chain().focus().toggleBlockquote().run(),\n editor?.isActive('blockquote') === true,\n )\n : null}\n {typeof toolbarExtra === 'function' ? toolbarExtra(editor) : toolbarExtra}\n </div>\n ) : null}\n <EditorContent editor={editor} />\n </div>\n )\n },\n)\n"]}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
|
|
3
|
+
type DictationStatus = 'idle' | 'recording' | 'transcribing';
|
|
4
|
+
interface DictationError {
|
|
5
|
+
kind: 'unsupported' | 'denied' | 'unassigned' | 'failed';
|
|
6
|
+
detail?: string;
|
|
7
|
+
}
|
|
8
|
+
interface DictationResult {
|
|
9
|
+
text: string;
|
|
10
|
+
}
|
|
11
|
+
interface UseDictationOptions {
|
|
12
|
+
/** App-owned transport: upload the blob, resolve with the transcript. */
|
|
13
|
+
transcribe: (audio: Blob) => Promise<DictationResult>;
|
|
14
|
+
/** Map a transport failure to a structured error (e.g. 409 → 'unassigned'). */
|
|
15
|
+
classifyError?: (error: unknown) => DictationError;
|
|
16
|
+
/** Called with the transcript on success. */
|
|
17
|
+
onResult?: (text: string) => void;
|
|
18
|
+
}
|
|
19
|
+
declare function useDictation(options: UseDictationOptions): {
|
|
20
|
+
status: DictationStatus;
|
|
21
|
+
seconds: number;
|
|
22
|
+
error: DictationError | null;
|
|
23
|
+
levelRef: React.RefObject<number>;
|
|
24
|
+
start: () => Promise<void>;
|
|
25
|
+
stop: () => Promise<void>;
|
|
26
|
+
cancel: () => void;
|
|
27
|
+
dismissError: () => void;
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
interface DictationButtonProps {
|
|
31
|
+
status: DictationStatus;
|
|
32
|
+
onStart: () => void;
|
|
33
|
+
/** Accessible name / tooltip. English default: 'Dictate'. */
|
|
34
|
+
label?: string;
|
|
35
|
+
recordingLabel?: string;
|
|
36
|
+
className?: string;
|
|
37
|
+
}
|
|
38
|
+
declare function DictationButton({ status, onStart, label, recordingLabel, className, }: DictationButtonProps): React.JSX.Element;
|
|
39
|
+
interface DictationStripLabels {
|
|
40
|
+
recording?: string;
|
|
41
|
+
transcribing?: string;
|
|
42
|
+
stop?: string;
|
|
43
|
+
cancel?: string;
|
|
44
|
+
dismissError?: string;
|
|
45
|
+
unsupported?: string;
|
|
46
|
+
denied?: string;
|
|
47
|
+
unassigned?: string;
|
|
48
|
+
/** `{detail}` is interpolated with the transport error message. */
|
|
49
|
+
failed?: string;
|
|
50
|
+
}
|
|
51
|
+
interface DictationStripProps {
|
|
52
|
+
status: DictationStatus;
|
|
53
|
+
seconds: number;
|
|
54
|
+
levelRef: React.RefObject<number>;
|
|
55
|
+
error: DictationError | null;
|
|
56
|
+
labels?: Partial<DictationStripLabels>;
|
|
57
|
+
onStop: () => void;
|
|
58
|
+
onCancel: () => void;
|
|
59
|
+
onDismissError: () => void;
|
|
60
|
+
className?: string;
|
|
61
|
+
}
|
|
62
|
+
declare function DictationStrip({ status, seconds, levelRef, error, labels, onStop, onCancel, onDismissError, className, }: DictationStripProps): React.JSX.Element | null;
|
|
63
|
+
|
|
64
|
+
export { DictationButton, type DictationButtonProps, type DictationError, type DictationResult, type DictationStatus, DictationStrip, type DictationStripLabels, type DictationStripProps, type UseDictationOptions, useDictation };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"dictation.js"}
|
package/dist/index.d.ts
CHANGED
|
@@ -58,6 +58,10 @@ export { TimePicker, TimePickerContent, TimePickerContentProps, TimePickerProps
|
|
|
58
58
|
export { UndoNotice, UndoNoticeProps } from './undo-notice.js';
|
|
59
59
|
export { ViewToggle, ViewToggleProps, ViewToggleView } from './view-toggle.js';
|
|
60
60
|
export { Stepper, StepperProps, StepperStep, Wizard, WizardContext, WizardProps, WizardStep } from './wizard.js';
|
|
61
|
+
export { RichTextEditor, RichTextEditorIcons, RichTextEditorLabels, RichTextEditorProps, RichTextToolbarGroup } from './rich-text-editor.js';
|
|
62
|
+
export { DictationButton, DictationButtonProps, DictationError, DictationResult, DictationStatus, DictationStrip, DictationStripLabels, DictationStripProps, UseDictationOptions, useDictation } from './dictation.js';
|
|
63
|
+
export { AiTextTransformEventHandlers, AiTextTransformStatus, AiTextTransformTransport, UseAiTextTransformOptions, useAiTextTransform } from './ai-text-transform.js';
|
|
64
|
+
export { DiffCell, DiffRow, DiffSegment, LineDiffOptions, LineDiffResult, TextDiffView, TextDiffViewLabels, TextDiffViewProps, computeLineDiff, wordSegments } from './text-diff-view.js';
|
|
61
65
|
import 'class-variance-authority/types';
|
|
62
66
|
import 'class-variance-authority';
|
|
63
67
|
import 'lucide-react';
|
|
@@ -65,6 +69,7 @@ import '@radix-ui/react-dropdown-menu';
|
|
|
65
69
|
import '@radix-ui/react-dialog';
|
|
66
70
|
import '@radix-ui/react-popover';
|
|
67
71
|
import '@radix-ui/react-tooltip';
|
|
72
|
+
import '@tiptap/react';
|
|
68
73
|
|
|
69
74
|
declare function cn(...inputs: ClassValue[]): string;
|
|
70
75
|
|
package/dist/index.js
CHANGED
|
@@ -1,31 +1,35 @@
|
|
|
1
|
+
export { ThemeScope } from './chunk-TGU3PKNM.js';
|
|
2
|
+
export { TimeList } from './chunk-GVOC3ARM.js';
|
|
3
|
+
export { TimePicker, TimePickerContent } from './chunk-CR42EAF4.js';
|
|
4
|
+
export { InfoTooltip, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from './chunk-34NO2UOB.js';
|
|
1
5
|
export { UndoNotice } from './chunk-OUHUVACM.js';
|
|
2
6
|
export { ViewToggle } from './chunk-MXOBOS4Y.js';
|
|
3
7
|
export { Stepper, Wizard } from './chunk-YMCMUAIF.js';
|
|
8
|
+
export { ModelRegistry } from './chunk-RBEPQY2A.js';
|
|
9
|
+
export { SelectionBar } from './chunk-HSUCCANX.js';
|
|
10
|
+
export { Table } from './chunk-5LRRVD27.js';
|
|
4
11
|
export { TaskAssignmentPicker } from './chunk-VULOVVKF.js';
|
|
5
12
|
export { SettingsShell } from './chunk-AHLNXCP2.js';
|
|
6
13
|
export { SidebarNav } from './chunk-SW3YNICQ.js';
|
|
7
14
|
export { UserMenu } from './chunk-535TM7SK.js';
|
|
8
|
-
export {
|
|
9
|
-
export {
|
|
10
|
-
export {
|
|
11
|
-
export { InfoTooltip, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from './chunk-34NO2UOB.js';
|
|
15
|
+
export { Portal } from './chunk-7YLR4AGA.js';
|
|
16
|
+
export { ProviderForm } from './chunk-4WDXLXHL.js';
|
|
17
|
+
export { RangeBar } from './chunk-PFAH25VU.js';
|
|
12
18
|
export { ScaleSlider, scaleColorForValue } from './chunk-PSFJN7WH.js';
|
|
13
19
|
export { SearchInput } from './chunk-H5U4KNXF.js';
|
|
14
|
-
export { ModelRegistry } from './chunk-RBEPQY2A.js';
|
|
15
20
|
export { CapabilityChips } from './chunk-G3DWN2DJ.js';
|
|
16
|
-
export {
|
|
17
|
-
export {
|
|
21
|
+
export { DictationButton, DictationStrip, useDictation } from './chunk-KAC2DOLH.js';
|
|
22
|
+
export { useAiTextTransform } from './chunk-BKAO7BTU.js';
|
|
23
|
+
export { TextDiffView, computeLineDiff, wordSegments } from './chunk-2PR6POP6.js';
|
|
24
|
+
export { MarqueeBand, MarqueeSurface, hitTestIds, marqueeRect, rectsIntersect, useMarquee } from './chunk-RU3DEF2O.js';
|
|
18
25
|
export { ModelPicker } from './chunk-SVQK7TXU.js';
|
|
19
26
|
export { PanelModal } from './chunk-G6557MEN.js';
|
|
20
|
-
export { Portal } from './chunk-7YLR4AGA.js';
|
|
21
|
-
export { ProviderForm } from './chunk-4WDXLXHL.js';
|
|
22
|
-
export { RangeBar } from './chunk-PFAH25VU.js';
|
|
23
27
|
export { FlowStatusCard } from './chunk-PRHTQBCP.js';
|
|
24
28
|
export { FieldLabel } from './chunk-I5J6SDLK.js';
|
|
25
29
|
export { InfoButton } from './chunk-OT6EQFMP.js';
|
|
26
30
|
export { PopoverButton } from './chunk-BE3XFZWU.js';
|
|
27
31
|
export { Input } from './chunk-M4V7XHL7.js';
|
|
28
|
-
export {
|
|
32
|
+
export { RichTextEditor } from './chunk-XUDCCQRN.js';
|
|
29
33
|
export { CopyButton } from './chunk-CZ2BL2ZL.js';
|
|
30
34
|
export { ContextMenu } from './chunk-YIGLULRG.js';
|
|
31
35
|
export { ActionMenu, Menu, MenuCheckboxItem, MenuContent, MenuGroup, MenuItem, MenuLabel, MenuSeparator, MenuTrigger } from './chunk-XSJ3TWWZ.js';
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/upload-dropzone/UploadDropzone.tsx"],"names":["UploadDropzone"],"mappings":"
|
|
1
|
+
{"version":3,"sources":["../src/components/upload-dropzone/UploadDropzone.tsx"],"names":["UploadDropzone"],"mappings":"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","file":"index.js","sourcesContent":["import * as React from 'react'\nimport { FolderUp, Loader2, Upload } from 'lucide-react'\nimport { cn } from '../../lib/utils'\n\nexport interface UploadDropzoneProps {\n onFiles: (files: File[]) => void\n uploading?: boolean\n variant?: 'block' | 'row'\n label?: string\n hint?: string\n browseLabel?: string\n folderLabel?: string\n accept?: string\n multiple?: boolean\n allowFolders?: boolean\n disabled?: boolean\n className?: string\n}\n\n/**\n * Presentational dropzone: drag events and file-picker results go out via\n * `onFiles` — uploading, storage and progress stay app-side. Pass\n * `uploading` to render a busy state and suppress input.\n */\nexport const UploadDropzone = React.forwardRef<HTMLDivElement, UploadDropzoneProps>(\n function UploadDropzone(\n {\n onFiles,\n uploading = false,\n variant = 'block',\n label = 'Drop files here or click to browse',\n hint,\n browseLabel = 'Choose files',\n folderLabel = 'Choose folder',\n accept,\n multiple = true,\n allowFolders = false,\n disabled = false,\n className,\n },\n ref,\n ) {\n const [dragging, setDragging] = React.useState(false)\n const fileInput = React.useRef<HTMLInputElement>(null)\n const folderInput = React.useRef<HTMLInputElement>(null)\n\n const active = !disabled && !uploading\n\n const emit = (list: FileList | null) => {\n if (!active || !list || list.length === 0) return\n onFiles(Array.from(list))\n }\n\n const input = allowFolders ? (\n <>\n <input\n ref={fileInput}\n type=\"file\"\n accept={accept}\n multiple={multiple}\n className=\"hidden\"\n aria-hidden\n tabIndex={-1}\n onChange={(event) => {\n emit(event.target.files)\n event.target.value = ''\n }}\n />\n <input\n ref={folderInput}\n type=\"file\"\n multiple\n className=\"hidden\"\n // @ts-expect-error non-standard but universally supported directory picker\n webkitdirectory=\"\"\n aria-hidden\n tabIndex={-1}\n onChange={(event) => {\n emit(event.target.files)\n event.target.value = ''\n }}\n />\n </>\n ) : (\n <input\n ref={fileInput}\n type=\"file\"\n accept={accept}\n multiple={multiple}\n className=\"hidden\"\n aria-hidden\n tabIndex={-1}\n onChange={(event) => {\n emit(event.target.files)\n event.target.value = ''\n }}\n />\n )\n\n return (\n <>\n {input}\n <div\n ref={ref}\n data-as=\"upload-dropzone\"\n data-variant={variant}\n data-dragging={dragging || undefined}\n role=\"button\"\n tabIndex={active ? 0 : -1}\n aria-label={label}\n aria-disabled={disabled || uploading || undefined}\n onClick={() => active && fileInput.current?.click()}\n onKeyDown={(event) => {\n if (active && (event.key === 'Enter' || event.key === ' ')) {\n event.preventDefault()\n fileInput.current?.click()\n }\n }}\n onDragOver={(event) => {\n event.preventDefault()\n if (active) setDragging(true)\n }}\n onDragLeave={() => setDragging(false)}\n onDrop={(event) => {\n event.preventDefault()\n setDragging(false)\n emit(event.dataTransfer.files)\n }}\n className={cn(\n 'flex cursor-pointer items-center justify-center gap-3 border border-dashed border-[var(--as-border)] bg-[var(--as-surface)] text-[var(--as-muted-fg)] transition-colors',\n 'hover:border-[var(--as-primary)] hover:text-[var(--as-fg)]',\n 'focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-[var(--as-focus-ring)]',\n variant === 'block' ? 'rounded-[var(--as-radius-lg)] p-8' : 'rounded-[var(--as-radius)] px-4 py-3',\n dragging && 'border-[var(--as-primary)] bg-[color-mix(in_srgb,var(--as-primary)_8%,transparent)] text-[var(--as-fg)]',\n uploading && 'cursor-progress opacity-70',\n disabled && 'pointer-events-none opacity-50',\n className,\n )}\n >\n {uploading ? (\n <Loader2 className=\"size-5 shrink-0 animate-spin\" aria-hidden />\n ) : allowFolders ? (\n <FolderUp className=\"size-5 shrink-0\" aria-hidden />\n ) : (\n <Upload className=\"size-5 shrink-0\" aria-hidden />\n )}\n <span className=\"flex min-w-0 flex-col\">\n <span className=\"truncate text-sm font-medium\" role={uploading ? 'status' : undefined}>\n {uploading ? `${browseLabel}…` : dragging ? folderLabel : label}\n </span>\n {hint ? <span className=\"truncate text-xs\">{hint}</span> : null}\n </span>\n </div>\n </>\n )\n },\n)\n"]}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { Editor, Extensions } from '@tiptap/react';
|
|
3
|
+
import { LucideIcon } from 'lucide-react';
|
|
4
|
+
|
|
5
|
+
type RichTextToolbarGroup = 'history' | 'heading' | 'format' | 'list' | 'quote';
|
|
6
|
+
interface RichTextEditorLabels {
|
|
7
|
+
toolbar?: string;
|
|
8
|
+
bold?: string;
|
|
9
|
+
italic?: string;
|
|
10
|
+
strike?: string;
|
|
11
|
+
code?: string;
|
|
12
|
+
heading?: string;
|
|
13
|
+
bulletList?: string;
|
|
14
|
+
orderedList?: string;
|
|
15
|
+
blockquote?: string;
|
|
16
|
+
undo?: string;
|
|
17
|
+
redo?: string;
|
|
18
|
+
}
|
|
19
|
+
interface RichTextEditorIcons {
|
|
20
|
+
bold?: LucideIcon;
|
|
21
|
+
italic?: LucideIcon;
|
|
22
|
+
strike?: LucideIcon;
|
|
23
|
+
code?: LucideIcon;
|
|
24
|
+
heading?: LucideIcon;
|
|
25
|
+
bulletList?: LucideIcon;
|
|
26
|
+
orderedList?: LucideIcon;
|
|
27
|
+
blockquote?: LucideIcon;
|
|
28
|
+
undo?: LucideIcon;
|
|
29
|
+
redo?: LucideIcon;
|
|
30
|
+
}
|
|
31
|
+
interface RichTextEditorProps {
|
|
32
|
+
value: string;
|
|
33
|
+
onValueChange: (markdown: string) => void;
|
|
34
|
+
ariaLabel: string;
|
|
35
|
+
disabled?: boolean;
|
|
36
|
+
toolbar?: RichTextToolbarGroup[] | false;
|
|
37
|
+
/** App-owned controls at the end of the toolbar; render-prop form receives the editor. */
|
|
38
|
+
toolbarExtra?: React.ReactNode | ((editor: Editor | null) => React.ReactNode);
|
|
39
|
+
/** App extensions merged after the starter kit (math, tables, custom nodes…). */
|
|
40
|
+
extensions?: Extensions;
|
|
41
|
+
/** Map incoming app-domain markdown before it reaches the document. */
|
|
42
|
+
parseMarkdown?: (markdown: string) => string;
|
|
43
|
+
/** Map the serialized document before it is emitted / echo-compared. */
|
|
44
|
+
serializeMarkdown?: (markdown: string) => string;
|
|
45
|
+
labels?: Partial<RichTextEditorLabels>;
|
|
46
|
+
icons?: Partial<RichTextEditorIcons>;
|
|
47
|
+
className?: string;
|
|
48
|
+
}
|
|
49
|
+
declare const RichTextEditor: React.ForwardRefExoticComponent<RichTextEditorProps & React.RefAttributes<HTMLDivElement>>;
|
|
50
|
+
|
|
51
|
+
export { RichTextEditor, type RichTextEditorIcons, type RichTextEditorLabels, type RichTextEditorProps, type RichTextToolbarGroup };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"rich-text-editor.js"}
|