react-word-editor 0.0.0-stage → 0.1.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.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["/Users/harsh/Documents/Flabs/flabs-editor/dist/index.cjs","../src/RichTextEditor.jsx","../src/editor/outputs.js","../src/editor/handle.js","../src/toolbar/Toolbar.jsx","../src/toolbar/controls.jsx","../src/toolbar/ToolbarSelect.jsx","../src/toolbar/ColorButton.jsx","../src/toolbar/TablePicker.jsx","../src/toolbar/MenuButton.jsx","../src/toolbar/icons.jsx","../src/toolbar/TableTools.jsx","../src/toolbar/toolbarState.js"],"names":["useRef","jsx","toggle","jsxs"],"mappings":"AAAA;AACE;AACA;AACF,wDAA6B;AAC7B;AACE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACF,wDAA6B;AAC7B;AACA;ACjDA,4EAAkD;AAClD,uCAAyD;ADmDzD;AACA;AEjDO,IAAM,eAAA,EAAiB,CAAC,MAAA,EAAQ,MAAA,EAAQ,MAAA,EAAQ,KAAA,EAAO,KAAK,CAAA;AAEnE,IAAM,WAAA,EAAa,CAAC,MAAA,EAAA,GAAW,MAAA,CAAO,OAAA;AAE/B,IAAM,UAAA,EAAY,CAAC,MAAA,EAAQ,OAAA,EAAS,MAAA,EAAQ,UAAA,EAAA,GAAe;AAChE,EAAA,GAAA,CAAI,CAAC,OAAA,GAAU,MAAA,CAAO,WAAA,EAAa,OAAO,IAAA;AAC1C,EAAA,MAAM,KAAA,EAAO,CAAA,EAAA,GAAM,MAAA,CAAO,OAAA,CAAQ,CAAA;AAClC,EAAA,MAAM,KAAA,EAAO,CAAA,EAAA,GAAO,UAAA,CAAW,MAAM,EAAA,EAAI,GAAA,EAAK,MAAA,CAAO,OAAA,CAAQ,CAAA;AAC7D,EAAA,OAAA,CAAQ,MAAA,EAAQ;AAAA,IACd,KAAK,MAAA;AACH,MAAA,OAAO,0CAAA,IAAW,CAAK,CAAC,CAAA;AAAA,IAC1B,KAAK,MAAA;AACH,MAAA,OAAO,IAAA,CAAK,CAAA;AAAA,IACd,KAAK,KAAA;AACH,MAAA,OAAO,6CAAA,IAAc,CAAK,CAAA,EAAG,UAAU,CAAA;AAAA,IACzC,KAAK,KAAA,EAAO;AACV,MAAA,MAAM,IAAA,EAAM,IAAA,CAAK,CAAA;AACjB,MAAA,OAAO;AAAA,QACL,IAAA,EAAM,IAAA,CAAK,CAAA;AAAA,QACX,IAAA,EAAM,0CAAA,GAAc,CAAA;AAAA,QACpB,IAAA,EAAM,GAAA;AAAA,QACN,GAAA,EAAK,6CAAA,GAAc,EAAK,UAAU;AAAA,MACpC,CAAA;AAAA,IACF;AAAA,IACA,OAAA;AACE,MAAA,OAAO,IAAA,CAAK,CAAA;AAAA,EAChB;AACF,CAAA;AAGO,IAAM,gBAAA,EAAkB,CAAC,KAAA,EAAA,GAAU;AACxC,EAAA,GAAA,CAAI,yCAAA,KAAe,CAAA,EAAG,OAAO,KAAA;AAC7B,EAAA,GAAA,CAAI,MAAA,GAAS,OAAO,MAAA,IAAU,SAAA,GAAY,yCAAA,KAAU,CAAM,IAAI,CAAA,EAAG,OAAO,KAAA,CAAM,IAAA;AAC9E,EAAA,GAAA,CAAI,MAAA,GAAS,OAAO,MAAA,IAAU,SAAA,GAAY,OAAO,KAAA,CAAM,KAAA,IAAS,QAAA,EAAU;AACxE,IAAA,OAAO,kDAAA,KAAmB,CAAM,IAAI,CAAA;AAAA,EACtC;AACA,EAAA,GAAA,CAAI,MAAA,GAAS,OAAO,MAAA,IAAU,QAAA,EAAU,OAAO,EAAA;AAC/C,EAAA,OAAO,kDAAA,KAAwB,CAAA;AACjC,CAAA;AAEO,IAAM,UAAA,EAAY,CAAC,CAAA,EAAG,CAAA,EAAA,GAAM;AACjC,EAAA,GAAA,CAAI,EAAA,IAAM,CAAA,EAAG,OAAO,IAAA;AACpB,EAAA,GAAA,CAAI,EAAA,GAAK,EAAA,GAAK,OAAO,EAAA,IAAM,SAAA,GAAY,OAAO,EAAA,IAAM,QAAA,EAAU;AAC5D,IAAA,IAAI;AACF,MAAA,OAAO,IAAA,CAAK,SAAA,CAAU,CAAC,EAAA,IAAM,IAAA,CAAK,SAAA,CAAU,CAAC,CAAA;AAAA,IAC/C,EAAA,MAAA,CAAS,CAAA,EAAG;AACV,MAAA,OAAO,KAAA;AAAA,IACT;AAAA,EACF;AACA,EAAA,OAAO,KAAA;AACT,CAAA;AF8CA;AACA;AGjGO,IAAM,mBAAA,EAAqB,CAAC,MAAA,EAAQ,EAAE,WAAW,EAAA,EAAI,CAAC,CAAA,EAAA,GAAA,CAAO;AAAA,EAClE,MAAA,EAAQ,MAAA;AAAA,EACR,UAAA,EAAY,CAAC,KAAA,EAAO,CAAC,CAAA,EAAA,GAAM,SAAA,CAAU,MAAA,EAAQ,IAAA,CAAK,OAAA,GAAU,MAAA,EAAQ,UAAU,CAAA;AAAA,EAC9E,UAAA,EAAY,CAAC,KAAA,EAAO,EAAE,WAAA,EAAa,KAAK,EAAA,EAAI,CAAC,CAAA,EAAA,GAAM;AACjD,IAAA,MAAA,CAAO,QAAA,CAAS,UAAA,CAAW,eAAA,CAAgB,KAAK,CAAA,EAAG,EAAE,WAAW,CAAC,CAAA;AAAA,EACnE,CAAA;AAAA,EACA,aAAA,EAAe,CAAC,KAAA,EAAA,GAAU,MAAA,CAAO,KAAA,CAAM,CAAA,CAAE,KAAA,CAAM,CAAA,CAAE,aAAA,CAAc,eAAA,CAAgB,KAAK,CAAC,CAAA,CAAE,GAAA,CAAI,CAAA;AAAA,EAC3F,OAAA,EAAS,CAAA,EAAA,GAAM,SAAA,CAAU,MAAA,EAAQ,MAAM,CAAA;AAAA,EACvC,OAAA,EAAS,CAAA,EAAA,GAAM,SAAA,CAAU,MAAA,EAAQ,MAAM,CAAA;AAAA,EACvC,OAAA,EAAS,CAAA,EAAA,GAAM,MAAA,CAAO,OAAA,CAAQ,CAAA;AAAA,EAC9B,UAAA,EAAY,CAAC,OAAA,EAAA,GAAY,SAAA,CAAU,MAAA,EAAQ,KAAA,EAAO,QAAA,GAAW,UAAU,CAAA;AAAA,EACvE,OAAA,EAAS,CAAA,EAAA,GAAG;AAfd,IAAA,IAAA,EAAA;AAeiB,IAAA,OAAA,CAAA,GAAA,EAAA,MAAA,CAAO,IAAA,EAAA,GAAP,KAAA,EAAA,KAAA,EAAA,EAAA,EAAA,CAAa,GAAA;AAAA,EAAA,CAAA;AAAA,EAC5B,KAAA,EAAO,CAAA,EAAA,GAAM,MAAA,CAAO,QAAA,CAAS,KAAA,CAAM,CAAA;AAAA,EACnC,OAAA,EAAS,CAAA,EAAA,GAAM,MAAA,CAAO,OAAA;AAAA,EACtB,WAAA,EAAa,CAAC,QAAA,EAAA,GAAa,MAAA,CAAO,WAAA,CAAY,CAAC,QAAQ;AACzD,CAAA,CAAA;AHsGA;AACA;AI1HA;AACA;AACE;AAAa;AAAc;AAAW;AAAY;AAAU;AAAM;AAClE;AAAe;AAAW;AAAgB;AAAgB;AAAQ;AAAO;AAAM;AAC/E;AAAO;AAAO;AAAkB;AAAe;AAAW;AAC1D;AAAW;AAAO;AAAA,2CACb;AJgJP;AACA;AKvJA;AAKE,+CAAA;AAHF,IAAM,cAAA,EAAgB,CAAC,CAAA,EAAA,GAAM,CAAA,CAAE,cAAA,CAAe,CAAA;AAEvC,IAAM,cAAA,EAAgB,CAAC,EAAE,IAAA,EAAM,IAAA,EAAM,KAAA,EAAO,MAAA,EAAQ,QAAA,EAAU,OAAA,EAAS,SAAS,CAAA,EAAA,mBACrF,8BAAA;AAAA,EAAC,QAAA;AAAA,EAAA;AAAA,IACC,IAAA,EAAK,QAAA;AAAA,IACL,SAAA,EAAW,CAAA,MAAA,EAAS,OAAA,EAAS,kBAAA,EAAoB,EAAE,CAAA,CAAA;AAC5C,IAAA;AACK,IAAA;AACoB,IAAA;AAChC,IAAA;AACa,IAAA;AACb,IAAA;AAEC,IAAA;AAAuB,MAAA;AACvB,MAAA;AAAA,IAAA;AAAA,EAAA;AACH;AAGiC;AAE8B;AACzB,EAAA;AACY,EAAA;AAC3B,EAAA;AACK,EAAA;AAGN,EAAA;AA7BxB,IAAA;AA8ByC,IAAA;AACd,IAAA;AACR,IAAA;AAC0B,IAAA;AAClC,IAAA;AACA,EAAA;AAEO,EAAA;AACI,IAAA;AACG,IAAA;AAC8B,MAAA;AACnD,IAAA;AACmD,IAAA;AACP,IAAA;AACF,IAAA;AAC7B,IAAA;AACoC,MAAA;AACF,MAAA;AAC/C,IAAA;AACO,EAAA;AAGS,EAAA;AACuC,IAAA;AAEnD,IAAA;AAAC,MAAA;AAAA,MAAA;AACM,QAAA;AACmC,QAAA;AAC3B,QAAA;AAEyB,QAAA;AAAG,MAAA;AAEzC,IAAA;AACN,EAAA;AAEJ;ALmJwD;AACA;AMrN7BA;AAejB;AAZ6C;AAC1B,EAAA;AAEX,EAAA;AANlB,IAAA;AAOI,IAAA;AACG,EAAA;AAGY,EAAA;AAIR,IAAA;AAAA,IAAA;AAEM,MAAA;AACA,MAAA;AACwB,MAAA;AACoB,MAAA;AACtC,MAAA;AACoB,MAAA;AAET,MAAA;AAAA,IAAA;AARb,IAAA;AAWjB,EAAA;AAEJ;AAE0D;AACJ,EAAA;AAGlDC,EAAAA;AAAC,IAAA;AAAA,IAAA;AACC,MAAA;AACU,MAAA;AACkB,MAAA;AAtClC,QAAA;AAuCQA,QAAAA;AAAC,UAAA;AAAA,UAAA;AACM,YAAA;AACyB,YAAA;AACvB,YAAA;AACK,YAAA;AACE,YAAA;AACC,YAAA;AACf,YAAA;AAC2B,YAAA;AACU,YAAA;AAC5BC,YAAAA;AAEH,YAAA;AAAsD,UAAA;AAC9D,QAAA;AAAA,MAAA;AAIAD,MAAAA;AAAC,QAAA;AAAA,QAAA;AACC,UAAA;AACA,UAAA;AACU,UAAA;AACK,UAAA;AACc,YAAA;AACrB,YAAA;AACR,UAAA;AAAA,QAAA;AACF,MAAA;AAAA,IAAA;AAEJ,EAAA;AAEJ;AAEe;ANgNyC;AACA;AOvRtC;AACU;AAiBpB;AAbyC;AAC9C,EAAA;AAAA,EAAA;AACC,IAAA;AAEE,IAAA;AAAC,MAAA;AAAA,MAAA;AACM,QAAA;AACoC,QAAA;AAClC,QAAA;AACK,QAAA;AACZ,QAAA;AACqC,QAAA;AAC5BC,QAAAA;AAET,QAAA;AAAgB,0BAAA;AACE,4BAAA;AACA,4BAAA;AAClB,UAAA;AACuB,0BAAA;AAAA,QAAA;AAAA,MAAA;AACzB,IAAA;AAIC,IAAA;AACCD,sBAAAA;AAAC,QAAA;AAAA,QAAA;AACM,UAAA;AACK,UAAA;AACK,UAAA;AACL,YAAA;AACF,YAAA;AACR,UAAA;AAEC,UAAA;AAAA,QAAA;AACH,MAAA;AACe,sBAAA;AAEV,QAAA;AAAA,QAAA;AAEM,UAAA;AACK,UAAA;AACH,UAAA;AACK,UAAA;AACW,UAAA;AACR,UAAA;AACL,YAAA;AACF,YAAA;AACR,UAAA;AAAA,QAAA;AATK,QAAA;AAYX,MAAA;AACiB,sBAAA;AAAoB,QAAA;AAEnCA,wBAAAA;AAAC,UAAA;AAAA,UAAA;AACM,YAAA;AACoC,YAAA;AACH,YAAA;AAAA,UAAA;AACxC,QAAA;AACF,MAAA;AACF,IAAA;AAAA,EAAA;AAEJ;AAGa;AP0RyC;AACA;AQ9VxB;AACT;AAqBb;AAjBoC;AACQ,EAAA;AAC7B,EAAA;AAGrBA,EAAAA;AAAC,IAAA;AAAA,IAAA;AACC,MAAA;AAEE,MAAA;AAAC,QAAA;AAAA,QAAA;AACM,UAAA;AACsB,UAAA;AACrB,UAAA;AACK,UAAA;AACX,UAAA;AACqC,UAAA;AAC5BC,UAAAA;AAED,UAAA;AAAU,QAAA;AACpB,MAAA;AAIC,MAAA;AACCD,wBAAAA;AAAC,UAAA;AAAA,UAAA;AACW,YAAA;AACkC,YAAA;AAEV,YAAA;AACC,cAAA;AACV,cAAA;AACkB,cAAA;AAEvCA,cAAAA;AAAC,gBAAA;AAAA,gBAAA;AAEM,kBAAA;AACmB,kBAAA;AACW,kBAAA;AACE,kBAAA;AACtB,kBAAA;AACsB,oBAAA;AAC7B,oBAAA;AACR,kBAAA;AAAA,gBAAA;AARK,gBAAA;AASP,cAAA;AAEH,YAAA;AAAA,UAAA;AACH,QAAA;AACe,wBAAA;AAGjB,MAAA;AAAA,IAAA;AAEJ,EAAA;AAEJ;AAEe;AR2VyC;AACA;ASxZtC;AACiB;AAQ7B;AALiD;AACpD,EAAA;AAAA,EAAA;AACC,IAAA;AACU,IAAA;AAER,IAAA;AAAC,MAAA;AAAA,MAAA;AACM,QAAA;AACoC,QAAA;AAClC,QAAA;AACK,QAAA;AACE,QAAA;AACC,QAAA;AACf,QAAA;AACqC,QAAA;AAC5BC,QAAAA;AAET,QAAA;AAAgB,0BAAA;AACG,0BAAA;AAAI,QAAA;AAAA,MAAA;AACzB,IAAA;AAIC,IAAA;AA1BP,MAAA;AA4BoC,MAAA;AACV,MAAA;AAEdC,MAAAA;AAAC,QAAA;AAAA,QAAA;AAEM,UAAA;AACmC,UAAA;AACD,UAAA;AACF,UAAA;AACtB,UAAA;AACA,UAAA;AACM,YAAA;AACb,YAAA;AACR,UAAA;AAEC,UAAA;AACO,YAAA;AAEW,YAAA;AACZ,4BAAA;AAAW,UAAA;AAAA,QAAA;AAfR,QAAA;AAgBZ,MAAA;AAGN,IAAA;AAAA,EAAA;AAEJ;AAGa;ATuZyC;AACA;AUhdtC;AAYhB;AAVY;AACP,EAAA;AACG,EAAA;AACF,EAAA;AACC,EAAA;AACE,EAAA;AACA,EAAA;AACX;AAGEA;AACEF,kBAAAA;AAAC,IAAA;AAAA,IAAA;AACiC,MAAA;AACzB,MAAA;AACO,MAAA;AACE,MAAA;AAAA,IAAA;AAClB,EAAA;AAEW,EAAA;AAEb;AAI0C;AAC5B,EAAA;AACN,EAAA;AAC6C,EAAA;AACjC,IAAA;AACT,IAAA;AACX,EAAA;AAEkB,EAAA;AAIpB;AV0cwD;AACA;AI7cK;AApBR;AAEb;AACH,EAAA;AACiB,EAAA;AACE,EAAA;AACxD;AAE+B;AACyB,EAAA;AAC5B,EAAA;AACR,EAAA;AACmC,EAAA;AACd,EAAA;AACM,EAAA;AAC/C;AAEsB;AACD,EAAA;AACnB,EAAA;AACqD,EAAA;AACvD;AAEoB;AACiC,EAAA;AACA,EAAA;AACG,EAAA;AACA,EAAA;AACxD;AAEmB;AACgC,EAAA;AACC,EAAA;AACb,EAAA;AACC,EAAA;AACY,EAAA;AACT,EAAA;AACQ,EAAA;AACK,EAAA;AACxD;AAE0C;AACb,EAAA;AACP,EAAA;AAEA,EAAA;AAC+B,IAAA;AACE,IAAA;AACF,IAAA;AAGnD,EAAA;AACsB,EAAA;AACiC,IAAA;AACD,IAAA;AAGtD,EAAA;AAE2B,EAAA;AACA,IAAA;AACJ,IAAA;AACwB,MAAA;AACX,MAAA;AAClC,IAAA;AACsB,IAAA;AAC0B,MAAA;AACd,MAAA;AAClC,IAAA;AACa,IAAA;AACN,MAAA;AAC6B,QAAA;AAC7B,MAAA;AAC6B,QAAA;AAC7B,MAAA;AACK,QAAA;AACL,MAAA;AACK,QAAA;AACL,MAAA;AACK,QAAA;AACL,MAAA;AACK,QAAA;AACL,MAAA;AACK,QAAA;AACL,MAAA;AAC6B,QAAA;AAC7B,MAAA;AAC6B,QAAA;AAC7B,MAAA;AACK,QAAA;AACL,MAAA;AACK,QAAA;AACL,MAAA;AACK,QAAA;AACL,MAAA;AACK,QAAA;AACL,MAAA;AAGC,QAAA;AAAqB,0BAAA;AAnHjC,YAAA;AAmHsG,YAAA;AAA0B,UAAA;AACpHA,0BAAAA;AAAC,YAAA;AAAA,YAAA;AACM,cAAA;AACA,cAAA;AACE,cAAA;AACD,cAAA;AACW,cAAA;AACmB,gBAAA;AACjB,gBAAA;AACnB,cAAA;AAAA,YAAA;AACF,UAAA;AACF,QAAA;AAEC,MAAA;AAC6B,QAAA;AAC7B,MAAA;AAC6B,QAAA;AAC7B,MAAA;AAC6B,QAAA;AAClC,MAAA;AACS,QAAA;AACX,IAAA;AACF,EAAA;AAGiB,EAAA;AAInB;AAEe;AJsdyC;AACA;AWzmBtC;AAClB;AACE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACK;AAOsB;AAAC;AAES;AAzBvC,EAAA;AA0BiC,EAAA;AACsB,EAAA;AAC9C,EAAA;AACT;AAGuB;AAGf,EAAA;AACa,IAAA;AACA,IAAA;AACkB,IAAA;AACJ,IAAA;AACe,IAAA;AAC1C,EAAA;AACN;AAEa;AACoC,EAAA;AACI,EAAA;AACH,EAAA;AACpD;AAEoD;AACG,EAAA;AAC9B,EAAA;AAGN,EAAA;AACG,oBAAA;AACK,oBAAA;AACA,oBAAA;AACA,oBAAA;AACA,oBAAA;AACZ,oBAAA;AACmB,oBAAA;AACP,oBAAA;AACQ,oBAAA;AACpB,oBAAA;AACY,oBAAA;AACA,oBAAA;AACA,oBAAA;AACZ,oBAAA;AACTA,oBAAAA;AAAC,MAAA;AAAA,MAAA;AACO,QAAA;AACA,QAAA;AACK,QAAA;AACE,QAAA;AACb,QAAA;AAC0C,QAAA;AACJ,QAAA;AAA8C,MAAA;AACtF,IAAA;AAEE,IAAA;AAAC,MAAA;AAAA,MAAA;AAEC,QAAA;AACA,QAAA;AACoC,QAAA;AACpC,QAAA;AACuC,QAAA;AAAuB,MAAA;AALzD,MAAA;AAOR,IAAA;AACDA,oBAAAA;AAAC,MAAA;AAAA,MAAA;AACO,QAAA;AACA,QAAA;AAC+B,QAAA;AAC3B,QAAA;AACV,QAAA;AAC2C,QAAA;AAA0B,MAAA;AACvE,IAAA;AACF,EAAA;AAEJ;AAEe;AXmmByC;AACA;AYtsBxB;AACc,EAAA;AACQ,IAAA;AACpD,EAAA;AACO,EAAA;AACT;AAEsC;AACL,EAAA;AACW,EAAA;AACf,IAAA;AACuB,IAAA;AAClD,EAAA;AACQ,EAAA;AACV;AAEqC;AACJ,EAAA;AACW,EAAA;AACf,IAAA;AACuB,IAAA;AAClD,EAAA;AACO,EAAA;AACT;AAEkD;AAC3B,EAAA;AAC6B,EAAA;AACZ,EAAA;AACF,EAAA;AAC7B,EAAA;AACuB,IAAA;AACI,IAAA;AACM,IAAA;AACN,IAAA;AACM,IAAA;AACI,IAAA;AACF,IAAA;AACE,IAAA;AACd,IAAA;AACC,IAAA;AACC,IAAA;AACE,IAAA;AACU,IAAA;AACN,IAAA;AACJ,IAAA;AACN,IAAA;AACoB,IAAA;AACnB,IAAA;AACA,IAAA;AAChB,IAAA;AACW,IAAA;AACG,IAAA;AACuB,IAAA;AAClD,EAAA;AACF;AZqsBwD;AACA;AC1mBhD;AAvIgD;AAEhC;AACtB,EAAA;AACA,EAAA;AACA,EAAA;AACW,EAAA;AACI,EAAA;AACf,EAAA;AACA,EAAA;AACY,EAAA;AACD,EAAA;AACA,EAAA;AACX,EAAA;AACU,EAAA;AACK,EAAA;AACH,EAAA;AACZ,EAAA;AACU,EAAA;AACV,EAAA;AACA,EAAA;AACA,EAAA;AACA,EAAA;AACA,EAAA;AACA,EAAA;AACA,EAAA;AACA,EAAA;AACY,EAAA;AACD,EAAA;AACK,EAAA;AACJ,EAAA;AACZ,EAAA;AACmB,EAAA;AACf;AACoB,EAAA;AACwB,EAAA;AAChB,EAAA;AACL,EAAA;AAEF,EAAA;AACN,IAAA;AAC+B,IAAA;AAC1B,IAAA;AAC8B,IAAA;AACT,IAAA;AAC7C,EAAA;AAEmB,EAAA;AAEO,IAAA;AACpB,MAAA;AACA,MAAA;AACyB,MAAA;AACO,QAAA;AACe,QAAA;AAC/C,MAAA;AACA,MAAA;AACe,MAAA;AAxEvB,QAAA;AAwE0B,QAAA;AAAyB,MAAA;AAC5C,IAAA;AAAA;AAAA;AAGkB,IAAA;AACvB,EAAA;AACmC,EAAA;AAEpB,EAAA;AACb,IAAA;AACE,MAAA;AAC8B,MAAA;AACnB,MAAA;AACA,MAAA;AACQ,MAAA;AACU,MAAA;AAChB,MAAA;AACU,QAAA;AACc,QAAA;AACrC,MAAA;AAC2C,MAAA;AACH,QAAA;AAC/B,QAAA;AACT,MAAA;AACwB,MAAA;AAhG9B,QAAA;AAiGQ,QAAA;AACe,QAAA;AACjB,MAAA;AACmC,MAAA;AApGzC,QAAA;AAqGwC,QAAA;AAChC,QAAA;AACF,MAAA;AACF,IAAA;AACW,IAAA;AACb,EAAA;AAEuC,EAAA;AAEvB,EAAA;AACU,IAAA;AACS,IAAA;AACR,IAAA;AACf,IAAA;AAGD,EAAA;AAEK,EAAA;AACqB,IAAA;AACQ,IAAA;AACO,IAAA;AAC1B,MAAA;AACtB,MAAA;AACF,IAAA;AACsB,IAAA;AAC6B,IAAA;AAClB,IAAA;AACM,EAAA;AAEzB,EAAA;AAC4B,IAAA;AACzB,EAAA;AAE8B,EAAA;AACpB,EAAA;AAC3B,IAAA;AACqD,IAAA;AACtD,EAAA;AAE6C,EAAA;AACG,EAAA;AAG/CE,EAAAA;AAAC,IAAA;AAAA,IAAA;AACmC,MAAA;AACc,MAAA;AAE/C,MAAA;AACE,QAAA;AACCF,0BAAAA;AAAC,YAAA;AAAA,YAAA;AACC,cAAA;AACA,cAAA;AACO,cAAA;AACG,cAAA;AACV,cAAA;AACA,cAAA;AAC+B,cAAA;AAAsB,YAAA;AACvD,UAAA;AAC4BA,UAAAA;AAE5B,QAAA;AACW,wBAAA;AAMR,QAAA;AACF,UAAA;AAAM,UAAA;AAAyB,UAAA;AAEhC,QAAA;AAAA,MAAA;AAAA,IAAA;AACN,EAAA;AAEJ;AAEe;ADyuByC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA","file":"/Users/harsh/Documents/Flabs/flabs-editor/dist/index.cjs","sourcesContent":[null,"import React, { useEffect, useMemo, useRef } from 'react';\nimport { EditorContent, useEditor, useEditorState } from '@tiptap/react';\nimport { buildEditorExtensions } from './extensions';\nimport { readAsDataUrl } from './extensions/imageUpload';\nimport { ensureNodeIds } from './extensions/nodeIds';\nimport { cleanHtml } from './paste/cleanHtml';\nimport { getOutput, sameValue, toEditorContent } from './editor/outputs';\nimport { createEditorHandle } from './editor/handle';\nimport { replaceVariables } from './editor/variables';\nimport { SILENT_META } from './utils/meta';\nimport Toolbar from './toolbar/Toolbar';\nimport TableTools from './toolbar/TableTools';\nimport { selectToolbarState } from './toolbar/toolbarState';\nimport { DEFAULT_FONT_FAMILIES, DEFAULT_FONT_SIZES, DEFAULT_TOOLBAR } from './toolbar/constants';\n\nconst countWords = (text) => (text.trim() ? text.trim().split(/\\s+/).length : 0);\n\nconst RichTextEditor = ({\n value,\n onChange,\n setValue,\n fnProps = [],\n outputFormat = 'html',\n pdfOptions,\n height,\n minHeight = 200,\n disabled = false,\n readOnly = false,\n placeholder,\n toolbar = true,\n fontFamilies = DEFAULT_FONT_FAMILIES,\n fontSizes = DEFAULT_FONT_SIZES,\n dynamicData,\n nodeIds = false,\n onInit,\n onReady,\n onFocus,\n onBlur,\n handleFocusRestore,\n onImageUpload,\n maxImageSize,\n onError,\n autoFocus = false,\n pageView = false,\n showWordCount = true,\n className = '',\n style,\n contentClassName = '',\n}) => {\n const latest = useRef({});\n latest.current = { onChange, setValue, fnProps, outputFormat, pdfOptions, dynamicData, onFocus, onBlur, handleFocusRestore, onError };\n const lastEmitted = useRef(value);\n const locked = disabled || readOnly;\n\n const emit = (editor) => {\n const l = latest.current;\n const out = getOutput(editor, l.outputFormat, l.pdfOptions);\n lastEmitted.current = out;\n if (l.onChange) l.onChange(out, ...(l.fnProps || []));\n else if (l.setValue) l.setValue(out, ...(l.fnProps || []));\n };\n\n const extensions = useMemo(\n () =>\n buildEditorExtensions({\n nodeIds,\n placeholder,\n onImageUpload: (file) => {\n const upload = latest.current.onImageUploadProp;\n return upload ? upload(file) : readAsDataUrl(file);\n },\n maxImageSize,\n onError: (err) => latest.current.onError?.(err),\n }),\n // Extensions are fixed for the editor's lifetime.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [nodeIds, placeholder],\n );\n latest.current.onImageUploadProp = onImageUpload;\n\n const editor = useEditor(\n {\n extensions,\n content: toEditorContent(value),\n editable: !locked,\n autofocus: autoFocus,\n immediatelyRender: true,\n shouldRerenderOnTransaction: false,\n editorProps: {\n transformPastedHTML: cleanHtml,\n attributes: { class: `fe-content ${contentClassName}`.trim(), spellcheck: 'true' },\n },\n onUpdate: ({ editor: ed, transaction }) => {\n if (transaction.getMeta(SILENT_META)) return;\n emit(ed);\n },\n onFocus: ({ event }) => {\n latest.current.onFocus?.(event);\n latest.current.handleFocusRestore?.(event);\n },\n onBlur: ({ editor: ed, event }) => {\n if (latest.current.dynamicData) replaceVariables(ed, latest.current.dynamicData);\n latest.current.onBlur?.(event);\n },\n },\n [extensions],\n );\n\n const handle = useMemo(() => (editor ? createEditorHandle(editor, { pdfOptions }) : null), [editor, pdfOptions]);\n\n useEffect(() => {\n if (!editor || !handle) return;\n if (nodeIds) ensureNodeIds(editor);\n onInit?.({ type: 'init', target: handle }, handle);\n onReady?.(handle);\n // Fire once per editor instance, like TinyMCE's onInit.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [editor]);\n\n useEffect(() => {\n if (!editor || editor.isDestroyed) return;\n if (sameValue(value, lastEmitted.current)) return;\n if (typeof value === 'string' && outputFormat === 'html' && value === getOutput(editor, 'html')) {\n lastEmitted.current = value;\n return;\n }\n lastEmitted.current = value;\n editor.commands.setContent(toEditorContent(value), { emitUpdate: false });\n if (nodeIds) ensureNodeIds(editor);\n }, [editor, value, outputFormat, nodeIds]);\n\n useEffect(() => {\n if (editor && !editor.isDestroyed) editor.setEditable(!locked, false);\n }, [editor, locked]);\n\n const state = useEditorState({ editor, selector: selectToolbarState }) || {};\n const words = useEditorState({\n editor,\n selector: ({ editor: ed }) => (showWordCount && ed ? countWords(ed.state.doc.textBetween(0, ed.state.doc.content.size, ' ', ' ')) : 0),\n });\n\n const toolbarItems = Array.isArray(toolbar) ? toolbar : DEFAULT_TOOLBAR;\n const sized = height !== undefined && height !== null;\n\n return (\n <div\n className={`fe-editor${pageView ? ' fe-editor--page' : ''}${locked ? ' fe-editor--disabled' : ''}${sized ? ' fe-editor--sized' : ''} ${className}`.trim()}\n style={{ ...(sized ? { height } : {}), ...style }}\n >\n {toolbar && !readOnly ? (\n <div className=\"fe-toolbars\">\n <Toolbar\n editor={editor}\n state={state}\n items={toolbarItems}\n disabled={locked}\n fontFamilies={fontFamilies}\n fontSizes={fontSizes}\n imageOptions={{ onImageUpload, maxImageSize, onError }}\n />\n {state.inTable && !locked ? <TableTools editor={editor} state={state} disabled={locked} /> : null}\n </div>\n ) : null}\n <div className=\"fe-scroll\" style={sized ? undefined : { minHeight }} onClick={() => !locked && editor?.isFocused === false && editor?.commands.focus()}>\n <div className=\"fe-page\">\n <EditorContent editor={editor} />\n </div>\n </div>\n {showWordCount ? (\n <div className=\"fe-status\">\n {words} {words === 1 ? 'word' : 'words'}\n </div>\n ) : null}\n </div>\n );\n};\n\nexport default RichTextEditor;\n","import { jsonToText } from '../output/text';\nimport { jsonToPdfTree } from '../pdf/tree';\nimport { isDocJson, normalizeHtmlInput } from '../output/convert';\n\nexport const OUTPUT_FORMATS = ['html', 'text', 'json', 'pdf', 'all'];\n\nconst isEmptyDoc = (editor) => editor.isEmpty;\n\nexport const getOutput = (editor, format = 'html', pdfOptions) => {\n if (!editor || editor.isDestroyed) return null;\n const json = () => editor.getJSON();\n const html = () => (isEmptyDoc(editor) ? '' : editor.getHTML());\n switch (format) {\n case 'text':\n return jsonToText(json());\n case 'json':\n return json();\n case 'pdf':\n return jsonToPdfTree(json(), pdfOptions);\n case 'all': {\n const doc = json();\n return {\n html: html(),\n text: jsonToText(doc),\n json: doc,\n pdf: jsonToPdfTree(doc, pdfOptions),\n };\n }\n default:\n return html();\n }\n};\n\n// What to hand to editor.setContent for a `value` prop.\nexport const toEditorContent = (value) => {\n if (isDocJson(value)) return value;\n if (value && typeof value === 'object' && isDocJson(value.json)) return value.json;\n if (value && typeof value === 'object' && typeof value.html === 'string') {\n return normalizeHtmlInput(value.html);\n }\n if (value && typeof value === 'object') return '';\n return normalizeHtmlInput(value);\n};\n\nexport const sameValue = (a, b) => {\n if (a === b) return true;\n if (a && b && typeof a === 'object' && typeof b === 'object') {\n try {\n return JSON.stringify(a) === JSON.stringify(b);\n } catch (e) {\n return false;\n }\n }\n return false;\n};\n","import { getOutput, toEditorContent } from './outputs';\n\n// A small TinyMCE-like facade so code written against `onInit(evt, editor)`\n// keeps working: editor.getContent(), setContent(), getBody(), focus().\nexport const createEditorHandle = (editor, { pdfOptions } = {}) => ({\n tiptap: editor,\n getContent: (args = {}) => getOutput(editor, args.format || 'html', pdfOptions),\n setContent: (value, { emitUpdate = true } = {}) => {\n editor.commands.setContent(toEditorContent(value), { emitUpdate });\n },\n insertContent: (value) => editor.chain().focus().insertContent(toEditorContent(value)).run(),\n getHTML: () => getOutput(editor, 'html'),\n getText: () => getOutput(editor, 'text'),\n getJSON: () => editor.getJSON(),\n getPdfTree: (options) => getOutput(editor, 'pdf', options || pdfOptions),\n getBody: () => editor.view?.dom,\n focus: () => editor.commands.focus(),\n isEmpty: () => editor.isEmpty,\n setDisabled: (disabled) => editor.setEditable(!disabled),\n});\n","import React, { useRef } from 'react';\nimport {\n AlignCenter, AlignJustify, AlignLeft, AlignRight, Baseline, Bold, Highlighter,\n CaseSensitive, ImagePlus, IndentDecrease, IndentIncrease, Italic, Link2, List, ListOrdered,\n Minus, Redo2, RemoveFormatting, Strikethrough, Subscript, Superscript,\n Underline, Undo2, UnfoldVertical,\n} from 'lucide-react';\nimport { BLOCK_TYPES, DEFAULT_TOOLBAR, LINE_HEIGHTS, PARAGRAPH_SPACING, TEXT_CASES } from './constants';\nimport { Divider, ToolbarButton } from './controls';\nimport ToolbarSelect from './ToolbarSelect';\nimport ColorButton from './ColorButton';\nimport TablePicker from './TablePicker';\nimport MenuButton from './MenuButton';\nimport { SpacingIcon } from './icons';\nimport { insertImages } from '../extensions/imageUpload';\n\nconst toggle = (editor, cmd) => () => editor.chain().focus()[cmd]().run();\n\nconst setBlockType = (editor, value) => {\n const chain = editor.chain().focus();\n if (value === 'paragraph') chain.setParagraph().run();\n else chain.setHeading({ level: Number(value.slice(1)) }).run();\n};\n\nconst promptLink = (editor) => {\n const previous = editor.getAttributes('link').href || '';\n const url = window.prompt('Link URL (leave empty to remove)', previous);\n if (url === null) return;\n const chain = editor.chain().focus().extendMarkRange('link');\n if (!url.trim()) chain.unsetLink().run();\n else chain.setLink({ href: url.trim() }).run();\n};\n\nconst SPACING_ITEMS = [\n PARAGRAPH_SPACING[0],\n '|',\n ...PARAGRAPH_SPACING.slice(1).map((p, i) => ({ ...p, icon: <SpacingIcon gap={i} /> })),\n];\n\nconst ALIGN_ITEMS = {\n alignLeft: { icon: AlignLeft, label: 'Align left', value: 'left' },\n alignCenter: { icon: AlignCenter, label: 'Center', value: 'center' },\n alignRight: { icon: AlignRight, label: 'Align right', value: 'right' },\n alignJustify: { icon: AlignJustify, label: 'Justify', value: 'justify' },\n};\n\nconst MARK_ITEMS = {\n bold: { icon: Bold, label: 'Bold (Ctrl+B)', cmd: 'toggleBold' },\n italic: { icon: Italic, label: 'Italic (Ctrl+I)', cmd: 'toggleItalic' },\n underline: { icon: Underline, label: 'Underline (Ctrl+U)', cmd: 'toggleUnderline' },\n strike: { icon: Strikethrough, label: 'Strikethrough', cmd: 'toggleStrike' },\n subscript: { icon: Subscript, label: 'Subscript', cmd: 'toggleSubscript' },\n superscript: { icon: Superscript, label: 'Superscript', cmd: 'toggleSuperscript' },\n bulletList: { icon: List, label: 'Bullets', cmd: 'toggleBulletList' },\n orderedList: { icon: ListOrdered, label: 'Numbering', cmd: 'toggleOrderedList' },\n};\n\nconst Toolbar = ({ editor, state, items = DEFAULT_TOOLBAR, disabled, fontFamilies, fontSizes, imageOptions }) => {\n const fileRef = useRef(null);\n if (!editor) return null;\n\n const sizeOptions = [\n { value: '', label: 'Size', menuLabel: 'Default' },\n ...fontSizes.map((s) => ({ value: `${s}pt`, label: s })),\n ...(state.fontSize && !fontSizes.some((s) => `${s}pt` === state.fontSize)\n ? [{ value: state.fontSize, label: state.fontSize.replace(/pt$/, ''), hidden: true }]\n : []),\n ];\n const familyOptions = [\n ...fontFamilies.map((f) => (f.value ? { ...f, style: { fontFamily: f.value } } : f)),\n ...(state.fontFamily && !fontFamilies.some((f) => f.value === state.fontFamily)\n ? [{ value: state.fontFamily, label: state.fontFamily.split(',')[0].replace(/[\"']/g, ''), hidden: true }]\n : []),\n ];\n\n const render = (key, i) => {\n if (key === '|') return <Divider key={`d${i}`} />;\n if (MARK_ITEMS[key]) {\n const { icon, label, cmd } = MARK_ITEMS[key];\n return <ToolbarButton key={key} icon={icon} label={label} active={state[key]} disabled={disabled} onClick={toggle(editor, cmd)} />;\n }\n if (ALIGN_ITEMS[key]) {\n const { icon, label, value } = ALIGN_ITEMS[key];\n return <ToolbarButton key={key} icon={icon} label={label} active={state.textAlign === value} disabled={disabled} onClick={() => editor.chain().focus().setTextAlign(value).run()} />;\n }\n switch (key) {\n case 'undo':\n return <ToolbarButton key={key} icon={Undo2} label=\"Undo (Ctrl+Z)\" disabled={disabled || !state.canUndo} onClick={toggle(editor, 'undo')} />;\n case 'redo':\n return <ToolbarButton key={key} icon={Redo2} label=\"Redo (Ctrl+Y)\" disabled={disabled || !state.canRedo} onClick={toggle(editor, 'redo')} />;\n case 'blockType':\n return <ToolbarSelect key={key} label=\"Text style\" width={108} value={state.blockType} options={BLOCK_TYPES} disabled={disabled} onChange={(v) => setBlockType(editor, v)} />;\n case 'fontFamily':\n return <ToolbarSelect key={key} label=\"Font\" width={130} value={state.fontFamily || ''} options={familyOptions} disabled={disabled} onChange={(v) => (v ? editor.chain().focus().setFontFamily(v).run() : editor.chain().focus().unsetFontFamily().run())} />;\n case 'fontSize':\n return <ToolbarSelect key={key} label=\"Font size\" width={64} value={state.fontSize || ''} options={sizeOptions} disabled={disabled} onChange={(v) => (v ? editor.chain().focus().setFontSize(v).run() : editor.chain().focus().unsetFontSize().run())} />;\n case 'textColor':\n return <ColorButton key={key} icon={Baseline} label=\"Font colour\" clearLabel=\"Automatic\" color={state.color} disabled={disabled} onPick={(c) => editor.chain().focus().setColor(c).run()} onClear={() => editor.chain().focus().unsetColor().run()} />;\n case 'highlight':\n return <ColorButton key={key} icon={Highlighter} label=\"Highlight\" clearLabel=\"No colour\" color={state.backgroundColor} disabled={disabled} onPick={(c) => editor.chain().focus().setBackgroundColor(c).run()} onClear={() => editor.chain().focus().unsetBackgroundColor().run()} />;\n case 'indent':\n return <ToolbarButton key={key} icon={IndentIncrease} label=\"Increase indent (Tab)\" disabled={disabled} onClick={toggle(editor, 'indent')} />;\n case 'outdent':\n return <ToolbarButton key={key} icon={IndentDecrease} label=\"Decrease indent (Shift+Tab)\" disabled={disabled} onClick={toggle(editor, 'outdent')} />;\n case 'lineHeight':\n return <ToolbarSelect key={key} label=\"Line spacing\" width={108} value={state.lineHeight ? String(state.lineHeight) : ''} options={LINE_HEIGHTS} disabled={disabled} onChange={(v) => editor.chain().focus().setLineHeight(v || null).run()} />;\n case 'paragraphSpacing':\n return <MenuButton key={key} icon={UnfoldVertical} label=\"Paragraph spacing\" items={SPACING_ITEMS} value={state.paragraphSpacing} showChecks disabled={disabled} onSelect={(v) => editor.chain().focus().setParagraphSpacing(v).run()} />;\n case 'textCase':\n return <MenuButton key={key} icon={CaseSensitive} label=\"Change case\" items={TEXT_CASES} disabled={disabled} onSelect={(v) => editor.chain().focus().setTextCase(v).run()} />;\n case 'table':\n return <TablePicker key={key} editor={editor} disabled={disabled} />;\n case 'image':\n return (\n <React.Fragment key={key}>\n <ToolbarButton icon={ImagePlus} label=\"Insert picture\" disabled={disabled} onClick={() => fileRef.current?.click()} />\n <input\n ref={fileRef}\n type=\"file\"\n accept=\"image/*\"\n hidden\n onChange={(e) => {\n insertImages(editor, Array.from(e.target.files || []), imageOptions);\n e.target.value = '';\n }}\n />\n </React.Fragment>\n );\n case 'link':\n return <ToolbarButton key={key} icon={Link2} label=\"Link\" active={state.link} disabled={disabled} onClick={() => promptLink(editor)} />;\n case 'horizontalRule':\n return <ToolbarButton key={key} icon={Minus} label=\"Horizontal line\" disabled={disabled} onClick={toggle(editor, 'setHorizontalRule')} />;\n case 'clearFormatting':\n return <ToolbarButton key={key} icon={RemoveFormatting} label=\"Clear formatting\" disabled={disabled} onClick={() => editor.chain().focus().unsetAllMarks().unsetParagraphFormat().unsetTextAlign().run()} />;\n default:\n return null;\n }\n };\n\n return (\n <div className=\"fe-toolbar\" role=\"toolbar\" aria-label=\"Formatting\">\n {items.map(render)}\n </div>\n );\n};\n\nexport default Toolbar;\n","import React, { useEffect, useLayoutEffect, useRef, useState } from 'react';\n\nconst keepSelection = (e) => e.preventDefault();\n\nexport const ToolbarButton = ({ icon: Icon, label, active, disabled, onClick, children }) => (\n <button\n type=\"button\"\n className={`fe-btn${active ? ' fe-btn--active' : ''}`}\n title={label}\n aria-label={label}\n aria-pressed={active ? 'true' : undefined}\n disabled={disabled}\n onMouseDown={keepSelection}\n onClick={onClick}\n >\n {Icon ? <Icon size={16} strokeWidth={2} /> : null}\n {children}\n </button>\n);\n\nexport const Divider = () => <span className=\"fe-divider\" aria-hidden=\"true\" />;\n\nexport const Popover = ({ trigger, children, disabled, className }) => {\n const [open, setOpen] = useState(false);\n const [alignRight, setAlignRight] = useState(false);\n const ref = useRef(null);\n const panelRef = useRef(null);\n\n // The editor clips overflow, so open leftwards when the panel would run past its right edge.\n useLayoutEffect(() => {\n if (!open) return setAlignRight(false);\n const panel = panelRef.current;\n const bounds = ref.current?.closest('.fe-editor')?.getBoundingClientRect();\n if (panel && bounds) setAlignRight(panel.getBoundingClientRect().right > bounds.right);\n return undefined;\n }, [open]);\n\n useEffect(() => {\n if (!open) return undefined;\n const close = (e) => {\n if (ref.current && !ref.current.contains(e.target)) setOpen(false);\n };\n const onKey = (e) => e.key === 'Escape' && setOpen(false);\n document.addEventListener('mousedown', close);\n document.addEventListener('keydown', onKey);\n return () => {\n document.removeEventListener('mousedown', close);\n document.removeEventListener('keydown', onKey);\n };\n }, [open]);\n\n return (\n <span className=\"fe-popover-anchor\" ref={ref}>\n {trigger({ open, toggle: () => !disabled && setOpen((o) => !o) })}\n {open ? (\n <div\n ref={panelRef}\n className={`fe-popover${className ? ` ${className}` : ''}${alignRight ? ' fe-popover--right' : ''}`}\n onMouseDown={keepSelection}\n >\n {children({ close: () => setOpen(false) })}\n </div>\n ) : null}\n </span>\n );\n};\n","import React, { useEffect, useRef } from 'react';\nimport { Popover } from './controls';\n\nconst SelectList = ({ options, value, minWidth, onPick }) => {\n const listRef = useRef(null);\n\n useEffect(() => {\n listRef.current?.querySelector('.is-checked')?.scrollIntoView?.({ block: 'nearest' });\n }, []);\n\n return (\n <div className=\"fe-menu fe-menu--select\" role=\"listbox\" ref={listRef} style={{ minWidth }}>\n {options\n .filter((opt) => !opt.hidden)\n .map((opt) => (\n <button\n key={opt.value}\n type=\"button\"\n role=\"option\"\n aria-selected={opt.value === value}\n className={`fe-menu__item${opt.value === value ? ' is-checked' : ''}`}\n style={opt.style}\n onClick={() => onPick(opt.value)}\n >\n {opt.menuLabel || opt.label}\n </button>\n ))}\n </div>\n );\n};\n\nconst ToolbarSelect = ({ label, value, options, disabled, onChange, width }) => {\n const current = options.find((opt) => opt.value === value);\n\n return (\n <Popover\n disabled={disabled}\n className=\"fe-popover--menu\"\n trigger={({ toggle, open }) => (\n <button\n type=\"button\"\n className={`fe-select${open ? ' fe-select--open' : ''}`}\n title={label}\n aria-label={label}\n aria-haspopup=\"listbox\"\n aria-expanded={open}\n disabled={disabled}\n style={width ? { width } : undefined}\n onMouseDown={(e) => e.preventDefault()}\n onClick={toggle}\n >\n <span className=\"fe-select__value\">{current?.label ?? label}</span>\n </button>\n )}\n >\n {({ close }) => (\n <SelectList\n options={options}\n value={value}\n minWidth={width}\n onPick={(v) => {\n if (v !== value) onChange(v);\n close();\n }}\n />\n )}\n </Popover>\n );\n};\n\nexport default ToolbarSelect;\n","import React from 'react';\nimport { ChevronDown } from 'lucide-react';\nimport { COLOR_SWATCHES } from './constants';\nimport { Popover } from './controls';\n\nconst ColorButton = ({ icon: Icon, label, color, disabled, onPick, onClear, clearLabel }) => (\n <Popover\n disabled={disabled}\n trigger={({ toggle, open }) => (\n <button\n type=\"button\"\n className={`fe-btn fe-btn--split${open ? ' fe-btn--active' : ''}`}\n title={label}\n aria-label={label}\n disabled={disabled}\n onMouseDown={(e) => e.preventDefault()}\n onClick={toggle}\n >\n <span className=\"fe-color-icon\">\n <Icon size={16} />\n <span className=\"fe-color-bar\" style={{ background: color || 'transparent' }} />\n </span>\n <ChevronDown size={12} />\n </button>\n )}\n >\n {({ close }) => (\n <div className=\"fe-colors\">\n <button\n type=\"button\"\n className=\"fe-colors__clear\"\n onClick={() => {\n onClear();\n close();\n }}\n >\n {clearLabel}\n </button>\n <div className=\"fe-colors__grid\">\n {COLOR_SWATCHES.map((c) => (\n <button\n key={c}\n type=\"button\"\n className=\"fe-swatch\"\n title={c}\n aria-label={c}\n style={{ background: c }}\n onClick={() => {\n onPick(c);\n close();\n }}\n />\n ))}\n </div>\n <label className=\"fe-colors__custom\">\n More colours\n <input\n type=\"color\"\n value={/^#[0-9a-f]{6}$/i.test(color || '') ? color : '#000000'}\n onChange={(e) => onPick(e.target.value)}\n />\n </label>\n </div>\n )}\n </Popover>\n);\n\nexport default ColorButton;\n","import React, { useState } from 'react';\nimport { Table2 } from 'lucide-react';\nimport { TABLE_PICKER_SIZE } from './constants';\nimport { Popover } from './controls';\n\nconst TablePicker = ({ editor, disabled }) => {\n const [hover, setHover] = useState({ rows: 0, cols: 0 });\n const { rows, cols } = TABLE_PICKER_SIZE;\n\n return (\n <Popover\n disabled={disabled}\n trigger={({ toggle, open }) => (\n <button\n type=\"button\"\n className={`fe-btn${open ? ' fe-btn--active' : ''}`}\n title=\"Insert table\"\n aria-label=\"Insert table\"\n disabled={disabled}\n onMouseDown={(e) => e.preventDefault()}\n onClick={toggle}\n >\n <Table2 size={16} />\n </button>\n )}\n >\n {({ close }) => (\n <div className=\"fe-table-picker\" onMouseLeave={() => setHover({ rows: 0, cols: 0 })}>\n <div\n className=\"fe-table-picker__grid\"\n style={{ gridTemplateColumns: `repeat(${cols}, 16px)` }}\n >\n {Array.from({ length: rows * cols }, (_, i) => {\n const r = Math.floor(i / cols) + 1;\n const c = (i % cols) + 1;\n const on = r <= hover.rows && c <= hover.cols;\n return (\n <button\n key={i}\n type=\"button\"\n aria-label={`${r} by ${c} table`}\n className={`fe-table-picker__cell${on ? ' is-on' : ''}`}\n onMouseEnter={() => setHover({ rows: r, cols: c })}\n onClick={() => {\n editor.chain().focus().insertTable({ rows: r, cols: c, withHeaderRow: false }).run();\n close();\n }}\n />\n );\n })}\n </div>\n <div className=\"fe-table-picker__label\">\n {hover.rows ? `${hover.rows} × ${hover.cols} table` : 'Insert table'}\n </div>\n </div>\n )}\n </Popover>\n );\n};\n\nexport default TablePicker;\n","import React from 'react';\nimport { Check, ChevronDown } from 'lucide-react';\nimport { Popover } from './controls';\n\nconst MenuButton = ({ icon: Icon, label, items, value, disabled, onSelect, showChecks }) => (\n <Popover\n disabled={disabled}\n className=\"fe-popover--menu\"\n trigger={({ toggle, open }) => (\n <button\n type=\"button\"\n className={`fe-btn fe-btn--split${open ? ' fe-btn--active' : ''}`}\n title={label}\n aria-label={label}\n aria-haspopup=\"menu\"\n aria-expanded={open}\n disabled={disabled}\n onMouseDown={(e) => e.preventDefault()}\n onClick={toggle}\n >\n <Icon size={16} />\n <ChevronDown size={12} />\n </button>\n )}\n >\n {({ close }) => (\n <div className=\"fe-menu\" role=\"menu\" aria-label={label}>\n {items.map((item, i) => {\n if (item === '|') return <div key={`s${i}`} className=\"fe-menu__sep\" role=\"separator\" />;\n const checked = item.checked ?? (value !== undefined && item.value === value);\n return (\n <button\n key={item.value}\n type=\"button\"\n role={showChecks ? 'menuitemcheckbox' : 'menuitem'}\n aria-checked={showChecks ? !!checked : undefined}\n className={`fe-menu__item${checked ? ' is-checked' : ''}`}\n disabled={item.disabled}\n onClick={() => {\n onSelect(item.value);\n close();\n }}\n >\n {showChecks ? (\n <span className=\"fe-menu__check\">{checked ? <Check size={14} /> : null}</span>\n ) : null}\n {item.icon ? <span className=\"fe-menu__icon\">{item.icon}</span> : null}\n <span>{item.label}</span>\n </button>\n );\n })}\n </div>\n )}\n </Popover>\n);\n\nexport default MenuButton;\n","import React from 'react';\n\nconst LINES = {\n top: 'M2 2H14',\n bottom: 'M2 14H14',\n left: 'M2 2V14',\n right: 'M14 2V14',\n insideH: 'M2 8H14',\n insideV: 'M8 2V14',\n};\n\nexport const BorderIcon = ({ lines = [] }) => (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" aria-hidden=\"true\">\n <path\n d={Object.values(LINES).join(' ')}\n stroke=\"currentColor\"\n strokeOpacity=\".35\"\n strokeDasharray=\"1 1.5\"\n />\n {lines.length ? (\n <path d={lines.map((l) => LINES[l]).join(' ')} stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"square\" />\n ) : null}\n </svg>\n);\n\n// Gap between three groups of lines grows with the spacing preset.\nexport const SpacingIcon = ({ gap = 2 }) => {\n const rows = [];\n let y = 2;\n for (let group = 0; group < 3 && y < 15; group += 1) {\n rows.push(y, y + 2);\n y += 4 + gap;\n }\n return (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" aria-hidden=\"true\">\n <path d={rows.filter((r) => r < 15).map((r) => `M2 ${r}H14`).join(' ')} stroke=\"currentColor\" />\n </svg>\n );\n};\n","import React from 'react';\nimport {\n BetweenHorizontalEnd,\n BetweenHorizontalStart,\n BetweenVerticalEnd,\n BetweenVerticalStart,\n PaintBucket,\n PanelTop,\n SquareSplitHorizontal,\n TableCellsMerge,\n Trash2,\n Rows3,\n Columns3,\n AlignVerticalJustifyStart,\n AlignVerticalJustifyCenter,\n AlignVerticalJustifyEnd,\n} from 'lucide-react';\nimport { Divider, ToolbarButton } from './controls';\nimport ColorButton from './ColorButton';\nimport MenuButton from './MenuButton';\nimport { BorderIcon } from './icons';\nimport { TABLE_BORDER_OPTIONS } from './constants';\n\nconst AllBordersIcon = () => <BorderIcon lines={['top', 'bottom', 'left', 'right', 'insideH', 'insideV']} />;\n\nconst unavailable = (mode, borders) => {\n if (mode === 'inside') return !borders?.hasInside;\n if (mode === 'insideH' || mode === 'insideV') return !borders?.exists?.[mode];\n return false;\n};\n\nconst borderItems = (borders) =>\n TABLE_BORDER_OPTIONS.map((opt) =>\n opt === '|'\n ? opt\n : {\n value: opt.value,\n label: opt.label,\n icon: <BorderIcon lines={opt.lines} />,\n checked: !!borders?.[opt.value],\n disabled: unavailable(opt.value, borders),\n },\n );\n\nconst VALIGN = [\n { value: 'top', icon: AlignVerticalJustifyStart, label: 'Align cell top' },\n { value: 'middle', icon: AlignVerticalJustifyCenter, label: 'Align cell middle' },\n { value: 'bottom', icon: AlignVerticalJustifyEnd, label: 'Align cell bottom' },\n];\n\nconst TableTools = ({ editor, state, disabled }) => {\n const run = (fn) => () => fn(editor.chain().focus()).run();\n const can = editor.can();\n\n return (\n <div className=\"fe-toolbar fe-toolbar--table\" role=\"toolbar\" aria-label=\"Table tools\">\n <span className=\"fe-toolbar__caption\">Table</span>\n <ToolbarButton icon={BetweenHorizontalStart} label=\"Insert row above\" disabled={disabled} onClick={run((c) => c.addRowBefore())} />\n <ToolbarButton icon={BetweenHorizontalEnd} label=\"Insert row below\" disabled={disabled} onClick={run((c) => c.addRowAfter())} />\n <ToolbarButton icon={BetweenVerticalStart} label=\"Insert column left\" disabled={disabled} onClick={run((c) => c.addColumnBefore())} />\n <ToolbarButton icon={BetweenVerticalEnd} label=\"Insert column right\" disabled={disabled} onClick={run((c) => c.addColumnAfter())} />\n <Divider />\n <ToolbarButton icon={Rows3} label=\"Delete row\" disabled={disabled} onClick={run((c) => c.deleteRow())} />\n <ToolbarButton icon={Columns3} label=\"Delete column\" disabled={disabled} onClick={run((c) => c.deleteColumn())} />\n <ToolbarButton icon={Trash2} label=\"Delete table\" disabled={disabled} onClick={run((c) => c.deleteTable())} />\n <Divider />\n <ToolbarButton icon={TableCellsMerge} label=\"Merge cells\" disabled={disabled || !can.mergeCells()} onClick={run((c) => c.mergeCells())} />\n <ToolbarButton icon={SquareSplitHorizontal} label=\"Split cell\" disabled={disabled || !can.splitCell()} onClick={run((c) => c.splitCell())} />\n <ToolbarButton icon={PanelTop} label=\"Toggle header row\" disabled={disabled} onClick={run((c) => c.toggleHeaderRow())} />\n <Divider />\n <ColorButton\n icon={PaintBucket}\n label=\"Cell shading\"\n clearLabel=\"No fill\"\n color={state.cellBackground}\n disabled={disabled}\n onPick={(color) => editor.chain().focus().setCellAttribute('backgroundColor', color).run()}\n onClear={() => editor.chain().focus().setCellAttribute('backgroundColor', null).run()}\n />\n {VALIGN.map(({ value, icon, label }) => (\n <ToolbarButton\n key={value}\n icon={icon}\n label={label}\n active={state.cellVerticalAlign === value}\n disabled={disabled}\n onClick={run((c) => c.setCellAttribute('verticalAlign', value))}\n />\n ))}\n <MenuButton\n icon={AllBordersIcon}\n label=\"Borders\"\n items={borderItems(state.tableBorders)}\n showChecks\n disabled={disabled}\n onSelect={(mode) => editor.chain().focus().setTableBorders(mode).run()}\n />\n </div>\n );\n};\n\nexport default TableTools;\n","import { matchSpacingPreset } from '../extensions/paragraphFormat';\nimport { getTableBorderState } from '../extensions/tableBorders';\n\nconst blockTypeOf = (editor) => {\n for (let level = 1; level <= 4; level += 1) {\n if (editor.isActive('heading', { level })) return `h${level}`;\n }\n return 'paragraph';\n};\n\nconst currentBlockAttrs = (editor) => {\n const { $from } = editor.state.selection;\n for (let d = $from.depth; d >= 0; d -= 1) {\n const node = $from.node(d);\n if (node.type.name === 'paragraph' || node.type.name === 'heading') return node.attrs;\n }\n return {};\n};\n\nconst currentCellAttrs = (editor) => {\n const { $from } = editor.state.selection;\n for (let d = $from.depth; d >= 0; d -= 1) {\n const node = $from.node(d);\n if (node.type.name === 'tableCell' || node.type.name === 'tableHeader') return node.attrs;\n }\n return null;\n};\n\nexport const selectToolbarState = ({ editor }) => {\n if (!editor) return {};\n const textStyle = editor.getAttributes('textStyle');\n const block = currentBlockAttrs(editor);\n const cell = currentCellAttrs(editor);\n return {\n bold: editor.isActive('bold'),\n italic: editor.isActive('italic'),\n underline: editor.isActive('underline'),\n strike: editor.isActive('strike'),\n subscript: editor.isActive('subscript'),\n superscript: editor.isActive('superscript'),\n bulletList: editor.isActive('bulletList'),\n orderedList: editor.isActive('orderedList'),\n link: editor.isActive('link'),\n blockType: blockTypeOf(editor),\n textAlign: block.textAlign || 'left',\n lineHeight: block.lineHeight || null,\n paragraphSpacing: matchSpacingPreset(block),\n fontFamily: textStyle.fontFamily || '',\n fontSize: textStyle.fontSize || '',\n color: textStyle.color || null,\n backgroundColor: textStyle.backgroundColor || null,\n canUndo: editor.can().undo(),\n canRedo: editor.can().redo(),\n inTable: !!cell,\n cellBackground: cell?.backgroundColor || null,\n cellVerticalAlign: cell?.verticalAlign || null,\n tableBorders: cell ? getTableBorderState(editor.state) : null,\n };\n};\n"]}