@arbidocs/blocks 0.5.106 → 0.5.107
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/README.md +60 -6
- package/dist/{ConnectedCallDock-P7LK2HYF.cjs → ConnectedCallDock-H3WWFGXF.cjs} +8 -8
- package/dist/{ConnectedCallDock-P7LK2HYF.cjs.map → ConnectedCallDock-H3WWFGXF.cjs.map} +1 -1
- package/dist/{ConnectedCallDock-NEZJNTKH.js → ConnectedCallDock-TDYRHPAK.js} +6 -6
- package/dist/{ConnectedCallDock-NEZJNTKH.js.map → ConnectedCallDock-TDYRHPAK.js.map} +1 -1
- package/dist/{ConnectedCallRoom-FXTR4YFI.cjs → ConnectedCallRoom-55O5OUN7.cjs} +7 -7
- package/dist/{ConnectedCallRoom-FXTR4YFI.cjs.map → ConnectedCallRoom-55O5OUN7.cjs.map} +1 -1
- package/dist/{ConnectedCallRoom-K3X6ICCG.js → ConnectedCallRoom-Z6F6WCLH.js} +6 -6
- package/dist/{ConnectedCallRoom-K3X6ICCG.js.map → ConnectedCallRoom-Z6F6WCLH.js.map} +1 -1
- package/dist/{ConnectedNativeDocxComparison-7VJKOKYU.cjs → ConnectedNativeDocxComparison-DGBZJ4XA.cjs} +10 -10
- package/dist/{ConnectedNativeDocxComparison-7VJKOKYU.cjs.map → ConnectedNativeDocxComparison-DGBZJ4XA.cjs.map} +1 -1
- package/dist/{ConnectedNativeDocxComparison-FENZYWDH.js → ConnectedNativeDocxComparison-NVZRVNOS.js} +9 -9
- package/dist/{ConnectedNativeDocxComparison-FENZYWDH.js.map → ConnectedNativeDocxComparison-NVZRVNOS.js.map} +1 -1
- package/dist/{ConnectedNativeDocxEditor-HB5BHGZ2.cjs → ConnectedNativeDocxEditor-R4WINUUB.cjs} +10 -10
- package/dist/{ConnectedNativeDocxEditor-HB5BHGZ2.cjs.map → ConnectedNativeDocxEditor-R4WINUUB.cjs.map} +1 -1
- package/dist/{ConnectedNativeDocxEditor-CNQAMO2N.js → ConnectedNativeDocxEditor-RSVBN7DY.js} +8 -8
- package/dist/{ConnectedNativeDocxEditor-CNQAMO2N.js.map → ConnectedNativeDocxEditor-RSVBN7DY.js.map} +1 -1
- package/dist/{ConnectedProductionSetDialog-O4FWTZNF.js → ConnectedProductionSetDialog-2DFBXE2X.js} +5 -5
- package/dist/{ConnectedProductionSetDialog-O4FWTZNF.js.map → ConnectedProductionSetDialog-2DFBXE2X.js.map} +1 -1
- package/dist/{ConnectedProductionSetDialog-ENAIZWPK.cjs → ConnectedProductionSetDialog-KYDPQ7SG.cjs} +6 -6
- package/dist/{ConnectedProductionSetDialog-ENAIZWPK.cjs.map → ConnectedProductionSetDialog-KYDPQ7SG.cjs.map} +1 -1
- package/dist/{ConnectedStreamedWordArtifact-ILMKFCDC.js → ConnectedStreamedWordArtifact-HLJ5IIOU.js} +9 -9
- package/dist/ConnectedStreamedWordArtifact-HLJ5IIOU.js.map +1 -0
- package/dist/{ConnectedStreamedWordArtifact-BF6JET2D.cjs → ConnectedStreamedWordArtifact-JQ34AOUU.cjs} +10 -10
- package/dist/ConnectedStreamedWordArtifact-JQ34AOUU.cjs.map +1 -0
- package/dist/{DocumentReviewCard-UOLXZKZE.js → DocumentReviewCard-7JSXRJZ2.js} +6 -6
- package/dist/{DocumentReviewCard-UOLXZKZE.js.map → DocumentReviewCard-7JSXRJZ2.js.map} +1 -1
- package/dist/{DocumentReviewCard-QVQ2LGFH.cjs → DocumentReviewCard-C4HVT3WM.cjs} +8 -8
- package/dist/{DocumentReviewCard-QVQ2LGFH.cjs.map → DocumentReviewCard-C4HVT3WM.cjs.map} +1 -1
- package/dist/{FilesViewerDialog-5ELQYWAZ.js → FilesViewerDialog-IMQTZWKD.js} +16 -16
- package/dist/{FilesViewerDialog-5ELQYWAZ.js.map → FilesViewerDialog-IMQTZWKD.js.map} +1 -1
- package/dist/{FilesViewerDialog-XNGHHWYS.cjs → FilesViewerDialog-UP7GFHYN.cjs} +23 -23
- package/dist/{FilesViewerDialog-XNGHHWYS.cjs.map → FilesViewerDialog-UP7GFHYN.cjs.map} +1 -1
- package/dist/{RechartsRenderer-EJRIFAAP.js → RechartsRenderer-23OF4H6X.js} +3 -3
- package/dist/{RechartsRenderer-EJRIFAAP.js.map → RechartsRenderer-23OF4H6X.js.map} +1 -1
- package/dist/{RechartsRenderer-CNFQ5EHF.cjs → RechartsRenderer-GIRCW7DB.cjs} +4 -4
- package/dist/{RechartsRenderer-CNFQ5EHF.cjs.map → RechartsRenderer-GIRCW7DB.cjs.map} +1 -1
- package/dist/{WorkspaceTableView-HRCV6WR7.cjs → WorkspaceTableView-PJM47B5F.cjs} +8 -8
- package/dist/{WorkspaceTableView-HRCV6WR7.cjs.map → WorkspaceTableView-PJM47B5F.cjs.map} +1 -1
- package/dist/{WorkspaceTableView-DIMTW5P5.js → WorkspaceTableView-YDA7A4UJ.js} +6 -6
- package/dist/{WorkspaceTableView-DIMTW5P5.js.map → WorkspaceTableView-YDA7A4UJ.js.map} +1 -1
- package/dist/{ai-E6FA4Y4J.cjs → ai-ADS6YSS2.cjs} +17 -17
- package/dist/ai-ADS6YSS2.cjs.map +1 -0
- package/dist/{ai-WASSGEMI.js → ai-KHWTGBT5.js} +9 -9
- package/dist/ai-KHWTGBT5.js.map +1 -0
- package/dist/auth/index.cjs +32 -32
- package/dist/auth/index.js +1 -1
- package/dist/calls/index.cjs +49 -49
- package/dist/calls/index.js +10 -10
- package/dist/{chunk-VJAMDAR6.cjs → chunk-22KAKJ3W.cjs} +4 -4
- package/dist/{chunk-VJAMDAR6.cjs.map → chunk-22KAKJ3W.cjs.map} +1 -1
- package/dist/{chunk-DEIF2VAA.js → chunk-3GFQNJYE.js} +3 -3
- package/dist/{chunk-DEIF2VAA.js.map → chunk-3GFQNJYE.js.map} +1 -1
- package/dist/{chunk-LUO46ELJ.cjs → chunk-3YZKDCWY.cjs} +2 -2
- package/dist/chunk-3YZKDCWY.cjs.map +1 -0
- package/dist/{chunk-5OUOPKGE.cjs → chunk-45OU2UAA.cjs} +18 -18
- package/dist/{chunk-5OUOPKGE.cjs.map → chunk-45OU2UAA.cjs.map} +1 -1
- package/dist/{chunk-JXKNPKU6.cjs → chunk-4CIVQWAX.cjs} +4 -4
- package/dist/{chunk-JXKNPKU6.cjs.map → chunk-4CIVQWAX.cjs.map} +1 -1
- package/dist/{chunk-VOI26MXJ.cjs → chunk-5AC52BHL.cjs} +16 -16
- package/dist/{chunk-VOI26MXJ.cjs.map → chunk-5AC52BHL.cjs.map} +1 -1
- package/dist/{chunk-OG3TI5GX.js → chunk-6M5NAAWX.js} +47 -5
- package/dist/chunk-6M5NAAWX.js.map +1 -0
- package/dist/{chunk-IIUEDF3F.js → chunk-6ZYOUT73.js} +7 -7
- package/dist/{chunk-IIUEDF3F.js.map → chunk-6ZYOUT73.js.map} +1 -1
- package/dist/{chunk-TRI3LQVR.js → chunk-7S7YVBFK.js} +5 -5
- package/dist/{chunk-TRI3LQVR.js.map → chunk-7S7YVBFK.js.map} +1 -1
- package/dist/{chunk-QN5GTCPB.cjs → chunk-7V4OCZS6.cjs} +8 -8
- package/dist/{chunk-QN5GTCPB.cjs.map → chunk-7V4OCZS6.cjs.map} +1 -1
- package/dist/{chunk-S7NJVJJX.cjs → chunk-AHMRYY7J.cjs} +25 -25
- package/dist/{chunk-S7NJVJJX.cjs.map → chunk-AHMRYY7J.cjs.map} +1 -1
- package/dist/{chunk-GK5BMDS6.js → chunk-AVGHTUPE.js} +4 -4
- package/dist/{chunk-GK5BMDS6.js.map → chunk-AVGHTUPE.js.map} +1 -1
- package/dist/{chunk-RAYNCZ7O.js → chunk-AZCMKGDG.js} +3 -3
- package/dist/{chunk-RAYNCZ7O.js.map → chunk-AZCMKGDG.js.map} +1 -1
- package/dist/{chunk-IJVU5MZA.js → chunk-BAUZUIHB.js} +5 -5
- package/dist/{chunk-IJVU5MZA.js.map → chunk-BAUZUIHB.js.map} +1 -1
- package/dist/{chunk-2VHZUSFW.js → chunk-BBWLFK3C.js} +3 -3
- package/dist/{chunk-2VHZUSFW.js.map → chunk-BBWLFK3C.js.map} +1 -1
- package/dist/{chunk-MW7FGIF4.cjs → chunk-BFVCYBND.cjs} +9 -9
- package/dist/{chunk-MW7FGIF4.cjs.map → chunk-BFVCYBND.cjs.map} +1 -1
- package/dist/{chunk-7ONU7EWY.js → chunk-BH6IKGZ3.js} +5 -5
- package/dist/{chunk-7ONU7EWY.js.map → chunk-BH6IKGZ3.js.map} +1 -1
- package/dist/{chunk-RNX5LAQK.cjs → chunk-C42WBPH4.cjs} +7 -7
- package/dist/{chunk-RNX5LAQK.cjs.map → chunk-C42WBPH4.cjs.map} +1 -1
- package/dist/{chunk-LM5CPXJO.cjs → chunk-CRLFLMTK.cjs} +19 -13
- package/dist/chunk-CRLFLMTK.cjs.map +1 -0
- package/dist/{chunk-CWC6W2NE.cjs → chunk-D35EHOK5.cjs} +11 -11
- package/dist/{chunk-CWC6W2NE.cjs.map → chunk-D35EHOK5.cjs.map} +1 -1
- package/dist/{chunk-BMHW7WTF.js → chunk-DBKZANTC.js} +4 -4
- package/dist/{chunk-BMHW7WTF.js.map → chunk-DBKZANTC.js.map} +1 -1
- package/dist/{chunk-Q5U6Y2NO.js → chunk-E2P4JJLJ.js} +4 -45
- package/dist/chunk-E2P4JJLJ.js.map +1 -0
- package/dist/{chunk-D3GZWKHW.cjs → chunk-EKSHUNJI.cjs} +9 -9
- package/dist/{chunk-D3GZWKHW.cjs.map → chunk-EKSHUNJI.cjs.map} +1 -1
- package/dist/{chunk-5XQNXDST.js → chunk-FPOKWML2.js} +18 -5
- package/dist/chunk-FPOKWML2.js.map +1 -0
- package/dist/{chunk-M4TM3K52.cjs → chunk-FSXQHEFQ.cjs} +16 -16
- package/dist/{chunk-M4TM3K52.cjs.map → chunk-FSXQHEFQ.cjs.map} +1 -1
- package/dist/{chunk-35BADIIF.cjs → chunk-GX75YCWJ.cjs} +23 -23
- package/dist/{chunk-35BADIIF.cjs.map → chunk-GX75YCWJ.cjs.map} +1 -1
- package/dist/{chunk-7IF3E3I2.cjs → chunk-I7CJDF3V.cjs} +4 -4
- package/dist/{chunk-7IF3E3I2.cjs.map → chunk-I7CJDF3V.cjs.map} +1 -1
- package/dist/{chunk-KYLQRS3O.js → chunk-IHOV6OTA.js} +4 -4
- package/dist/{chunk-KYLQRS3O.js.map → chunk-IHOV6OTA.js.map} +1 -1
- package/dist/{chunk-OXHAZN43.cjs → chunk-IXL2KJOZ.cjs} +26 -26
- package/dist/{chunk-OXHAZN43.cjs.map → chunk-IXL2KJOZ.cjs.map} +1 -1
- package/dist/{chunk-632JXVXY.js → chunk-KIXFXCHL.js} +15 -9
- package/dist/chunk-KIXFXCHL.js.map +1 -0
- package/dist/{chunk-PIWT2GCY.cjs → chunk-LFYKB7KF.cjs} +15 -15
- package/dist/{chunk-PIWT2GCY.cjs.map → chunk-LFYKB7KF.cjs.map} +1 -1
- package/dist/{chunk-7Q6EVFMT.js → chunk-LYW5A35J.js} +9 -9
- package/dist/{chunk-7Q6EVFMT.js.map → chunk-LYW5A35J.js.map} +1 -1
- package/dist/chunk-NFK2SEUD.js +577 -0
- package/dist/chunk-NFK2SEUD.js.map +1 -0
- package/dist/{chunk-TJQMC7GJ.cjs → chunk-NNBL3HPG.cjs} +4 -4
- package/dist/{chunk-TJQMC7GJ.cjs.map → chunk-NNBL3HPG.cjs.map} +1 -1
- package/dist/{chunk-Y5P5ZMHQ.js → chunk-NWBCZ4PA.js} +4 -4
- package/dist/{chunk-Y5P5ZMHQ.js.map → chunk-NWBCZ4PA.js.map} +1 -1
- package/dist/{chunk-5UMZXDGL.cjs → chunk-O27K7KTZ.cjs} +161 -7
- package/dist/chunk-O27K7KTZ.cjs.map +1 -0
- package/dist/{chunk-GARDQALH.js → chunk-OLAYDOPC.js} +5 -5
- package/dist/{chunk-GARDQALH.js.map → chunk-OLAYDOPC.js.map} +1 -1
- package/dist/chunk-ORELHENJ.cjs +594 -0
- package/dist/chunk-ORELHENJ.cjs.map +1 -0
- package/dist/{chunk-NUOMPVKQ.js → chunk-OWHO2TO3.js} +3 -3
- package/dist/{chunk-NUOMPVKQ.js.map → chunk-OWHO2TO3.js.map} +1 -1
- package/dist/{chunk-6XNWGOS3.cjs → chunk-PHDUN4SG.cjs} +187 -80
- package/dist/chunk-PHDUN4SG.cjs.map +1 -0
- package/dist/{chunk-KGUBKE3V.cjs → chunk-PL7O3RJJ.cjs} +48 -4
- package/dist/chunk-PL7O3RJJ.cjs.map +1 -0
- package/dist/{chunk-BH4MK2J5.js → chunk-QG6MRLZG.js} +2 -2
- package/dist/chunk-QG6MRLZG.js.map +1 -0
- package/dist/{chunk-YPTZNQPJ.cjs → chunk-RCZRI72J.cjs} +4 -4
- package/dist/{chunk-YPTZNQPJ.cjs.map → chunk-RCZRI72J.cjs.map} +1 -1
- package/dist/{chunk-E7STRFBT.cjs → chunk-SCLGUHLU.cjs} +4 -4
- package/dist/{chunk-E7STRFBT.cjs.map → chunk-SCLGUHLU.cjs.map} +1 -1
- package/dist/{chunk-EOTJX536.js → chunk-T5ZMG6MC.js} +3 -3
- package/dist/{chunk-EOTJX536.js.map → chunk-T5ZMG6MC.js.map} +1 -1
- package/dist/{chunk-LWEX3AOZ.js → chunk-TG4IICWO.js} +4 -4
- package/dist/{chunk-LWEX3AOZ.js.map → chunk-TG4IICWO.js.map} +1 -1
- package/dist/{chunk-ET3W24JV.js → chunk-TNKPQ3EF.js} +9 -9
- package/dist/{chunk-ET3W24JV.js.map → chunk-TNKPQ3EF.js.map} +1 -1
- package/dist/{chunk-QFKL4HV2.js → chunk-U5F5P4YU.js} +118 -15
- package/dist/chunk-U5F5P4YU.js.map +1 -0
- package/dist/{chunk-N52PBUAP.cjs → chunk-U6LQ6Z3P.cjs} +10 -10
- package/dist/{chunk-N52PBUAP.cjs.map → chunk-U6LQ6Z3P.cjs.map} +1 -1
- package/dist/{chunk-JNVJQCGF.cjs → chunk-UCA4JLLJ.cjs} +4 -4
- package/dist/{chunk-JNVJQCGF.cjs.map → chunk-UCA4JLLJ.cjs.map} +1 -1
- package/dist/{chunk-3RUQHIDC.js → chunk-UQ2OBHMV.js} +7 -7
- package/dist/{chunk-3RUQHIDC.js.map → chunk-UQ2OBHMV.js.map} +1 -1
- package/dist/{chunk-VYJF4ZQY.cjs → chunk-V6C2MBFY.cjs} +3 -2
- package/dist/chunk-V6C2MBFY.cjs.map +1 -0
- package/dist/{chunk-O4X7HXLF.cjs → chunk-VCEX7COE.cjs} +2 -45
- package/dist/chunk-VCEX7COE.cjs.map +1 -0
- package/dist/{chunk-QTSNHGSI.js → chunk-WFM6E7DD.js} +3 -3
- package/dist/{chunk-QTSNHGSI.js.map → chunk-WFM6E7DD.js.map} +1 -1
- package/dist/{chunk-SY2WD6VA.cjs → chunk-WI3BVKEC.cjs} +5 -5
- package/dist/{chunk-SY2WD6VA.cjs.map → chunk-WI3BVKEC.cjs.map} +1 -1
- package/dist/{chunk-LWCLAAEX.js → chunk-WJHRWXWJ.js} +3 -3
- package/dist/{chunk-LWCLAAEX.js.map → chunk-WJHRWXWJ.js.map} +1 -1
- package/dist/{chunk-FVZ2CN4A.js → chunk-WQH2WWZE.js} +3 -2
- package/dist/chunk-WQH2WWZE.js.map +1 -0
- package/dist/{chunk-V2CKYM4B.cjs → chunk-XHN5KOI2.cjs} +9 -9
- package/dist/{chunk-V2CKYM4B.cjs.map → chunk-XHN5KOI2.cjs.map} +1 -1
- package/dist/{chunk-DBHBJIF4.js → chunk-YJWAGXYM.js} +3 -3
- package/dist/{chunk-DBHBJIF4.js.map → chunk-YJWAGXYM.js.map} +1 -1
- package/dist/{chunk-KUI2IC7W.js → chunk-YLKHTBYA.js} +3 -3
- package/dist/{chunk-KUI2IC7W.js.map → chunk-YLKHTBYA.js.map} +1 -1
- package/dist/{chunk-73FJ6L6I.cjs → chunk-ZMVF7EYJ.cjs} +18 -5
- package/dist/chunk-ZMVF7EYJ.cjs.map +1 -0
- package/dist/{chunk-CEVVGJQX.js → chunk-ZNY5W3VX.js} +162 -9
- package/dist/chunk-ZNY5W3VX.js.map +1 -0
- package/dist/connect/docx.cjs +13 -13
- package/dist/connect/docx.js +9 -9
- package/dist/connect/index.cjs +1100 -884
- package/dist/connect/index.cjs.map +1 -1
- package/dist/connect/index.d.ts +1 -0
- package/dist/connect/index.js +475 -274
- package/dist/connect/index.js.map +1 -1
- package/dist/connect/viewer.cjs +12 -12
- package/dist/connect/viewer.js +10 -10
- package/dist/connection/account-cluster/ConnectedAccountCluster.d.ts +1 -1
- package/dist/connection/dashboards/ConnectedDashboardsPage.d.ts +13 -2
- package/dist/connection/dashboards/index.d.ts +1 -1
- package/dist/connection/dashboards/templates.d.ts +14 -3
- package/dist/connection/remote-control/ConnectedRemoteControlConsent.d.ts +17 -0
- package/dist/connection/remote-control/ConnectedRemoteControlIndicator.d.ts +8 -0
- package/dist/connection/remote-control/ConnectedRemoteControlSwitch.d.ts +1 -0
- package/dist/connection/remote-control/index.d.ts +4 -0
- package/dist/connection/remote-control/remoteControl.d.ts +40 -0
- package/dist/connection/routes/useDeepLinkSync.d.ts +4 -1
- package/dist/connection/runtime/ConnectedAppRuntime.d.ts +1 -1
- package/dist/connection/settings-page/settingsSections.d.ts +1 -1
- package/dist/connection/tags/ConnectedTagTable.d.ts +1 -1
- package/dist/dashboards/index.cjs +327 -116
- package/dist/dashboards/index.cjs.map +1 -1
- package/dist/dashboards/index.js +311 -101
- package/dist/dashboards/index.js.map +1 -1
- package/dist/embed/index.cjs +21 -21
- package/dist/embed/index.js +14 -14
- package/dist/guided/GuidedCursor.d.ts +21 -0
- package/dist/guided/cursor.d.ts +56 -0
- package/dist/guided/index.d.ts +5 -0
- package/dist/guided/runner.d.ts +30 -0
- package/dist/guided/sequences.d.ts +80 -0
- package/dist/guided/surfaces.d.ts +13 -0
- package/dist/guided/useGuidedRuns.d.ts +3 -0
- package/dist/index.cjs +171 -135
- package/dist/index.d.ts +1 -0
- package/dist/index.js +7 -7
- package/dist/provider/host.d.ts +6 -0
- package/dist/settings/PlanBadge.d.ts +1 -1
- package/dist/settings/TipsEditor.d.ts +6 -3
- package/dist/settings/index.cjs +152 -151
- package/dist/settings/index.js +3 -2
- package/dist/shell/index.cjs +46 -46
- package/dist/shell/index.js +3 -3
- package/dist/studio/index.cjs +15 -15
- package/dist/studio/index.js +9 -9
- package/dist/styles.css +1 -1
- package/dist/workflow-canvas/index.cjs +25 -25
- package/dist/workflow-canvas/index.js +13 -13
- package/node_modules/@arbidocs/coedit/package.json +1 -1
- package/package.json +5 -5
- package/dist/ConnectedStreamedWordArtifact-BF6JET2D.cjs.map +0 -1
- package/dist/ConnectedStreamedWordArtifact-ILMKFCDC.js.map +0 -1
- package/dist/ai-E6FA4Y4J.cjs.map +0 -1
- package/dist/ai-WASSGEMI.js.map +0 -1
- package/dist/chunk-5UMZXDGL.cjs.map +0 -1
- package/dist/chunk-5XQNXDST.js.map +0 -1
- package/dist/chunk-632JXVXY.js.map +0 -1
- package/dist/chunk-6XNWGOS3.cjs.map +0 -1
- package/dist/chunk-73FJ6L6I.cjs.map +0 -1
- package/dist/chunk-BH4MK2J5.js.map +0 -1
- package/dist/chunk-C4TGESIB.cjs +0 -260
- package/dist/chunk-C4TGESIB.cjs.map +0 -1
- package/dist/chunk-CEVVGJQX.js.map +0 -1
- package/dist/chunk-FVZ2CN4A.js.map +0 -1
- package/dist/chunk-KGUBKE3V.cjs.map +0 -1
- package/dist/chunk-LM5CPXJO.cjs.map +0 -1
- package/dist/chunk-LUO46ELJ.cjs.map +0 -1
- package/dist/chunk-MHFWGIF4.js +0 -254
- package/dist/chunk-MHFWGIF4.js.map +0 -1
- package/dist/chunk-O4X7HXLF.cjs.map +0 -1
- package/dist/chunk-OG3TI5GX.js.map +0 -1
- package/dist/chunk-Q5U6Y2NO.js.map +0 -1
- package/dist/chunk-QFKL4HV2.js.map +0 -1
- package/dist/chunk-VYJF4ZQY.cjs.map +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/dashboards/chartModel.ts"],"names":[],"mappings":"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","file":"chunk-73FJ6L6I.cjs","sourcesContent":["/**\n * The renderer adapter's first half: a `ChartSpec` and its aggregated `Dataset` (long form: a row\n * per group and series) become a `ChartModel`, the categories and series a drawing component plots.\n * Nothing here knows the drawing library, so it can change without touching specs or sources.\n */\nimport type {\n AGGREGATE_FIELDS,\n ChartSpec,\n Dataset,\n DatasetField,\n DatasetValue,\n TimeBucket,\n} from '@arbidocs/react'\n\n/** The aggregated dataset's field ids (`@arbidocs/react`'s `AGGREGATE_FIELDS`, checked). */\nconst F = {\n group: 'group',\n key: 'key',\n series: 'series',\n value: 'value',\n} as const satisfies typeof AGGREGATE_FIELDS\n\n/** The drawing types (a metric and a table are not drawn). */\nexport type DrawnChartType = 'bar' | 'line' | 'area' | 'pie' | 'donut'\n\nexport interface ChartModelSeries {\n id: string\n label: string\n /** One per category; `null` where the group has no value. */\n values: (number | null)[]\n /** The series' colour as a CSS value (a theme token). */\n color: string\n}\n\n/** What a chart plots, library-free. */\nexport interface ChartModel {\n type: DrawnChartType\n stacked: boolean\n /** Category labels, in order (x axis, or pie slices). */\n categories: string[]\n series: ChartModelSeries[]\n /** The x axis's name (the grouped field). */\n xLabel: string\n /** The value's name (\"count\", \"sum of Fee\"). */\n valueLabel: string\n /** Formats a value for ticks, the tooltip and the table. */\n format: (value: number) => string\n /** Short form of `format` for axis ticks. */\n formatTick: (value: number) => string\n}\n\n/** Formats by unit (`gbp`, `bytes`, `tokens`, …); a host passes its own (the SDK's £ formatter). */\nexport type UnitFormatters = Readonly<Record<string, (value: number) => string>>\n\n/** The theme's series colours, then a muted \"Other\". */\nexport const SERIES_COLORS = [1, 2, 3, 4, 5].map((i) => `hsl(var(--chart-${i}))`)\nexport const OTHER_COLOR = 'hsl(var(--muted-foreground))'\n\nconst MONTHS = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']\n\n/** A date bucket key as people read it: \"12 Jun 2026\", \"W24 2026\", \"Jun 2026\", \"Q2 2026\", \"2026\". */\nexport function formatBucketLabel(key: string, bucket: TimeBucket = 'month'): string {\n let m: RegExpMatchArray | null\n if (bucket === 'day' && (m = key.match(/^(\\d{4})-(\\d{2})-(\\d{2})$/)))\n return `${Number(m[3])} ${MONTHS[Number(m[2]) - 1]} ${m[1]}`\n if (bucket === 'week' && (m = key.match(/^(\\d{4})-W(\\d{2})$/))) return `W${Number(m[2])} ${m[1]}`\n if (bucket === 'month' && (m = key.match(/^(\\d{4})-(\\d{2})$/)))\n return `${MONTHS[Number(m[2]) - 1]} ${m[1]}`\n if (bucket === 'quarter' && (m = key.match(/^(\\d{4})-Q(\\d)$/))) return `Q${m[2]} ${m[1]}`\n return key\n}\n\nconst compact = new Intl.NumberFormat('en-GB', { notation: 'compact', maximumFractionDigits: 1 })\nconst plain = new Intl.NumberFormat('en-GB', { maximumFractionDigits: 2 })\n\n/** The default formatters: £ with pence, bytes in KB/MB/GB, tokens compact. */\nexport const DEFAULT_UNIT_FORMATTERS: UnitFormatters = {\n gbp: (v) =>\n `${v < 0 ? '-' : ''}£${Math.abs(v).toLocaleString('en-GB', {\n minimumFractionDigits: Number.isInteger(v) ? 0 : 2,\n maximumFractionDigits: 2,\n })}`,\n bytes: (v) =>\n v < 1024\n ? `${v} B`\n : v < 1024 ** 2\n ? `${(v / 1024).toFixed(1)} KB`\n : v < 1024 ** 3\n ? `${(v / 1024 ** 2).toFixed(1)} MB`\n : `${(v / 1024 ** 3).toFixed(1)} GB`,\n tokens: (v) => compact.format(v),\n}\n\n/** The formatter of a value field: by its unit, a suffix for any other unit, else a number. */\nexport function formatterOf(\n field: Pick<DatasetField, 'unit'> | undefined,\n formatters: UnitFormatters = DEFAULT_UNIT_FORMATTERS\n): (value: number) => string {\n const unit = field?.unit\n if (!unit) return (v) => plain.format(v)\n const known = formatters[unit] ?? DEFAULT_UNIT_FORMATTERS[unit]\n return known ?? ((v) => `${plain.format(v)} ${unit}`)\n}\n\n/** The most series (or pie slices) drawn in their own colour; the rest fold into \"Other\". */\nexport const MAX_COLORED = SERIES_COLORS.length\n\nconst additive = (spec: ChartSpec) =>\n (spec.aggregate ?? 'count') === 'count' || spec.aggregate === 'sum'\n\nconst num = (v: DatasetValue | undefined) => (typeof v === 'number' ? v : null)\n\nexport interface ChartModelOptions {\n /** The source's fields, for the x axis's name. */\n fields?: readonly DatasetField[]\n formatters?: UnitFormatters\n /** The words for the folded series and slices. Default \"Other\". */\n otherLabel?: string\n}\n\n/**\n * Turn an aggregated dataset into what a chart plots. Series (and pie slices) beyond the theme's\n * colours fold into \"Other\" when the values add up (count, sum); otherwise the smallest are left out.\n */\nexport function chartModelOf(\n spec: ChartSpec & { type: DrawnChartType },\n dataset: Dataset,\n options: ChartModelOptions = {}\n): ChartModel {\n const other = options.otherLabel ?? 'Other'\n const valueField = dataset.fields.find((f) => f.id === F.value)\n const xField = options.fields?.find((f) => f.id === spec.x)\n const isDate = xField?.type === 'date'\n const keys: string[] = []\n const labels = new Map<string, string>()\n const seriesIds: string[] = []\n const cells = new Map<string, number | null>()\n for (const row of dataset.rows) {\n const key = String(row[F.key] ?? row[F.group] ?? '')\n if (!labels.has(key)) {\n keys.push(key)\n const label = String(row[F.group] ?? key)\n labels.set(key, isDate && key ? formatBucketLabel(key, spec.bucket) : label)\n }\n const s = row[F.series] === undefined ? '' : String(row[F.series])\n if (!seriesIds.includes(s)) seriesIds.push(s)\n cells.set(`${key}\\u0000${s}`, num(row[F.value]))\n }\n const valueLabel = valueField?.label ?? 'value'\n let series = seriesIds.map((s) => ({\n id: s || F.value,\n label: s || valueLabel,\n values: keys.map((k) => cells.get(`${k}\\u0000${s}`) ?? null),\n }))\n let categories = keys.map((k) => labels.get(k) ?? k)\n const sum = (values: (number | null)[]) => values.reduce<number>((a, v) => a + (v ?? 0), 0)\n\n if (spec.type === 'pie' || spec.type === 'donut') {\n const values = series[0]?.values ?? []\n if (categories.length > MAX_COLORED) {\n const order = values.map((_, i) => i).sort((a, b) => (values[b] ?? 0) - (values[a] ?? 0))\n const kept = order.slice(0, MAX_COLORED - 1)\n const rest = order.slice(MAX_COLORED - 1)\n categories = [...kept.map((i) => categories[i]), ...(additive(spec) ? [other] : [])]\n const keptValues = kept.map((i) => values[i])\n series = [\n {\n ...series[0],\n values: additive(spec) ? [...keptValues, sum(rest.map((i) => values[i]))] : keptValues,\n },\n ]\n }\n } else if (series.length > MAX_COLORED) {\n const order = [...series].sort((a, b) => sum(b.values) - sum(a.values))\n const kept = order.slice(0, MAX_COLORED - 1)\n const rest = order.slice(MAX_COLORED - 1)\n series = [\n ...series.filter((s) => kept.includes(s)),\n ...(additive(spec)\n ? [\n {\n id: '__other',\n label: other,\n values: keys.map((_, i) =>\n rest.some((s) => s.values[i] !== null) ? sum(rest.map((s) => s.values[i])) : null\n ),\n },\n ]\n : []),\n ]\n }\n\n const format = formatterOf(valueField, options.formatters)\n return {\n type: spec.type,\n stacked: Boolean(spec.stacked) && (spec.type === 'bar' || spec.type === 'area'),\n categories,\n series: series.map((s, i) => ({\n ...s,\n color: s.id === '__other' ? OTHER_COLOR : SERIES_COLORS[i % SERIES_COLORS.length],\n })),\n xLabel: xField?.label ?? '',\n valueLabel,\n format,\n formatTick:\n valueField?.unit === 'gbp' || valueField?.unit === 'bytes'\n ? format\n : (v) => compact.format(v),\n }\n}\n\n/** The pie slice colours (one per category; \"Other\" muted). */\nexport function sliceColors(model: Pick<ChartModel, 'categories'>, otherLabel = 'Other') {\n return model.categories.map((c, i) =>\n c === otherLabel && i === model.categories.length - 1 && i >= MAX_COLORED - 1\n ? OTHER_COLOR\n : SERIES_COLORS[i % SERIES_COLORS.length]\n )\n}\n\n/** The single value of a metric (an aggregated dataset with one group), or null. */\nexport function metricValueOf(dataset: Dataset | undefined): number | null {\n if (!dataset?.rows.length) return null\n return dataset.rows.reduce<number | null>((total, row) => {\n const v = num(row[F.value])\n return v === null ? total : (total ?? 0) + v\n }, null)\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/provider/host.ts"],"names":["GenericArbiHost"],"mappings":";;;AAwDO,IAAM,QAAA,GAAmEA;AAGzE,SAAS,OAAA,GAA0B;AACxC,EAAA,OAAO,mBAAA,EAAoB;AAC7B","file":"chunk-BH4MK2J5.js","sourcesContent":["/**\n * The host configuration of `@arbidocs/blocks`: the `@arbidocs/react` domains plus the blocks ones,\n * handed over once:\n *\n * <ArbiHost config={{ arbi, session, environment: { navigate, notify }, billing, viewer, … }}>\n * <App />\n * </ArbiHost>\n *\n * Every field is optional and has a default; each kit reads its domain (`useHost().billing`, or a\n * domain hook such as `useBlocksEnvironment()` that fills in the defaults). A blocks-only site gets\n * `arbi` and its sign-in layer from `defaultHost` (`@arbidocs/blocks/connect`); ARBI-frontend\n * passes its own (src/host/app-host.tsx), and is the reference for a site that looks like it.\n * A field whose value lives in the host's state is a hook (`use…`), so the configuration stays one\n * stable object. There is no other host provider: a new domain is a new optional field here.\n *\n * SDK-free: the provider is `@arbidocs/react/shell`'s, and the domain types are type-only.\n */\n\nimport type { PanelHostSupport } from '../shell/panel-host'\nimport type { ReactElement } from 'react'\nimport { ArbiHost as GenericArbiHost, useHostConfigRecord } from '@arbidocs/react/shell'\nimport type { ArbiHostProps } from '@arbidocs/react/shell'\nimport type { ArbiHostConfig as ArbiReactHostConfig } from '@arbidocs/react'\nimport type { BillingSupport } from '../connection/billing/support'\nimport type { NativeDocxSupport } from '../connection/docx/support'\nimport type { DocumentViewerSupport } from '../connection/viewer/support'\nimport type { DocumentToolsHost } from '../connection/viewer/ConnectedDocumentToolsProvider'\nimport type { ConnectedWorkspaceData } from '../connection/workspaceData'\nimport type { BlocksEnvironment } from './environment'\nimport type { AuthPagesSupport, SsoSupport } from '../connection/auth/support'\nimport type { WorkflowsHost } from '../connection/workflows/support'\n\nexport interface ArbiHostConfig extends ArbiReactHostConfig {\n /** Panel popup registry and site-specific titles. Absent: shared browser windows, plain titles. */\n panels?: PanelHostSupport\n /** Router, notices, dialogs, runtime config and where documents, threads, … open. */\n environment?: Partial<BlocksEnvironment>\n /** Selling plans (Stripe). Absent: nothing is for sale; projects show limits and usage only. */\n billing?: BillingSupport\n /** The Word editor's host additions. Absent: no Defined term, no Generate image. */\n docx?: NativeDocxSupport\n /** The document viewer's host additions. Absent: no drafts, Translate, … */\n viewer?: DocumentViewerSupport\n /** The PDF document tools' host binding (its upload, its lists to refresh, Mail). */\n documentTools?: DocumentToolsHost\n /** Workspace lists the host already keeps live. Absent: the kits read their own. */\n workspaceData?: ConnectedWorkspaceData\n /** The auth pages' look, password rules and sign-in follow-ups. Absent: plain pages. */\n auth?: AuthPagesSupport\n /** The single sign-on provider. Absent: no SSO. */\n sso?: SsoSupport\n /** The workflows a site offers to start from, in its categories. Absent: none. */\n workflows?: WorkflowsHost\n}\n\n/** `<ArbiHost config>` with the blocks domains. */\nexport const ArbiHost: (props: ArbiHostProps<ArbiHostConfig>) => ReactElement = GenericArbiHost\n\n/** The host configuration in scope (`{}` outside an `<ArbiHost>`). */\nexport function useHost(): ArbiHostConfig {\n return useHostConfigRecord() as ArbiHostConfig\n}\n"]}
|
package/dist/chunk-C4TGESIB.cjs
DELETED
|
@@ -1,260 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
'use strict';
|
|
3
|
-
|
|
4
|
-
var ui = require('@arbidocs/react/ui');
|
|
5
|
-
var jsxRuntime = require('react/jsx-runtime');
|
|
6
|
-
|
|
7
|
-
// src/tips/registry.ts
|
|
8
|
-
var TIP_MAX_CHARS = 80;
|
|
9
|
-
var TIP_CTA_LABEL_MAX_CHARS = 24;
|
|
10
|
-
function createTipsRegistry(config) {
|
|
11
|
-
const { tips, everywhere, hiddenLabel = "Hidden (off)" } = config;
|
|
12
|
-
let content = config.content;
|
|
13
|
-
const listeners = /* @__PURE__ */ new Set();
|
|
14
|
-
const effective = (tip) => {
|
|
15
|
-
const o = content.overrides?.[tip.code];
|
|
16
|
-
if (!o) return { tip, hidden: false };
|
|
17
|
-
return {
|
|
18
|
-
tip: {
|
|
19
|
-
...tip,
|
|
20
|
-
message: o.message ?? tip.message,
|
|
21
|
-
cta: o.cta === null ? void 0 : o.cta ?? tip.cta,
|
|
22
|
-
context: o.context ?? tip.context
|
|
23
|
-
},
|
|
24
|
-
hidden: o.hidden === true
|
|
25
|
-
};
|
|
26
|
-
};
|
|
27
|
-
const custom = () => content.custom ?? [];
|
|
28
|
-
const applies = (tipContext, context) => tipContext === context || tipContext === everywhere;
|
|
29
|
-
const placements = [
|
|
30
|
-
...config.placements,
|
|
31
|
-
{ value: "hidden", label: hiddenLabel }
|
|
32
|
-
];
|
|
33
|
-
return {
|
|
34
|
-
select: (context, state) => {
|
|
35
|
-
const builtins = tips.map(effective).filter(
|
|
36
|
-
({ tip, hidden }) => !hidden && applies(tip.context, context) && (!tip.when || tip.when(state))
|
|
37
|
-
).map(({ tip }) => tip);
|
|
38
|
-
const authored = custom().filter((t) => t.hidden !== true && applies(t.context, context));
|
|
39
|
-
return [...builtins, ...authored].sort(
|
|
40
|
-
(a, b) => (b.priority ?? 0) - (a.priority ?? 0)
|
|
41
|
-
);
|
|
42
|
-
},
|
|
43
|
-
editorTips: () => [
|
|
44
|
-
...tips.map((t) => {
|
|
45
|
-
const e = effective(t);
|
|
46
|
-
return { tip: e.tip, isCustom: false, isHidden: e.hidden };
|
|
47
|
-
}),
|
|
48
|
-
...custom().map((t) => ({ tip: t, isCustom: true, isHidden: t.hidden === true }))
|
|
49
|
-
],
|
|
50
|
-
getContent: () => content,
|
|
51
|
-
setContent: (next) => {
|
|
52
|
-
content = next;
|
|
53
|
-
listeners.forEach((listener) => listener());
|
|
54
|
-
},
|
|
55
|
-
subscribe: (listener) => {
|
|
56
|
-
listeners.add(listener);
|
|
57
|
-
return () => {
|
|
58
|
-
listeners.delete(listener);
|
|
59
|
-
};
|
|
60
|
-
},
|
|
61
|
-
everywhere,
|
|
62
|
-
placements,
|
|
63
|
-
placementLabel: (p) => placements.find((o) => o.value === p)?.label ?? p
|
|
64
|
-
};
|
|
65
|
-
}
|
|
66
|
-
function usageMeterState(used, allowance) {
|
|
67
|
-
if (allowance <= 0) return used > 0 ? "over" : "under";
|
|
68
|
-
const ratio = used / allowance;
|
|
69
|
-
return ratio >= 1 ? "over" : ratio >= 0.8 ? "near" : "under";
|
|
70
|
-
}
|
|
71
|
-
var STATE_TONE = {
|
|
72
|
-
under: "bg-primary",
|
|
73
|
-
near: "bg-yellow-500",
|
|
74
|
-
over: "bg-red-500"
|
|
75
|
-
};
|
|
76
|
-
var pctOf = (n, scale) => scale > 0 ? Math.max(0, Math.min(100, n / scale * 100)) : 0;
|
|
77
|
-
var SWATCH = {
|
|
78
|
-
plan: "bg-muted-foreground/40",
|
|
79
|
-
topUps: "bg-primary/30",
|
|
80
|
-
autoRoom: "bg-muted"
|
|
81
|
-
};
|
|
82
|
-
var HATCH = {
|
|
83
|
-
backgroundImage: "repeating-linear-gradient(135deg, currentColor 0 1.5px, transparent 1.5px 5px)"
|
|
84
|
-
};
|
|
85
|
-
function AllowanceBar({ allowance, label }) {
|
|
86
|
-
const { used, plan } = allowance;
|
|
87
|
-
const topUps = Math.max(0, allowance.topUps ?? 0);
|
|
88
|
-
const room = Math.max(0, allowance.autoRoom ?? 0);
|
|
89
|
-
const total = plan + topUps;
|
|
90
|
-
const scale = Math.max(total + room, used, Number.EPSILON);
|
|
91
|
-
const state = usageMeterState(used, total);
|
|
92
|
-
const usedPct = total > 0 ? Math.round(used / total * 100) : used > 0 ? 100 : 0;
|
|
93
|
-
const markPlan = plan > 0 && plan < scale && (topUps > 0 || room > 0);
|
|
94
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative h-2 overflow-hidden rounded-full bg-muted", "data-slot": "usage-meter-bar", children: [
|
|
95
|
-
topUps > 0 && /* @__PURE__ */ jsxRuntime.jsx(
|
|
96
|
-
"div",
|
|
97
|
-
{
|
|
98
|
-
className: ui.cn("absolute inset-y-0", SWATCH.topUps),
|
|
99
|
-
style: { left: `${pctOf(plan, scale)}%`, width: `${pctOf(topUps, scale)}%` },
|
|
100
|
-
"data-slot": "usage-meter-topups"
|
|
101
|
-
}
|
|
102
|
-
),
|
|
103
|
-
room > 0 && /* @__PURE__ */ jsxRuntime.jsx(
|
|
104
|
-
"div",
|
|
105
|
-
{
|
|
106
|
-
className: "absolute inset-y-0 text-muted-foreground/35",
|
|
107
|
-
style: { left: `${pctOf(total, scale)}%`, width: `${pctOf(room, scale)}%`, ...HATCH },
|
|
108
|
-
"data-slot": "usage-meter-auto-room"
|
|
109
|
-
}
|
|
110
|
-
),
|
|
111
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
112
|
-
"div",
|
|
113
|
-
{
|
|
114
|
-
className: ui.cn(
|
|
115
|
-
"absolute inset-y-0 left-0 rounded-full transition-[width]",
|
|
116
|
-
STATE_TONE[state]
|
|
117
|
-
),
|
|
118
|
-
style: { width: `${pctOf(Math.min(used, scale), scale)}%` },
|
|
119
|
-
role: "progressbar",
|
|
120
|
-
"aria-valuenow": Math.min(usedPct, 100),
|
|
121
|
-
"aria-valuemin": 0,
|
|
122
|
-
"aria-valuemax": 100,
|
|
123
|
-
"aria-label": label,
|
|
124
|
-
"data-state": state
|
|
125
|
-
}
|
|
126
|
-
),
|
|
127
|
-
markPlan && /* @__PURE__ */ jsxRuntime.jsx(
|
|
128
|
-
"div",
|
|
129
|
-
{
|
|
130
|
-
className: "absolute inset-y-0 w-0.5 -translate-x-1/2 bg-foreground/70",
|
|
131
|
-
style: { left: `${pctOf(plan, scale)}%` },
|
|
132
|
-
"aria-hidden": true,
|
|
133
|
-
"data-slot": "usage-meter-plan-mark"
|
|
134
|
-
}
|
|
135
|
-
),
|
|
136
|
-
room > 0 && total > 0 && /* @__PURE__ */ jsxRuntime.jsx(
|
|
137
|
-
"div",
|
|
138
|
-
{
|
|
139
|
-
className: "absolute inset-y-0 w-px bg-foreground/40",
|
|
140
|
-
style: { left: `${pctOf(total, scale)}%` },
|
|
141
|
-
"aria-hidden": true
|
|
142
|
-
}
|
|
143
|
-
)
|
|
144
|
-
] });
|
|
145
|
-
}
|
|
146
|
-
function UsageMeter({
|
|
147
|
-
icon: Icon,
|
|
148
|
-
label,
|
|
149
|
-
value,
|
|
150
|
-
pct = 0,
|
|
151
|
-
hint,
|
|
152
|
-
allowance,
|
|
153
|
-
legend,
|
|
154
|
-
details,
|
|
155
|
-
actions,
|
|
156
|
-
className,
|
|
157
|
-
testId
|
|
158
|
-
}) {
|
|
159
|
-
const clamped = Math.max(0, Math.min(100, pct));
|
|
160
|
-
const tone = clamped >= 100 ? "bg-red-500" : clamped >= 50 ? "bg-yellow-500" : "bg-primary";
|
|
161
|
-
const state = allowance ? usageMeterState(allowance.used, allowance.plan + Math.max(0, allowance.topUps ?? 0)) : void 0;
|
|
162
|
-
const legendItems = legend ? [
|
|
163
|
-
["plan", legend.plan],
|
|
164
|
-
["topUps", legend.topUps],
|
|
165
|
-
["autoRoom", legend.autoRoom]
|
|
166
|
-
].filter(([, text]) => !!text) : [];
|
|
167
|
-
const meter = /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0 flex-1 space-y-1.5", children: [
|
|
168
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-w-0 items-center justify-between gap-3 text-sm", children: [
|
|
169
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
170
|
-
"span",
|
|
171
|
-
{
|
|
172
|
-
className: ui.cn(
|
|
173
|
-
"flex min-w-0 items-center gap-1.5",
|
|
174
|
-
allowance ? "font-medium text-foreground" : "text-muted-foreground"
|
|
175
|
-
),
|
|
176
|
-
children: [
|
|
177
|
-
Icon && /* @__PURE__ */ jsxRuntime.jsx(Icon, { className: "size-3.5 shrink-0" }),
|
|
178
|
-
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "truncate", children: [
|
|
179
|
-
label,
|
|
180
|
-
hint ? ` (${hint})` : ""
|
|
181
|
-
] })
|
|
182
|
-
]
|
|
183
|
-
}
|
|
184
|
-
),
|
|
185
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
186
|
-
"span",
|
|
187
|
-
{
|
|
188
|
-
className: "shrink-0 font-medium tabular-nums text-foreground",
|
|
189
|
-
"data-slot": "usage-meter-value",
|
|
190
|
-
children: value
|
|
191
|
-
}
|
|
192
|
-
)
|
|
193
|
-
] }),
|
|
194
|
-
allowance ? /* @__PURE__ */ jsxRuntime.jsx(AllowanceBar, { allowance, label }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-1.5 overflow-hidden rounded-full bg-muted", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
195
|
-
"div",
|
|
196
|
-
{
|
|
197
|
-
className: ui.cn("h-full rounded-full transition-[width]", tone),
|
|
198
|
-
style: { width: `${clamped}%` },
|
|
199
|
-
role: "progressbar",
|
|
200
|
-
"aria-valuenow": clamped,
|
|
201
|
-
"aria-valuemin": 0,
|
|
202
|
-
"aria-valuemax": 100,
|
|
203
|
-
"aria-label": label
|
|
204
|
-
}
|
|
205
|
-
) }),
|
|
206
|
-
legendItems.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(
|
|
207
|
-
"ul",
|
|
208
|
-
{
|
|
209
|
-
className: "flex flex-wrap gap-x-4 gap-y-1 text-xs tabular-nums text-muted-foreground",
|
|
210
|
-
"data-slot": "usage-meter-legend",
|
|
211
|
-
children: legendItems.map(([key, text]) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
212
|
-
"li",
|
|
213
|
-
{
|
|
214
|
-
className: "flex items-center gap-1.5",
|
|
215
|
-
"data-slot": `usage-meter-legend-${key}`,
|
|
216
|
-
children: [
|
|
217
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
218
|
-
"span",
|
|
219
|
-
{
|
|
220
|
-
className: ui.cn(
|
|
221
|
-
"inline-block size-2 rounded-sm",
|
|
222
|
-
SWATCH[key],
|
|
223
|
-
key === "autoRoom" && "text-muted-foreground/60"
|
|
224
|
-
),
|
|
225
|
-
style: key === "autoRoom" ? HATCH : void 0,
|
|
226
|
-
"aria-hidden": true
|
|
227
|
-
}
|
|
228
|
-
),
|
|
229
|
-
text
|
|
230
|
-
]
|
|
231
|
-
},
|
|
232
|
-
key
|
|
233
|
-
))
|
|
234
|
-
}
|
|
235
|
-
),
|
|
236
|
-
details && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-1 text-xs text-muted-foreground", children: details })
|
|
237
|
-
] });
|
|
238
|
-
if (!actions) {
|
|
239
|
-
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: ui.cn("space-y-1.5", className), "data-testid": testId, "data-state": state, children: meter });
|
|
240
|
-
}
|
|
241
|
-
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: ui.cn("@container", className), "data-testid": testId, "data-state": state, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3 @lg:flex-row @lg:items-start @lg:gap-6", children: [
|
|
242
|
-
meter,
|
|
243
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
244
|
-
"div",
|
|
245
|
-
{
|
|
246
|
-
className: "flex min-w-0 flex-wrap items-center gap-2 @lg:w-60 @lg:shrink-0 @lg:flex-col @lg:items-stretch",
|
|
247
|
-
"data-slot": "usage-meter-actions",
|
|
248
|
-
children: actions
|
|
249
|
-
}
|
|
250
|
-
)
|
|
251
|
-
] }) });
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
exports.TIP_CTA_LABEL_MAX_CHARS = TIP_CTA_LABEL_MAX_CHARS;
|
|
255
|
-
exports.TIP_MAX_CHARS = TIP_MAX_CHARS;
|
|
256
|
-
exports.UsageMeter = UsageMeter;
|
|
257
|
-
exports.createTipsRegistry = createTipsRegistry;
|
|
258
|
-
exports.usageMeterState = usageMeterState;
|
|
259
|
-
//# sourceMappingURL=chunk-C4TGESIB.cjs.map
|
|
260
|
-
//# sourceMappingURL=chunk-C4TGESIB.cjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/tips/registry.ts","../src/components/UsageMeter.tsx"],"names":["jsxs","jsx","cn"],"mappings":"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","file":"chunk-C4TGESIB.cjs","sourcesContent":["/**\n * The contextual tips engine: which tips apply where, and the editable layer over them. The tips\n * themselves (their words, pages, situations and actions) are the site's content; a site hands\n * them to {@link createTipsRegistry} once and shows the result in `TipCard` / its tip bar, edits it\n * in `TipsEditorDialog`, and hides tips per user with `useDismissedTips` (`@arbidocs/react`).\n *\n * Each tip has a stable `code`. The editable layer (`TipsContent`) overrides a built-in tip's\n * message, action or page, hides it, or adds tips authored in the editor; swapping it in\n * (`setContent`) updates every subscriber without a reload.\n */\n\n/** Max length of a tip message: the bar is one line, so a tip is one short sentence. */\nexport const TIP_MAX_CHARS = 80\n/** Max length of a tip's action label, so the inline button doesn't dominate. */\nexport const TIP_CTA_LABEL_MAX_CHARS = 24\n\n/**\n * A tip's action: a label and exactly one target. `action` and `sequence` are the site's own ids\n * (what its action registry runs); `href` opens in a new window.\n */\nexport interface TipCta<Action extends string = string, Sequence extends string = string> {\n label: string\n action?: Action\n sequence?: Sequence\n href?: string\n}\n\nexport interface TipDefinition<Context extends string, State, Cta> {\n /** Stable id (e.g. a page letter and a number). */\n code: string\n context: Context\n message: string\n /** Situation predicate; omitted: always applies on its page. */\n when?: (state: State) => boolean\n cta?: Cta\n /** Higher shows first. Default 0. */\n priority?: number\n /** Using the action also hides the tip for good (a one-shot offer, now taken). */\n dismissOnCta?: boolean\n}\n\n/** The editable layer over a built-in tip: omitted fields keep the built-in's; `cta: null` drops it. */\nexport interface TipOverride<Context extends string, Cta> {\n message?: string\n cta?: Cta | null\n context?: Context\n hidden?: boolean\n}\n\n/** A tip written in the editor: no situation predicate, so it always applies on its page. */\nexport interface CustomTip<Context extends string, Cta> {\n code: string\n context: Context\n message: string\n cta?: Cta\n priority?: number\n hidden?: boolean\n}\n\n/** The whole editable layer (a site keeps it as JSON next to its tips). */\nexport interface TipsContent<Context extends string, Cta> {\n overrides: Record<string, TipOverride<Context, Cta>>\n custom: CustomTip<Context, Cta>[]\n}\n\n/** A tip as the editor lists it: its effective form, where it came from and whether it is off. */\nexport interface EditorTip<Context extends string, State, Cta> {\n tip: TipDefinition<Context, State, Cta>\n isCustom: boolean\n isHidden: boolean\n}\n\nexport interface TipsRegistryConfig<Context extends string, State, Cta> {\n tips: readonly TipDefinition<Context, State, Cta>[]\n /** The committed editable layer. */\n content: TipsContent<Context, Cta>\n /** The page whose tips show on every page. */\n everywhere: Context\n /** Where a tip can be placed, with the editor's labels (\"All pages\" first, say). */\n placements: readonly { value: Context; label: string }[]\n /** The editor's label for \"off\". Default \"Hidden (off)\". */\n hiddenLabel?: string\n}\n\nexport type TipPlacement<Context extends string> = Context | 'hidden'\n\nexport interface TipsRegistry<Context extends string, State, Cta> {\n /** Tips for a page whose situation matches, highest priority first (plus every-page tips). */\n select: (context: Context, state: State) => TipDefinition<Context, State, Cta>[]\n /** Every tip for the editor, across pages, hidden ones included. */\n editorTips: () => EditorTip<Context, State, Cta>[]\n /** The live editable layer. */\n getContent: () => TipsContent<Context, Cta>\n /** Swap the editable layer and notify subscribers (no reload). */\n setContent: (next: TipsContent<Context, Cta>) => void\n /** Follow changes to the editable layer; returns the unsubscribe. */\n subscribe: (listener: () => void) => () => void\n /** The page whose tips show on every page (where a new tip starts in the editor). */\n everywhere: Context\n /** The editor's placement choices: each page, then \"off\". */\n placements: readonly { value: TipPlacement<Context>; label: string }[]\n placementLabel: (placement: TipPlacement<Context>) => string\n}\n\nexport function createTipsRegistry<Context extends string, State, Cta>(\n config: TipsRegistryConfig<Context, State, Cta>\n): TipsRegistry<Context, State, Cta> {\n const { tips, everywhere, hiddenLabel = 'Hidden (off)' } = config\n let content = config.content\n const listeners = new Set<() => void>()\n type Tip = TipDefinition<Context, State, Cta>\n\n const effective = (tip: Tip): { tip: Tip; hidden: boolean } => {\n const o = content.overrides?.[tip.code]\n if (!o) return { tip, hidden: false }\n return {\n tip: {\n ...tip,\n message: o.message ?? tip.message,\n cta: o.cta === null ? undefined : (o.cta ?? tip.cta),\n context: o.context ?? tip.context,\n },\n hidden: o.hidden === true,\n }\n }\n const custom = () => content.custom ?? []\n const applies = (tipContext: Context, context: Context) =>\n tipContext === context || tipContext === everywhere\n const placements: { value: TipPlacement<Context>; label: string }[] = [\n ...config.placements,\n { value: 'hidden', label: hiddenLabel },\n ]\n\n return {\n select: (context, state) => {\n const builtins = tips\n .map(effective)\n .filter(\n ({ tip, hidden }) =>\n !hidden && applies(tip.context, context) && (!tip.when || tip.when(state))\n )\n .map(({ tip }) => tip)\n const authored = custom().filter((t) => t.hidden !== true && applies(t.context, context))\n return [...builtins, ...(authored as Tip[])].sort(\n (a, b) => (b.priority ?? 0) - (a.priority ?? 0)\n )\n },\n editorTips: () => [\n ...tips.map((t) => {\n const e = effective(t)\n return { tip: e.tip, isCustom: false, isHidden: e.hidden }\n }),\n ...custom().map((t) => ({ tip: t as Tip, isCustom: true, isHidden: t.hidden === true })),\n ],\n getContent: () => content,\n setContent: (next) => {\n content = next\n listeners.forEach((listener) => listener())\n },\n subscribe: (listener) => {\n listeners.add(listener)\n return () => {\n listeners.delete(listener)\n }\n },\n everywhere,\n placements,\n placementLabel: (p) => placements.find((o) => o.value === p)?.label ?? p,\n }\n}\n","import type { ReactNode } from 'react'\nimport type { LucideIcon } from 'lucide-react'\nimport { cn } from '@arbidocs/react/ui'\n\n/**\n * What an allowance is made of, in the meter's own unit (£ of AI usage, GB, users): what was used, the plan's part\n * of the allowance, the top-ups on top of it, and how much more automatic top-ups may still add before a usage cap\n * (or budget) stops them.\n */\nexport interface UsageMeterAllowance {\n used: number\n /** The plan's part of the allowance (marked on the bar when top-ups or automatic room follow it). */\n plan: number\n /** Top-ups on top of the plan: the allowance now is `plan + topUps`. */\n topUps?: number\n /**\n * Room automatic top-ups may still add before the cap stops them (drawn hatched after the allowance).\n * `null` = no limit (nothing drawn: the room is unbounded); omitted = not applicable.\n */\n autoRoom?: number | null\n}\n\n/** Pressure on an allowance: under 80% used, 80% to under 100%, or at / over it. */\nexport type UsageMeterState = 'under' | 'near' | 'over'\n\n/** The allowance meter's pressure state for `used` of `allowance`. */\nexport function usageMeterState(used: number, allowance: number): UsageMeterState {\n if (allowance <= 0) return used > 0 ? 'over' : 'under'\n const ratio = used / allowance\n return ratio >= 1 ? 'over' : ratio >= 0.8 ? 'near' : 'under'\n}\n\nconst STATE_TONE: Record<UsageMeterState, string> = {\n under: 'bg-primary',\n near: 'bg-yellow-500',\n over: 'bg-red-500',\n}\n\nconst pctOf = (n: number, scale: number) =>\n scale > 0 ? Math.max(0, Math.min(100, (n / scale) * 100)) : 0\n\n/** Legend swatches, matching the bar's segments. */\nconst SWATCH = {\n plan: 'bg-muted-foreground/40',\n topUps: 'bg-primary/30',\n autoRoom: 'bg-muted',\n}\n\nconst HATCH = {\n backgroundImage: 'repeating-linear-gradient(135deg, currentColor 0 1.5px, transparent 1.5px 5px)',\n} as const\n\n/** The segmented bar of an allowance meter: used, the plan mark, top-ups, and the automatic room. */\nfunction AllowanceBar({ allowance, label }: { allowance: UsageMeterAllowance; label: string }) {\n const { used, plan } = allowance\n const topUps = Math.max(0, allowance.topUps ?? 0)\n const room = Math.max(0, allowance.autoRoom ?? 0)\n const total = plan + topUps\n const scale = Math.max(total + room, used, Number.EPSILON)\n const state = usageMeterState(used, total)\n const usedPct = total > 0 ? Math.round((used / total) * 100) : used > 0 ? 100 : 0\n const markPlan = plan > 0 && plan < scale && (topUps > 0 || room > 0)\n return (\n <div className=\"relative h-2 overflow-hidden rounded-full bg-muted\" data-slot=\"usage-meter-bar\">\n {topUps > 0 && (\n <div\n className={cn('absolute inset-y-0', SWATCH.topUps)}\n style={{ left: `${pctOf(plan, scale)}%`, width: `${pctOf(topUps, scale)}%` }}\n data-slot=\"usage-meter-topups\"\n />\n )}\n {room > 0 && (\n <div\n className=\"absolute inset-y-0 text-muted-foreground/35\"\n style={{ left: `${pctOf(total, scale)}%`, width: `${pctOf(room, scale)}%`, ...HATCH }}\n data-slot=\"usage-meter-auto-room\"\n />\n )}\n <div\n className={cn(\n 'absolute inset-y-0 left-0 rounded-full transition-[width]',\n STATE_TONE[state]\n )}\n style={{ width: `${pctOf(Math.min(used, scale), scale)}%` }}\n role=\"progressbar\"\n aria-valuenow={Math.min(usedPct, 100)}\n aria-valuemin={0}\n aria-valuemax={100}\n aria-label={label}\n data-state={state}\n />\n {markPlan && (\n <div\n className=\"absolute inset-y-0 w-0.5 -translate-x-1/2 bg-foreground/70\"\n style={{ left: `${pctOf(plan, scale)}%` }}\n aria-hidden\n data-slot=\"usage-meter-plan-mark\"\n />\n )}\n {room > 0 && total > 0 && (\n <div\n className=\"absolute inset-y-0 w-px bg-foreground/40\"\n style={{ left: `${pctOf(total, scale)}%` }}\n aria-hidden\n />\n )}\n </div>\n )\n}\n\n/**\n * One labelled quota meter: icon + label on the left, used-of-limit on the right, a thin bar underneath.\n *\n * Simple mode (`pct`): the bar's tone follows pressure with the shared green → yellow → red gradation — green while\n * there's room, yellow past the halfway mark, red at the limit — so a stack of meters reads at a glance which quota\n * is the one to think about.\n *\n * Allowance mode (`allowance`): the bar spans the allowance plus what automatic top-ups may still add; it marks the\n * plan's part, shades the top-ups, hatches the automatic room, and fills what was used (red at the allowance, yellow\n * from 80%). `legend` names the segments; `details` (next period, cap) sit under the bar and `actions` (+ / −) beside\n * it. The meter's `data-state` is `under` / `near` / `over`.\n */\nexport function UsageMeter({\n icon: Icon,\n label,\n value,\n pct = 0,\n hint,\n allowance,\n legend,\n details,\n actions,\n className,\n testId,\n}: {\n icon?: LucideIcon\n label: string\n /** Formatted used-of-limit text, e.g. \"1,200 / 25,000\" or \"40 / 500 MB\". */\n value: string\n /** Simple mode: fill percentage, 0–100 (values are clamped). Ignored with `allowance`. */\n pct?: number\n /** Inline parenthetical after the label, e.g. \"resets May 31, 2025\" —\n * same font as the label, so the meter never grows an extra row. */\n hint?: string\n /** Allowance mode: the allowance's parts, in the meter's unit. */\n allowance?: UsageMeterAllowance\n /** Formatted legend entries for the allowance's segments (each shown only when set). */\n legend?: { plan?: string; topUps?: string; autoRoom?: string }\n details?: ReactNode\n actions?: ReactNode\n className?: string\n testId?: string\n}) {\n const clamped = Math.max(0, Math.min(100, pct))\n // Shared green → yellow → red gradation (same thresholds as the project-card\n // quota badges): green with room, yellow past the halfway mark, red at limit.\n const tone = clamped >= 100 ? 'bg-red-500' : clamped >= 50 ? 'bg-yellow-500' : 'bg-primary'\n const state = allowance\n ? usageMeterState(allowance.used, allowance.plan + Math.max(0, allowance.topUps ?? 0))\n : undefined\n const legendItems = legend\n ? (\n [\n ['plan', legend.plan],\n ['topUps', legend.topUps],\n ['autoRoom', legend.autoRoom],\n ] as const\n ).filter(([, text]) => !!text)\n : []\n\n const meter = (\n <div className=\"min-w-0 flex-1 space-y-1.5\">\n <div className=\"flex min-w-0 items-center justify-between gap-3 text-sm\">\n <span\n className={cn(\n 'flex min-w-0 items-center gap-1.5',\n allowance ? 'font-medium text-foreground' : 'text-muted-foreground'\n )}\n >\n {Icon && <Icon className=\"size-3.5 shrink-0\" />}\n <span className=\"truncate\">\n {label}\n {hint ? ` (${hint})` : ''}\n </span>\n </span>\n <span\n className=\"shrink-0 font-medium tabular-nums text-foreground\"\n data-slot=\"usage-meter-value\"\n >\n {value}\n </span>\n </div>\n {allowance ? (\n <AllowanceBar allowance={allowance} label={label} />\n ) : (\n <div className=\"h-1.5 overflow-hidden rounded-full bg-muted\">\n <div\n className={cn('h-full rounded-full transition-[width]', tone)}\n style={{ width: `${clamped}%` }}\n role=\"progressbar\"\n aria-valuenow={clamped}\n aria-valuemin={0}\n aria-valuemax={100}\n aria-label={label}\n />\n </div>\n )}\n {legendItems.length > 0 && (\n <ul\n className=\"flex flex-wrap gap-x-4 gap-y-1 text-xs tabular-nums text-muted-foreground\"\n data-slot=\"usage-meter-legend\"\n >\n {legendItems.map(([key, text]) => (\n <li\n key={key}\n className=\"flex items-center gap-1.5\"\n data-slot={`usage-meter-legend-${key}`}\n >\n <span\n className={cn(\n 'inline-block size-2 rounded-sm',\n SWATCH[key],\n key === 'autoRoom' && 'text-muted-foreground/60'\n )}\n style={key === 'autoRoom' ? HATCH : undefined}\n aria-hidden\n />\n {text}\n </li>\n ))}\n </ul>\n )}\n {details && <div className=\"space-y-1 text-xs text-muted-foreground\">{details}</div>}\n </div>\n )\n\n if (!actions) {\n return (\n <div className={cn('space-y-1.5', className)} data-testid={testId} data-state={state}>\n {meter}\n </div>\n )\n }\n // The actions sit beside the meter when the meter's own box is wide enough, under it otherwise\n // (a container query, so a narrow panel on a wide screen stacks too); nothing overflows at 390px.\n return (\n <div className={cn('@container', className)} data-testid={testId} data-state={state}>\n <div className=\"flex flex-col gap-3 @lg:flex-row @lg:items-start @lg:gap-6\">\n {meter}\n <div\n className=\"flex min-w-0 flex-wrap items-center gap-2 @lg:w-60 @lg:shrink-0 @lg:flex-col @lg:items-stretch\"\n data-slot=\"usage-meter-actions\"\n >\n {actions}\n </div>\n </div>\n </div>\n )\n}\n"]}
|