@forgeax/view 0.2.1-beta-20260924075842
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +11 -0
- package/README.md +742 -0
- package/dist/modules/backend.mjs +54 -0
- package/dist/modules/backend.mjs.map +7 -0
- package/dist/modules/browser.mjs +180 -0
- package/dist/modules/browser.mjs.map +7 -0
- package/dist/modules/carrier-contract.mjs +38 -0
- package/dist/modules/carrier-contract.mjs.map +7 -0
- package/dist/modules/carrier.mjs +13 -0
- package/dist/modules/carrier.mjs.map +7 -0
- package/dist/modules/chunks/chunk-2ASWB6IX.mjs +225 -0
- package/dist/modules/chunks/chunk-2ASWB6IX.mjs.map +7 -0
- package/dist/modules/chunks/chunk-2IJKOG2F.mjs +801 -0
- package/dist/modules/chunks/chunk-2IJKOG2F.mjs.map +7 -0
- package/dist/modules/chunks/chunk-2K3BBJ5S.mjs +9 -0
- package/dist/modules/chunks/chunk-2K3BBJ5S.mjs.map +7 -0
- package/dist/modules/chunks/chunk-32GD5LL6.mjs +482 -0
- package/dist/modules/chunks/chunk-32GD5LL6.mjs.map +7 -0
- package/dist/modules/chunks/chunk-3B4KFAEC.mjs +10 -0
- package/dist/modules/chunks/chunk-3B4KFAEC.mjs.map +7 -0
- package/dist/modules/chunks/chunk-46O5WX43.mjs +25 -0
- package/dist/modules/chunks/chunk-46O5WX43.mjs.map +7 -0
- package/dist/modules/chunks/chunk-47J5JXAB.mjs +237 -0
- package/dist/modules/chunks/chunk-47J5JXAB.mjs.map +7 -0
- package/dist/modules/chunks/chunk-4BXQOUDQ.mjs +17 -0
- package/dist/modules/chunks/chunk-4BXQOUDQ.mjs.map +7 -0
- package/dist/modules/chunks/chunk-4GQWYU2V.mjs +126 -0
- package/dist/modules/chunks/chunk-4GQWYU2V.mjs.map +7 -0
- package/dist/modules/chunks/chunk-4N5X2PRQ.mjs +48 -0
- package/dist/modules/chunks/chunk-4N5X2PRQ.mjs.map +7 -0
- package/dist/modules/chunks/chunk-4WXD2KYX.mjs +56 -0
- package/dist/modules/chunks/chunk-4WXD2KYX.mjs.map +7 -0
- package/dist/modules/chunks/chunk-6ZWWVAZK.mjs +468 -0
- package/dist/modules/chunks/chunk-6ZWWVAZK.mjs.map +7 -0
- package/dist/modules/chunks/chunk-73UZNRHN.mjs +296 -0
- package/dist/modules/chunks/chunk-73UZNRHN.mjs.map +7 -0
- package/dist/modules/chunks/chunk-7ITLCRND.mjs +10 -0
- package/dist/modules/chunks/chunk-7ITLCRND.mjs.map +7 -0
- package/dist/modules/chunks/chunk-7TGVWKH7.mjs +59 -0
- package/dist/modules/chunks/chunk-7TGVWKH7.mjs.map +7 -0
- package/dist/modules/chunks/chunk-7URFF53W.mjs +42 -0
- package/dist/modules/chunks/chunk-7URFF53W.mjs.map +7 -0
- package/dist/modules/chunks/chunk-7YSDRIFN.mjs +14 -0
- package/dist/modules/chunks/chunk-7YSDRIFN.mjs.map +7 -0
- package/dist/modules/chunks/chunk-AAFVCQPK.mjs +52 -0
- package/dist/modules/chunks/chunk-AAFVCQPK.mjs.map +7 -0
- package/dist/modules/chunks/chunk-AEK7ZESQ.mjs +18 -0
- package/dist/modules/chunks/chunk-AEK7ZESQ.mjs.map +7 -0
- package/dist/modules/chunks/chunk-AL6ZWIEU.mjs +42 -0
- package/dist/modules/chunks/chunk-AL6ZWIEU.mjs.map +7 -0
- package/dist/modules/chunks/chunk-ALT7XVMQ.mjs +73 -0
- package/dist/modules/chunks/chunk-ALT7XVMQ.mjs.map +7 -0
- package/dist/modules/chunks/chunk-ASI2HBE6.mjs +116 -0
- package/dist/modules/chunks/chunk-ASI2HBE6.mjs.map +7 -0
- package/dist/modules/chunks/chunk-ATWGCH7I.mjs +174 -0
- package/dist/modules/chunks/chunk-ATWGCH7I.mjs.map +7 -0
- package/dist/modules/chunks/chunk-C45U6IIY.mjs +692 -0
- package/dist/modules/chunks/chunk-C45U6IIY.mjs.map +7 -0
- package/dist/modules/chunks/chunk-C7R3YRA7.mjs +98 -0
- package/dist/modules/chunks/chunk-C7R3YRA7.mjs.map +7 -0
- package/dist/modules/chunks/chunk-CRMICXKN.mjs +87 -0
- package/dist/modules/chunks/chunk-CRMICXKN.mjs.map +7 -0
- package/dist/modules/chunks/chunk-CUH2G6UF.mjs +81 -0
- package/dist/modules/chunks/chunk-CUH2G6UF.mjs.map +7 -0
- package/dist/modules/chunks/chunk-D7GWRZLL.mjs +77 -0
- package/dist/modules/chunks/chunk-D7GWRZLL.mjs.map +7 -0
- package/dist/modules/chunks/chunk-DBWUIBE3.mjs +10 -0
- package/dist/modules/chunks/chunk-DBWUIBE3.mjs.map +7 -0
- package/dist/modules/chunks/chunk-DQWVWWUU.mjs +77 -0
- package/dist/modules/chunks/chunk-DQWVWWUU.mjs.map +7 -0
- package/dist/modules/chunks/chunk-DZZ2WFEU.mjs +122 -0
- package/dist/modules/chunks/chunk-DZZ2WFEU.mjs.map +7 -0
- package/dist/modules/chunks/chunk-E4UIAN26.mjs +58 -0
- package/dist/modules/chunks/chunk-E4UIAN26.mjs.map +7 -0
- package/dist/modules/chunks/chunk-EJGBVKFE.mjs +77 -0
- package/dist/modules/chunks/chunk-EJGBVKFE.mjs.map +7 -0
- package/dist/modules/chunks/chunk-EPSTTHWV.mjs +173 -0
- package/dist/modules/chunks/chunk-EPSTTHWV.mjs.map +7 -0
- package/dist/modules/chunks/chunk-ER7T6QJ3.mjs +64 -0
- package/dist/modules/chunks/chunk-ER7T6QJ3.mjs.map +7 -0
- package/dist/modules/chunks/chunk-FD4BAJ6K.mjs +389 -0
- package/dist/modules/chunks/chunk-FD4BAJ6K.mjs.map +7 -0
- package/dist/modules/chunks/chunk-FJM6WWIY.mjs +80 -0
- package/dist/modules/chunks/chunk-FJM6WWIY.mjs.map +7 -0
- package/dist/modules/chunks/chunk-FKCQYDLX.mjs +162 -0
- package/dist/modules/chunks/chunk-FKCQYDLX.mjs.map +7 -0
- package/dist/modules/chunks/chunk-FLGC65SR.mjs +10 -0
- package/dist/modules/chunks/chunk-FLGC65SR.mjs.map +7 -0
- package/dist/modules/chunks/chunk-FMCACPX5.mjs +289 -0
- package/dist/modules/chunks/chunk-FMCACPX5.mjs.map +7 -0
- package/dist/modules/chunks/chunk-FOBRLUQV.mjs +51 -0
- package/dist/modules/chunks/chunk-FOBRLUQV.mjs.map +7 -0
- package/dist/modules/chunks/chunk-FV3DSKZB.mjs +33 -0
- package/dist/modules/chunks/chunk-FV3DSKZB.mjs.map +7 -0
- package/dist/modules/chunks/chunk-G7BAFAGO.mjs +98 -0
- package/dist/modules/chunks/chunk-G7BAFAGO.mjs.map +7 -0
- package/dist/modules/chunks/chunk-GQBZMCTK.mjs +145 -0
- package/dist/modules/chunks/chunk-GQBZMCTK.mjs.map +7 -0
- package/dist/modules/chunks/chunk-GYWIY7AL.mjs +131 -0
- package/dist/modules/chunks/chunk-GYWIY7AL.mjs.map +7 -0
- package/dist/modules/chunks/chunk-H3KNBALD.mjs +256 -0
- package/dist/modules/chunks/chunk-H3KNBALD.mjs.map +7 -0
- package/dist/modules/chunks/chunk-H3M22JDL.mjs +144 -0
- package/dist/modules/chunks/chunk-H3M22JDL.mjs.map +7 -0
- package/dist/modules/chunks/chunk-HES3DNTM.mjs +40 -0
- package/dist/modules/chunks/chunk-HES3DNTM.mjs.map +7 -0
- package/dist/modules/chunks/chunk-I5BFP7SS.mjs +2392 -0
- package/dist/modules/chunks/chunk-I5BFP7SS.mjs.map +7 -0
- package/dist/modules/chunks/chunk-IGRMZYRD.mjs +15 -0
- package/dist/modules/chunks/chunk-IGRMZYRD.mjs.map +7 -0
- package/dist/modules/chunks/chunk-IKNGC766.mjs +321 -0
- package/dist/modules/chunks/chunk-IKNGC766.mjs.map +7 -0
- package/dist/modules/chunks/chunk-IVHNYKZB.mjs +35 -0
- package/dist/modules/chunks/chunk-IVHNYKZB.mjs.map +7 -0
- package/dist/modules/chunks/chunk-JHOURMYW.mjs +101 -0
- package/dist/modules/chunks/chunk-JHOURMYW.mjs.map +7 -0
- package/dist/modules/chunks/chunk-JURXMRFA.mjs +282 -0
- package/dist/modules/chunks/chunk-JURXMRFA.mjs.map +7 -0
- package/dist/modules/chunks/chunk-JWZIREC3.mjs +18 -0
- package/dist/modules/chunks/chunk-JWZIREC3.mjs.map +7 -0
- package/dist/modules/chunks/chunk-KHRTIZ56.mjs +1400 -0
- package/dist/modules/chunks/chunk-KHRTIZ56.mjs.map +7 -0
- package/dist/modules/chunks/chunk-KLJZZ23J.mjs +102 -0
- package/dist/modules/chunks/chunk-KLJZZ23J.mjs.map +7 -0
- package/dist/modules/chunks/chunk-KNBAYU5I.mjs +49 -0
- package/dist/modules/chunks/chunk-KNBAYU5I.mjs.map +7 -0
- package/dist/modules/chunks/chunk-KSZNCFU4.mjs +125 -0
- package/dist/modules/chunks/chunk-KSZNCFU4.mjs.map +7 -0
- package/dist/modules/chunks/chunk-L45W6KM6.mjs +158 -0
- package/dist/modules/chunks/chunk-L45W6KM6.mjs.map +7 -0
- package/dist/modules/chunks/chunk-LERMYZRC.mjs +239 -0
- package/dist/modules/chunks/chunk-LERMYZRC.mjs.map +7 -0
- package/dist/modules/chunks/chunk-LKJCXYSJ.mjs +91 -0
- package/dist/modules/chunks/chunk-LKJCXYSJ.mjs.map +7 -0
- package/dist/modules/chunks/chunk-MBS3EICT.mjs +25 -0
- package/dist/modules/chunks/chunk-MBS3EICT.mjs.map +7 -0
- package/dist/modules/chunks/chunk-MUOQZPVH.mjs +609 -0
- package/dist/modules/chunks/chunk-MUOQZPVH.mjs.map +7 -0
- package/dist/modules/chunks/chunk-MVEPGFSB.mjs +1 -0
- package/dist/modules/chunks/chunk-MVEPGFSB.mjs.map +7 -0
- package/dist/modules/chunks/chunk-NBJKLWJ5.mjs +42 -0
- package/dist/modules/chunks/chunk-NBJKLWJ5.mjs.map +7 -0
- package/dist/modules/chunks/chunk-NBLGKTEM.mjs +86 -0
- package/dist/modules/chunks/chunk-NBLGKTEM.mjs.map +7 -0
- package/dist/modules/chunks/chunk-NI7CS3I2.mjs +110 -0
- package/dist/modules/chunks/chunk-NI7CS3I2.mjs.map +7 -0
- package/dist/modules/chunks/chunk-NJH2OJFC.mjs +2113 -0
- package/dist/modules/chunks/chunk-NJH2OJFC.mjs.map +7 -0
- package/dist/modules/chunks/chunk-OBK4LIJB.mjs +20 -0
- package/dist/modules/chunks/chunk-OBK4LIJB.mjs.map +7 -0
- package/dist/modules/chunks/chunk-PEUT3FW7.mjs +1 -0
- package/dist/modules/chunks/chunk-PEUT3FW7.mjs.map +7 -0
- package/dist/modules/chunks/chunk-PRZOWPDN.mjs +66 -0
- package/dist/modules/chunks/chunk-PRZOWPDN.mjs.map +7 -0
- package/dist/modules/chunks/chunk-Q4RXBGQS.mjs +55 -0
- package/dist/modules/chunks/chunk-Q4RXBGQS.mjs.map +7 -0
- package/dist/modules/chunks/chunk-QBHBKOIL.mjs +55 -0
- package/dist/modules/chunks/chunk-QBHBKOIL.mjs.map +7 -0
- package/dist/modules/chunks/chunk-QD6CCRMG.mjs +20 -0
- package/dist/modules/chunks/chunk-QD6CCRMG.mjs.map +7 -0
- package/dist/modules/chunks/chunk-QF4V23GW.mjs +39 -0
- package/dist/modules/chunks/chunk-QF4V23GW.mjs.map +7 -0
- package/dist/modules/chunks/chunk-QK6W7MJO.mjs +42 -0
- package/dist/modules/chunks/chunk-QK6W7MJO.mjs.map +7 -0
- package/dist/modules/chunks/chunk-QL7V6DK7.mjs +34 -0
- package/dist/modules/chunks/chunk-QL7V6DK7.mjs.map +7 -0
- package/dist/modules/chunks/chunk-QLBQQKRI.mjs +25 -0
- package/dist/modules/chunks/chunk-QLBQQKRI.mjs.map +7 -0
- package/dist/modules/chunks/chunk-QLZQGZDC.mjs +418 -0
- package/dist/modules/chunks/chunk-QLZQGZDC.mjs.map +7 -0
- package/dist/modules/chunks/chunk-QSKQZGK7.mjs +1625 -0
- package/dist/modules/chunks/chunk-QSKQZGK7.mjs.map +7 -0
- package/dist/modules/chunks/chunk-QURKBAG4.mjs +25 -0
- package/dist/modules/chunks/chunk-QURKBAG4.mjs.map +7 -0
- package/dist/modules/chunks/chunk-R274XBEH.mjs +53 -0
- package/dist/modules/chunks/chunk-R274XBEH.mjs.map +7 -0
- package/dist/modules/chunks/chunk-R4I4JEY5.mjs +77 -0
- package/dist/modules/chunks/chunk-R4I4JEY5.mjs.map +7 -0
- package/dist/modules/chunks/chunk-RR6L6VVR.mjs +9 -0
- package/dist/modules/chunks/chunk-RR6L6VVR.mjs.map +7 -0
- package/dist/modules/chunks/chunk-RXF7SBBZ.mjs +125 -0
- package/dist/modules/chunks/chunk-RXF7SBBZ.mjs.map +7 -0
- package/dist/modules/chunks/chunk-SR66S6EJ.mjs +138 -0
- package/dist/modules/chunks/chunk-SR66S6EJ.mjs.map +7 -0
- package/dist/modules/chunks/chunk-SSQMQJ52.mjs +27 -0
- package/dist/modules/chunks/chunk-SSQMQJ52.mjs.map +7 -0
- package/dist/modules/chunks/chunk-TP26TASL.mjs +20 -0
- package/dist/modules/chunks/chunk-TP26TASL.mjs.map +7 -0
- package/dist/modules/chunks/chunk-TSAEK5P3.mjs +50 -0
- package/dist/modules/chunks/chunk-TSAEK5P3.mjs.map +7 -0
- package/dist/modules/chunks/chunk-UAY27HT3.mjs +68 -0
- package/dist/modules/chunks/chunk-UAY27HT3.mjs.map +7 -0
- package/dist/modules/chunks/chunk-UDLIWGWS.mjs +103 -0
- package/dist/modules/chunks/chunk-UDLIWGWS.mjs.map +7 -0
- package/dist/modules/chunks/chunk-UDVQHPWV.mjs +89 -0
- package/dist/modules/chunks/chunk-UDVQHPWV.mjs.map +7 -0
- package/dist/modules/chunks/chunk-UM23W3G7.mjs +237 -0
- package/dist/modules/chunks/chunk-UM23W3G7.mjs.map +7 -0
- package/dist/modules/chunks/chunk-VDZJWEAA.mjs +214 -0
- package/dist/modules/chunks/chunk-VDZJWEAA.mjs.map +7 -0
- package/dist/modules/chunks/chunk-VIGOJWSO.mjs +42 -0
- package/dist/modules/chunks/chunk-VIGOJWSO.mjs.map +7 -0
- package/dist/modules/chunks/chunk-VY3S5BWI.mjs +284 -0
- package/dist/modules/chunks/chunk-VY3S5BWI.mjs.map +7 -0
- package/dist/modules/chunks/chunk-VZXGRZYU.mjs +47 -0
- package/dist/modules/chunks/chunk-VZXGRZYU.mjs.map +7 -0
- package/dist/modules/chunks/chunk-W5DMQZB5.mjs +42 -0
- package/dist/modules/chunks/chunk-W5DMQZB5.mjs.map +7 -0
- package/dist/modules/chunks/chunk-WOMHSTVZ.mjs +918 -0
- package/dist/modules/chunks/chunk-WOMHSTVZ.mjs.map +7 -0
- package/dist/modules/chunks/chunk-XFQT7XCG.mjs +42 -0
- package/dist/modules/chunks/chunk-XFQT7XCG.mjs.map +7 -0
- package/dist/modules/chunks/chunk-XJZEVRYX.mjs +98 -0
- package/dist/modules/chunks/chunk-XJZEVRYX.mjs.map +7 -0
- package/dist/modules/chunks/chunk-XUYFV23R.mjs +317 -0
- package/dist/modules/chunks/chunk-XUYFV23R.mjs.map +7 -0
- package/dist/modules/chunks/chunk-Y5HXCPPQ.mjs +58 -0
- package/dist/modules/chunks/chunk-Y5HXCPPQ.mjs.map +7 -0
- package/dist/modules/chunks/chunk-YTHGRKGI.mjs +147 -0
- package/dist/modules/chunks/chunk-YTHGRKGI.mjs.map +7 -0
- package/dist/modules/chunks/chunk-YVQSDKAO.mjs +341 -0
- package/dist/modules/chunks/chunk-YVQSDKAO.mjs.map +7 -0
- package/dist/modules/chunks/chunk-YYXQDUVT.mjs +123 -0
- package/dist/modules/chunks/chunk-YYXQDUVT.mjs.map +7 -0
- package/dist/modules/chunks/chunk-ZFXZ2NUI.mjs +142 -0
- package/dist/modules/chunks/chunk-ZFXZ2NUI.mjs.map +7 -0
- package/dist/modules/chunks/chunk-ZLNWF4ET.mjs +9 -0
- package/dist/modules/chunks/chunk-ZLNWF4ET.mjs.map +7 -0
- package/dist/modules/chunks/chunk-ZLU5QW2O.mjs +9 -0
- package/dist/modules/chunks/chunk-ZLU5QW2O.mjs.map +7 -0
- package/dist/modules/chunks/chunk-ZNZPYE2V.mjs +28 -0
- package/dist/modules/chunks/chunk-ZNZPYE2V.mjs.map +7 -0
- package/dist/modules/chunks/core-564N45MO.mjs +7480 -0
- package/dist/modules/chunks/core-564N45MO.mjs.map +7 -0
- package/dist/modules/chunks/css-BKH4SVJG.mjs +8 -0
- package/dist/modules/chunks/css-BKH4SVJG.mjs.map +7 -0
- package/dist/modules/chunks/engine-javascript-PDVIGNGR.mjs +3241 -0
- package/dist/modules/chunks/engine-javascript-PDVIGNGR.mjs.map +7 -0
- package/dist/modules/chunks/github-dark-default-6HVTHEWF.mjs +8 -0
- package/dist/modules/chunks/github-dark-default-6HVTHEWF.mjs.map +7 -0
- package/dist/modules/chunks/github-light-default-LAXRA6XL.mjs +8 -0
- package/dist/modules/chunks/github-light-default-LAXRA6XL.mjs.map +7 -0
- package/dist/modules/chunks/glsl-UC3YWUD2.mjs +18 -0
- package/dist/modules/chunks/glsl-UC3YWUD2.mjs.map +7 -0
- package/dist/modules/chunks/html-FRVIUV63.mjs +19 -0
- package/dist/modules/chunks/html-FRVIUV63.mjs.map +7 -0
- package/dist/modules/chunks/javascript-LN3OC7S2.mjs +8 -0
- package/dist/modules/chunks/javascript-LN3OC7S2.mjs.map +7 -0
- package/dist/modules/chunks/json-5CUGWTOP.mjs +11 -0
- package/dist/modules/chunks/json-5CUGWTOP.mjs.map +7 -0
- package/dist/modules/chunks/json5-YZQI5VNO.mjs +11 -0
- package/dist/modules/chunks/json5-YZQI5VNO.mjs.map +7 -0
- package/dist/modules/chunks/jsonc-SWID6VOZ.mjs +11 -0
- package/dist/modules/chunks/jsonc-SWID6VOZ.mjs.map +7 -0
- package/dist/modules/chunks/jsx-A7RDCLJO.mjs +11 -0
- package/dist/modules/chunks/jsx-A7RDCLJO.mjs.map +7 -0
- package/dist/modules/chunks/markdown-QTCU5KP5.mjs +11 -0
- package/dist/modules/chunks/markdown-QTCU5KP5.mjs.map +7 -0
- package/dist/modules/chunks/python-LAZONBIB.mjs +11 -0
- package/dist/modules/chunks/python-LAZONBIB.mjs.map +7 -0
- package/dist/modules/chunks/rust-XWTPJFJO.mjs +11 -0
- package/dist/modules/chunks/rust-XWTPJFJO.mjs.map +7 -0
- package/dist/modules/chunks/scss-CFXRHUUW.mjs +15 -0
- package/dist/modules/chunks/scss-CFXRHUUW.mjs.map +7 -0
- package/dist/modules/chunks/shellscript-OHO3LCVU.mjs +11 -0
- package/dist/modules/chunks/shellscript-OHO3LCVU.mjs.map +7 -0
- package/dist/modules/chunks/toml-IOHFZJ5B.mjs +11 -0
- package/dist/modules/chunks/toml-IOHFZJ5B.mjs.map +7 -0
- package/dist/modules/chunks/tsx-2E6WNX2E.mjs +11 -0
- package/dist/modules/chunks/tsx-2E6WNX2E.mjs.map +7 -0
- package/dist/modules/chunks/typescript-PBKAS54P.mjs +11 -0
- package/dist/modules/chunks/typescript-PBKAS54P.mjs.map +7 -0
- package/dist/modules/chunks/wgsl-PS6QPRLZ.mjs +11 -0
- package/dist/modules/chunks/wgsl-PS6QPRLZ.mjs.map +7 -0
- package/dist/modules/chunks/xml-JECR2ACB.mjs +18 -0
- package/dist/modules/chunks/xml-JECR2ACB.mjs.map +7 -0
- package/dist/modules/chunks/yaml-P2SV4LOE.mjs +11 -0
- package/dist/modules/chunks/yaml-P2SV4LOE.mjs.map +7 -0
- package/dist/modules/cli-contributions.mjs +32 -0
- package/dist/modules/cli-contributions.mjs.map +7 -0
- package/dist/modules/cli.mjs +14 -0
- package/dist/modules/cli.mjs.map +7 -0
- package/dist/modules/command-executor.mjs +65 -0
- package/dist/modules/command-executor.mjs.map +7 -0
- package/dist/modules/commands.mjs +10 -0
- package/dist/modules/commands.mjs.map +7 -0
- package/dist/modules/embedded.mjs +18608 -0
- package/dist/modules/embedded.mjs.map +7 -0
- package/dist/modules/extension-bridge.mjs +18 -0
- package/dist/modules/extension-bridge.mjs.map +7 -0
- package/dist/modules/frontend-root.mjs +61 -0
- package/dist/modules/frontend-root.mjs.map +7 -0
- package/dist/modules/index.mjs +784 -0
- package/dist/modules/index.mjs.map +7 -0
- package/dist/modules/page.mjs +45 -0
- package/dist/modules/page.mjs.map +7 -0
- package/dist/modules/pages/scene.mjs +18 -0
- package/dist/modules/pages/scene.mjs.map +7 -0
- package/dist/modules/plugin.mjs +56 -0
- package/dist/modules/plugin.mjs.map +7 -0
- package/dist/modules/plugins/asset/frontend.mjs +23 -0
- package/dist/modules/plugins/asset/frontend.mjs.map +7 -0
- package/dist/modules/plugins/asset/i18n.mjs +15 -0
- package/dist/modules/plugins/asset/i18n.mjs.map +7 -0
- package/dist/modules/plugins/asset/identity.mjs +42 -0
- package/dist/modules/plugins/asset/identity.mjs.map +7 -0
- package/dist/modules/plugins/asset/schema.mjs +10 -0
- package/dist/modules/plugins/asset/schema.mjs.map +7 -0
- package/dist/modules/plugins/asset/ui.mjs +16 -0
- package/dist/modules/plugins/asset/ui.mjs.map +7 -0
- package/dist/modules/plugins/content-browser/frontend.mjs +17 -0
- package/dist/modules/plugins/content-browser/frontend.mjs.map +7 -0
- package/dist/modules/plugins/content-browser/i18n.mjs +15 -0
- package/dist/modules/plugins/content-browser/i18n.mjs.map +7 -0
- package/dist/modules/plugins/content-browser/identity.mjs +22 -0
- package/dist/modules/plugins/content-browser/identity.mjs.map +7 -0
- package/dist/modules/plugins/content-browser/schema.mjs +12 -0
- package/dist/modules/plugins/content-browser/schema.mjs.map +7 -0
- package/dist/modules/plugins/content-browser/ui.mjs +15 -0
- package/dist/modules/plugins/content-browser/ui.mjs.map +7 -0
- package/dist/modules/plugins/display/api.mjs +10 -0
- package/dist/modules/plugins/display/api.mjs.map +7 -0
- package/dist/modules/plugins/display/backend.mjs +16 -0
- package/dist/modules/plugins/display/backend.mjs.map +7 -0
- package/dist/modules/plugins/display/carrier-contract.mjs +38 -0
- package/dist/modules/plugins/display/carrier-contract.mjs.map +7 -0
- package/dist/modules/plugins/display/carrier.mjs +13 -0
- package/dist/modules/plugins/display/carrier.mjs.map +7 -0
- package/dist/modules/plugins/display/effects.mjs +8 -0
- package/dist/modules/plugins/display/effects.mjs.map +7 -0
- package/dist/modules/plugins/display/frontend.mjs +14 -0
- package/dist/modules/plugins/display/frontend.mjs.map +7 -0
- package/dist/modules/plugins/display/i18n.mjs +58 -0
- package/dist/modules/plugins/display/i18n.mjs.map +7 -0
- package/dist/modules/plugins/display/identity.mjs +30 -0
- package/dist/modules/plugins/display/identity.mjs.map +7 -0
- package/dist/modules/plugins/display/page-broker.mjs +12 -0
- package/dist/modules/plugins/display/page-broker.mjs.map +7 -0
- package/dist/modules/plugins/display/schema.mjs +40 -0
- package/dist/modules/plugins/display/schema.mjs.map +7 -0
- package/dist/modules/plugins/display/ui.mjs +9 -0
- package/dist/modules/plugins/display/ui.mjs.map +7 -0
- package/dist/modules/plugins/inspector/frontend.mjs +17 -0
- package/dist/modules/plugins/inspector/frontend.mjs.map +7 -0
- package/dist/modules/plugins/inspector/i18n.mjs +15 -0
- package/dist/modules/plugins/inspector/i18n.mjs.map +7 -0
- package/dist/modules/plugins/inspector/identity.mjs +22 -0
- package/dist/modules/plugins/inspector/identity.mjs.map +7 -0
- package/dist/modules/plugins/inspector/schema.mjs +12 -0
- package/dist/modules/plugins/inspector/schema.mjs.map +7 -0
- package/dist/modules/plugins/inspector/ui.mjs +16 -0
- package/dist/modules/plugins/inspector/ui.mjs.map +7 -0
- package/dist/modules/plugins/material/frontend.mjs +25 -0
- package/dist/modules/plugins/material/frontend.mjs.map +7 -0
- package/dist/modules/plugins/material/i18n.mjs +15 -0
- package/dist/modules/plugins/material/i18n.mjs.map +7 -0
- package/dist/modules/plugins/material/identity.mjs +60 -0
- package/dist/modules/plugins/material/identity.mjs.map +7 -0
- package/dist/modules/plugins/material/schema.mjs +47 -0
- package/dist/modules/plugins/material/schema.mjs.map +7 -0
- package/dist/modules/plugins/material/ui.mjs +28 -0
- package/dist/modules/plugins/material/ui.mjs.map +7 -0
- package/dist/modules/plugins/mesh/frontend.mjs +23 -0
- package/dist/modules/plugins/mesh/frontend.mjs.map +7 -0
- package/dist/modules/plugins/mesh/i18n.mjs +15 -0
- package/dist/modules/plugins/mesh/i18n.mjs.map +7 -0
- package/dist/modules/plugins/mesh/identity.mjs +54 -0
- package/dist/modules/plugins/mesh/identity.mjs.map +7 -0
- package/dist/modules/plugins/mesh/schema.mjs +10 -0
- package/dist/modules/plugins/mesh/schema.mjs.map +7 -0
- package/dist/modules/plugins/mesh/ui.mjs +26 -0
- package/dist/modules/plugins/mesh/ui.mjs.map +7 -0
- package/dist/modules/plugins/plugins/api.mjs +11 -0
- package/dist/modules/plugins/plugins/api.mjs.map +7 -0
- package/dist/modules/plugins/plugins/backend.mjs +21 -0
- package/dist/modules/plugins/plugins/backend.mjs.map +7 -0
- package/dist/modules/plugins/plugins/cli.mjs +12 -0
- package/dist/modules/plugins/plugins/cli.mjs.map +7 -0
- package/dist/modules/plugins/plugins/frontend.mjs +17 -0
- package/dist/modules/plugins/plugins/frontend.mjs.map +7 -0
- package/dist/modules/plugins/plugins/i18n.mjs +15 -0
- package/dist/modules/plugins/plugins/i18n.mjs.map +7 -0
- package/dist/modules/plugins/plugins/identity.mjs +26 -0
- package/dist/modules/plugins/plugins/identity.mjs.map +7 -0
- package/dist/modules/plugins/plugins/runtime.mjs +50 -0
- package/dist/modules/plugins/plugins/runtime.mjs.map +7 -0
- package/dist/modules/plugins/plugins/schema.mjs +12 -0
- package/dist/modules/plugins/plugins/schema.mjs.map +7 -0
- package/dist/modules/plugins/plugins/ui/panel.mjs +14 -0
- package/dist/modules/plugins/plugins/ui/panel.mjs.map +7 -0
- package/dist/modules/plugins/plugins/ui.mjs +15 -0
- package/dist/modules/plugins/plugins/ui.mjs.map +7 -0
- package/dist/modules/plugins/scene/frontend.mjs +18 -0
- package/dist/modules/plugins/scene/frontend.mjs.map +7 -0
- package/dist/modules/plugins/scene/identity.mjs +14 -0
- package/dist/modules/plugins/scene/identity.mjs.map +7 -0
- package/dist/modules/plugins/scene-tree/frontend.mjs +17 -0
- package/dist/modules/plugins/scene-tree/frontend.mjs.map +7 -0
- package/dist/modules/plugins/scene-tree/i18n.mjs +15 -0
- package/dist/modules/plugins/scene-tree/i18n.mjs.map +7 -0
- package/dist/modules/plugins/scene-tree/identity.mjs +22 -0
- package/dist/modules/plugins/scene-tree/identity.mjs.map +7 -0
- package/dist/modules/plugins/scene-tree/schema.mjs +12 -0
- package/dist/modules/plugins/scene-tree/schema.mjs.map +7 -0
- package/dist/modules/plugins/scene-tree/ui.mjs +16 -0
- package/dist/modules/plugins/scene-tree/ui.mjs.map +7 -0
- package/dist/modules/plugins/texture/frontend.mjs +23 -0
- package/dist/modules/plugins/texture/frontend.mjs.map +7 -0
- package/dist/modules/plugins/texture/i18n.mjs +15 -0
- package/dist/modules/plugins/texture/i18n.mjs.map +7 -0
- package/dist/modules/plugins/texture/identity.mjs +54 -0
- package/dist/modules/plugins/texture/identity.mjs.map +7 -0
- package/dist/modules/plugins/texture/schema.mjs +10 -0
- package/dist/modules/plugins/texture/schema.mjs.map +7 -0
- package/dist/modules/plugins/texture/ui.mjs +26 -0
- package/dist/modules/plugins/texture/ui.mjs.map +7 -0
- package/dist/modules/plugins/viewport/frontend.mjs +27 -0
- package/dist/modules/plugins/viewport/frontend.mjs.map +7 -0
- package/dist/modules/plugins/viewport/identity.mjs +28 -0
- package/dist/modules/plugins/viewport/identity.mjs.map +7 -0
- package/dist/modules/plugins/viewport/presentation-identity.mjs +10 -0
- package/dist/modules/plugins/viewport/presentation-identity.mjs.map +7 -0
- package/dist/modules/plugins/viewport/presentation.mjs +18 -0
- package/dist/modules/plugins/viewport/presentation.mjs.map +7 -0
- package/dist/modules/plugins/viewport/schema.mjs +18 -0
- package/dist/modules/plugins/viewport/schema.mjs.map +7 -0
- package/dist/modules/plugins/viewport/workspace-shell.mjs +29 -0
- package/dist/modules/plugins/viewport/workspace-shell.mjs.map +7 -0
- package/dist/modules/shell/contract.mjs +10 -0
- package/dist/modules/shell/contract.mjs.map +7 -0
- package/dist/modules/shell/frontend.mjs +14 -0
- package/dist/modules/shell/frontend.mjs.map +7 -0
- package/dist/modules/shell/layout-zones.mjs +20 -0
- package/dist/modules/shell/layout-zones.mjs.map +7 -0
- package/dist/modules/start-cli.mjs +57 -0
- package/dist/modules/start-cli.mjs.map +7 -0
- package/dist/modules/start.mjs +18 -0
- package/dist/modules/start.mjs.map +7 -0
- package/dist/modules/viewer/catalog/backend.mjs +47 -0
- package/dist/modules/viewer/catalog/backend.mjs.map +7 -0
- package/dist/modules/viewer/catalog/frontend.mjs +55 -0
- package/dist/modules/viewer/catalog/frontend.mjs.map +7 -0
- package/dist/modules/viewer/catalog/shared.mjs +43 -0
- package/dist/modules/viewer/catalog/shared.mjs.map +7 -0
- package/dist/modules/viewer/catalog.mjs +85 -0
- package/dist/modules/viewer/catalog.mjs.map +7 -0
- package/dist/modules/viewer/cli.mjs +23 -0
- package/dist/modules/viewer/cli.mjs.map +7 -0
- package/dist/modules/viewer-host/frontend.mjs +65 -0
- package/dist/modules/viewer-host/frontend.mjs.map +7 -0
- package/dist/modules/viewer-host/page-registry.mjs +27 -0
- package/dist/modules/viewer-host/page-registry.mjs.map +7 -0
- package/dist/modules/viewer-host/slot-registry.mjs +8 -0
- package/dist/modules/viewer-host/slot-registry.mjs.map +7 -0
- package/dist/modules/viewer-host.mjs +43 -0
- package/dist/modules/viewer-host.mjs.map +7 -0
- package/dist/modules/viewer.mjs +85 -0
- package/dist/modules/viewer.mjs.map +7 -0
- package/dist/modules/workspace/adopt-surface.mjs +16 -0
- package/dist/modules/workspace/adopt-surface.mjs.map +7 -0
- package/dist/modules/workspace/api.mjs +8 -0
- package/dist/modules/workspace/api.mjs.map +7 -0
- package/dist/modules/workspace/backend.mjs +23 -0
- package/dist/modules/workspace/backend.mjs.map +7 -0
- package/dist/modules/workspace/broker.mjs +16 -0
- package/dist/modules/workspace/broker.mjs.map +7 -0
- package/dist/modules/workspace/cli.mjs +9 -0
- package/dist/modules/workspace/cli.mjs.map +7 -0
- package/dist/modules/workspace/client.mjs +15 -0
- package/dist/modules/workspace/client.mjs.map +7 -0
- package/dist/modules/workspace/command-error.mjs +16 -0
- package/dist/modules/workspace/command-error.mjs.map +7 -0
- package/dist/modules/workspace/contract.mjs +71 -0
- package/dist/modules/workspace/contract.mjs.map +7 -0
- package/dist/modules/workspace/demo-client.mjs +127 -0
- package/dist/modules/workspace/demo-client.mjs.map +7 -0
- package/dist/modules/workspace/engine-adapter.mjs +16 -0
- package/dist/modules/workspace/engine-adapter.mjs.map +7 -0
- package/dist/modules/workspace/engine-presentation.mjs +10 -0
- package/dist/modules/workspace/engine-presentation.mjs.map +7 -0
- package/dist/modules/workspace/extension-bridge.mjs +18 -0
- package/dist/modules/workspace/extension-bridge.mjs.map +7 -0
- package/dist/modules/workspace/frontend-plugin.mjs +18 -0
- package/dist/modules/workspace/frontend-plugin.mjs.map +7 -0
- package/dist/modules/workspace/frontend.mjs +29 -0
- package/dist/modules/workspace/frontend.mjs.map +7 -0
- package/dist/modules/workspace/id.mjs +8 -0
- package/dist/modules/workspace/id.mjs.map +7 -0
- package/dist/modules/workspace/inspection-presentation.mjs +12 -0
- package/dist/modules/workspace/inspection-presentation.mjs.map +7 -0
- package/dist/modules/workspace/locale-bridge.mjs +14 -0
- package/dist/modules/workspace/locale-bridge.mjs.map +7 -0
- package/dist/modules/workspace/page-title.mjs +13 -0
- package/dist/modules/workspace/page-title.mjs.map +7 -0
- package/dist/modules/workspace/presentation.mjs +18 -0
- package/dist/modules/workspace/presentation.mjs.map +7 -0
- package/dist/modules/workspace/preview-surface.mjs +17 -0
- package/dist/modules/workspace/preview-surface.mjs.map +7 -0
- package/dist/modules/workspace/project-session.mjs +18 -0
- package/dist/modules/workspace/project-session.mjs.map +7 -0
- package/dist/modules/workspace/render-resize-sync.mjs +12 -0
- package/dist/modules/workspace/render-resize-sync.mjs.map +7 -0
- package/dist/modules/workspace/resident.mjs +16 -0
- package/dist/modules/workspace/resident.mjs.map +7 -0
- package/dist/modules/workspace/resource-open.mjs +34 -0
- package/dist/modules/workspace/resource-open.mjs.map +7 -0
- package/dist/modules/workspace/resource-page.mjs +27 -0
- package/dist/modules/workspace/resource-page.mjs.map +7 -0
- package/dist/modules/workspace/tool-runtime.mjs +14 -0
- package/dist/modules/workspace/tool-runtime.mjs.map +7 -0
- package/dist/modules/workspace/view-trace.mjs +60 -0
- package/dist/modules/workspace/view-trace.mjs.map +7 -0
- package/dist/modules/workspace/workspace-client-connection.mjs +22 -0
- package/dist/modules/workspace/workspace-client-connection.mjs.map +7 -0
- package/dist/modules/workspace/workspace-recovery.mjs +35 -0
- package/dist/modules/workspace/workspace-recovery.mjs.map +7 -0
- package/dist/modules/workspace/workspace-state.mjs +12 -0
- package/dist/modules/workspace/workspace-state.mjs.map +7 -0
- package/dist/modules/workspace-frontend.mjs +17 -0
- package/dist/modules/workspace-frontend.mjs.map +7 -0
- package/dist/viewer/assets/chunk-CilyBKbf.js +1 -0
- package/dist/viewer/assets/core-DSQma37-.js +13 -0
- package/dist/viewer/assets/core-DSQma37-.js.map +1 -0
- package/dist/viewer/assets/css-Bq1BXecw.js +2 -0
- package/dist/viewer/assets/css-Bq1BXecw.js.map +1 -0
- package/dist/viewer/assets/css-CWQWazmX.js +1 -0
- package/dist/viewer/assets/embedded-D4ZDx--W.js +2 -0
- package/dist/viewer/assets/embedded-D4ZDx--W.js.map +1 -0
- package/dist/viewer/assets/engine-javascript-BvokIV9O.js +142 -0
- package/dist/viewer/assets/engine-javascript-BvokIV9O.js.map +1 -0
- package/dist/viewer/assets/github-dark-default-DaDlj-WZ.js +2 -0
- package/dist/viewer/assets/github-dark-default-DaDlj-WZ.js.map +1 -0
- package/dist/viewer/assets/github-light-default-BqhWxAZd.js +2 -0
- package/dist/viewer/assets/github-light-default-BqhWxAZd.js.map +1 -0
- package/dist/viewer/assets/glsl-BJgVnv11.js +2 -0
- package/dist/viewer/assets/glsl-BJgVnv11.js.map +1 -0
- package/dist/viewer/assets/html-AaaHGGyt.js +2 -0
- package/dist/viewer/assets/html-AaaHGGyt.js.map +1 -0
- package/dist/viewer/assets/javascript-BX9W64FE.js +1 -0
- package/dist/viewer/assets/javascript-DQODvD07.js +2 -0
- package/dist/viewer/assets/javascript-DQODvD07.js.map +1 -0
- package/dist/viewer/assets/json-CpcIDpT7.js +2 -0
- package/dist/viewer/assets/json-CpcIDpT7.js.map +1 -0
- package/dist/viewer/assets/json5-Czq4A7dk.js +2 -0
- package/dist/viewer/assets/json5-Czq4A7dk.js.map +1 -0
- package/dist/viewer/assets/jsonc-BXDfCMmu.js +2 -0
- package/dist/viewer/assets/jsonc-BXDfCMmu.js.map +1 -0
- package/dist/viewer/assets/jsx-DAWscEnf.js +2 -0
- package/dist/viewer/assets/jsx-DAWscEnf.js.map +1 -0
- package/dist/viewer/assets/main-C-2CHTN_.js +15 -0
- package/dist/viewer/assets/main-C-2CHTN_.js.map +1 -0
- package/dist/viewer/assets/markdown-Cx1FMNw-.js +2 -0
- package/dist/viewer/assets/markdown-Cx1FMNw-.js.map +1 -0
- package/dist/viewer/assets/panels-entry-Ddhfjgf0.js +46 -0
- package/dist/viewer/assets/panels-entry-Ddhfjgf0.js.map +1 -0
- package/dist/viewer/assets/python-CYPKjWV9.js +2 -0
- package/dist/viewer/assets/python-CYPKjWV9.js.map +1 -0
- package/dist/viewer/assets/rust-0e5cNx_V.js +2 -0
- package/dist/viewer/assets/rust-0e5cNx_V.js.map +1 -0
- package/dist/viewer/assets/scss-B-aKzLbT.js +2 -0
- package/dist/viewer/assets/scss-B-aKzLbT.js.map +1 -0
- package/dist/viewer/assets/shellscript-CpXD-pSm.js +2 -0
- package/dist/viewer/assets/shellscript-CpXD-pSm.js.map +1 -0
- package/dist/viewer/assets/style-ClttNKZk.css +2 -0
- package/dist/viewer/assets/styles-BXozhwiU.js +11 -0
- package/dist/viewer/assets/styles-BXozhwiU.js.map +1 -0
- package/dist/viewer/assets/toml-GmchYTXa.js +2 -0
- package/dist/viewer/assets/toml-GmchYTXa.js.map +1 -0
- package/dist/viewer/assets/tsx-Crj1Bi53.js +2 -0
- package/dist/viewer/assets/tsx-Crj1Bi53.js.map +1 -0
- package/dist/viewer/assets/typescript-xi0cSHCO.js +2 -0
- package/dist/viewer/assets/typescript-xi0cSHCO.js.map +1 -0
- package/dist/viewer/assets/wgsl-BoEPRo9U.js +2 -0
- package/dist/viewer/assets/wgsl-BoEPRo9U.js.map +1 -0
- package/dist/viewer/assets/xml-B8JqQrMD.js +2 -0
- package/dist/viewer/assets/xml-B8JqQrMD.js.map +1 -0
- package/dist/viewer/assets/yaml-DsIB85X9.js +2 -0
- package/dist/viewer/assets/yaml-DsIB85X9.js.map +1 -0
- package/dist/viewer/index.html +15 -0
- package/dist/viewer/panels.js +1 -0
- package/host.pack.json +13 -0
- package/package.json +174 -0
- package/skills/forgeax-view-cli/SKILL.md +74 -0
- package/skills/forgeax-view-start/SKILL.md +202 -0
- package/skills/forgeax-view-start/scripts/start-view.mjs +202 -0
|
@@ -0,0 +1,2392 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Button,
|
|
3
|
+
Checkbox,
|
|
4
|
+
ContextMenu,
|
|
5
|
+
EmptyState,
|
|
6
|
+
FloatingMenu,
|
|
7
|
+
IconButton,
|
|
8
|
+
MenuDropdown,
|
|
9
|
+
OverlayRootProvider,
|
|
10
|
+
PanelHeader,
|
|
11
|
+
RangeInput,
|
|
12
|
+
SearchField,
|
|
13
|
+
Spinner,
|
|
14
|
+
Switch,
|
|
15
|
+
Toolbar,
|
|
16
|
+
anchorRectFromPoint,
|
|
17
|
+
useWorkspaceClientConnected
|
|
18
|
+
} from "./chunk-NJH2OJFC.mjs";
|
|
19
|
+
import {
|
|
20
|
+
getLocale,
|
|
21
|
+
subscribeLocale,
|
|
22
|
+
t
|
|
23
|
+
} from "./chunk-IKNGC766.mjs";
|
|
24
|
+
import {
|
|
25
|
+
CONTENT_BROWSER_ACTIONS
|
|
26
|
+
} from "./chunk-CRMICXKN.mjs";
|
|
27
|
+
import {
|
|
28
|
+
VIEW_FILE_GET_SERVICE,
|
|
29
|
+
VIEW_WORKSPACE_TAB_ID,
|
|
30
|
+
workspaceUiFingerprint
|
|
31
|
+
} from "./chunk-32GD5LL6.mjs";
|
|
32
|
+
|
|
33
|
+
// packages/view-plugin-content-browser/src/ui/mount.tsx
|
|
34
|
+
import { createRoot } from "react-dom/client";
|
|
35
|
+
|
|
36
|
+
// packages/view-plugin-content-browser/src/ui/ContentBrowserPanel.tsx
|
|
37
|
+
import {
|
|
38
|
+
ArrowDownWideNarrow,
|
|
39
|
+
ArrowUpDown,
|
|
40
|
+
ArrowUpNarrowWide,
|
|
41
|
+
CaseSensitive,
|
|
42
|
+
ChevronDown as ChevronDown2,
|
|
43
|
+
Clock,
|
|
44
|
+
Copy,
|
|
45
|
+
Filter,
|
|
46
|
+
Folder as Folder3,
|
|
47
|
+
FolderOpen as FolderOpen2,
|
|
48
|
+
Grid2X2,
|
|
49
|
+
HardDrive,
|
|
50
|
+
List,
|
|
51
|
+
Settings2,
|
|
52
|
+
Shapes,
|
|
53
|
+
Star,
|
|
54
|
+
StarOff,
|
|
55
|
+
Table2
|
|
56
|
+
} from "lucide-react";
|
|
57
|
+
import {
|
|
58
|
+
useCallback as useCallback4,
|
|
59
|
+
useEffect as useEffect4,
|
|
60
|
+
useMemo,
|
|
61
|
+
useRef as useRef3,
|
|
62
|
+
useState as useState6
|
|
63
|
+
} from "react";
|
|
64
|
+
|
|
65
|
+
// packages/view-plugin-content-browser/src/i18n/useTranslation.ts
|
|
66
|
+
import { useCallback, useSyncExternalStore } from "react";
|
|
67
|
+
function useTranslation() {
|
|
68
|
+
const locale = useSyncExternalStore(subscribeLocale, getLocale, getLocale);
|
|
69
|
+
const t2 = useCallback(
|
|
70
|
+
(key, vars) => t(key, vars),
|
|
71
|
+
[locale]
|
|
72
|
+
);
|
|
73
|
+
return { t: t2, locale };
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// packages/view-plugin-content-browser/src/ui/format.ts
|
|
77
|
+
var ALL_FILTER_FAMILIES = [
|
|
78
|
+
"dir",
|
|
79
|
+
"scene",
|
|
80
|
+
"pack",
|
|
81
|
+
"meta",
|
|
82
|
+
"model",
|
|
83
|
+
"image",
|
|
84
|
+
"audio",
|
|
85
|
+
"font",
|
|
86
|
+
"ui",
|
|
87
|
+
"code",
|
|
88
|
+
"config",
|
|
89
|
+
"doc",
|
|
90
|
+
"data"
|
|
91
|
+
];
|
|
92
|
+
var FILTERABLE_ASSET_KINDS = [
|
|
93
|
+
"plugin",
|
|
94
|
+
"mesh",
|
|
95
|
+
"material",
|
|
96
|
+
"texture",
|
|
97
|
+
"equirect",
|
|
98
|
+
"cube-texture",
|
|
99
|
+
"animation-clip",
|
|
100
|
+
"skeleton",
|
|
101
|
+
"audio",
|
|
102
|
+
"font",
|
|
103
|
+
"ui"
|
|
104
|
+
];
|
|
105
|
+
var SOURCE_TEXT_FAMILIES = /* @__PURE__ */ new Set([
|
|
106
|
+
"code",
|
|
107
|
+
"config",
|
|
108
|
+
"doc",
|
|
109
|
+
"data",
|
|
110
|
+
"pack",
|
|
111
|
+
"meta",
|
|
112
|
+
"scene"
|
|
113
|
+
]);
|
|
114
|
+
var SOURCE_VIEW_EXTENSIONS = /* @__PURE__ */ new Set(["ts", "tsx", "js", "jsx", "mjs", "cjs", "json"]);
|
|
115
|
+
function dirOfPath(path) {
|
|
116
|
+
const index = path.lastIndexOf("/");
|
|
117
|
+
return index < 0 ? "" : path.slice(0, index);
|
|
118
|
+
}
|
|
119
|
+
function normalizePathInput(raw) {
|
|
120
|
+
return raw.trim().replace(/\\/g, "/").replace(/\/+/g, "/").replace(/^\/+|\/+$/g, "");
|
|
121
|
+
}
|
|
122
|
+
function viewItemKey(item) {
|
|
123
|
+
return item.type === "asset" ? item.guid : item.path;
|
|
124
|
+
}
|
|
125
|
+
function isResourceGroup(assetCount) {
|
|
126
|
+
return assetCount > 1;
|
|
127
|
+
}
|
|
128
|
+
function fileFamilyOf(name) {
|
|
129
|
+
const lower = name.toLowerCase();
|
|
130
|
+
if (lower.endsWith(".meta.json")) return "meta";
|
|
131
|
+
if (lower.endsWith(".pack.ts")) return "pack";
|
|
132
|
+
if (lower.endsWith(".pack.json")) return lower.includes("scene") ? "scene" : "pack";
|
|
133
|
+
if (lower.endsWith(".scene.json") || lower === "scene.json") return "scene";
|
|
134
|
+
if (lower.endsWith(".colliders.json")) return "data";
|
|
135
|
+
const ext = lower.split(".").pop() ?? "";
|
|
136
|
+
if (["html", "css", "ts", "tsx", "js", "jsx", "mjs", "cjs", "py"].includes(ext)) return "code";
|
|
137
|
+
if (["json", "lock"].includes(ext)) return "config";
|
|
138
|
+
if (["md", "markdown", "txt"].includes(ext)) return "doc";
|
|
139
|
+
if (["png", "jpg", "jpeg", "webp", "gif", "svg", "ico", "hdr"].includes(ext)) return "image";
|
|
140
|
+
if (["mp3", "wav", "ogg", "flac", "aac", "m4a", "opus"].includes(ext)) return "audio";
|
|
141
|
+
if (["glb", "gltf", "fbx"].includes(ext)) return "model";
|
|
142
|
+
if (["ttf", "otf", "woff", "woff2"].includes(ext)) return "font";
|
|
143
|
+
return "other";
|
|
144
|
+
}
|
|
145
|
+
function fileFamilyOfWithAssets(name, assets) {
|
|
146
|
+
if (name.toLowerCase().endsWith(".pack.ts")) return "pack";
|
|
147
|
+
const byName = fileFamilyOf(name);
|
|
148
|
+
if (byName === "pack" && assets.some((asset2) => asset2.kind === "scene")) return "scene";
|
|
149
|
+
return byName;
|
|
150
|
+
}
|
|
151
|
+
function isSourceViewableFileName(name) {
|
|
152
|
+
const lower = name.toLowerCase();
|
|
153
|
+
if (lower.endsWith(".pack.json") || lower.endsWith(".pack.ts")) return true;
|
|
154
|
+
const ext = lower.includes(".") ? lower.slice(lower.lastIndexOf(".") + 1) : lower;
|
|
155
|
+
return SOURCE_VIEW_EXTENSIONS.has(ext);
|
|
156
|
+
}
|
|
157
|
+
function fileSupportsDualPreview(file2) {
|
|
158
|
+
if (file2.assets.length === 0) return false;
|
|
159
|
+
return SOURCE_TEXT_FAMILIES.has(file2.family) || isSourceViewableFileName(file2.name);
|
|
160
|
+
}
|
|
161
|
+
function resolveDualPreviewFile(item, diskFiles) {
|
|
162
|
+
if (item.type === "file") return item;
|
|
163
|
+
if (item.type === "asset") return diskFiles.find((file2) => file2.path === item.packPath);
|
|
164
|
+
return void 0;
|
|
165
|
+
}
|
|
166
|
+
function formatBytes(bytes) {
|
|
167
|
+
if (bytes === void 0 || bytes <= 0) return "";
|
|
168
|
+
if (bytes < 1024) return `${bytes} B`;
|
|
169
|
+
if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
|
|
170
|
+
return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
|
|
171
|
+
}
|
|
172
|
+
function formatDate(ms) {
|
|
173
|
+
if (!ms) return "";
|
|
174
|
+
try {
|
|
175
|
+
return new Date(ms).toLocaleDateString(void 0, { year: "numeric", month: "short", day: "numeric" });
|
|
176
|
+
} catch {
|
|
177
|
+
return "";
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
function compareItems(a, b, key, dir) {
|
|
181
|
+
const sign = dir === "desc" ? -1 : 1;
|
|
182
|
+
if (key === "kind") {
|
|
183
|
+
return sign * itemKind(a).localeCompare(itemKind(b)) || sign * a.name.localeCompare(b.name);
|
|
184
|
+
}
|
|
185
|
+
if (key === "packModifiedAt") {
|
|
186
|
+
return sign * (itemModified(a) - itemModified(b) || a.name.localeCompare(b.name));
|
|
187
|
+
}
|
|
188
|
+
if (key === "estimatedSize") {
|
|
189
|
+
return sign * (itemSize(a) - itemSize(b) || a.name.localeCompare(b.name));
|
|
190
|
+
}
|
|
191
|
+
return sign * a.name.localeCompare(b.name);
|
|
192
|
+
}
|
|
193
|
+
function itemKind(item) {
|
|
194
|
+
if (item.type === "folder") return "folder";
|
|
195
|
+
if (item.type === "file") return item.kindLabel || item.family;
|
|
196
|
+
return item.kind;
|
|
197
|
+
}
|
|
198
|
+
function itemModified(item) {
|
|
199
|
+
if (item.type === "asset") return item.packModifiedAt ?? 0;
|
|
200
|
+
if (item.type === "file") return item.packModifiedAt ?? 0;
|
|
201
|
+
return 0;
|
|
202
|
+
}
|
|
203
|
+
function itemSize(item) {
|
|
204
|
+
if (item.type === "asset") return item.estimatedSize ?? 0;
|
|
205
|
+
if (item.type === "file") return item.estimatedSize ?? 0;
|
|
206
|
+
return 0;
|
|
207
|
+
}
|
|
208
|
+
function matchesSearch(item, query) {
|
|
209
|
+
if (!query) return true;
|
|
210
|
+
if (item.type === "folder") {
|
|
211
|
+
return item.name.toLowerCase().includes(query) || item.path.toLowerCase().includes(query);
|
|
212
|
+
}
|
|
213
|
+
if (item.type === "file") {
|
|
214
|
+
return item.name.toLowerCase().includes(query) || item.path.toLowerCase().includes(query) || item.assets.some((asset2) => asset2.name.toLowerCase().includes(query) || asset2.kind.toLowerCase().includes(query));
|
|
215
|
+
}
|
|
216
|
+
return item.name.toLowerCase().includes(query) || item.guid.toLowerCase().startsWith(query) || item.kind.toLowerCase().includes(query);
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
// packages/view-plugin-content-browser/src/ui/icons.ts
|
|
220
|
+
import {
|
|
221
|
+
Bone,
|
|
222
|
+
Box,
|
|
223
|
+
Braces,
|
|
224
|
+
Clapperboard,
|
|
225
|
+
Database,
|
|
226
|
+
File,
|
|
227
|
+
FileCode2,
|
|
228
|
+
FileText,
|
|
229
|
+
Film,
|
|
230
|
+
Folder,
|
|
231
|
+
FolderOpen,
|
|
232
|
+
Globe,
|
|
233
|
+
Image,
|
|
234
|
+
Layers,
|
|
235
|
+
Music,
|
|
236
|
+
Package,
|
|
237
|
+
Paintbrush,
|
|
238
|
+
Puzzle,
|
|
239
|
+
Type
|
|
240
|
+
} from "lucide-react";
|
|
241
|
+
var FAMILY_ICONS = {
|
|
242
|
+
dir: Folder,
|
|
243
|
+
scene: Clapperboard,
|
|
244
|
+
pack: Package,
|
|
245
|
+
meta: Layers,
|
|
246
|
+
model: Box,
|
|
247
|
+
image: Image,
|
|
248
|
+
audio: Music,
|
|
249
|
+
font: Type,
|
|
250
|
+
ui: Paintbrush,
|
|
251
|
+
code: FileCode2,
|
|
252
|
+
config: Braces,
|
|
253
|
+
doc: FileText,
|
|
254
|
+
data: Database,
|
|
255
|
+
other: File
|
|
256
|
+
};
|
|
257
|
+
var KIND_ICONS = {
|
|
258
|
+
plugin: Puzzle,
|
|
259
|
+
mesh: Box,
|
|
260
|
+
material: Paintbrush,
|
|
261
|
+
texture: Image,
|
|
262
|
+
image: Image,
|
|
263
|
+
equirect: Globe,
|
|
264
|
+
"cube-texture": Globe,
|
|
265
|
+
sampler: Layers,
|
|
266
|
+
"animation-clip": Film,
|
|
267
|
+
"animation-graph": Film,
|
|
268
|
+
skeleton: Bone,
|
|
269
|
+
skin: Bone,
|
|
270
|
+
scene: Clapperboard,
|
|
271
|
+
ui: Paintbrush,
|
|
272
|
+
audio: Music,
|
|
273
|
+
font: Type,
|
|
274
|
+
video: Film,
|
|
275
|
+
tileset: Layers,
|
|
276
|
+
"particle-effect": Layers,
|
|
277
|
+
"render-pipeline": Layers
|
|
278
|
+
};
|
|
279
|
+
function familyIcon(family) {
|
|
280
|
+
return FAMILY_ICONS[family] ?? File;
|
|
281
|
+
}
|
|
282
|
+
function kindIcon(kind) {
|
|
283
|
+
return KIND_ICONS[kind] ?? Package;
|
|
284
|
+
}
|
|
285
|
+
function itemIcon(item, folderOpen = false) {
|
|
286
|
+
if (item.type === "folder") return folderOpen ? FolderOpen : Folder;
|
|
287
|
+
if (item.type === "file") return familyIcon(item.family);
|
|
288
|
+
return kindIcon(item.kind);
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
// packages/view-plugin-content-browser/src/ui/derived-view.ts
|
|
292
|
+
function translatedOrFallback(t2, key, fallbackKey) {
|
|
293
|
+
const label = t2(key);
|
|
294
|
+
return label === key ? t2(fallbackKey) : label;
|
|
295
|
+
}
|
|
296
|
+
function assetKindLabel(kind, t2) {
|
|
297
|
+
return translatedOrFallback(
|
|
298
|
+
t2,
|
|
299
|
+
`contentBrowser.assetKinds.${kind}`,
|
|
300
|
+
"contentBrowser.assetKinds.default"
|
|
301
|
+
);
|
|
302
|
+
}
|
|
303
|
+
function buildFamilyFilters(activeFamilies, t2) {
|
|
304
|
+
return ALL_FILTER_FAMILIES.map((family) => ({
|
|
305
|
+
id: `family:${family}`,
|
|
306
|
+
family,
|
|
307
|
+
label: translatedOrFallback(
|
|
308
|
+
t2,
|
|
309
|
+
family === "dir" ? "contentBrowser.fileKinds.dir" : `contentBrowser.fileKinds.${family}`,
|
|
310
|
+
"contentBrowser.fileKinds.other"
|
|
311
|
+
),
|
|
312
|
+
active: activeFamilies.has(family)
|
|
313
|
+
}));
|
|
314
|
+
}
|
|
315
|
+
function buildKindFilters(activeKinds, t2) {
|
|
316
|
+
return FILTERABLE_ASSET_KINDS.map((kind) => ({
|
|
317
|
+
id: `kind:${kind}`,
|
|
318
|
+
kind,
|
|
319
|
+
label: assetKindLabel(kind, t2),
|
|
320
|
+
active: activeKinds.has(kind)
|
|
321
|
+
}));
|
|
322
|
+
}
|
|
323
|
+
function toggleFilterId(filterId, activeFamilies, activeKinds) {
|
|
324
|
+
const [scope, value] = filterId.split(":");
|
|
325
|
+
const families = new Set(activeFamilies);
|
|
326
|
+
const kinds = new Set(activeKinds);
|
|
327
|
+
if (scope === "kind" && value) {
|
|
328
|
+
if (kinds.has(value)) kinds.delete(value);
|
|
329
|
+
else kinds.add(value);
|
|
330
|
+
return { families, kinds };
|
|
331
|
+
}
|
|
332
|
+
const family = value;
|
|
333
|
+
if (families.has(family)) families.delete(family);
|
|
334
|
+
else families.add(family);
|
|
335
|
+
return { families, kinds };
|
|
336
|
+
}
|
|
337
|
+
function fileKindLabel(file2, t2) {
|
|
338
|
+
return file2.isAssetPackage ? t2("contentBrowser.fileKinds.assetPackage") : translatedOrFallback(
|
|
339
|
+
t2,
|
|
340
|
+
`contentBrowser.fileKinds.${file2.family}`,
|
|
341
|
+
"contentBrowser.fileKinds.other"
|
|
342
|
+
);
|
|
343
|
+
}
|
|
344
|
+
function deriveViewItems({
|
|
345
|
+
folders,
|
|
346
|
+
files,
|
|
347
|
+
currentPath,
|
|
348
|
+
searchQuery,
|
|
349
|
+
activeFamilies,
|
|
350
|
+
activeKinds,
|
|
351
|
+
sortState,
|
|
352
|
+
expandedPacks,
|
|
353
|
+
withKindLabel
|
|
354
|
+
}) {
|
|
355
|
+
const query = searchQuery.trim().toLowerCase();
|
|
356
|
+
const searchActive = query !== "";
|
|
357
|
+
const kindFilterActive = activeKinds.size > 0;
|
|
358
|
+
const labeledFiles = files.map(withKindLabel);
|
|
359
|
+
const foldersInPath = folders.filter((folder) => dirOfPath(folder.path) === currentPath).filter(() => activeFamilies.size === 0 || activeFamilies.has("dir")).filter((folder) => {
|
|
360
|
+
if (!query) return true;
|
|
361
|
+
const prefix = `${folder.path}/`;
|
|
362
|
+
return matchesSearch(folder, query) || labeledFiles.some((file2) => file2.path.startsWith(prefix) && matchesSearch(file2, query));
|
|
363
|
+
}).toSorted((a, b) => compareItems(a, b, "name", sortState.dir));
|
|
364
|
+
const filesInPath = labeledFiles.filter((file2) => dirOfPath(file2.path) === currentPath).filter((file2) => activeFamilies.size === 0 || activeFamilies.has(file2.family)).filter((file2) => !query || matchesSearch(file2, query)).toSorted((a, b) => compareItems(a, b, sortState.key, sortState.dir));
|
|
365
|
+
if (kindFilterActive) {
|
|
366
|
+
const seen = /* @__PURE__ */ new Set();
|
|
367
|
+
const out = [];
|
|
368
|
+
for (const file2 of filesInPath) {
|
|
369
|
+
for (const asset2 of file2.assets) {
|
|
370
|
+
if (seen.has(asset2.guid) || !activeKinds.has(asset2.kind)) continue;
|
|
371
|
+
if (query && !matchesSearch(asset2, query) && !file2.name.toLowerCase().includes(query)) continue;
|
|
372
|
+
seen.add(asset2.guid);
|
|
373
|
+
out.push(asset2);
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
out.sort((a, b) => a.name.localeCompare(b.name));
|
|
377
|
+
return { foldersInPath: [], filesInPath, viewItems: out, searchActive, kindFilterActive };
|
|
378
|
+
}
|
|
379
|
+
const items = [...foldersInPath];
|
|
380
|
+
for (const file2 of filesInPath) {
|
|
381
|
+
if (file2.assets.length === 0) {
|
|
382
|
+
items.push(file2);
|
|
383
|
+
continue;
|
|
384
|
+
}
|
|
385
|
+
if (file2.assets.length === 1) {
|
|
386
|
+
items.push(...file2.assets);
|
|
387
|
+
continue;
|
|
388
|
+
}
|
|
389
|
+
items.push(file2);
|
|
390
|
+
if (searchActive || expandedPacks.has(file2.path)) items.push(...file2.assets);
|
|
391
|
+
}
|
|
392
|
+
return { foldersInPath, filesInPath, viewItems: items, searchActive, kindFilterActive };
|
|
393
|
+
}
|
|
394
|
+
function nextSortState(current, key) {
|
|
395
|
+
if (current.key === key) return { key, dir: current.dir === "asc" ? "desc" : "asc" };
|
|
396
|
+
return { key, dir: "asc" };
|
|
397
|
+
}
|
|
398
|
+
function setSortDir(current, dir) {
|
|
399
|
+
return current.dir === dir ? current : { ...current, dir };
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
// packages/view-plugin-content-browser/src/ui/CBDetailsList.tsx
|
|
403
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
404
|
+
var COLUMNS = [
|
|
405
|
+
{ key: "name", labelKey: "contentBrowser.details.colName", track: "minmax(160px, 1fr)" },
|
|
406
|
+
{ key: "kind", labelKey: "contentBrowser.details.colType", track: "160px" },
|
|
407
|
+
{ key: "estimatedSize", labelKey: "contentBrowser.details.colSize", track: "90px" },
|
|
408
|
+
{ key: "packModifiedAt", labelKey: "contentBrowser.details.colModified", track: "130px" }
|
|
409
|
+
];
|
|
410
|
+
function CBDetailsList({
|
|
411
|
+
items,
|
|
412
|
+
selectedIds,
|
|
413
|
+
openingKeys,
|
|
414
|
+
sortState,
|
|
415
|
+
onSort,
|
|
416
|
+
onSelect,
|
|
417
|
+
onActivate,
|
|
418
|
+
onContextMenu,
|
|
419
|
+
onBlankClick
|
|
420
|
+
}) {
|
|
421
|
+
const { t: t2 } = useTranslation();
|
|
422
|
+
const gridStyle = { "--cb-details-cols": COLUMNS.map((column) => column.track).join(" ") };
|
|
423
|
+
return /* @__PURE__ */ jsxs(
|
|
424
|
+
"div",
|
|
425
|
+
{
|
|
426
|
+
className: "cb-details-view cb-details-column",
|
|
427
|
+
role: "grid",
|
|
428
|
+
style: gridStyle,
|
|
429
|
+
onClick: (event) => {
|
|
430
|
+
if (event.target === event.currentTarget) onBlankClick();
|
|
431
|
+
},
|
|
432
|
+
children: [
|
|
433
|
+
/* @__PURE__ */ jsx("div", { className: "cb-details-header", role: "row", children: COLUMNS.map((column) => {
|
|
434
|
+
const active = sortState.key === column.key;
|
|
435
|
+
return /* @__PURE__ */ jsxs(
|
|
436
|
+
"button",
|
|
437
|
+
{
|
|
438
|
+
type: "button",
|
|
439
|
+
role: "columnheader",
|
|
440
|
+
className: `cb-details-cell cb-details-th${active ? " active" : ""}`,
|
|
441
|
+
"data-active": active ? "true" : "false",
|
|
442
|
+
"aria-sort": active ? sortState.dir === "asc" ? "ascending" : "descending" : "none",
|
|
443
|
+
onClick: () => onSort(column.key),
|
|
444
|
+
children: [
|
|
445
|
+
/* @__PURE__ */ jsx("span", { children: t2(column.labelKey) }),
|
|
446
|
+
active ? /* @__PURE__ */ jsx("span", { className: "cb-details-sort-arrow", "aria-hidden": "true", children: sortState.dir === "asc" ? "\u25B2" : "\u25BC" }) : null
|
|
447
|
+
]
|
|
448
|
+
},
|
|
449
|
+
column.key
|
|
450
|
+
);
|
|
451
|
+
}) }),
|
|
452
|
+
/* @__PURE__ */ jsx("div", { className: "cb-details-body", children: items.map((item) => {
|
|
453
|
+
const key = viewItemKey(item);
|
|
454
|
+
const selected = selectedIds.has(key);
|
|
455
|
+
const opening = openingKeys?.has(key) ?? false;
|
|
456
|
+
const Icon = itemIcon(item);
|
|
457
|
+
const typeLabel = item.type === "folder" ? t2("contentBrowser.details.typeFolder") : item.type === "file" ? item.kindLabel || fileKindLabel(item, t2) : assetKindLabel(item.kind, t2);
|
|
458
|
+
const sizeLabel = item.type === "folder" ? t2("contentBrowser.details.itemCount", { count: item.childCount }) : formatBytes(item.type === "file" ? item.estimatedSize : item.estimatedSize);
|
|
459
|
+
const modifiedLabel = item.type === "folder" ? "" : formatDate(item.packModifiedAt);
|
|
460
|
+
return /* @__PURE__ */ jsxs(
|
|
461
|
+
"div",
|
|
462
|
+
{
|
|
463
|
+
role: "row",
|
|
464
|
+
tabIndex: 0,
|
|
465
|
+
className: `cb-details-row${selected ? " sel" : ""}${opening ? " is-busy" : ""}`,
|
|
466
|
+
"data-action": CONTENT_BROWSER_ACTIONS.select,
|
|
467
|
+
"aria-selected": selected,
|
|
468
|
+
"aria-busy": opening || void 0,
|
|
469
|
+
onClick: (event) => onSelect(item, event),
|
|
470
|
+
onDoubleClick: () => onActivate(item),
|
|
471
|
+
onKeyDown: (event) => {
|
|
472
|
+
if (event.key === "Enter") {
|
|
473
|
+
event.preventDefault();
|
|
474
|
+
onActivate(item);
|
|
475
|
+
} else if (event.key === " ") {
|
|
476
|
+
event.preventDefault();
|
|
477
|
+
onSelect(item, event);
|
|
478
|
+
}
|
|
479
|
+
},
|
|
480
|
+
onContextMenu: (event) => onContextMenu(event, item),
|
|
481
|
+
children: [
|
|
482
|
+
/* @__PURE__ */ jsxs("div", { className: "cb-details-cell cb-details-name", role: "gridcell", children: [
|
|
483
|
+
/* @__PURE__ */ jsx("span", { className: `cb-details-icon${item.type === "folder" ? " cb-folder-icon" : ""}`, children: /* @__PURE__ */ jsx(Icon, { size: 16 }) }),
|
|
484
|
+
/* @__PURE__ */ jsx("span", { className: "cb-details-label", children: item.name }),
|
|
485
|
+
opening ? /* @__PURE__ */ jsx(Spinner, { className: "cb-item-busy-inline", label: t2("contentBrowser.opening") }) : null
|
|
486
|
+
] }),
|
|
487
|
+
/* @__PURE__ */ jsx("div", { className: "cb-details-cell cb-details-type", role: "gridcell", children: typeLabel }),
|
|
488
|
+
/* @__PURE__ */ jsx("div", { className: "cb-details-cell cb-details-size", role: "gridcell", children: sizeLabel }),
|
|
489
|
+
/* @__PURE__ */ jsx("div", { className: "cb-details-cell cb-details-modified", role: "gridcell", children: modifiedLabel })
|
|
490
|
+
]
|
|
491
|
+
},
|
|
492
|
+
key
|
|
493
|
+
);
|
|
494
|
+
}) })
|
|
495
|
+
]
|
|
496
|
+
}
|
|
497
|
+
);
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
// packages/view-plugin-content-browser/src/ui/CBGrid.tsx
|
|
501
|
+
import { ChevronDown } from "lucide-react";
|
|
502
|
+
import {
|
|
503
|
+
useCallback as useCallback2,
|
|
504
|
+
useLayoutEffect,
|
|
505
|
+
useRef,
|
|
506
|
+
useState
|
|
507
|
+
} from "react";
|
|
508
|
+
import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
509
|
+
function CBGrid({
|
|
510
|
+
items,
|
|
511
|
+
thumbnailSize,
|
|
512
|
+
layout,
|
|
513
|
+
searchActive,
|
|
514
|
+
expandedPacks,
|
|
515
|
+
selectedIds,
|
|
516
|
+
openingKeys,
|
|
517
|
+
onSelect,
|
|
518
|
+
onActivate,
|
|
519
|
+
onContextMenu,
|
|
520
|
+
onTogglePackExpansion,
|
|
521
|
+
onBlankClick
|
|
522
|
+
}) {
|
|
523
|
+
const { t: t2 } = useTranslation();
|
|
524
|
+
const rootRef = useRef(null);
|
|
525
|
+
const [backdrops, setBackdrops] = useState([]);
|
|
526
|
+
const grouping = !searchActive;
|
|
527
|
+
const measureGroups = useCallback2(() => {
|
|
528
|
+
const container = rootRef.current;
|
|
529
|
+
if (!container) {
|
|
530
|
+
setBackdrops((prev) => prev.length ? [] : prev);
|
|
531
|
+
return;
|
|
532
|
+
}
|
|
533
|
+
const members = container.querySelectorAll("[data-cb-group]");
|
|
534
|
+
if (members.length === 0) {
|
|
535
|
+
setBackdrops((prev) => prev.length ? [] : prev);
|
|
536
|
+
return;
|
|
537
|
+
}
|
|
538
|
+
const byGroup = /* @__PURE__ */ new Map();
|
|
539
|
+
members.forEach((el) => {
|
|
540
|
+
const key = el.dataset.cbGroup;
|
|
541
|
+
if (!key) return;
|
|
542
|
+
const list = byGroup.get(key);
|
|
543
|
+
if (list) list.push(el);
|
|
544
|
+
else byGroup.set(key, [el]);
|
|
545
|
+
});
|
|
546
|
+
const pad = layout === "list" ? 2 : 4;
|
|
547
|
+
const radius = 8;
|
|
548
|
+
const containerRight = container.clientWidth;
|
|
549
|
+
const next = [];
|
|
550
|
+
for (const [key, els] of byGroup) {
|
|
551
|
+
const rows = [];
|
|
552
|
+
for (const el of els) {
|
|
553
|
+
const top = el.offsetTop;
|
|
554
|
+
const row = rows.find((entry) => Math.abs(entry.top - top) <= 4);
|
|
555
|
+
if (row) row.els.push(el);
|
|
556
|
+
else rows.push({ top, els: [el] });
|
|
557
|
+
}
|
|
558
|
+
const multiRow = rows.length > 1;
|
|
559
|
+
rows.forEach((row, idx) => {
|
|
560
|
+
let left = Infinity;
|
|
561
|
+
let right = -Infinity;
|
|
562
|
+
let top = Infinity;
|
|
563
|
+
let bottom = -Infinity;
|
|
564
|
+
for (const el of row.els) {
|
|
565
|
+
left = Math.min(left, el.offsetLeft);
|
|
566
|
+
right = Math.max(right, el.offsetLeft + el.offsetWidth);
|
|
567
|
+
top = Math.min(top, el.offsetTop);
|
|
568
|
+
bottom = Math.max(bottom, el.offsetTop + el.offsetHeight);
|
|
569
|
+
}
|
|
570
|
+
const extendLeft = multiRow && idx > 0;
|
|
571
|
+
const extendRight = multiRow && idx < rows.length - 1;
|
|
572
|
+
const x0 = extendLeft ? 0 : left - pad;
|
|
573
|
+
const x1 = extendRight ? containerRight : right + pad;
|
|
574
|
+
next.push({
|
|
575
|
+
key: `${key}#${idx}`,
|
|
576
|
+
left: x0,
|
|
577
|
+
top: top - pad,
|
|
578
|
+
width: x1 - x0,
|
|
579
|
+
height: bottom - top + pad * 2,
|
|
580
|
+
radius: `${extendLeft ? 0 : radius}px ${extendRight ? 0 : radius}px ${extendRight ? 0 : radius}px ${extendLeft ? 0 : radius}px`
|
|
581
|
+
});
|
|
582
|
+
});
|
|
583
|
+
}
|
|
584
|
+
setBackdrops(next);
|
|
585
|
+
}, [layout]);
|
|
586
|
+
useLayoutEffect(() => {
|
|
587
|
+
measureGroups();
|
|
588
|
+
const container = rootRef.current;
|
|
589
|
+
if (!container) return;
|
|
590
|
+
let raf = 0;
|
|
591
|
+
const schedule = () => {
|
|
592
|
+
cancelAnimationFrame(raf);
|
|
593
|
+
raf = requestAnimationFrame(measureGroups);
|
|
594
|
+
};
|
|
595
|
+
const observer = new ResizeObserver(schedule);
|
|
596
|
+
observer.observe(container);
|
|
597
|
+
container.querySelectorAll("[data-cb-group]").forEach((el) => observer.observe(el));
|
|
598
|
+
return () => {
|
|
599
|
+
cancelAnimationFrame(raf);
|
|
600
|
+
observer.disconnect();
|
|
601
|
+
};
|
|
602
|
+
}, [measureGroups, items, expandedPacks, thumbnailSize, searchActive]);
|
|
603
|
+
const renderCard = (item, expanded = false, groupKey) => {
|
|
604
|
+
const key = viewItemKey(item);
|
|
605
|
+
const selected = selectedIds.has(key);
|
|
606
|
+
const opening = openingKeys?.has(key) ?? false;
|
|
607
|
+
const Icon = itemIcon(item);
|
|
608
|
+
const isFolder = item.type === "folder";
|
|
609
|
+
const isFile = item.type === "file";
|
|
610
|
+
const groupCount = grouping && isFile && item.assets.length >= 2 ? item.assets.length : 0;
|
|
611
|
+
const stacked = groupCount >= 2;
|
|
612
|
+
const meta = isFolder ? null : isFile ? item.kindLabel : assetKindLabel(item.kind, t2);
|
|
613
|
+
return /* @__PURE__ */ jsxs2(
|
|
614
|
+
"div",
|
|
615
|
+
{
|
|
616
|
+
role: "button",
|
|
617
|
+
tabIndex: 0,
|
|
618
|
+
className: `cb-grid-item cb-fe-card${isFolder ? " cb-grid-folder" : ""}${isFile ? " cb-file-card" : ""}${selected ? " sel" : ""}${expanded ? " cb-pack-expanded" : ""}${stacked ? " cb-group-card" : ""}${groupKey ? " cb-group-member" : ""}${opening ? " is-busy" : ""}`,
|
|
619
|
+
"data-action": CONTENT_BROWSER_ACTIONS.select,
|
|
620
|
+
"data-cb-group": groupKey,
|
|
621
|
+
"aria-selected": selected,
|
|
622
|
+
"aria-busy": opening || void 0,
|
|
623
|
+
onClick: (event) => onSelect(item, event),
|
|
624
|
+
onDoubleClick: () => onActivate(item),
|
|
625
|
+
onKeyDown: (event) => {
|
|
626
|
+
if (event.key === "Enter") {
|
|
627
|
+
event.preventDefault();
|
|
628
|
+
onActivate(item);
|
|
629
|
+
} else if (event.key === " ") {
|
|
630
|
+
event.preventDefault();
|
|
631
|
+
onSelect(item, event);
|
|
632
|
+
}
|
|
633
|
+
},
|
|
634
|
+
onContextMenu: (event) => onContextMenu(event, item),
|
|
635
|
+
children: [
|
|
636
|
+
/* @__PURE__ */ jsxs2("span", { className: `cb-grid-thumb cb-fe-thumb${isFile ? " cb-file-thumb" : ""}${isFolder ? " cb-folder-thumb" : ""}`, children: [
|
|
637
|
+
/* @__PURE__ */ jsx2("span", { className: isFolder ? "cb-folder-icon" : "cb-grid-icon", children: /* @__PURE__ */ jsx2(Icon, {}) }),
|
|
638
|
+
groupCount >= 1 ? /* @__PURE__ */ jsxs2(
|
|
639
|
+
"button",
|
|
640
|
+
{
|
|
641
|
+
type: "button",
|
|
642
|
+
className: `cb-group-badge${expanded ? " open" : ""}`,
|
|
643
|
+
"data-action": CONTENT_BROWSER_ACTIONS.togglePackExpansion,
|
|
644
|
+
title: t2("contentBrowser.menu.expandSubAssets"),
|
|
645
|
+
onClick: (event) => {
|
|
646
|
+
event.stopPropagation();
|
|
647
|
+
onSelect(item, event);
|
|
648
|
+
onTogglePackExpansion(item.path);
|
|
649
|
+
},
|
|
650
|
+
children: [
|
|
651
|
+
/* @__PURE__ */ jsx2("span", { className: "cb-group-badge-num", children: groupCount }),
|
|
652
|
+
/* @__PURE__ */ jsx2(ChevronDown, { size: 11 })
|
|
653
|
+
]
|
|
654
|
+
}
|
|
655
|
+
) : null
|
|
656
|
+
] }),
|
|
657
|
+
/* @__PURE__ */ jsxs2("span", { className: `cb-grid-label cb-fe-label${meta ? " has-kind" : ""}`, children: [
|
|
658
|
+
/* @__PURE__ */ jsx2("span", { className: "cb-fe-name", children: item.name }),
|
|
659
|
+
meta ? /* @__PURE__ */ jsx2("span", { className: "cb-card-meta", children: meta }) : null
|
|
660
|
+
] }),
|
|
661
|
+
opening ? layout === "list" ? /* @__PURE__ */ jsx2(Spinner, { className: "cb-item-busy-inline", label: t2("contentBrowser.opening") }) : /* @__PURE__ */ jsx2("span", { className: "cb-item-busy-veil", children: /* @__PURE__ */ jsx2(Spinner, { label: t2("contentBrowser.opening") }) }) : null
|
|
662
|
+
]
|
|
663
|
+
},
|
|
664
|
+
key
|
|
665
|
+
);
|
|
666
|
+
};
|
|
667
|
+
const nodes = [];
|
|
668
|
+
for (let index = 0; index < items.length; ) {
|
|
669
|
+
const item = items[index];
|
|
670
|
+
if (!item) {
|
|
671
|
+
index += 1;
|
|
672
|
+
continue;
|
|
673
|
+
}
|
|
674
|
+
if (grouping && item.type === "file" && item.assets.length >= 2 && expandedPacks.has(item.path)) {
|
|
675
|
+
const guids = new Set(item.assets.map((asset2) => asset2.guid));
|
|
676
|
+
nodes.push(renderCard(item, true, item.path));
|
|
677
|
+
let nextIndex = index + 1;
|
|
678
|
+
for (; nextIndex < items.length; nextIndex += 1) {
|
|
679
|
+
const next = items[nextIndex];
|
|
680
|
+
if (!next || next.type !== "asset" || !guids.has(next.guid)) break;
|
|
681
|
+
nodes.push(renderCard(next, false, item.path));
|
|
682
|
+
}
|
|
683
|
+
index = nextIndex;
|
|
684
|
+
continue;
|
|
685
|
+
}
|
|
686
|
+
nodes.push(renderCard(item));
|
|
687
|
+
index += 1;
|
|
688
|
+
}
|
|
689
|
+
return /* @__PURE__ */ jsxs2(
|
|
690
|
+
"div",
|
|
691
|
+
{
|
|
692
|
+
ref: rootRef,
|
|
693
|
+
className: `cb-grid-view cb-fe-grid cb-layout-${layout}`,
|
|
694
|
+
style: { "--cb-thumb": `${thumbnailSize}px` },
|
|
695
|
+
onClick: (event) => {
|
|
696
|
+
if (event.target === event.currentTarget) onBlankClick();
|
|
697
|
+
},
|
|
698
|
+
children: [
|
|
699
|
+
backdrops.length > 0 ? /* @__PURE__ */ jsx2("div", { className: "cb-group-backdrops", "aria-hidden": "true", children: backdrops.map((backdrop) => /* @__PURE__ */ jsx2("div", { className: "cb-group-backdrop", style: { left: backdrop.left, top: backdrop.top, width: backdrop.width, height: backdrop.height, borderRadius: backdrop.radius } }, backdrop.key)) }) : null,
|
|
700
|
+
nodes
|
|
701
|
+
]
|
|
702
|
+
}
|
|
703
|
+
);
|
|
704
|
+
}
|
|
705
|
+
|
|
706
|
+
// packages/view-plugin-content-browser/src/ui/CBNavigationBar.tsx
|
|
707
|
+
import { ChevronLeft, ChevronRight, Folder as Folder2, RefreshCw } from "lucide-react";
|
|
708
|
+
import { useCallback as useCallback3, useState as useState2 } from "react";
|
|
709
|
+
import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
710
|
+
function immediateChildren(allDirs, path) {
|
|
711
|
+
const prefix = path ? `${path}/` : "";
|
|
712
|
+
const depth = path ? path.split("/").length : 0;
|
|
713
|
+
const out = [];
|
|
714
|
+
for (const dir of allDirs) {
|
|
715
|
+
if (path && dir === path) continue;
|
|
716
|
+
if (!dir.startsWith(prefix)) continue;
|
|
717
|
+
if (dir.split("/").length !== depth + 1) continue;
|
|
718
|
+
out.push({ name: dir.split("/").pop() ?? dir, path: dir });
|
|
719
|
+
}
|
|
720
|
+
return out.sort((a, b) => a.name.localeCompare(b.name));
|
|
721
|
+
}
|
|
722
|
+
function LevelChevron({
|
|
723
|
+
levelPath,
|
|
724
|
+
activeNextSeg,
|
|
725
|
+
allDirs,
|
|
726
|
+
onNavigate,
|
|
727
|
+
label
|
|
728
|
+
}) {
|
|
729
|
+
const children = immediateChildren(allDirs, levelPath);
|
|
730
|
+
if (children.length === 0) {
|
|
731
|
+
return /* @__PURE__ */ jsx3("span", { className: "cb-crumb-chevron", "aria-hidden": "true", children: /* @__PURE__ */ jsx3(ChevronRight, { size: 12 }) });
|
|
732
|
+
}
|
|
733
|
+
return /* @__PURE__ */ jsx3("span", { className: "cb-crumb-chevron", onClick: (event) => event.stopPropagation(), children: /* @__PURE__ */ jsx3(
|
|
734
|
+
MenuDropdown,
|
|
735
|
+
{
|
|
736
|
+
label,
|
|
737
|
+
align: "start",
|
|
738
|
+
className: "cb-crumb-menu",
|
|
739
|
+
trigger: /* @__PURE__ */ jsx3(
|
|
740
|
+
"button",
|
|
741
|
+
{
|
|
742
|
+
type: "button",
|
|
743
|
+
className: "cb-crumb-chevron-btn",
|
|
744
|
+
"aria-label": label,
|
|
745
|
+
title: label,
|
|
746
|
+
onClick: (event) => event.stopPropagation(),
|
|
747
|
+
children: /* @__PURE__ */ jsx3(ChevronRight, { size: 12 })
|
|
748
|
+
}
|
|
749
|
+
),
|
|
750
|
+
items: children.map((child) => ({
|
|
751
|
+
id: child.path,
|
|
752
|
+
label: child.name,
|
|
753
|
+
icon: /* @__PURE__ */ jsx3(Folder2, { size: 14 }),
|
|
754
|
+
buttonProps: child.name === activeNextSeg ? { "data-active": "" } : void 0,
|
|
755
|
+
onSelect: () => onNavigate(child.path)
|
|
756
|
+
}))
|
|
757
|
+
}
|
|
758
|
+
) });
|
|
759
|
+
}
|
|
760
|
+
function CBNavigationBar({
|
|
761
|
+
currentPath,
|
|
762
|
+
projectLabel,
|
|
763
|
+
allDirs,
|
|
764
|
+
canGoBack,
|
|
765
|
+
canGoForward,
|
|
766
|
+
refreshDisabled,
|
|
767
|
+
onBack,
|
|
768
|
+
onForward,
|
|
769
|
+
onRefresh,
|
|
770
|
+
onNavigate
|
|
771
|
+
}) {
|
|
772
|
+
const { t: t2 } = useTranslation();
|
|
773
|
+
const segments = currentPath ? currentPath.split("/").filter(Boolean) : [];
|
|
774
|
+
const [editing, setEditing] = useState2(false);
|
|
775
|
+
const [draft, setDraft] = useState2("");
|
|
776
|
+
const beginEdit = useCallback3(() => {
|
|
777
|
+
setDraft(currentPath);
|
|
778
|
+
setEditing(true);
|
|
779
|
+
}, [currentPath]);
|
|
780
|
+
const commit = useCallback3(() => {
|
|
781
|
+
onNavigate(normalizePathInput(draft));
|
|
782
|
+
setEditing(false);
|
|
783
|
+
}, [draft, onNavigate]);
|
|
784
|
+
const onInputKeyDown = useCallback3((event) => {
|
|
785
|
+
if (event.key === "Enter") {
|
|
786
|
+
event.preventDefault();
|
|
787
|
+
commit();
|
|
788
|
+
} else if (event.key === "Escape") {
|
|
789
|
+
event.preventDefault();
|
|
790
|
+
setEditing(false);
|
|
791
|
+
}
|
|
792
|
+
}, [commit]);
|
|
793
|
+
const onAddressKeyDown = useCallback3((event) => {
|
|
794
|
+
if (event.key === "Enter" || event.key === " ") {
|
|
795
|
+
event.preventDefault();
|
|
796
|
+
beginEdit();
|
|
797
|
+
}
|
|
798
|
+
}, [beginEdit]);
|
|
799
|
+
const stopAndNavigate = (event, path) => {
|
|
800
|
+
event.stopPropagation();
|
|
801
|
+
onNavigate(path);
|
|
802
|
+
};
|
|
803
|
+
return /* @__PURE__ */ jsxs3(Toolbar, { className: "cb-navigation-bar", children: [
|
|
804
|
+
/* @__PURE__ */ jsx3(
|
|
805
|
+
IconButton,
|
|
806
|
+
{
|
|
807
|
+
size: "compact",
|
|
808
|
+
variant: "quiet",
|
|
809
|
+
label: t2("contentBrowser.back"),
|
|
810
|
+
icon: /* @__PURE__ */ jsx3(ChevronLeft, { size: 14 }),
|
|
811
|
+
"data-action": CONTENT_BROWSER_ACTIONS.navigateBack,
|
|
812
|
+
disabled: !canGoBack,
|
|
813
|
+
onClick: onBack
|
|
814
|
+
}
|
|
815
|
+
),
|
|
816
|
+
/* @__PURE__ */ jsx3(
|
|
817
|
+
IconButton,
|
|
818
|
+
{
|
|
819
|
+
size: "compact",
|
|
820
|
+
variant: "quiet",
|
|
821
|
+
label: t2("contentBrowser.forward"),
|
|
822
|
+
icon: /* @__PURE__ */ jsx3(ChevronRight, { size: 14 }),
|
|
823
|
+
"data-action": CONTENT_BROWSER_ACTIONS.navigateForward,
|
|
824
|
+
disabled: !canGoForward,
|
|
825
|
+
onClick: onForward
|
|
826
|
+
}
|
|
827
|
+
),
|
|
828
|
+
/* @__PURE__ */ jsx3(
|
|
829
|
+
IconButton,
|
|
830
|
+
{
|
|
831
|
+
size: "compact",
|
|
832
|
+
variant: "quiet",
|
|
833
|
+
label: t2("contentBrowser.refresh"),
|
|
834
|
+
disabled: refreshDisabled,
|
|
835
|
+
icon: /* @__PURE__ */ jsx3(RefreshCw, { size: 13 }),
|
|
836
|
+
"data-action": CONTENT_BROWSER_ACTIONS.refresh,
|
|
837
|
+
onClick: onRefresh
|
|
838
|
+
}
|
|
839
|
+
),
|
|
840
|
+
/* @__PURE__ */ jsx3("div", { className: "cb-address-slot", children: editing ? /* @__PURE__ */ jsx3(
|
|
841
|
+
"input",
|
|
842
|
+
{
|
|
843
|
+
autoFocus: true,
|
|
844
|
+
spellCheck: false,
|
|
845
|
+
className: "cb-address-input",
|
|
846
|
+
value: draft,
|
|
847
|
+
placeholder: t2("contentBrowser.actions.editPathPlaceholder"),
|
|
848
|
+
onChange: (event) => setDraft(event.target.value),
|
|
849
|
+
onKeyDown: onInputKeyDown,
|
|
850
|
+
onBlur: () => setEditing(false),
|
|
851
|
+
onFocus: (event) => event.currentTarget.select()
|
|
852
|
+
}
|
|
853
|
+
) : /* @__PURE__ */ jsx3(
|
|
854
|
+
"div",
|
|
855
|
+
{
|
|
856
|
+
className: "cb-address",
|
|
857
|
+
role: "button",
|
|
858
|
+
tabIndex: 0,
|
|
859
|
+
title: t2("contentBrowser.actions.editPath"),
|
|
860
|
+
onClick: beginEdit,
|
|
861
|
+
onKeyDown: onAddressKeyDown,
|
|
862
|
+
children: /* @__PURE__ */ jsxs3("div", { className: "cb-address-crumb", children: [
|
|
863
|
+
/* @__PURE__ */ jsx3(
|
|
864
|
+
"button",
|
|
865
|
+
{
|
|
866
|
+
type: "button",
|
|
867
|
+
className: segments.length ? "cb-crumb-item" : "cb-crumb-item cb-crumb-current",
|
|
868
|
+
"aria-current": segments.length === 0 ? "page" : void 0,
|
|
869
|
+
"data-action": CONTENT_BROWSER_ACTIONS.navigate,
|
|
870
|
+
onClick: (event) => stopAndNavigate(event, ""),
|
|
871
|
+
children: projectLabel
|
|
872
|
+
}
|
|
873
|
+
),
|
|
874
|
+
segments.map((segment, index) => {
|
|
875
|
+
const path = segments.slice(0, index + 1).join("/");
|
|
876
|
+
const parentPath = segments.slice(0, index).join("/");
|
|
877
|
+
const parentLabel = index === 0 ? projectLabel : segments[index - 1] ?? projectLabel;
|
|
878
|
+
const isCurrent = index === segments.length - 1;
|
|
879
|
+
return /* @__PURE__ */ jsxs3("span", { className: "cb-crumb-segment", children: [
|
|
880
|
+
/* @__PURE__ */ jsx3(
|
|
881
|
+
LevelChevron,
|
|
882
|
+
{
|
|
883
|
+
levelPath: parentPath,
|
|
884
|
+
activeNextSeg: segment,
|
|
885
|
+
allDirs,
|
|
886
|
+
onNavigate,
|
|
887
|
+
label: t2("contentBrowser.actions.openSubfolders", { name: parentLabel })
|
|
888
|
+
}
|
|
889
|
+
),
|
|
890
|
+
/* @__PURE__ */ jsx3(
|
|
891
|
+
"button",
|
|
892
|
+
{
|
|
893
|
+
type: "button",
|
|
894
|
+
className: isCurrent ? "cb-crumb-item cb-crumb-current" : "cb-crumb-item",
|
|
895
|
+
"aria-current": isCurrent ? "page" : void 0,
|
|
896
|
+
"data-action": CONTENT_BROWSER_ACTIONS.navigate,
|
|
897
|
+
onClick: (event) => stopAndNavigate(event, path),
|
|
898
|
+
children: segment
|
|
899
|
+
}
|
|
900
|
+
)
|
|
901
|
+
] }, path);
|
|
902
|
+
})
|
|
903
|
+
] })
|
|
904
|
+
}
|
|
905
|
+
) })
|
|
906
|
+
] });
|
|
907
|
+
}
|
|
908
|
+
|
|
909
|
+
// packages/view-plugin-content-browser/src/ui/CBPreviewPanel.tsx
|
|
910
|
+
import { X } from "lucide-react";
|
|
911
|
+
import { useEffect as useEffect3, useState as useState5 } from "react";
|
|
912
|
+
|
|
913
|
+
// packages/view-plugin-content-browser/src/ui/preview/media-preview-policy.ts
|
|
914
|
+
var MAX_BINARY_PREVIEW_BYTES = 10 * 1024 * 1024;
|
|
915
|
+
function isBrowserMediaPreviewKind(kind) {
|
|
916
|
+
return kind === "image" || kind === "audio" || kind === "video";
|
|
917
|
+
}
|
|
918
|
+
function isFontPreviewInfo(info) {
|
|
919
|
+
return info.kind === "binary" && info.mime.startsWith("font/");
|
|
920
|
+
}
|
|
921
|
+
function familySuggestsMediaPreview(family) {
|
|
922
|
+
return family === "image" || family === "audio" || family === "font";
|
|
923
|
+
}
|
|
924
|
+
function familySuggestsEnginePreview(family) {
|
|
925
|
+
return family === "model";
|
|
926
|
+
}
|
|
927
|
+
function svgMarkupSrc(content) {
|
|
928
|
+
return `data:image/svg+xml;charset=utf-8,${encodeURIComponent(content)}`;
|
|
929
|
+
}
|
|
930
|
+
function mediaPreviewBlockedReason(info) {
|
|
931
|
+
if (info.dataUrl || info.kind === "image" && info.content) return null;
|
|
932
|
+
if (info.size > MAX_BINARY_PREVIEW_BYTES) return "too-large";
|
|
933
|
+
return "unavailable";
|
|
934
|
+
}
|
|
935
|
+
|
|
936
|
+
// packages/view-plugin-content-browser/src/ui/preview/MediaPreview.tsx
|
|
937
|
+
import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
938
|
+
function MediaPreview({
|
|
939
|
+
info,
|
|
940
|
+
fileName,
|
|
941
|
+
t: t2
|
|
942
|
+
}) {
|
|
943
|
+
if (isFontPreviewInfo(info)) {
|
|
944
|
+
return /* @__PURE__ */ jsx4(FontPreview, { info, sample: fileName, t: t2 });
|
|
945
|
+
}
|
|
946
|
+
if (!isBrowserMediaPreviewKind(info.kind)) {
|
|
947
|
+
return /* @__PURE__ */ jsx4("div", { className: "cb-preview-note", children: t2("contentBrowser.preview.noMediaPreview") });
|
|
948
|
+
}
|
|
949
|
+
const blocked = mediaPreviewBlockedReason(info);
|
|
950
|
+
if (blocked === "too-large") {
|
|
951
|
+
return /* @__PURE__ */ jsx4("div", { className: "cb-preview-note", children: t2("contentBrowser.preview.previewTooLarge") });
|
|
952
|
+
}
|
|
953
|
+
if (blocked === "unavailable") {
|
|
954
|
+
return /* @__PURE__ */ jsx4("div", { className: "cb-preview-note", children: t2("contentBrowser.preview.noMediaPreview") });
|
|
955
|
+
}
|
|
956
|
+
const src = info.dataUrl ?? (info.content ? svgMarkupSrc(info.content) : void 0);
|
|
957
|
+
if (!src) {
|
|
958
|
+
return /* @__PURE__ */ jsx4("div", { className: "cb-preview-note", children: t2("contentBrowser.preview.noMediaPreview") });
|
|
959
|
+
}
|
|
960
|
+
if (info.kind === "audio") {
|
|
961
|
+
return /* @__PURE__ */ jsx4("div", { className: "cb-preview-media", children: /* @__PURE__ */ jsx4("audio", { className: "cb-preview-audio", controls: true, preload: "metadata", src, "aria-label": fileName }) });
|
|
962
|
+
}
|
|
963
|
+
if (info.kind === "video") {
|
|
964
|
+
return /* @__PURE__ */ jsx4("div", { className: "cb-preview-media", children: /* @__PURE__ */ jsx4("video", { className: "cb-preview-video", controls: true, preload: "metadata", src, "aria-label": fileName }) });
|
|
965
|
+
}
|
|
966
|
+
return /* @__PURE__ */ jsx4("div", { className: "cb-preview-media", children: /* @__PURE__ */ jsx4("img", { className: "cb-preview-image", src, alt: fileName, decoding: "async" }) });
|
|
967
|
+
}
|
|
968
|
+
function FontPreview({
|
|
969
|
+
info,
|
|
970
|
+
sample,
|
|
971
|
+
t: t2
|
|
972
|
+
}) {
|
|
973
|
+
const blocked = mediaPreviewBlockedReason(info);
|
|
974
|
+
if (blocked === "too-large") {
|
|
975
|
+
return /* @__PURE__ */ jsx4("div", { className: "cb-preview-note", children: t2("contentBrowser.preview.previewTooLarge") });
|
|
976
|
+
}
|
|
977
|
+
if (!info.dataUrl) {
|
|
978
|
+
return /* @__PURE__ */ jsx4("div", { className: "cb-preview-note", children: t2("contentBrowser.preview.noMediaPreview") });
|
|
979
|
+
}
|
|
980
|
+
const fontId = `cb-preview-font-${info.path.replace(/[^\w-]+/g, "-")}`;
|
|
981
|
+
return /* @__PURE__ */ jsxs4("div", { className: "cb-preview-media cb-preview-font", children: [
|
|
982
|
+
/* @__PURE__ */ jsx4("style", { children: `@font-face{font-family:${fontId};src:url(${info.dataUrl});font-display:swap;}` }),
|
|
983
|
+
/* @__PURE__ */ jsx4("p", { className: "cb-preview-font-sample", style: { fontFamily: fontId }, children: t2("contentBrowser.preview.fontSample") }),
|
|
984
|
+
/* @__PURE__ */ jsx4("p", { className: "cb-preview-font-meta", children: sample })
|
|
985
|
+
] });
|
|
986
|
+
}
|
|
987
|
+
|
|
988
|
+
// packages/view-plugin-content-browser/src/ui/preview/CodePreview.tsx
|
|
989
|
+
import { useEffect, useState as useState3 } from "react";
|
|
990
|
+
|
|
991
|
+
// packages/view-plugin-content-browser/src/ui/preview/ext-language.ts
|
|
992
|
+
var EXT_LANGUAGE = {
|
|
993
|
+
ts: { lang: "typescript", label: "TypeScript" },
|
|
994
|
+
mts: { lang: "typescript", label: "TypeScript" },
|
|
995
|
+
cts: { lang: "typescript", label: "TypeScript" },
|
|
996
|
+
tsx: { lang: "tsx", label: "TSX" },
|
|
997
|
+
js: { lang: "javascript", label: "JavaScript" },
|
|
998
|
+
mjs: { lang: "javascript", label: "JavaScript" },
|
|
999
|
+
cjs: { lang: "javascript", label: "JavaScript" },
|
|
1000
|
+
jsx: { lang: "jsx", label: "JSX" },
|
|
1001
|
+
json: { lang: "json", label: "JSON" },
|
|
1002
|
+
jsonc: { lang: "jsonc", label: "JSONC" },
|
|
1003
|
+
json5: { lang: "json5", label: "JSON5" },
|
|
1004
|
+
css: { lang: "css", label: "CSS" },
|
|
1005
|
+
scss: { lang: "scss", label: "SCSS" },
|
|
1006
|
+
html: { lang: "html", label: "HTML" },
|
|
1007
|
+
htm: { lang: "html", label: "HTML" },
|
|
1008
|
+
md: { lang: "markdown", label: "Markdown" },
|
|
1009
|
+
markdown: { lang: "markdown", label: "Markdown" },
|
|
1010
|
+
py: { lang: "python", label: "Python" },
|
|
1011
|
+
rs: { lang: "rust", label: "Rust" },
|
|
1012
|
+
wgsl: { lang: "wgsl", label: "WGSL" },
|
|
1013
|
+
glsl: { lang: "glsl", label: "GLSL" },
|
|
1014
|
+
vert: { lang: "glsl", label: "GLSL" },
|
|
1015
|
+
frag: { lang: "glsl", label: "GLSL" },
|
|
1016
|
+
sh: { lang: "shellscript", label: "Shell" },
|
|
1017
|
+
bash: { lang: "shellscript", label: "Shell" },
|
|
1018
|
+
zsh: { lang: "shellscript", label: "Shell" },
|
|
1019
|
+
yaml: { lang: "yaml", label: "YAML" },
|
|
1020
|
+
yml: { lang: "yaml", label: "YAML" },
|
|
1021
|
+
toml: { lang: "toml", label: "TOML" },
|
|
1022
|
+
xml: { lang: "xml", label: "XML" }
|
|
1023
|
+
};
|
|
1024
|
+
function resolveLanguage(ext) {
|
|
1025
|
+
const key = ext.replace(/^\./, "").toLowerCase();
|
|
1026
|
+
return EXT_LANGUAGE[key];
|
|
1027
|
+
}
|
|
1028
|
+
|
|
1029
|
+
// packages/view-plugin-content-browser/src/ui/preview/code-preview-policy.ts
|
|
1030
|
+
var MAX_HIGHLIGHT_BYTES = 200 * 1024;
|
|
1031
|
+
var MAX_HIGHLIGHT_LINES = 5e3;
|
|
1032
|
+
function countLines(text) {
|
|
1033
|
+
let lines = 1;
|
|
1034
|
+
for (let index = 0; index < text.length; index += 1) {
|
|
1035
|
+
if (text.charCodeAt(index) === 10) lines += 1;
|
|
1036
|
+
}
|
|
1037
|
+
return lines;
|
|
1038
|
+
}
|
|
1039
|
+
function decideHighlight(input) {
|
|
1040
|
+
const { ext, size, content } = input;
|
|
1041
|
+
if (content == null) return { highlight: false, reason: "no-content" };
|
|
1042
|
+
const resolved = resolveLanguage(ext);
|
|
1043
|
+
if (!resolved) return { highlight: false, reason: "unknown-language" };
|
|
1044
|
+
const byteSize = Math.max(size, content.length);
|
|
1045
|
+
if (byteSize > MAX_HIGHLIGHT_BYTES || countLines(content) > MAX_HIGHLIGHT_LINES) {
|
|
1046
|
+
return { highlight: false, reason: "too-large" };
|
|
1047
|
+
}
|
|
1048
|
+
return { highlight: true, lang: resolved.lang, label: resolved.label };
|
|
1049
|
+
}
|
|
1050
|
+
|
|
1051
|
+
// packages/view-plugin-content-browser/src/ui/preview/highlighter.ts
|
|
1052
|
+
var HIGHLIGHT_THEMES = {
|
|
1053
|
+
light: "github-light-default",
|
|
1054
|
+
dark: "github-dark-default"
|
|
1055
|
+
};
|
|
1056
|
+
var LANG_LOADERS = {
|
|
1057
|
+
typescript: () => import("./typescript-PBKAS54P.mjs"),
|
|
1058
|
+
tsx: () => import("./tsx-2E6WNX2E.mjs"),
|
|
1059
|
+
javascript: () => import("./javascript-LN3OC7S2.mjs"),
|
|
1060
|
+
jsx: () => import("./jsx-A7RDCLJO.mjs"),
|
|
1061
|
+
json: () => import("./json-5CUGWTOP.mjs"),
|
|
1062
|
+
jsonc: () => import("./jsonc-SWID6VOZ.mjs"),
|
|
1063
|
+
json5: () => import("./json5-YZQI5VNO.mjs"),
|
|
1064
|
+
css: () => import("./css-BKH4SVJG.mjs"),
|
|
1065
|
+
scss: () => import("./scss-CFXRHUUW.mjs"),
|
|
1066
|
+
html: () => import("./html-FRVIUV63.mjs"),
|
|
1067
|
+
markdown: () => import("./markdown-QTCU5KP5.mjs"),
|
|
1068
|
+
python: () => import("./python-LAZONBIB.mjs"),
|
|
1069
|
+
rust: () => import("./rust-XWTPJFJO.mjs"),
|
|
1070
|
+
wgsl: () => import("./wgsl-PS6QPRLZ.mjs"),
|
|
1071
|
+
glsl: () => import("./glsl-UC3YWUD2.mjs"),
|
|
1072
|
+
shellscript: () => import("./shellscript-OHO3LCVU.mjs"),
|
|
1073
|
+
yaml: () => import("./yaml-P2SV4LOE.mjs"),
|
|
1074
|
+
toml: () => import("./toml-IOHFZJ5B.mjs"),
|
|
1075
|
+
xml: () => import("./xml-JECR2ACB.mjs")
|
|
1076
|
+
};
|
|
1077
|
+
var corePromise = null;
|
|
1078
|
+
var loadedLangs = /* @__PURE__ */ new Set();
|
|
1079
|
+
var inFlightLangs = /* @__PURE__ */ new Map();
|
|
1080
|
+
async function getCore() {
|
|
1081
|
+
if (!corePromise) {
|
|
1082
|
+
corePromise = (async () => {
|
|
1083
|
+
const [coreMod, engineMod, darkTheme, lightTheme] = await Promise.all([
|
|
1084
|
+
import("./core-564N45MO.mjs"),
|
|
1085
|
+
import("./engine-javascript-PDVIGNGR.mjs"),
|
|
1086
|
+
import("./github-dark-default-6HVTHEWF.mjs"),
|
|
1087
|
+
import("./github-light-default-LAXRA6XL.mjs")
|
|
1088
|
+
]);
|
|
1089
|
+
const core = await coreMod.createHighlighterCore({
|
|
1090
|
+
themes: [darkTheme.default, lightTheme.default],
|
|
1091
|
+
langs: [],
|
|
1092
|
+
engine: engineMod.createJavaScriptRegexEngine({ forgiving: true })
|
|
1093
|
+
});
|
|
1094
|
+
return core;
|
|
1095
|
+
})();
|
|
1096
|
+
}
|
|
1097
|
+
return corePromise;
|
|
1098
|
+
}
|
|
1099
|
+
async function ensureLanguage(core, lang) {
|
|
1100
|
+
if (loadedLangs.has(lang)) return true;
|
|
1101
|
+
const loader = LANG_LOADERS[lang];
|
|
1102
|
+
if (!loader) return false;
|
|
1103
|
+
let pending = inFlightLangs.get(lang);
|
|
1104
|
+
if (!pending) {
|
|
1105
|
+
pending = (async () => {
|
|
1106
|
+
const mod = await loader();
|
|
1107
|
+
await core.loadLanguage(mod.default);
|
|
1108
|
+
loadedLangs.add(lang);
|
|
1109
|
+
return true;
|
|
1110
|
+
})();
|
|
1111
|
+
inFlightLangs.set(lang, pending);
|
|
1112
|
+
}
|
|
1113
|
+
return pending;
|
|
1114
|
+
}
|
|
1115
|
+
async function highlightToHtml(code, lang, appearance = "dark") {
|
|
1116
|
+
const core = await getCore();
|
|
1117
|
+
const ready = await ensureLanguage(core, lang);
|
|
1118
|
+
if (!ready) return null;
|
|
1119
|
+
return core.codeToHtml(code, { lang, theme: HIGHLIGHT_THEMES[appearance] });
|
|
1120
|
+
}
|
|
1121
|
+
|
|
1122
|
+
// packages/view-plugin-content-browser/src/ui/preview/CodePreview.tsx
|
|
1123
|
+
import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
1124
|
+
function readDocumentAppearance() {
|
|
1125
|
+
if (typeof document === "undefined") return "light";
|
|
1126
|
+
return document.documentElement.dataset.theme === "dark" ? "dark" : "light";
|
|
1127
|
+
}
|
|
1128
|
+
function useDocumentAppearance() {
|
|
1129
|
+
const [appearance, setAppearance] = useState3(readDocumentAppearance);
|
|
1130
|
+
useEffect(() => {
|
|
1131
|
+
const root = document.documentElement;
|
|
1132
|
+
const sync = () => setAppearance(readDocumentAppearance());
|
|
1133
|
+
sync();
|
|
1134
|
+
const observer = new MutationObserver(sync);
|
|
1135
|
+
observer.observe(root, { attributes: true, attributeFilter: ["data-theme"] });
|
|
1136
|
+
return () => observer.disconnect();
|
|
1137
|
+
}, []);
|
|
1138
|
+
return appearance;
|
|
1139
|
+
}
|
|
1140
|
+
function CodePreview({
|
|
1141
|
+
name,
|
|
1142
|
+
ext,
|
|
1143
|
+
size,
|
|
1144
|
+
content
|
|
1145
|
+
}) {
|
|
1146
|
+
const { t: t2 } = useTranslation();
|
|
1147
|
+
const appearance = useDocumentAppearance();
|
|
1148
|
+
const decision = decideHighlight({ ext, size, content });
|
|
1149
|
+
const targetLang = decision.highlight ? decision.lang : null;
|
|
1150
|
+
const label = resolveLanguage(ext)?.label ?? ext.toUpperCase();
|
|
1151
|
+
const [html, setHtml] = useState3(null);
|
|
1152
|
+
useEffect(() => {
|
|
1153
|
+
setHtml(null);
|
|
1154
|
+
if (targetLang == null) return;
|
|
1155
|
+
let cancelled = false;
|
|
1156
|
+
void highlightToHtml(content, targetLang, appearance).then((out) => {
|
|
1157
|
+
if (!cancelled) setHtml(out);
|
|
1158
|
+
}).catch(() => {
|
|
1159
|
+
if (!cancelled) setHtml(null);
|
|
1160
|
+
});
|
|
1161
|
+
return () => {
|
|
1162
|
+
cancelled = true;
|
|
1163
|
+
};
|
|
1164
|
+
}, [appearance, content, targetLang]);
|
|
1165
|
+
const skippedForSize = !decision.highlight && decision.reason === "too-large";
|
|
1166
|
+
return /* @__PURE__ */ jsxs5("div", { className: "cb-preview-code", "data-lang": resolveLanguage(ext)?.lang ?? "text", children: [
|
|
1167
|
+
/* @__PURE__ */ jsxs5("div", { className: "cb-preview-code-head", children: [
|
|
1168
|
+
/* @__PURE__ */ jsx5("span", { className: "cb-preview-code-badge", children: label }),
|
|
1169
|
+
skippedForSize ? /* @__PURE__ */ jsx5("span", { className: "cb-preview-code-hint", children: t2("contentBrowser.preview.highlightSkipped") }) : null
|
|
1170
|
+
] }),
|
|
1171
|
+
html != null ? /* @__PURE__ */ jsx5("div", { className: "cb-preview-code-shiki", dangerouslySetInnerHTML: { __html: html } }) : /* @__PURE__ */ jsx5("pre", { className: "cb-preview-code-plain", "aria-label": name, children: content })
|
|
1172
|
+
] });
|
|
1173
|
+
}
|
|
1174
|
+
|
|
1175
|
+
// packages/view-plugin-content-browser/src/ui/preview/FileContentPreview.tsx
|
|
1176
|
+
import { jsx as jsx6 } from "react/jsx-runtime";
|
|
1177
|
+
function FileContentPreview({
|
|
1178
|
+
file: file2,
|
|
1179
|
+
previewInfo,
|
|
1180
|
+
status,
|
|
1181
|
+
pendingRemote,
|
|
1182
|
+
t: t2
|
|
1183
|
+
}) {
|
|
1184
|
+
if (status === "loading" || pendingRemote) {
|
|
1185
|
+
return /* @__PURE__ */ jsx6("div", { className: "cb-preview-note", children: t2("contentBrowser.preview.loadingSource") });
|
|
1186
|
+
}
|
|
1187
|
+
if (previewInfo && (isBrowserMediaPreviewKind(previewInfo.kind) || isFontPreviewInfo(previewInfo))) {
|
|
1188
|
+
return /* @__PURE__ */ jsx6(MediaPreview, { info: previewInfo, fileName: file2.name, t: t2 });
|
|
1189
|
+
}
|
|
1190
|
+
if (previewInfo?.kind === "model" || familySuggestsEnginePreview(file2.family)) {
|
|
1191
|
+
return /* @__PURE__ */ jsx6("div", { className: "cb-preview-note", children: t2("contentBrowser.preview.previewEngineRequired") });
|
|
1192
|
+
}
|
|
1193
|
+
if (!previewInfo && familySuggestsMediaPreview(file2.family)) {
|
|
1194
|
+
return /* @__PURE__ */ jsx6("div", { className: "cb-preview-note", children: t2("contentBrowser.preview.noMediaPreview") });
|
|
1195
|
+
}
|
|
1196
|
+
const content = previewInfo?.content ?? file2.sourcePreview;
|
|
1197
|
+
if (content == null) {
|
|
1198
|
+
return /* @__PURE__ */ jsx6("div", { className: "cb-preview-note", children: t2("contentBrowser.preview.noTextPreview") });
|
|
1199
|
+
}
|
|
1200
|
+
const dotIndex = file2.name.lastIndexOf(".");
|
|
1201
|
+
const ext = dotIndex >= 0 ? file2.name.slice(dotIndex + 1).toLowerCase() : "";
|
|
1202
|
+
if (resolveLanguage(ext)) {
|
|
1203
|
+
return /* @__PURE__ */ jsx6(
|
|
1204
|
+
CodePreview,
|
|
1205
|
+
{
|
|
1206
|
+
name: file2.name,
|
|
1207
|
+
ext,
|
|
1208
|
+
size: previewInfo?.size ?? file2.estimatedSize ?? 0,
|
|
1209
|
+
content
|
|
1210
|
+
}
|
|
1211
|
+
);
|
|
1212
|
+
}
|
|
1213
|
+
return /* @__PURE__ */ jsx6("pre", { className: "cb-preview-source", children: /* @__PURE__ */ jsx6("code", { children: content }) });
|
|
1214
|
+
}
|
|
1215
|
+
|
|
1216
|
+
// packages/view-plugin-content-browser/src/ui/resize-handle.tsx
|
|
1217
|
+
import { useEffect as useEffect2, useRef as useRef2, useState as useState4 } from "react";
|
|
1218
|
+
import { jsx as jsx7 } from "react/jsx-runtime";
|
|
1219
|
+
function useLocalSize(key, initial, min, max) {
|
|
1220
|
+
const clamp = (value2) => Math.min(max, Math.max(min, value2));
|
|
1221
|
+
const [value, setValueRaw] = useState4(() => {
|
|
1222
|
+
if (typeof window === "undefined") return initial;
|
|
1223
|
+
try {
|
|
1224
|
+
const raw = window.localStorage.getItem(key);
|
|
1225
|
+
if (!raw) return initial;
|
|
1226
|
+
const parsed = Number(raw);
|
|
1227
|
+
return Number.isFinite(parsed) ? clamp(parsed) : initial;
|
|
1228
|
+
} catch {
|
|
1229
|
+
return initial;
|
|
1230
|
+
}
|
|
1231
|
+
});
|
|
1232
|
+
useEffect2(() => {
|
|
1233
|
+
try {
|
|
1234
|
+
window.localStorage.setItem(key, String(value));
|
|
1235
|
+
} catch {
|
|
1236
|
+
}
|
|
1237
|
+
}, [key, value]);
|
|
1238
|
+
const setValue = (next) => {
|
|
1239
|
+
setValueRaw((prev) => clamp(typeof next === "function" ? next(prev) : next));
|
|
1240
|
+
};
|
|
1241
|
+
return [value, setValue];
|
|
1242
|
+
}
|
|
1243
|
+
function ResizeHandle({
|
|
1244
|
+
onDrag,
|
|
1245
|
+
onDragEnd,
|
|
1246
|
+
title
|
|
1247
|
+
}) {
|
|
1248
|
+
const startRef = useRef2(null);
|
|
1249
|
+
const onPointerDown = (event) => {
|
|
1250
|
+
event.preventDefault();
|
|
1251
|
+
event.currentTarget.setPointerCapture(event.pointerId);
|
|
1252
|
+
startRef.current = event.clientX;
|
|
1253
|
+
document.body.style.cursor = "col-resize";
|
|
1254
|
+
document.body.style.userSelect = "none";
|
|
1255
|
+
};
|
|
1256
|
+
const onPointerMove = (event) => {
|
|
1257
|
+
if (startRef.current == null) return;
|
|
1258
|
+
const delta = event.clientX - startRef.current;
|
|
1259
|
+
startRef.current = event.clientX;
|
|
1260
|
+
onDrag(delta);
|
|
1261
|
+
};
|
|
1262
|
+
const finish = (event) => {
|
|
1263
|
+
if (startRef.current == null) return;
|
|
1264
|
+
startRef.current = null;
|
|
1265
|
+
try {
|
|
1266
|
+
event.currentTarget.releasePointerCapture(event.pointerId);
|
|
1267
|
+
} catch {
|
|
1268
|
+
}
|
|
1269
|
+
document.body.style.cursor = "";
|
|
1270
|
+
document.body.style.userSelect = "";
|
|
1271
|
+
onDragEnd?.();
|
|
1272
|
+
};
|
|
1273
|
+
return /* @__PURE__ */ jsx7(
|
|
1274
|
+
"div",
|
|
1275
|
+
{
|
|
1276
|
+
className: "cb-resize-handle",
|
|
1277
|
+
onPointerDown,
|
|
1278
|
+
onPointerMove,
|
|
1279
|
+
onPointerUp: finish,
|
|
1280
|
+
onPointerCancel: finish,
|
|
1281
|
+
title,
|
|
1282
|
+
role: "separator",
|
|
1283
|
+
"aria-orientation": "vertical"
|
|
1284
|
+
}
|
|
1285
|
+
);
|
|
1286
|
+
}
|
|
1287
|
+
|
|
1288
|
+
// packages/view-plugin-content-browser/src/ui/CBPreviewPanel.tsx
|
|
1289
|
+
import { Fragment, jsx as jsx8, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
1290
|
+
function CBPreviewPanel({
|
|
1291
|
+
previewItem,
|
|
1292
|
+
foldersInPath,
|
|
1293
|
+
diskFiles,
|
|
1294
|
+
projectLabel,
|
|
1295
|
+
readPreview,
|
|
1296
|
+
onClose,
|
|
1297
|
+
onDrag,
|
|
1298
|
+
onDragEnd
|
|
1299
|
+
}) {
|
|
1300
|
+
const { t: t2 } = useTranslation();
|
|
1301
|
+
const [filePreviewMode, setFilePreviewMode] = useState5("assets");
|
|
1302
|
+
const [previewInfo, setPreviewInfo] = useState5(null);
|
|
1303
|
+
const [previewStatus, setPreviewStatus] = useState5("idle");
|
|
1304
|
+
const dualPreviewFile = previewItem ? resolveDualPreviewFile(previewItem, diskFiles) : void 0;
|
|
1305
|
+
const showDualPreview = dualPreviewFile !== void 0 && fileSupportsDualPreview(dualPreviewFile);
|
|
1306
|
+
const previewKey = previewItem ? previewItem.type === "asset" ? previewItem.guid : previewItem.path : null;
|
|
1307
|
+
const previewSourcePath = dualPreviewFile?.diskPath || dualPreviewFile?.path || null;
|
|
1308
|
+
const dualAssetCount = dualPreviewFile?.assets.length ?? 0;
|
|
1309
|
+
const dualSupportsPreview = dualPreviewFile ? fileSupportsDualPreview(dualPreviewFile) : false;
|
|
1310
|
+
const embeddedSourcePreview = dualPreviewFile?.sourcePreview ?? null;
|
|
1311
|
+
const canReadPreview = typeof readPreview === "function";
|
|
1312
|
+
useEffect3(() => {
|
|
1313
|
+
setFilePreviewMode("assets");
|
|
1314
|
+
}, [previewKey]);
|
|
1315
|
+
useEffect3(() => {
|
|
1316
|
+
if (!previewSourcePath) {
|
|
1317
|
+
setPreviewInfo(null);
|
|
1318
|
+
setPreviewStatus("idle");
|
|
1319
|
+
return;
|
|
1320
|
+
}
|
|
1321
|
+
const needsSource = dualAssetCount === 0 || dualSupportsPreview && filePreviewMode === "source";
|
|
1322
|
+
if (!needsSource) {
|
|
1323
|
+
setPreviewInfo(null);
|
|
1324
|
+
setPreviewStatus("idle");
|
|
1325
|
+
return;
|
|
1326
|
+
}
|
|
1327
|
+
if (embeddedSourcePreview != null && !canReadPreview) {
|
|
1328
|
+
setPreviewInfo({
|
|
1329
|
+
path: dualPreviewFile?.path ?? previewSourcePath,
|
|
1330
|
+
kind: "text",
|
|
1331
|
+
mime: "text/plain; charset=utf-8",
|
|
1332
|
+
size: dualPreviewFile?.estimatedSize ?? embeddedSourcePreview.length,
|
|
1333
|
+
mtime: dualPreviewFile?.packModifiedAt ?? 0,
|
|
1334
|
+
content: embeddedSourcePreview
|
|
1335
|
+
});
|
|
1336
|
+
setPreviewStatus("ready");
|
|
1337
|
+
return;
|
|
1338
|
+
}
|
|
1339
|
+
if (!canReadPreview || !readPreview) {
|
|
1340
|
+
setPreviewInfo(null);
|
|
1341
|
+
setPreviewStatus("ready");
|
|
1342
|
+
return;
|
|
1343
|
+
}
|
|
1344
|
+
let cancelled = false;
|
|
1345
|
+
setPreviewInfo(null);
|
|
1346
|
+
setPreviewStatus("loading");
|
|
1347
|
+
const controller = new AbortController();
|
|
1348
|
+
void readPreview(previewSourcePath, { signal: controller.signal }).then((info) => {
|
|
1349
|
+
if (cancelled) return;
|
|
1350
|
+
setPreviewInfo(info);
|
|
1351
|
+
setPreviewStatus("ready");
|
|
1352
|
+
}).catch(() => {
|
|
1353
|
+
if (cancelled) return;
|
|
1354
|
+
setPreviewInfo(null);
|
|
1355
|
+
setPreviewStatus("ready");
|
|
1356
|
+
});
|
|
1357
|
+
return () => {
|
|
1358
|
+
cancelled = true;
|
|
1359
|
+
controller.abort();
|
|
1360
|
+
};
|
|
1361
|
+
}, [
|
|
1362
|
+
canReadPreview,
|
|
1363
|
+
dualAssetCount,
|
|
1364
|
+
dualSupportsPreview,
|
|
1365
|
+
embeddedSourcePreview,
|
|
1366
|
+
filePreviewMode,
|
|
1367
|
+
previewSourcePath,
|
|
1368
|
+
readPreview
|
|
1369
|
+
]);
|
|
1370
|
+
if (!previewItem) {
|
|
1371
|
+
return /* @__PURE__ */ jsxs6(Fragment, { children: [
|
|
1372
|
+
/* @__PURE__ */ jsx8(ResizeHandle, { onDrag, onDragEnd, title: t2("contentBrowser.actions.resizePreview") }),
|
|
1373
|
+
/* @__PURE__ */ jsx8("aside", { className: "cb-preview-panel cb-preview-empty", children: /* @__PURE__ */ jsx8("div", { className: "cb-preview-body", children: /* @__PURE__ */ jsx8("div", { className: "cb-preview-note", children: t2("contentBrowser.preview.nothingSelected") }) }) })
|
|
1374
|
+
] });
|
|
1375
|
+
}
|
|
1376
|
+
const Icon = itemIcon(previewItem, true);
|
|
1377
|
+
const meta = previewItem.type === "folder" ? t2("contentBrowser.preview.folderMeta", { path: previewItem.path || projectLabel }) : previewItem.type === "file" ? t2("contentBrowser.preview.fileMeta", { kind: previewItem.kindLabel, path: previewItem.path }) : t2("contentBrowser.preview.assetMeta", { kind: assetKindLabel(previewItem.kind, t2), path: previewItem.packPath });
|
|
1378
|
+
let body;
|
|
1379
|
+
if (previewItem.type === "folder") {
|
|
1380
|
+
const kids = [
|
|
1381
|
+
...foldersInPath.filter((folder) => dirOfPath(folder.path) === previewItem.path),
|
|
1382
|
+
...diskFiles.filter((entry) => dirOfPath(entry.path) === previewItem.path)
|
|
1383
|
+
].slice(0, 40);
|
|
1384
|
+
body = kids.length === 0 ? /* @__PURE__ */ jsx8("div", { className: "cb-preview-note", children: t2("contentBrowser.preview.emptyFolder") }) : /* @__PURE__ */ jsx8("div", { className: "cb-preview-list", children: kids.map((child) => {
|
|
1385
|
+
const ChildIcon = itemIcon(child);
|
|
1386
|
+
return /* @__PURE__ */ jsxs6("div", { className: "cb-preview-list-item", children: [
|
|
1387
|
+
/* @__PURE__ */ jsx8("span", { className: `cb-preview-list-ico${child.type === "folder" ? " cb-folder-icon" : ""}`, children: /* @__PURE__ */ jsx8(ChildIcon, { size: 15 }) }),
|
|
1388
|
+
/* @__PURE__ */ jsx8("span", { children: child.name }),
|
|
1389
|
+
/* @__PURE__ */ jsx8("span", { className: "sub", children: child.type === "folder" ? t2("contentBrowser.preview.items", { count: child.childCount }) : child.kindLabel || fileKindLabel(child, t2) })
|
|
1390
|
+
] }, child.path);
|
|
1391
|
+
}) });
|
|
1392
|
+
} else if (previewItem.type === "file") {
|
|
1393
|
+
const showSource = filePreviewMode === "source" && showDualPreview;
|
|
1394
|
+
if (previewItem.assets.length > 0 && !showSource) {
|
|
1395
|
+
body = /* @__PURE__ */ jsx8(FileAssetList, { file: previewItem, t: t2 });
|
|
1396
|
+
} else {
|
|
1397
|
+
body = /* @__PURE__ */ jsx8(
|
|
1398
|
+
FileContentPreview,
|
|
1399
|
+
{
|
|
1400
|
+
file: showDualPreview ? dualPreviewFile ?? previewItem : previewItem,
|
|
1401
|
+
previewInfo,
|
|
1402
|
+
status: previewStatus,
|
|
1403
|
+
pendingRemote: isFilePreviewPending(canReadPreview, previewStatus, previewInfo, showDualPreview ? dualPreviewFile ?? previewItem : previewItem),
|
|
1404
|
+
t: t2
|
|
1405
|
+
}
|
|
1406
|
+
);
|
|
1407
|
+
}
|
|
1408
|
+
} else {
|
|
1409
|
+
const showSource = showDualPreview && filePreviewMode === "source" && dualPreviewFile;
|
|
1410
|
+
body = showSource ? /* @__PURE__ */ jsx8(
|
|
1411
|
+
FileContentPreview,
|
|
1412
|
+
{
|
|
1413
|
+
file: dualPreviewFile,
|
|
1414
|
+
previewInfo,
|
|
1415
|
+
status: previewStatus,
|
|
1416
|
+
pendingRemote: isFilePreviewPending(canReadPreview, previewStatus, previewInfo, dualPreviewFile),
|
|
1417
|
+
t: t2
|
|
1418
|
+
}
|
|
1419
|
+
) : /* @__PURE__ */ jsxs6(Fragment, { children: [
|
|
1420
|
+
/* @__PURE__ */ jsx8("div", { className: "cb-preview-media cb-preview-asset-hero", children: /* @__PURE__ */ jsx8("span", { className: "cb-preview-hero-icon", children: /* @__PURE__ */ jsx8(Icon, { size: 64 }) }) }),
|
|
1421
|
+
/* @__PURE__ */ jsx8("div", { className: "cb-preview-asset-list", children: /* @__PURE__ */ jsxs6("div", { className: "cb-preview-asset-row", children: [
|
|
1422
|
+
/* @__PURE__ */ jsx8("span", { className: "cb-preview-list-ico", children: /* @__PURE__ */ jsx8(Icon, { size: 15 }) }),
|
|
1423
|
+
/* @__PURE__ */ jsxs6("div", { className: "cb-preview-asset-main", title: previewItem.packPath, children: [
|
|
1424
|
+
/* @__PURE__ */ jsx8("div", { title: previewItem.name, children: previewItem.name }),
|
|
1425
|
+
/* @__PURE__ */ jsx8("div", { className: "kind", title: previewItem.packPath, children: previewItem.packPath })
|
|
1426
|
+
] }),
|
|
1427
|
+
/* @__PURE__ */ jsx8("span", { className: "guid", title: previewItem.guid, children: previewItem.guid })
|
|
1428
|
+
] }) })
|
|
1429
|
+
] });
|
|
1430
|
+
}
|
|
1431
|
+
return /* @__PURE__ */ jsxs6(Fragment, { children: [
|
|
1432
|
+
/* @__PURE__ */ jsx8(ResizeHandle, { onDrag, onDragEnd, title: t2("contentBrowser.actions.resizePreview") }),
|
|
1433
|
+
/* @__PURE__ */ jsxs6("aside", { className: "cb-preview-panel", "data-subject-id": previewItem.type === "asset" ? previewItem.guid : previewItem.path, children: [
|
|
1434
|
+
/* @__PURE__ */ jsxs6("div", { className: "cb-preview-head", children: [
|
|
1435
|
+
/* @__PURE__ */ jsx8("span", { className: `cb-preview-ico${previewItem.type === "folder" ? " cb-folder-icon" : ""}`, children: /* @__PURE__ */ jsx8(Icon, { size: 15 }) }),
|
|
1436
|
+
/* @__PURE__ */ jsxs6("div", { className: "cb-preview-title", children: [
|
|
1437
|
+
/* @__PURE__ */ jsx8("div", { className: "name", children: previewItem.name }),
|
|
1438
|
+
/* @__PURE__ */ jsx8("div", { className: "meta", children: meta })
|
|
1439
|
+
] }),
|
|
1440
|
+
/* @__PURE__ */ jsx8(
|
|
1441
|
+
IconButton,
|
|
1442
|
+
{
|
|
1443
|
+
size: "compact",
|
|
1444
|
+
variant: "quiet",
|
|
1445
|
+
className: "cb-preview-close",
|
|
1446
|
+
label: t2("contentBrowser.preview.close"),
|
|
1447
|
+
icon: /* @__PURE__ */ jsx8(X, { size: 14 }),
|
|
1448
|
+
onClick: onClose
|
|
1449
|
+
}
|
|
1450
|
+
)
|
|
1451
|
+
] }),
|
|
1452
|
+
showDualPreview ? /* @__PURE__ */ jsxs6("div", { className: "cb-preview-mode-bar", role: "tablist", "aria-label": t2("contentBrowser.preview.modeAssets"), children: [
|
|
1453
|
+
/* @__PURE__ */ jsx8("button", { type: "button", role: "tab", className: `cb-preview-mode-btn${filePreviewMode === "assets" ? " is-active" : ""}`, "aria-selected": filePreviewMode === "assets", onClick: () => setFilePreviewMode("assets"), children: t2("contentBrowser.preview.modeAssets") }),
|
|
1454
|
+
/* @__PURE__ */ jsx8("button", { type: "button", role: "tab", className: `cb-preview-mode-btn${filePreviewMode === "source" ? " is-active" : ""}`, "aria-selected": filePreviewMode === "source", onClick: () => setFilePreviewMode("source"), children: t2("contentBrowser.preview.modeSource") })
|
|
1455
|
+
] }) : null,
|
|
1456
|
+
/* @__PURE__ */ jsx8("div", { className: "cb-preview-body", children: body })
|
|
1457
|
+
] })
|
|
1458
|
+
] });
|
|
1459
|
+
}
|
|
1460
|
+
function FileAssetList({ file: file2, t: t2 }) {
|
|
1461
|
+
return /* @__PURE__ */ jsx8("div", { className: "cb-preview-asset-list", children: file2.assets.map((asset2) => {
|
|
1462
|
+
const Icon = itemIcon(asset2);
|
|
1463
|
+
return /* @__PURE__ */ jsxs6("div", { className: "cb-preview-asset-row", children: [
|
|
1464
|
+
/* @__PURE__ */ jsx8("span", { className: "cb-preview-list-ico", children: /* @__PURE__ */ jsx8(Icon, { size: 15 }) }),
|
|
1465
|
+
/* @__PURE__ */ jsxs6("div", { className: "cb-preview-asset-main", children: [
|
|
1466
|
+
/* @__PURE__ */ jsx8("div", { title: asset2.name, children: asset2.name }),
|
|
1467
|
+
/* @__PURE__ */ jsx8("div", { className: "kind", title: assetKindLabel(asset2.kind, t2), children: assetKindLabel(asset2.kind, t2) })
|
|
1468
|
+
] }),
|
|
1469
|
+
/* @__PURE__ */ jsx8("span", { className: "guid", title: asset2.guid, children: asset2.guid })
|
|
1470
|
+
] }, asset2.guid);
|
|
1471
|
+
}) });
|
|
1472
|
+
}
|
|
1473
|
+
function isFilePreviewPending(canReadPreview, status, previewInfo, file2) {
|
|
1474
|
+
if (!canReadPreview || status !== "idle") return false;
|
|
1475
|
+
if (previewInfo) return false;
|
|
1476
|
+
return file2.sourcePreview == null;
|
|
1477
|
+
}
|
|
1478
|
+
|
|
1479
|
+
// packages/view-plugin-content-browser/src/ui/mock-catalog.ts
|
|
1480
|
+
var PROJECT_LABEL = "47 game";
|
|
1481
|
+
var TODAY = Date.parse("2026-09-18T04:00:00Z");
|
|
1482
|
+
var YESTERDAY = Date.parse("2026-09-17T04:00:00Z");
|
|
1483
|
+
function asset(guid, kind, name, packPath, packIndex, estimatedSize, packModifiedAt) {
|
|
1484
|
+
return {
|
|
1485
|
+
type: "asset",
|
|
1486
|
+
guid,
|
|
1487
|
+
kind,
|
|
1488
|
+
name,
|
|
1489
|
+
packPath,
|
|
1490
|
+
packIndex,
|
|
1491
|
+
payload: { mock: true },
|
|
1492
|
+
refs: [],
|
|
1493
|
+
estimatedSize,
|
|
1494
|
+
packModifiedAt
|
|
1495
|
+
};
|
|
1496
|
+
}
|
|
1497
|
+
function file(path, assets, extra = {}) {
|
|
1498
|
+
const name = path.slice(path.lastIndexOf("/") + 1);
|
|
1499
|
+
const family = fileFamilyOfWithAssets(name, assets);
|
|
1500
|
+
const isAssetPackage = isResourceGroup(assets.length);
|
|
1501
|
+
return {
|
|
1502
|
+
type: "file",
|
|
1503
|
+
path,
|
|
1504
|
+
diskPath: path,
|
|
1505
|
+
name,
|
|
1506
|
+
family,
|
|
1507
|
+
assets,
|
|
1508
|
+
isAssetPackage,
|
|
1509
|
+
kindLabel: isAssetPackage ? "" : family,
|
|
1510
|
+
sourcePreview: extra.sourcePreview,
|
|
1511
|
+
estimatedSize: extra.estimatedSize,
|
|
1512
|
+
packModifiedAt: extra.packModifiedAt ?? assets[0]?.packModifiedAt
|
|
1513
|
+
};
|
|
1514
|
+
}
|
|
1515
|
+
var characterAssets = [
|
|
1516
|
+
asset("11111111-1111-4111-8111-111111111111", "mesh", "HeroMesh", "assets/character.glb", 0, 482e3, TODAY),
|
|
1517
|
+
asset("11111111-1111-4111-8111-111111111112", "material", "HeroMaterial", "assets/character.glb", 1, 12400, TODAY),
|
|
1518
|
+
asset("11111111-1111-4111-8111-111111111113", "texture", "HeroAlbedo", "assets/character.glb", 2, 1024e3, TODAY)
|
|
1519
|
+
];
|
|
1520
|
+
var environmentAssets = [
|
|
1521
|
+
asset("22222222-2222-4222-8222-222222222221", "mesh", "EnvMesh", "assets/environment.fbx", 0, 128e4, YESTERDAY),
|
|
1522
|
+
asset("22222222-2222-4222-8222-222222222222", "material", "EnvMaterial", "assets/environment.fbx", 1, 18200, YESTERDAY),
|
|
1523
|
+
asset("22222222-2222-4222-8222-222222222223", "animation-clip", "WalkClip", "assets/environment.fbx", 2, 96e3, YESTERDAY),
|
|
1524
|
+
asset("22222222-2222-4222-8222-222222222224", "skeleton", "EnvSkeleton", "assets/environment.fbx", 3, 22e3, YESTERDAY)
|
|
1525
|
+
];
|
|
1526
|
+
var packMaterials = [
|
|
1527
|
+
asset("33333333-3333-4333-8333-333333333331", "material", "Metal", "assets/materials.pack.json", 0, 9700, TODAY),
|
|
1528
|
+
asset("33333333-3333-4333-8333-333333333332", "material", "Wood", "assets/materials.pack.json", 1, 8200, TODAY)
|
|
1529
|
+
];
|
|
1530
|
+
var sceneAsset = asset("44444444-4444-4444-8444-444444444441", "scene", "Main Scene", "assets/scene-main.pack.json", 0, 18200, TODAY);
|
|
1531
|
+
var baseMaterial = asset("55555555-5555-4555-8555-555555555551", "material", "BaseMaterial", "assets/base-material.pack.json", 0, 9700, TODAY);
|
|
1532
|
+
var skyAsset = asset("66666666-6666-4666-8666-666666666661", "cube-texture", "SkyCubemap", "assets/sky.pack.json", 0, 24e5, YESTERDAY);
|
|
1533
|
+
var hudAsset = asset("77777777-7777-4777-8777-777777777771", "ui", "HUD", "assets/hud.pack.json", 0, 12500, YESTERDAY);
|
|
1534
|
+
var MOCK_FILES = [
|
|
1535
|
+
file("AGENTS.md", [], { sourcePreview: "# AGENTS\n\nProject agent notes.\n", estimatedSize: 7200, packModifiedAt: TODAY }),
|
|
1536
|
+
file("FORGE.md", [], { sourcePreview: "# FORGE\n\nWorkspace contract.\n", estimatedSize: 4800, packModifiedAt: YESTERDAY }),
|
|
1537
|
+
file("capability-adapters.json", [], {
|
|
1538
|
+
sourcePreview: '{\n "adapters": ["content-browser", "inspector"]\n}\n',
|
|
1539
|
+
estimatedSize: 3100,
|
|
1540
|
+
packModifiedAt: TODAY
|
|
1541
|
+
}),
|
|
1542
|
+
file("package.json", [], {
|
|
1543
|
+
sourcePreview: '{\n "name": "47-game",\n "private": true\n}\n',
|
|
1544
|
+
estimatedSize: 1600,
|
|
1545
|
+
packModifiedAt: TODAY
|
|
1546
|
+
}),
|
|
1547
|
+
file("main.ts", [], {
|
|
1548
|
+
sourcePreview: 'export function boot() {\n return "47 game";\n}\n',
|
|
1549
|
+
estimatedSize: 2400,
|
|
1550
|
+
packModifiedAt: TODAY
|
|
1551
|
+
}),
|
|
1552
|
+
file("assets/character.glb", characterAssets, { estimatedSize: 152e4, packModifiedAt: TODAY }),
|
|
1553
|
+
file("assets/environment.fbx", environmentAssets, { estimatedSize: 24e5, packModifiedAt: YESTERDAY }),
|
|
1554
|
+
file("assets/materials.pack.json", packMaterials, {
|
|
1555
|
+
sourcePreview: '{\n "assets": [\n { "kind": "material", "name": "Metal" },\n { "kind": "material", "name": "Wood" }\n ]\n}\n',
|
|
1556
|
+
estimatedSize: 4200,
|
|
1557
|
+
packModifiedAt: TODAY
|
|
1558
|
+
}),
|
|
1559
|
+
file("assets/scene-main.pack.json", [sceneAsset], {
|
|
1560
|
+
sourcePreview: '{\n "assets": [{ "kind": "scene", "name": "Main Scene" }]\n}\n',
|
|
1561
|
+
estimatedSize: 18200,
|
|
1562
|
+
packModifiedAt: TODAY
|
|
1563
|
+
}),
|
|
1564
|
+
file("assets/base-material.pack.json", [baseMaterial], {
|
|
1565
|
+
sourcePreview: '{\n "assets": [{ "kind": "material", "name": "BaseMaterial" }]\n}\n',
|
|
1566
|
+
estimatedSize: 9700,
|
|
1567
|
+
packModifiedAt: TODAY
|
|
1568
|
+
}),
|
|
1569
|
+
file("assets/sky.pack.json", [skyAsset], {
|
|
1570
|
+
sourcePreview: '{\n "assets": [{ "kind": "cube-texture", "name": "SkyCubemap" }]\n}\n',
|
|
1571
|
+
estimatedSize: 24e5,
|
|
1572
|
+
packModifiedAt: YESTERDAY
|
|
1573
|
+
}),
|
|
1574
|
+
file("assets/hud.pack.json", [hudAsset], {
|
|
1575
|
+
sourcePreview: '{\n "assets": [{ "kind": "ui", "name": "HUD" }]\n}\n',
|
|
1576
|
+
estimatedSize: 12500,
|
|
1577
|
+
packModifiedAt: YESTERDAY
|
|
1578
|
+
}),
|
|
1579
|
+
file("assets/hero.png", [], { estimatedSize: 84e3, packModifiedAt: TODAY }),
|
|
1580
|
+
file("assets/shot.wav", [], { estimatedSize: 22e4, packModifiedAt: YESTERDAY }),
|
|
1581
|
+
file("assets/Inter.ttf", [], { estimatedSize: 31e4, packModifiedAt: YESTERDAY }),
|
|
1582
|
+
file("assets/ground.colliders.json", [], {
|
|
1583
|
+
sourcePreview: '{\n "colliders": [{ "shape": "box" }]\n}\n',
|
|
1584
|
+
estimatedSize: 1200,
|
|
1585
|
+
packModifiedAt: TODAY
|
|
1586
|
+
}),
|
|
1587
|
+
file("scripts/smoke-geometry.mjs", [], {
|
|
1588
|
+
sourcePreview: 'export const geometry = { kind: "box" };\n',
|
|
1589
|
+
estimatedSize: 3800,
|
|
1590
|
+
packModifiedAt: TODAY
|
|
1591
|
+
}),
|
|
1592
|
+
file("scripts/smoke-rotation.mjs", [], {
|
|
1593
|
+
sourcePreview: "export function rotate(dt) { return dt * 0.2; }\n",
|
|
1594
|
+
estimatedSize: 2100,
|
|
1595
|
+
packModifiedAt: YESTERDAY
|
|
1596
|
+
}),
|
|
1597
|
+
file("sessions/logs/debug.log", [], { sourcePreview: "[info] boot\n[debug] frame 1\n", estimatedSize: 31e3, packModifiedAt: TODAY }),
|
|
1598
|
+
file("sessions/logs/latest.log", [], { sourcePreview: "[info] ready\n", estimatedSize: 11e3, packModifiedAt: TODAY }),
|
|
1599
|
+
file("src/index.ts", [], { sourcePreview: "export {};\n", estimatedSize: 80, packModifiedAt: YESTERDAY })
|
|
1600
|
+
];
|
|
1601
|
+
var folderPaths = ["assets", "scripts", "sessions", "sessions/logs", "src"];
|
|
1602
|
+
var MOCK_FOLDERS = folderPaths.map((path) => {
|
|
1603
|
+
const prefix = `${path}/`;
|
|
1604
|
+
const fileCount = MOCK_FILES.filter((entry) => entry.path.startsWith(prefix)).length;
|
|
1605
|
+
const folderCount = folderPaths.filter((entry) => entry !== path && entry.startsWith(prefix) && !entry.slice(prefix.length).includes("/")).length;
|
|
1606
|
+
return {
|
|
1607
|
+
type: "folder",
|
|
1608
|
+
path,
|
|
1609
|
+
name: path.slice(path.lastIndexOf("/") + 1),
|
|
1610
|
+
childCount: fileCount + folderCount
|
|
1611
|
+
};
|
|
1612
|
+
});
|
|
1613
|
+
var DIRECTORY_TREE = MOCK_FOLDERS.map((folder) => ({
|
|
1614
|
+
path: folder.path,
|
|
1615
|
+
name: folder.name,
|
|
1616
|
+
depth: folder.path.split("/").length - 1
|
|
1617
|
+
}));
|
|
1618
|
+
|
|
1619
|
+
// packages/view-plugin-content-browser/src/ui/workspace-catalog.ts
|
|
1620
|
+
function projectCatalog(root, assets) {
|
|
1621
|
+
const files = /* @__PURE__ */ new Map();
|
|
1622
|
+
const prefix = `${root.replaceAll("\\", "/").replace(/\/$/, "")}/`;
|
|
1623
|
+
for (const asset2 of assets) {
|
|
1624
|
+
const source = (asset2.sourcePath ?? asset2.path ?? asset2.guid).replaceAll("\\", "/");
|
|
1625
|
+
const relative = source.startsWith(prefix) ? source.slice(prefix.length) : source;
|
|
1626
|
+
const external = relative.startsWith("/") || /^[a-z]:\//i.test(relative) || relative.split("/").includes("..");
|
|
1627
|
+
const path = external ? `External assets/${encodeURIComponent(source)}` : relative.replace(/^\.\//, "");
|
|
1628
|
+
let file2 = files.get(path);
|
|
1629
|
+
if (!file2) {
|
|
1630
|
+
file2 = {
|
|
1631
|
+
type: "file",
|
|
1632
|
+
path,
|
|
1633
|
+
diskPath: source,
|
|
1634
|
+
name: source.split("/").at(-1),
|
|
1635
|
+
family: "pack",
|
|
1636
|
+
assets: [],
|
|
1637
|
+
isAssetPackage: false,
|
|
1638
|
+
kindLabel: ""
|
|
1639
|
+
};
|
|
1640
|
+
files.set(path, file2);
|
|
1641
|
+
}
|
|
1642
|
+
const item = {
|
|
1643
|
+
type: "asset",
|
|
1644
|
+
guid: asset2.guid,
|
|
1645
|
+
kind: asset2.kind,
|
|
1646
|
+
name: (source.toLowerCase().endsWith(".pack.ts") ? asset2.sourceKey : void 0) ?? asset2.name ?? asset2.label ?? asset2.guid,
|
|
1647
|
+
packPath: path
|
|
1648
|
+
};
|
|
1649
|
+
file2.assets.push(item);
|
|
1650
|
+
file2.family = fileFamilyOfWithAssets(file2.name, file2.assets);
|
|
1651
|
+
file2.isAssetPackage = isResourceGroup(file2.assets.length);
|
|
1652
|
+
}
|
|
1653
|
+
const folders = /* @__PURE__ */ new Map();
|
|
1654
|
+
for (const file2 of files.values()) {
|
|
1655
|
+
const parts = file2.path.split("/").filter(Boolean).slice(0, -1);
|
|
1656
|
+
for (let index = 0; index < parts.length; index++) {
|
|
1657
|
+
const path = parts.slice(0, index + 1).join("/");
|
|
1658
|
+
if (!folders.has(path)) folders.set(path, { type: "folder", path, name: parts[index], childCount: 0 });
|
|
1659
|
+
}
|
|
1660
|
+
}
|
|
1661
|
+
for (const folder of folders.values()) {
|
|
1662
|
+
folder.childCount = [...folders.values(), ...files.values()].filter((item) => item.path.slice(0, item.path.lastIndexOf("/")) === folder.path).length;
|
|
1663
|
+
}
|
|
1664
|
+
return { files: [...files.values()], folders: [...folders.values()] };
|
|
1665
|
+
}
|
|
1666
|
+
|
|
1667
|
+
// packages/view-plugin-content-browser/src/ui/ContentBrowserPanel.tsx
|
|
1668
|
+
import { jsx as jsx9, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
1669
|
+
var LAYOUT_OPTIONS = [
|
|
1670
|
+
{ mode: "grid", icon: /* @__PURE__ */ jsx9(Grid2X2, { size: 14 }), labelKey: "contentBrowser.layoutGrid" },
|
|
1671
|
+
{ mode: "list", icon: /* @__PURE__ */ jsx9(List, { size: 14 }), labelKey: "contentBrowser.layoutList" },
|
|
1672
|
+
{ mode: "column", icon: /* @__PURE__ */ jsx9(Table2, { size: 14 }), labelKey: "contentBrowser.layoutColumn" }
|
|
1673
|
+
];
|
|
1674
|
+
var SORT_KEYS = ["name", "kind", "packModifiedAt", "estimatedSize"];
|
|
1675
|
+
var SORT_KEY_ICONS = {
|
|
1676
|
+
name: CaseSensitive,
|
|
1677
|
+
kind: Shapes,
|
|
1678
|
+
packModifiedAt: Clock,
|
|
1679
|
+
estimatedSize: HardDrive
|
|
1680
|
+
};
|
|
1681
|
+
function isContextMenuAnchor(element) {
|
|
1682
|
+
return element.classList.contains("cb-grid-item") || element.classList.contains("cb-fe-card") || element.classList.contains("cb-details-row") || element.classList.contains("cb-source-row");
|
|
1683
|
+
}
|
|
1684
|
+
function toFxMenuItems(items, close) {
|
|
1685
|
+
return items.map((item) => {
|
|
1686
|
+
if (item.kind === "separator") return { type: "separator" };
|
|
1687
|
+
if (item.kind === "title") {
|
|
1688
|
+
return { type: "title", label: /* @__PURE__ */ jsxs7("span", { className: "cb-menu-title", children: [
|
|
1689
|
+
item.icon,
|
|
1690
|
+
item.label
|
|
1691
|
+
] }) };
|
|
1692
|
+
}
|
|
1693
|
+
return {
|
|
1694
|
+
id: item.id,
|
|
1695
|
+
label: item.label,
|
|
1696
|
+
icon: item.icon,
|
|
1697
|
+
shortcut: item.shortcut,
|
|
1698
|
+
disabled: item.disabled,
|
|
1699
|
+
danger: item.danger,
|
|
1700
|
+
buttonProps: { "data-operation": item.id },
|
|
1701
|
+
onSelect: () => {
|
|
1702
|
+
item.action();
|
|
1703
|
+
close?.();
|
|
1704
|
+
}
|
|
1705
|
+
};
|
|
1706
|
+
});
|
|
1707
|
+
}
|
|
1708
|
+
function ContentBrowserPanel({
|
|
1709
|
+
client,
|
|
1710
|
+
demo = false
|
|
1711
|
+
}) {
|
|
1712
|
+
const { t: t2 } = useTranslation();
|
|
1713
|
+
const [snapshot, setSnapshot] = useState6({});
|
|
1714
|
+
const [loadFailed, setLoadFailed] = useState6(false);
|
|
1715
|
+
const [actionError, setActionError] = useState6("");
|
|
1716
|
+
const [loading, setLoading] = useState6(false);
|
|
1717
|
+
const [openingKeys, setOpeningKeys] = useState6(/* @__PURE__ */ new Set());
|
|
1718
|
+
const project = snapshot.project;
|
|
1719
|
+
const projectLabel = demo ? PROJECT_LABEL : project?.name ?? project?.root ?? "No project";
|
|
1720
|
+
const catalog = useMemo(() => projectCatalog(project?.root ?? "", snapshot.assets ?? []), [project?.root, snapshot.assets]);
|
|
1721
|
+
const files = demo ? MOCK_FILES : catalog.files;
|
|
1722
|
+
const folders = demo ? MOCK_FOLDERS : catalog.folders;
|
|
1723
|
+
const directoryTree = demo ? DIRECTORY_TREE : folders.map((folder2) => ({ ...folder2, depth: folder2.path.split("/").length - 1 }));
|
|
1724
|
+
const clientRef = useRef3(client);
|
|
1725
|
+
clientRef.current = client;
|
|
1726
|
+
const connected = useWorkspaceClientConnected(demo ? void 0 : client);
|
|
1727
|
+
const readPreview = useCallback4((path, options) => {
|
|
1728
|
+
if (demo) return Promise.resolve(null);
|
|
1729
|
+
const transport = clientRef.current?.transport;
|
|
1730
|
+
if (typeof transport?.request !== "function") return Promise.resolve(null);
|
|
1731
|
+
return transport.request(VIEW_FILE_GET_SERVICE, { path }, options);
|
|
1732
|
+
}, [demo]);
|
|
1733
|
+
const refresh = useCallback4(async (signal) => {
|
|
1734
|
+
if (demo || !connected || !project || !client) return;
|
|
1735
|
+
setLoading(true);
|
|
1736
|
+
try {
|
|
1737
|
+
await client.listAssets(project.id, { tabId: VIEW_WORKSPACE_TAB_ID, signal });
|
|
1738
|
+
if (!signal?.aborted) setLoadFailed(false);
|
|
1739
|
+
} catch {
|
|
1740
|
+
if (!signal?.aborted) setLoadFailed(true);
|
|
1741
|
+
} finally {
|
|
1742
|
+
if (!signal?.aborted) setLoading(false);
|
|
1743
|
+
}
|
|
1744
|
+
}, [client, connected, demo, project?.id]);
|
|
1745
|
+
useEffect4(() => {
|
|
1746
|
+
if (demo) return;
|
|
1747
|
+
if (!client || !connected) {
|
|
1748
|
+
if (!client) setLoadFailed(true);
|
|
1749
|
+
return;
|
|
1750
|
+
}
|
|
1751
|
+
const controller = new AbortController();
|
|
1752
|
+
setSnapshot({});
|
|
1753
|
+
const accept = (next) => {
|
|
1754
|
+
if (controller.signal.aborted) return;
|
|
1755
|
+
setSnapshot((current) => {
|
|
1756
|
+
if ((next.revision ?? 0) < (current.revision ?? 0)) return current;
|
|
1757
|
+
if (workspaceUiFingerprint(next) === workspaceUiFingerprint(current)) return current;
|
|
1758
|
+
return next;
|
|
1759
|
+
});
|
|
1760
|
+
setLoadFailed(false);
|
|
1761
|
+
};
|
|
1762
|
+
const unsubscribe = client.subscribe(accept);
|
|
1763
|
+
void client.getState({ signal: controller.signal }).then(accept).catch(() => {
|
|
1764
|
+
if (!controller.signal.aborted) setLoadFailed(true);
|
|
1765
|
+
});
|
|
1766
|
+
return () => {
|
|
1767
|
+
controller.abort();
|
|
1768
|
+
unsubscribe?.();
|
|
1769
|
+
};
|
|
1770
|
+
}, [client, connected, demo]);
|
|
1771
|
+
useEffect4(() => {
|
|
1772
|
+
if (!connected) return;
|
|
1773
|
+
const controller = new AbortController();
|
|
1774
|
+
void refresh(controller.signal);
|
|
1775
|
+
return () => controller.abort();
|
|
1776
|
+
}, [connected, refresh]);
|
|
1777
|
+
const [layout, setLayout] = useState6("grid");
|
|
1778
|
+
const [thumbnailSize, setThumbnailSize] = useState6(80);
|
|
1779
|
+
const [detailPanelOpen, setDetailPanelOpen] = useState6(true);
|
|
1780
|
+
const [query, setQuery] = useState6("");
|
|
1781
|
+
const [activeFamilies, setActiveFamilies] = useState6(/* @__PURE__ */ new Set());
|
|
1782
|
+
const [activeKinds, setActiveKinds] = useState6(/* @__PURE__ */ new Set());
|
|
1783
|
+
const [sortState, setSortState] = useState6({ key: "name", dir: "asc" });
|
|
1784
|
+
const [history, setHistory] = useState6([""]);
|
|
1785
|
+
const [historyIndex, setHistoryIndex] = useState6(0);
|
|
1786
|
+
const [menu, setMenu] = useState6(null);
|
|
1787
|
+
const [contextMenu, setContextMenu] = useState6(null);
|
|
1788
|
+
const [toolbarMenuAnchor, setToolbarMenuAnchor] = useState6(null);
|
|
1789
|
+
const filterButtonRef = useRef3(null);
|
|
1790
|
+
const sortButtonRef = useRef3(null);
|
|
1791
|
+
const settingsButtonRef = useRef3(null);
|
|
1792
|
+
const splitRef = useRef3(null);
|
|
1793
|
+
const [groups, setGroups] = useState6({ favorites: true, project: true });
|
|
1794
|
+
const [favorites, setFavorites] = useState6(new Set(demo ? ["assets", "scripts"] : []));
|
|
1795
|
+
const [collapsed, setCollapsed] = useState6(/* @__PURE__ */ new Set());
|
|
1796
|
+
const [expandedPacks, setExpandedPacks] = useState6(/* @__PURE__ */ new Set());
|
|
1797
|
+
const [selectedIds, setSelectedIds] = useState6(/* @__PURE__ */ new Set());
|
|
1798
|
+
const [selectionAnchor, setSelectionAnchor] = useState6(null);
|
|
1799
|
+
const [previewKey, setPreviewKey] = useState6(null);
|
|
1800
|
+
const previewItem = [...folders, ...files.flatMap((file2) => [file2, ...file2.assets])].find((item) => viewItemKey(item) === previewKey) ?? null;
|
|
1801
|
+
const [srcWidth, setSrcWidth] = useLocalSize("view.cb.sourceWidth", 200, 140, 420);
|
|
1802
|
+
const [previewWidth, setPreviewWidth] = useLocalSize("view.cb.previewWidth", 280, 180, 560);
|
|
1803
|
+
useEffect4(() => {
|
|
1804
|
+
setHistory([""]);
|
|
1805
|
+
setHistoryIndex(0);
|
|
1806
|
+
setSelectedIds(/* @__PURE__ */ new Set());
|
|
1807
|
+
setSelectionAnchor(null);
|
|
1808
|
+
setPreviewKey(null);
|
|
1809
|
+
setExpandedPacks(/* @__PURE__ */ new Set());
|
|
1810
|
+
setFavorites(new Set(demo ? ["assets", "scripts"] : []));
|
|
1811
|
+
setQuery("");
|
|
1812
|
+
}, [project?.id, demo]);
|
|
1813
|
+
const folder = history[historyIndex] ?? "";
|
|
1814
|
+
const familyFilters = useMemo(() => buildFamilyFilters(activeFamilies, t2), [activeFamilies, t2]);
|
|
1815
|
+
const kindFilters = useMemo(() => buildKindFilters(activeKinds, t2), [activeKinds, t2]);
|
|
1816
|
+
const activeFilterCount = activeFamilies.size + activeKinds.size;
|
|
1817
|
+
const labeledFiles = useMemo(
|
|
1818
|
+
() => files.map((file2) => ({ ...file2, kindLabel: fileKindLabel(file2, t2) })),
|
|
1819
|
+
[files, t2]
|
|
1820
|
+
);
|
|
1821
|
+
const derived = useMemo(
|
|
1822
|
+
() => deriveViewItems({
|
|
1823
|
+
folders,
|
|
1824
|
+
files: labeledFiles,
|
|
1825
|
+
currentPath: folder,
|
|
1826
|
+
searchQuery: query,
|
|
1827
|
+
activeFamilies,
|
|
1828
|
+
activeKinds,
|
|
1829
|
+
sortState,
|
|
1830
|
+
expandedPacks,
|
|
1831
|
+
withKindLabel: (file2) => file2
|
|
1832
|
+
}),
|
|
1833
|
+
[activeFamilies, activeKinds, expandedPacks, folder, folders, labeledFiles, query, sortState]
|
|
1834
|
+
);
|
|
1835
|
+
const { viewItems, foldersInPath, searchActive } = derived;
|
|
1836
|
+
const navigate = (path) => {
|
|
1837
|
+
const normalized = normalizePathInput(path);
|
|
1838
|
+
if (normalized === folder) return;
|
|
1839
|
+
const next = history.slice(0, historyIndex + 1);
|
|
1840
|
+
next.push(normalized);
|
|
1841
|
+
setHistory(next);
|
|
1842
|
+
setHistoryIndex(next.length - 1);
|
|
1843
|
+
};
|
|
1844
|
+
const selectItem = (item, event) => {
|
|
1845
|
+
setActionError("");
|
|
1846
|
+
const key = viewItemKey(item);
|
|
1847
|
+
const toggleOff = Boolean((event?.ctrlKey || event?.metaKey) && selectedIds.has(key));
|
|
1848
|
+
setSelectedIds((current) => {
|
|
1849
|
+
if (event?.shiftKey && selectionAnchor) {
|
|
1850
|
+
const start = viewItems.findIndex((entry) => viewItemKey(entry) === selectionAnchor);
|
|
1851
|
+
const end = viewItems.findIndex((entry) => viewItemKey(entry) === key);
|
|
1852
|
+
if (start >= 0 && end >= 0) {
|
|
1853
|
+
const range = viewItems.slice(Math.min(start, end), Math.max(start, end) + 1).map((entry) => viewItemKey(entry));
|
|
1854
|
+
return new Set(event.ctrlKey || event.metaKey ? [...current, ...range] : range);
|
|
1855
|
+
}
|
|
1856
|
+
}
|
|
1857
|
+
if (event?.ctrlKey || event?.metaKey) {
|
|
1858
|
+
const next = new Set(current);
|
|
1859
|
+
if (next.has(key)) next.delete(key);
|
|
1860
|
+
else next.add(key);
|
|
1861
|
+
return next;
|
|
1862
|
+
}
|
|
1863
|
+
return /* @__PURE__ */ new Set([key]);
|
|
1864
|
+
});
|
|
1865
|
+
setSelectionAnchor(key);
|
|
1866
|
+
setPreviewKey(viewItemKey(item));
|
|
1867
|
+
if (!demo && !toggleOff && item.type === "asset" && client && project) {
|
|
1868
|
+
void client.inspectAsset(item.guid, { projectId: project.id, tabId: VIEW_WORKSPACE_TAB_ID }).catch(() => {
|
|
1869
|
+
});
|
|
1870
|
+
}
|
|
1871
|
+
};
|
|
1872
|
+
const assetToOpen = (item) => item.type === "asset" ? item : item.type === "file" ? item.assets.find((asset2) => asset2.kind === "scene") ?? item.assets[0] : void 0;
|
|
1873
|
+
const canActivate = (item) => item.type === "folder" || !demo && !!client && !!project && !!assetToOpen(item);
|
|
1874
|
+
const activateItem = (item) => {
|
|
1875
|
+
setActionError("");
|
|
1876
|
+
if (item.type === "folder") {
|
|
1877
|
+
navigate(item.path);
|
|
1878
|
+
return;
|
|
1879
|
+
}
|
|
1880
|
+
if (demo || !client || !project) return;
|
|
1881
|
+
const guid = assetToOpen(item)?.guid;
|
|
1882
|
+
if (!guid) return;
|
|
1883
|
+
const key = viewItemKey(item);
|
|
1884
|
+
if (openingKeys.has(key)) return;
|
|
1885
|
+
setOpeningKeys((current) => new Set(current).add(key));
|
|
1886
|
+
void client.openAsset(guid, { projectId: project.id, tabId: VIEW_WORKSPACE_TAB_ID }).catch((error) => setActionError(error instanceof Error ? error.message : String(error))).finally(() => {
|
|
1887
|
+
setOpeningKeys((current) => {
|
|
1888
|
+
if (!current.has(key)) return current;
|
|
1889
|
+
const next = new Set(current);
|
|
1890
|
+
next.delete(key);
|
|
1891
|
+
return next;
|
|
1892
|
+
});
|
|
1893
|
+
});
|
|
1894
|
+
};
|
|
1895
|
+
const toggleFavorite = (path) => setFavorites((current) => {
|
|
1896
|
+
const next = new Set(current);
|
|
1897
|
+
if (next.has(path)) next.delete(path);
|
|
1898
|
+
else next.add(path);
|
|
1899
|
+
return next;
|
|
1900
|
+
});
|
|
1901
|
+
const togglePackExpansion = (path) => setExpandedPacks((current) => {
|
|
1902
|
+
const next = new Set(current);
|
|
1903
|
+
if (next.has(path)) next.delete(path);
|
|
1904
|
+
else next.add(path);
|
|
1905
|
+
return next;
|
|
1906
|
+
});
|
|
1907
|
+
const toggleCollapsed = (path) => setCollapsed((current) => {
|
|
1908
|
+
const next = new Set(current);
|
|
1909
|
+
if (next.has(path)) next.delete(path);
|
|
1910
|
+
else next.add(path);
|
|
1911
|
+
return next;
|
|
1912
|
+
});
|
|
1913
|
+
useEffect4(() => {
|
|
1914
|
+
if (menu !== "filter" && menu !== "sort" && menu !== "settings") setToolbarMenuAnchor(null);
|
|
1915
|
+
}, [menu]);
|
|
1916
|
+
const showMenu = (event, items) => {
|
|
1917
|
+
event.preventDefault();
|
|
1918
|
+
event.stopPropagation();
|
|
1919
|
+
setMenu(null);
|
|
1920
|
+
setToolbarMenuAnchor(null);
|
|
1921
|
+
const target = event.currentTarget;
|
|
1922
|
+
const anchor = isContextMenuAnchor(target) ? target.getBoundingClientRect() : anchorRectFromPoint(event.clientX, event.clientY);
|
|
1923
|
+
setContextMenu({ anchor, items });
|
|
1924
|
+
};
|
|
1925
|
+
const openToolbarMenu = (kind) => {
|
|
1926
|
+
if (menu === kind) {
|
|
1927
|
+
setMenu(null);
|
|
1928
|
+
return;
|
|
1929
|
+
}
|
|
1930
|
+
const ref = kind === "filter" ? filterButtonRef : kind === "sort" ? sortButtonRef : settingsButtonRef;
|
|
1931
|
+
const rect = ref.current?.getBoundingClientRect();
|
|
1932
|
+
if (rect) setToolbarMenuAnchor(rect);
|
|
1933
|
+
setMenu(kind);
|
|
1934
|
+
};
|
|
1935
|
+
const folderMenu = (path, name) => [
|
|
1936
|
+
{ kind: "title", label: name, icon: /* @__PURE__ */ jsx9(Folder3, { className: "cb-folder-icon", size: 14 }) },
|
|
1937
|
+
{ kind: "item", id: "open", label: t2("contentBrowser.menu.open"), icon: /* @__PURE__ */ jsx9(FolderOpen2, { size: 14 }), action: () => navigate(path) },
|
|
1938
|
+
{
|
|
1939
|
+
kind: "item",
|
|
1940
|
+
id: "copy-path",
|
|
1941
|
+
label: t2("contentBrowser.menu.copyPath"),
|
|
1942
|
+
icon: /* @__PURE__ */ jsx9(Copy, { size: 14 }),
|
|
1943
|
+
action: () => void navigator.clipboard?.writeText(path || projectLabel)
|
|
1944
|
+
},
|
|
1945
|
+
{
|
|
1946
|
+
kind: "item",
|
|
1947
|
+
id: "favorite",
|
|
1948
|
+
label: favorites.has(path) ? t2("contentBrowser.menu.removeFromFavorites") : t2("contentBrowser.menu.addToFavorites"),
|
|
1949
|
+
icon: favorites.has(path) ? /* @__PURE__ */ jsx9(StarOff, { size: 14 }) : /* @__PURE__ */ jsx9(Star, { size: 14 }),
|
|
1950
|
+
action: () => toggleFavorite(path)
|
|
1951
|
+
}
|
|
1952
|
+
];
|
|
1953
|
+
const itemMenu = (item) => {
|
|
1954
|
+
const Icon = itemIcon(item);
|
|
1955
|
+
if (item.type === "folder") return folderMenu(item.path, item.name);
|
|
1956
|
+
return [
|
|
1957
|
+
{ kind: "title", label: item.name, icon: /* @__PURE__ */ jsx9(Icon, { size: 14 }) },
|
|
1958
|
+
...canActivate(item) ? [{ kind: "item", id: "open", label: t2("contentBrowser.menu.open"), shortcut: "Enter", action: () => activateItem(item) }] : [],
|
|
1959
|
+
...item.type === "asset" ? [{
|
|
1960
|
+
kind: "item",
|
|
1961
|
+
id: "copy-guid",
|
|
1962
|
+
label: t2("contentBrowser.menu.copyGuid"),
|
|
1963
|
+
icon: /* @__PURE__ */ jsx9(Copy, { size: 14 }),
|
|
1964
|
+
action: () => void navigator.clipboard?.writeText(item.guid)
|
|
1965
|
+
}] : [],
|
|
1966
|
+
{
|
|
1967
|
+
kind: "item",
|
|
1968
|
+
id: "copy-path",
|
|
1969
|
+
label: t2("contentBrowser.menu.copyAssetPath"),
|
|
1970
|
+
icon: /* @__PURE__ */ jsx9(Copy, { size: 14 }),
|
|
1971
|
+
shortcut: "Ctrl+Shift+C",
|
|
1972
|
+
action: () => void navigator.clipboard?.writeText(item.type === "asset" ? item.packPath : item.path)
|
|
1973
|
+
}
|
|
1974
|
+
];
|
|
1975
|
+
};
|
|
1976
|
+
const blankMenu = [
|
|
1977
|
+
{ kind: "title", label: t2("contentBrowser.readOnlyTitle") },
|
|
1978
|
+
{
|
|
1979
|
+
kind: "item",
|
|
1980
|
+
id: "copy-path",
|
|
1981
|
+
label: t2("contentBrowser.menu.copyCurrentPath"),
|
|
1982
|
+
icon: /* @__PURE__ */ jsx9(Copy, { size: 14 }),
|
|
1983
|
+
action: () => void navigator.clipboard?.writeText(folder || projectLabel)
|
|
1984
|
+
}
|
|
1985
|
+
];
|
|
1986
|
+
const applyFilter = (filterId) => {
|
|
1987
|
+
const next = toggleFilterId(filterId, activeFamilies, activeKinds);
|
|
1988
|
+
setActiveFamilies(next.families);
|
|
1989
|
+
setActiveKinds(next.kinds);
|
|
1990
|
+
};
|
|
1991
|
+
const renderTreeRow = (path, name, depth, favorite = false) => {
|
|
1992
|
+
const hasChildren = directoryTree.some((entry) => entry.path.startsWith(`${path}/`));
|
|
1993
|
+
const open = !collapsed.has(path);
|
|
1994
|
+
const folderItem = folders.find((entry) => entry.path === path);
|
|
1995
|
+
const selected = folder === path;
|
|
1996
|
+
const inPath = folder.startsWith(`${path}/`);
|
|
1997
|
+
const row = /* @__PURE__ */ jsxs7(
|
|
1998
|
+
"button",
|
|
1999
|
+
{
|
|
2000
|
+
type: "button",
|
|
2001
|
+
className: `cb-source-row${selected ? " is-sel" : inPath ? " is-path" : ""}${hasChildren && !open ? " collapsed" : ""}`,
|
|
2002
|
+
style: { paddingLeft: `calc(var(--fx-ref-space-16) + ${depth} * (var(--fx-ref-space-12) + var(--fx-ref-space-2)))` },
|
|
2003
|
+
onClick: () => {
|
|
2004
|
+
navigate(path);
|
|
2005
|
+
if (folderItem) {
|
|
2006
|
+
setPreviewKey(viewItemKey(folderItem));
|
|
2007
|
+
setSelectedIds(/* @__PURE__ */ new Set([path]));
|
|
2008
|
+
setSelectionAnchor(path);
|
|
2009
|
+
}
|
|
2010
|
+
},
|
|
2011
|
+
onDoubleClick: () => hasChildren && toggleCollapsed(path),
|
|
2012
|
+
onContextMenu: (event) => showMenu(event, folderMenu(path, name)),
|
|
2013
|
+
children: [
|
|
2014
|
+
/* @__PURE__ */ jsx9(
|
|
2015
|
+
"span",
|
|
2016
|
+
{
|
|
2017
|
+
className: `cb-source-chev${hasChildren ? "" : " hidden"}${open ? "" : " collapsed"}`,
|
|
2018
|
+
onClick: (event) => {
|
|
2019
|
+
if (!hasChildren) return;
|
|
2020
|
+
event.stopPropagation();
|
|
2021
|
+
toggleCollapsed(path);
|
|
2022
|
+
},
|
|
2023
|
+
children: /* @__PURE__ */ jsx9(ChevronDown2, { size: 12 })
|
|
2024
|
+
}
|
|
2025
|
+
),
|
|
2026
|
+
/* @__PURE__ */ jsx9("span", { className: "cb-source-icon", children: open ? /* @__PURE__ */ jsx9(FolderOpen2, { size: 15 }) : /* @__PURE__ */ jsx9(Folder3, { size: 15 }) }),
|
|
2027
|
+
/* @__PURE__ */ jsx9("span", { className: "cb-source-name", children: name })
|
|
2028
|
+
]
|
|
2029
|
+
}
|
|
2030
|
+
);
|
|
2031
|
+
if (!favorite) return /* @__PURE__ */ jsx9("div", { children: row }, `tree-${path}`);
|
|
2032
|
+
return /* @__PURE__ */ jsxs7(
|
|
2033
|
+
"div",
|
|
2034
|
+
{
|
|
2035
|
+
className: `cb-source-fav-row${selected ? " is-sel" : inPath ? " is-path" : ""}`,
|
|
2036
|
+
children: [
|
|
2037
|
+
row,
|
|
2038
|
+
/* @__PURE__ */ jsx9(
|
|
2039
|
+
"button",
|
|
2040
|
+
{
|
|
2041
|
+
type: "button",
|
|
2042
|
+
className: "cb-source-unfav",
|
|
2043
|
+
"data-action": CONTENT_BROWSER_ACTIONS.toggleFavorite,
|
|
2044
|
+
title: t2("contentBrowser.unfavorite"),
|
|
2045
|
+
"aria-label": t2("contentBrowser.unfavorite"),
|
|
2046
|
+
onClick: (event) => {
|
|
2047
|
+
event.stopPropagation();
|
|
2048
|
+
toggleFavorite(path);
|
|
2049
|
+
},
|
|
2050
|
+
children: /* @__PURE__ */ jsx9(Star, { size: 11, fill: "currentColor" })
|
|
2051
|
+
}
|
|
2052
|
+
)
|
|
2053
|
+
]
|
|
2054
|
+
},
|
|
2055
|
+
`fav-${path}`
|
|
2056
|
+
);
|
|
2057
|
+
};
|
|
2058
|
+
const filterLabel = activeFilterCount === 0 ? t2("contentBrowser.filterAll") : activeFilterCount === 1 ? (familyFilters.find((item) => item.active) ?? kindFilters.find((item) => item.active)).label : t2("contentBrowser.filterByType");
|
|
2059
|
+
const sortLabels = {
|
|
2060
|
+
name: t2("contentBrowser.sort.name"),
|
|
2061
|
+
kind: t2("contentBrowser.sort.kind"),
|
|
2062
|
+
packModifiedAt: t2("contentBrowser.sort.modified"),
|
|
2063
|
+
estimatedSize: t2("contentBrowser.sort.size")
|
|
2064
|
+
};
|
|
2065
|
+
return /* @__PURE__ */ jsxs7("div", { className: "cb-root", "data-testid": "panel-content-browser", "data-view-readonly": "true", children: [
|
|
2066
|
+
/* @__PURE__ */ jsxs7(
|
|
2067
|
+
"div",
|
|
2068
|
+
{
|
|
2069
|
+
className: "cb-split",
|
|
2070
|
+
ref: splitRef,
|
|
2071
|
+
style: { "--cb-src-w": `${srcWidth}px`, "--cb-preview-w": `${previewWidth}px` },
|
|
2072
|
+
children: [
|
|
2073
|
+
/* @__PURE__ */ jsx9("aside", { className: "cb-source-panel", children: /* @__PURE__ */ jsxs7("div", { className: "cb-source-tree", children: [
|
|
2074
|
+
/* @__PURE__ */ jsxs7("section", { className: "cb-source-group", children: [
|
|
2075
|
+
/* @__PURE__ */ jsxs7("button", { type: "button", "data-action": CONTENT_BROWSER_ACTIONS.toggleSourceGroup, className: `cb-source-group-head${groups.favorites ? "" : " collapsed"}`, onClick: () => setGroups((current) => ({ ...current, favorites: !current.favorites })), children: [
|
|
2076
|
+
/* @__PURE__ */ jsx9("span", { className: "cb-source-chev", children: /* @__PURE__ */ jsx9(ChevronDown2, { size: 12 }) }),
|
|
2077
|
+
/* @__PURE__ */ jsx9(Star, { className: "cb-source-group-icon", size: 15 }),
|
|
2078
|
+
/* @__PURE__ */ jsx9("span", { className: "cb-source-group-name", children: t2("contentBrowser.favorites") })
|
|
2079
|
+
] }),
|
|
2080
|
+
groups.favorites ? /* @__PURE__ */ jsx9("div", { className: "cb-source-group-body", children: favorites.size ? [...favorites].map((path) => renderTreeRow(path, path.split("/").at(-1) ?? path, 0, true)) : /* @__PURE__ */ jsx9("div", { className: "cb-source-empty", children: t2("contentBrowser.noFavorites") }) }) : null
|
|
2081
|
+
] }),
|
|
2082
|
+
/* @__PURE__ */ jsxs7("section", { className: "cb-source-group", children: [
|
|
2083
|
+
/* @__PURE__ */ jsxs7("button", { type: "button", "data-action": CONTENT_BROWSER_ACTIONS.toggleSourceGroup, className: `cb-source-group-head${groups.project ? "" : " collapsed"}`, onClick: () => setGroups((current) => ({ ...current, project: !current.project })), children: [
|
|
2084
|
+
/* @__PURE__ */ jsx9("span", { className: "cb-source-chev", children: /* @__PURE__ */ jsx9(ChevronDown2, { size: 12 }) }),
|
|
2085
|
+
/* @__PURE__ */ jsx9(FolderOpen2, { className: "cb-source-group-icon cb-folder-icon", size: 15 }),
|
|
2086
|
+
/* @__PURE__ */ jsx9("span", { className: "cb-source-group-name", children: projectLabel })
|
|
2087
|
+
] }),
|
|
2088
|
+
groups.project ? /* @__PURE__ */ jsxs7("div", { className: "cb-source-group-body", children: [
|
|
2089
|
+
/* @__PURE__ */ jsxs7("button", { type: "button", className: `cb-source-row cb-source-virtual-root${folder === "" ? " is-sel" : ""}`, onClick: () => navigate(""), onContextMenu: (event) => showMenu(event, folderMenu("", projectLabel)), children: [
|
|
2090
|
+
/* @__PURE__ */ jsx9("span", { className: "cb-source-chev", children: /* @__PURE__ */ jsx9(ChevronDown2, { size: 12 }) }),
|
|
2091
|
+
/* @__PURE__ */ jsx9("span", { className: "cb-source-icon", children: /* @__PURE__ */ jsx9(FolderOpen2, { size: 15 }) }),
|
|
2092
|
+
/* @__PURE__ */ jsx9("span", { className: "cb-source-name", children: t2("contentBrowser.all") })
|
|
2093
|
+
] }),
|
|
2094
|
+
directoryTree.filter((entry) => {
|
|
2095
|
+
if (entry.depth === 0) return true;
|
|
2096
|
+
const parent = entry.path.slice(0, entry.path.lastIndexOf("/"));
|
|
2097
|
+
return !collapsed.has(parent);
|
|
2098
|
+
}).map((entry) => renderTreeRow(entry.path, entry.name, entry.depth + 1))
|
|
2099
|
+
] }) : null
|
|
2100
|
+
] })
|
|
2101
|
+
] }) }),
|
|
2102
|
+
/* @__PURE__ */ jsx9(
|
|
2103
|
+
ResizeHandle,
|
|
2104
|
+
{
|
|
2105
|
+
title: t2("contentBrowser.actions.resizeFolderTree"),
|
|
2106
|
+
onDrag: (delta) => {
|
|
2107
|
+
const next = srcWidth + delta;
|
|
2108
|
+
setSrcWidth(next);
|
|
2109
|
+
splitRef.current?.style.setProperty("--cb-src-w", `${Math.min(420, Math.max(140, next))}px`);
|
|
2110
|
+
}
|
|
2111
|
+
}
|
|
2112
|
+
),
|
|
2113
|
+
/* @__PURE__ */ jsxs7("section", { className: "cb-asset-view", children: [
|
|
2114
|
+
/* @__PURE__ */ jsx9(
|
|
2115
|
+
PanelHeader,
|
|
2116
|
+
{
|
|
2117
|
+
className: "cb-toolbar",
|
|
2118
|
+
center: /* @__PURE__ */ jsx9(
|
|
2119
|
+
CBNavigationBar,
|
|
2120
|
+
{
|
|
2121
|
+
currentPath: folder,
|
|
2122
|
+
projectLabel,
|
|
2123
|
+
allDirs: folders.map((entry) => entry.path),
|
|
2124
|
+
canGoBack: historyIndex > 0,
|
|
2125
|
+
canGoForward: historyIndex < history.length - 1,
|
|
2126
|
+
refreshDisabled: !demo && (!project || loading),
|
|
2127
|
+
onBack: () => setHistoryIndex((index) => Math.max(0, index - 1)),
|
|
2128
|
+
onForward: () => setHistoryIndex((index) => Math.min(history.length - 1, index + 1)),
|
|
2129
|
+
onRefresh: () => void refresh(),
|
|
2130
|
+
onNavigate: navigate
|
|
2131
|
+
}
|
|
2132
|
+
),
|
|
2133
|
+
end: /* @__PURE__ */ jsx9(IconButton, { ref: settingsButtonRef, size: "compact", variant: "quiet", label: t2("contentBrowser.settings"), icon: /* @__PURE__ */ jsx9(Settings2, { size: 14 }), onClick: () => openToolbarMenu("settings") })
|
|
2134
|
+
}
|
|
2135
|
+
),
|
|
2136
|
+
/* @__PURE__ */ jsxs7("div", { className: "cb-content-body", children: [
|
|
2137
|
+
/* @__PURE__ */ jsxs7("div", { className: "cb-grid-column", children: [
|
|
2138
|
+
/* @__PURE__ */ jsxs7(Toolbar, { className: "cb-filter-bar", children: [
|
|
2139
|
+
/* @__PURE__ */ jsx9(
|
|
2140
|
+
Button,
|
|
2141
|
+
{
|
|
2142
|
+
size: "compact",
|
|
2143
|
+
variant: "quiet",
|
|
2144
|
+
"data-action": CONTENT_BROWSER_ACTIONS.activate,
|
|
2145
|
+
disabled: selectedIds.size !== 1 || !previewItem || !canActivate(previewItem),
|
|
2146
|
+
loading: Boolean(previewItem && openingKeys.has(viewItemKey(previewItem))),
|
|
2147
|
+
title: t2("contentBrowser.openHint"),
|
|
2148
|
+
onClick: () => {
|
|
2149
|
+
if (previewItem) activateItem(previewItem);
|
|
2150
|
+
},
|
|
2151
|
+
children: t2("contentBrowser.menu.open")
|
|
2152
|
+
}
|
|
2153
|
+
),
|
|
2154
|
+
/* @__PURE__ */ jsx9(Button, { ref: filterButtonRef, size: "compact", variant: "quiet", "data-action": CONTENT_BROWSER_ACTIONS.setFilter, className: activeFilterCount ? "is-active" : void 0, leadingIcon: /* @__PURE__ */ jsx9(Filter, { size: 14 }), onClick: () => openToolbarMenu("filter"), children: filterLabel }),
|
|
2155
|
+
/* @__PURE__ */ jsx9(SearchField, { className: "cb-search-box", "data-action": CONTENT_BROWSER_ACTIONS.search, value: query, onChange: (event) => setQuery(event.target.value), onClear: () => setQuery(""), placeholder: t2("contentBrowser.searchPlaceholder"), label: t2("contentBrowser.search") }),
|
|
2156
|
+
/* @__PURE__ */ jsx9(Button, { ref: sortButtonRef, size: "compact", variant: "quiet", "data-action": CONTENT_BROWSER_ACTIONS.setSort, leadingIcon: /* @__PURE__ */ jsx9(ArrowUpDown, { size: 14 }), onClick: () => openToolbarMenu("sort"), children: sortLabels[sortState.key] })
|
|
2157
|
+
] }),
|
|
2158
|
+
loading ? /* @__PURE__ */ jsx9("div", { role: "status", children: "Loading assets..." }) : null,
|
|
2159
|
+
actionError ? /* @__PURE__ */ jsx9("div", { role: "alert", children: actionError }) : null,
|
|
2160
|
+
loadFailed ? /* @__PURE__ */ jsx9(
|
|
2161
|
+
EmptyState,
|
|
2162
|
+
{
|
|
2163
|
+
className: "cb-empty",
|
|
2164
|
+
title: t2("contentBrowser.unavailable"),
|
|
2165
|
+
description: demo || client ? t2("contentBrowser.loadErrorDescription") : t2("contentBrowser.unavailableDescription"),
|
|
2166
|
+
icon: /* @__PURE__ */ jsx9(FolderOpen2, { size: 28 })
|
|
2167
|
+
}
|
|
2168
|
+
) : !demo && !project ? /* @__PURE__ */ jsx9(EmptyState, { className: "cb-empty", title: t2("contentBrowser.noProject"), description: t2("contentBrowser.openProjectHint"), icon: /* @__PURE__ */ jsx9(FolderOpen2, { size: 28 }) }) : viewItems.length === 0 ? /* @__PURE__ */ jsx9(EmptyState, { className: "cb-empty", title: t2("contentBrowser.emptyTitle"), description: t2("contentBrowser.emptyDescription"), icon: /* @__PURE__ */ jsx9(FolderOpen2, { size: 28 }) }) : layout === "column" ? /* @__PURE__ */ jsx9(
|
|
2169
|
+
CBDetailsList,
|
|
2170
|
+
{
|
|
2171
|
+
items: viewItems,
|
|
2172
|
+
selectedIds,
|
|
2173
|
+
openingKeys,
|
|
2174
|
+
sortState,
|
|
2175
|
+
onSort: (key) => setSortState((current) => nextSortState(current, key)),
|
|
2176
|
+
onSelect: selectItem,
|
|
2177
|
+
onActivate: activateItem,
|
|
2178
|
+
onContextMenu: (event, item) => showMenu(event, itemMenu(item)),
|
|
2179
|
+
onBlankClick: () => setSelectedIds(/* @__PURE__ */ new Set())
|
|
2180
|
+
}
|
|
2181
|
+
) : /* @__PURE__ */ jsx9(
|
|
2182
|
+
CBGrid,
|
|
2183
|
+
{
|
|
2184
|
+
items: viewItems,
|
|
2185
|
+
thumbnailSize,
|
|
2186
|
+
layout,
|
|
2187
|
+
searchActive,
|
|
2188
|
+
expandedPacks,
|
|
2189
|
+
selectedIds,
|
|
2190
|
+
openingKeys,
|
|
2191
|
+
onSelect: selectItem,
|
|
2192
|
+
onActivate: activateItem,
|
|
2193
|
+
onContextMenu: (event, item) => showMenu(event, itemMenu(item)),
|
|
2194
|
+
onTogglePackExpansion: togglePackExpansion,
|
|
2195
|
+
onBlankClick: () => setSelectedIds(/* @__PURE__ */ new Set())
|
|
2196
|
+
}
|
|
2197
|
+
),
|
|
2198
|
+
/* @__PURE__ */ jsxs7("footer", { className: "cb-status", children: [
|
|
2199
|
+
/* @__PURE__ */ jsx9("span", { children: selectedIds.size ? t2("contentBrowser.statusSelected", { count: viewItems.length, selected: selectedIds.size }) : t2("contentBrowser.statusCount", { count: viewItems.length }) }),
|
|
2200
|
+
/* @__PURE__ */ jsx9("span", { children: folder || projectLabel })
|
|
2201
|
+
] })
|
|
2202
|
+
] }),
|
|
2203
|
+
detailPanelOpen ? /* @__PURE__ */ jsx9(
|
|
2204
|
+
CBPreviewPanel,
|
|
2205
|
+
{
|
|
2206
|
+
previewItem,
|
|
2207
|
+
foldersInPath: folders,
|
|
2208
|
+
diskFiles: labeledFiles,
|
|
2209
|
+
projectLabel,
|
|
2210
|
+
readPreview: demo ? void 0 : readPreview,
|
|
2211
|
+
onClose: () => setPreviewKey(null),
|
|
2212
|
+
onDrag: (delta) => {
|
|
2213
|
+
const next = previewWidth - delta;
|
|
2214
|
+
setPreviewWidth(next);
|
|
2215
|
+
splitRef.current?.style.setProperty("--cb-preview-w", `${Math.min(560, Math.max(180, next))}px`);
|
|
2216
|
+
},
|
|
2217
|
+
onDragEnd: () => void 0
|
|
2218
|
+
}
|
|
2219
|
+
) : null
|
|
2220
|
+
] })
|
|
2221
|
+
] })
|
|
2222
|
+
]
|
|
2223
|
+
}
|
|
2224
|
+
),
|
|
2225
|
+
/* @__PURE__ */ jsx9(
|
|
2226
|
+
FloatingMenu,
|
|
2227
|
+
{
|
|
2228
|
+
open: Boolean(toolbarMenuAnchor && menu === "filter"),
|
|
2229
|
+
anchorRect: toolbarMenuAnchor,
|
|
2230
|
+
onClose: () => setMenu(null),
|
|
2231
|
+
ignorePointerWithin: [filterButtonRef],
|
|
2232
|
+
className: "cb-filter-menu",
|
|
2233
|
+
containerProps: { onPointerDown: (event) => event.stopPropagation() },
|
|
2234
|
+
children: /* @__PURE__ */ jsxs7("div", { className: "cb-filter-menu-body", "data-action": CONTENT_BROWSER_ACTIONS.setFilter, children: [
|
|
2235
|
+
/* @__PURE__ */ jsx9("div", { className: "cb-filter-section", children: t2("contentBrowser.fileTypeSection") }),
|
|
2236
|
+
familyFilters.map((item) => {
|
|
2237
|
+
const Icon = familyIcon(item.family);
|
|
2238
|
+
return /* @__PURE__ */ jsxs7("button", { type: "button", className: "cb-filter-option", "data-active": item.active ? "true" : "false", onClick: () => applyFilter(item.id), children: [
|
|
2239
|
+
/* @__PURE__ */ jsx9(Checkbox, { checked: item.active, onChange: () => applyFilter(item.id), tabIndex: -1, hideLabel: true, label: item.label, className: "cb-filter-check" }),
|
|
2240
|
+
/* @__PURE__ */ jsx9(Icon, { size: 14, className: `cb-filter-option-icon${item.family === "dir" ? " cb-folder-icon" : ""}` }),
|
|
2241
|
+
item.label
|
|
2242
|
+
] }, item.id);
|
|
2243
|
+
}),
|
|
2244
|
+
/* @__PURE__ */ jsx9("div", { className: "cb-filter-separator" }),
|
|
2245
|
+
/* @__PURE__ */ jsx9("div", { className: "cb-filter-section", children: t2("contentBrowser.assetTypeSection") }),
|
|
2246
|
+
kindFilters.map((item) => {
|
|
2247
|
+
const Icon = kindIcon(item.kind);
|
|
2248
|
+
return /* @__PURE__ */ jsxs7("button", { type: "button", className: "cb-filter-option", "data-active": item.active ? "true" : "false", onClick: () => applyFilter(item.id), children: [
|
|
2249
|
+
/* @__PURE__ */ jsx9(Checkbox, { checked: item.active, onChange: () => applyFilter(item.id), tabIndex: -1, hideLabel: true, label: item.label, className: "cb-filter-check" }),
|
|
2250
|
+
/* @__PURE__ */ jsx9(Icon, { size: 14, className: "cb-filter-option-icon" }),
|
|
2251
|
+
item.label
|
|
2252
|
+
] }, item.id);
|
|
2253
|
+
}),
|
|
2254
|
+
/* @__PURE__ */ jsx9("div", { className: "cb-filter-separator" }),
|
|
2255
|
+
/* @__PURE__ */ jsx9("button", { type: "button", className: "cb-filter-option cb-filter-clear", disabled: activeFilterCount === 0, onClick: () => {
|
|
2256
|
+
setActiveFamilies(/* @__PURE__ */ new Set());
|
|
2257
|
+
setActiveKinds(/* @__PURE__ */ new Set());
|
|
2258
|
+
}, children: t2("contentBrowser.clearFilters") })
|
|
2259
|
+
] })
|
|
2260
|
+
}
|
|
2261
|
+
),
|
|
2262
|
+
/* @__PURE__ */ jsx9(
|
|
2263
|
+
FloatingMenu,
|
|
2264
|
+
{
|
|
2265
|
+
open: Boolean(toolbarMenuAnchor && menu === "sort"),
|
|
2266
|
+
anchorRect: toolbarMenuAnchor,
|
|
2267
|
+
onClose: () => setMenu(null),
|
|
2268
|
+
ignorePointerWithin: [sortButtonRef],
|
|
2269
|
+
containerProps: { onPointerDown: (event) => event.stopPropagation() },
|
|
2270
|
+
children: /* @__PURE__ */ jsxs7("div", { className: "cb-filter-menu-body", children: [
|
|
2271
|
+
/* @__PURE__ */ jsx9("div", { className: "cb-filter-section", children: t2("contentBrowser.sort.by") }),
|
|
2272
|
+
SORT_KEYS.map((key) => {
|
|
2273
|
+
const Icon = SORT_KEY_ICONS[key];
|
|
2274
|
+
const active = sortState.key === key;
|
|
2275
|
+
return /* @__PURE__ */ jsxs7("button", { type: "button", className: "cb-filter-option", "data-active": active ? "true" : "false", onClick: () => setSortState((current) => nextSortState(current, key)), children: [
|
|
2276
|
+
/* @__PURE__ */ jsx9("span", { className: "cb-radio-menu", "data-checked": active ? "true" : "false" }),
|
|
2277
|
+
/* @__PURE__ */ jsx9(Icon, { size: 14, className: "cb-filter-option-icon" }),
|
|
2278
|
+
sortLabels[key]
|
|
2279
|
+
] }, key);
|
|
2280
|
+
}),
|
|
2281
|
+
/* @__PURE__ */ jsx9("div", { className: "cb-filter-separator" }),
|
|
2282
|
+
/* @__PURE__ */ jsx9("div", { className: "cb-filter-section", children: t2("contentBrowser.sort.order") }),
|
|
2283
|
+
[["asc", ArrowUpNarrowWide], ["desc", ArrowDownWideNarrow]].map(([dir, Icon]) => {
|
|
2284
|
+
const active = sortState.dir === dir;
|
|
2285
|
+
return /* @__PURE__ */ jsxs7("button", { type: "button", className: "cb-filter-option", "data-active": active ? "true" : "false", onClick: () => setSortState((current) => setSortDir(current, dir)), children: [
|
|
2286
|
+
/* @__PURE__ */ jsx9("span", { className: "cb-radio-menu", "data-checked": active ? "true" : "false" }),
|
|
2287
|
+
/* @__PURE__ */ jsx9(Icon, { size: 14, className: "cb-filter-option-icon" }),
|
|
2288
|
+
t2(dir === "asc" ? "contentBrowser.sort.asc" : "contentBrowser.sort.desc")
|
|
2289
|
+
] }, dir);
|
|
2290
|
+
})
|
|
2291
|
+
] })
|
|
2292
|
+
}
|
|
2293
|
+
),
|
|
2294
|
+
/* @__PURE__ */ jsx9(
|
|
2295
|
+
FloatingMenu,
|
|
2296
|
+
{
|
|
2297
|
+
open: Boolean(toolbarMenuAnchor && menu === "settings"),
|
|
2298
|
+
anchorRect: toolbarMenuAnchor,
|
|
2299
|
+
onClose: () => setMenu(null),
|
|
2300
|
+
ignorePointerWithin: [settingsButtonRef],
|
|
2301
|
+
containerProps: { onPointerDown: (event) => event.stopPropagation() },
|
|
2302
|
+
children: /* @__PURE__ */ jsxs7("div", { className: "cb-settings-menu", children: [
|
|
2303
|
+
/* @__PURE__ */ jsx9("strong", { children: t2("contentBrowser.layout") }),
|
|
2304
|
+
/* @__PURE__ */ jsx9("div", { className: "fx-segmented cb-layout-switch", children: LAYOUT_OPTIONS.map(({ mode, icon, labelKey }) => /* @__PURE__ */ jsxs7(
|
|
2305
|
+
"button",
|
|
2306
|
+
{
|
|
2307
|
+
type: "button",
|
|
2308
|
+
"data-action": CONTENT_BROWSER_ACTIONS.setView,
|
|
2309
|
+
className: "fx-segmented__item fx-segmented__item--stacked",
|
|
2310
|
+
"data-checked": layout === mode ? "true" : "false",
|
|
2311
|
+
onClick: () => setLayout(mode),
|
|
2312
|
+
children: [
|
|
2313
|
+
icon,
|
|
2314
|
+
/* @__PURE__ */ jsx9("span", { children: t2(labelKey) })
|
|
2315
|
+
]
|
|
2316
|
+
},
|
|
2317
|
+
mode
|
|
2318
|
+
)) }),
|
|
2319
|
+
/* @__PURE__ */ jsxs7("label", { className: "cb-settings-row", children: [
|
|
2320
|
+
/* @__PURE__ */ jsx9("span", { className: "cb-settings-label", children: t2("contentBrowser.thumbnailSize") }),
|
|
2321
|
+
/* @__PURE__ */ jsx9(
|
|
2322
|
+
RangeInput,
|
|
2323
|
+
{
|
|
2324
|
+
"data-action": CONTENT_BROWSER_ACTIONS.setThumbnailSize,
|
|
2325
|
+
className: "cb-settings-range",
|
|
2326
|
+
min: 48,
|
|
2327
|
+
max: 200,
|
|
2328
|
+
step: 4,
|
|
2329
|
+
value: thumbnailSize,
|
|
2330
|
+
onChange: (event) => setThumbnailSize(Number(event.target.value)),
|
|
2331
|
+
title: t2("contentBrowser.actions.thumbnailSize", { size: thumbnailSize })
|
|
2332
|
+
}
|
|
2333
|
+
)
|
|
2334
|
+
] }),
|
|
2335
|
+
/* @__PURE__ */ jsx9(
|
|
2336
|
+
Switch,
|
|
2337
|
+
{
|
|
2338
|
+
layout: "row",
|
|
2339
|
+
className: "cb-settings-switch-row",
|
|
2340
|
+
label: t2("contentBrowser.actions.detailPanel"),
|
|
2341
|
+
checked: detailPanelOpen,
|
|
2342
|
+
"data-action": CONTENT_BROWSER_ACTIONS.toggleDetailPanel,
|
|
2343
|
+
onCheckedChange: setDetailPanelOpen
|
|
2344
|
+
}
|
|
2345
|
+
)
|
|
2346
|
+
] })
|
|
2347
|
+
}
|
|
2348
|
+
),
|
|
2349
|
+
/* @__PURE__ */ jsx9(
|
|
2350
|
+
ContextMenu,
|
|
2351
|
+
{
|
|
2352
|
+
open: Boolean(contextMenu),
|
|
2353
|
+
anchorRect: contextMenu?.anchor ?? null,
|
|
2354
|
+
items: contextMenu ? toFxMenuItems(contextMenu.items) : [],
|
|
2355
|
+
onClose: () => setContextMenu(null),
|
|
2356
|
+
label: t2("contentBrowser.contextMenu"),
|
|
2357
|
+
containerProps: { "data-action": CONTENT_BROWSER_ACTIONS.showContextMenu }
|
|
2358
|
+
}
|
|
2359
|
+
)
|
|
2360
|
+
] });
|
|
2361
|
+
}
|
|
2362
|
+
|
|
2363
|
+
// packages/view-plugin-content-browser/src/ui/content-browser.css
|
|
2364
|
+
var css = '/* packages/view-plugin-content-browser/src/ui/content-browser.css */\n.cb-root {\n --cb-layout-min-width: calc(var(--fx-component-panel-chat-min-width) + var(--fx-ref-space-48) + var(--fx-ref-space-32));\n --cb-source-width: calc(var(--fx-component-panel-config-min-width) - var(--fx-ref-space-48));\n --cb-source-min-width: calc(var(--fx-ref-space-48) * 2 + var(--fx-ref-space-32) + var(--fx-ref-space-12));\n --cb-resize-width: var(--fx-ref-space-6);\n --cb-resize-offset: calc(-1 * var(--fx-ref-space-2));\n --cb-grid-min-width: calc(var(--fx-ref-space-48) * 2 + var(--fx-ref-space-24));\n --cb-grid-min-height: calc(var(--fx-ref-space-48) * 2 + var(--fx-ref-space-32) + var(--fx-ref-space-12));\n --cb-thumb-default: calc(var(--fx-ref-space-48) + var(--fx-ref-space-32) + var(--fx-ref-space-8));\n --cb-import-pop-left: calc(var(--fx-component-navigation-rail-width) + var(--fx-ref-space-12));\n --cb-card-line: 13px;\n --cb-folder-icon: #c9a86a;\n --cb-group-stack: 6px;\n position: relative;\n display: flex;\n flex-direction: column;\n width: 100%;\n height: 100%;\n min-width: var(--cb-layout-min-width);\n min-height: 0;\n overflow: hidden;\n background: var(--fx-color-surface-canvas);\n color: var(--fx-color-text-secondary);\n font: var(--fx-type-compact-font-weight) var(--fx-type-compact-font-size)/var(--fx-type-compact-line-height) var(--fx-type-compact-font-family);\n user-select: none;\n}\n.cb-root * {\n box-sizing: border-box;\n}\n.cb-root :where(input, textarea, .cb-address, .cb-address-input, .cb-preview-source, .cb-preview-code-plain, .cb-preview-code-shiki) {\n user-select: text;\n}\n.cb-root button,\n.cb-root input {\n font: inherit;\n}\n.cb-split {\n display: flex;\n flex: 1;\n min-height: 0;\n overflow: hidden;\n}\n.cb-source-panel {\n flex: 0 0 var(--cb-src-w, var(--cb-source-width));\n width: var(--cb-src-w, var(--cb-source-width));\n min-width: var(--cb-source-min-width);\n overflow: auto;\n background: var(--fx-color-surface-sidebar);\n}\n.cb-resize-handle {\n position: relative;\n z-index: var(--fx-layer-sticky);\n flex: 0 0 var(--cb-resize-width);\n width: var(--cb-resize-width);\n margin: 0 var(--cb-resize-offset);\n cursor: col-resize;\n}\n.cb-resize-handle::after {\n content: "";\n position: absolute;\n inset: 0 auto 0 50%;\n width: var(--fx-border-width);\n background: var(--fx-color-border-subtle);\n}\n.cb-resize-handle:hover::after {\n background: var(--fx-color-border-focus);\n}\n.cb-source-tree {\n min-width: 0;\n padding: var(--fx-ref-space-4) 0;\n}\n.cb-source-group + .cb-source-group {\n margin-top: var(--fx-ref-space-2);\n}\n.cb-source-group-head,\n.cb-source-row {\n appearance: none;\n display: flex;\n align-items: center;\n width: 100%;\n min-width: 0;\n border: var(--fx-border-width) solid transparent;\n text-align: left;\n cursor: pointer;\n}\n.cb-source-group-head {\n gap: var(--fx-ref-space-4);\n padding: var(--fx-ref-space-4) var(--fx-ref-space-8);\n background: var(--fx-color-surface-raised);\n color: var(--fx-color-text-secondary);\n font-weight: var(--fx-ref-font-weight-600);\n}\n.cb-source-group-head:hover,\n.cb-source-row:hover {\n background: var(--fx-color-surface-hover);\n color: var(--fx-color-text-primary);\n}\n.cb-source-group-head.collapsed .cb-source-chev,\n.cb-source-chev.collapsed {\n transform: rotate(-90deg);\n}\n.cb-source-group-icon {\n flex: 0 0 auto;\n color: var(--fx-color-text-muted);\n}\n.cb-source-group-head .cb-folder-icon {\n color: var(--cb-folder-icon);\n}\n.cb-source-group-name,\n.cb-source-name {\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.cb-source-group-body {\n padding: var(--fx-ref-space-2) 0 var(--fx-ref-space-4);\n}\n.cb-source-empty {\n padding: var(--fx-ref-space-4) var(--fx-ref-space-12) var(--fx-ref-space-4) var(--fx-ref-space-16);\n color: var(--fx-color-text-muted);\n font-size: var(--fx-type-caption-font-size);\n font-style: italic;\n}\n.cb-source-row {\n gap: var(--fx-ref-space-4);\n min-height: var(--fx-component-editor-row-height);\n padding-top: var(--fx-ref-space-4);\n padding-right: var(--fx-ref-space-12);\n padding-bottom: var(--fx-ref-space-4);\n background: transparent;\n color: var(--fx-color-text-secondary);\n}\n.cb-source-row.is-path:not(.is-sel) {\n background: color-mix(in srgb, var(--fx-color-surface-hover) 55%, transparent);\n color: var(--fx-color-text-primary);\n}\n.cb-source-row.is-sel {\n background: var(--fx-color-selection-bg);\n color: var(--fx-color-selection-fg);\n box-shadow: inset var(--fx-border-focus-width) 0 0 var(--fx-color-selection-indicator);\n}\n.cb-source-row:focus-visible,\n.cb-source-group-head:focus-visible {\n outline: var(--fx-border-focus-width) solid var(--fx-color-border-focus);\n outline-offset: calc(-1 * var(--fx-border-focus-width));\n}\n.cb-source-chev {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: var(--fx-component-choice-size);\n height: var(--fx-component-choice-size);\n flex: 0 0 var(--fx-component-choice-size);\n color: var(--fx-color-text-muted);\n transition: transform var(--fx-motion-hover) var(--fx-motion-ease);\n}\n.cb-source-chev.hidden {\n visibility: hidden;\n}\n.cb-source-icon {\n display: inline-flex;\n flex: 0 0 var(--fx-component-choice-size);\n color: var(--cb-folder-icon);\n}\n.cb-source-name {\n flex: 1;\n}\n.cb-source-fav-row {\n display: flex;\n align-items: stretch;\n width: 100%;\n min-width: 0;\n}\n.cb-source-fav-row .cb-source-row {\n flex: 1;\n width: auto;\n min-width: 0;\n padding-right: var(--fx-ref-space-4);\n background: transparent;\n box-shadow: none;\n}\n.cb-source-fav-row .cb-source-row:hover {\n background: transparent;\n}\n.cb-source-fav-row:hover {\n background: var(--fx-color-surface-hover);\n color: var(--fx-color-text-primary);\n}\n.cb-source-fav-row.is-path:not(.is-sel) {\n background: color-mix(in srgb, var(--fx-color-surface-hover) 55%, transparent);\n color: var(--fx-color-text-primary);\n}\n.cb-source-fav-row.is-sel {\n background: var(--fx-color-selection-bg);\n color: var(--fx-color-selection-fg);\n box-shadow: inset var(--fx-border-focus-width) 0 0 var(--fx-color-selection-indicator);\n}\n.cb-source-unfav {\n appearance: none;\n flex: 0 0 auto;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: var(--fx-component-control-icon-hit-area-min);\n padding: 0;\n border: 0;\n background: transparent;\n color: var(--fx-color-status-warning-fg);\n cursor: pointer;\n}\n.cb-source-unfav:hover {\n color: var(--fx-color-text-primary);\n}\n.cb-source-virtual-root {\n padding-left: var(--fx-ref-space-16);\n font-weight: var(--fx-ref-font-weight-600);\n}\n.cb-asset-view {\n position: relative;\n display: flex;\n flex: 1;\n flex-direction: column;\n min-width: 0;\n min-height: 0;\n overflow: hidden;\n}\n.cb-toolbar {\n position: relative;\n flex: 0 0 var(--fx-component-panel-header-height);\n gap: var(--fx-ref-space-6);\n min-width: 0;\n padding: 0 var(--fx-ref-space-8);\n}\n.cb-toolbar > .fx-panel-header__slot:nth-child(2) {\n flex: 1 1 auto;\n}\n.cb-toolbar-group {\n flex: 0 0 auto;\n}\n.cb-navigation-bar {\n flex: 1 1 auto;\n min-width: calc(var(--fx-ref-space-48) + var(--fx-ref-space-32));\n overflow: hidden;\n}\n.cb-address-slot {\n display: flex;\n flex: 1 1 auto;\n align-items: center;\n min-width: var(--fx-ref-space-32);\n height: var(--fx-component-control-height-compact);\n}\n.cb-address,\n.cb-address-input {\n width: 100%;\n height: var(--fx-component-control-height-compact);\n min-width: 0;\n box-sizing: border-box;\n border: var(--fx-border-width) solid var(--fx-color-border-control);\n border-radius: var(--fx-radius-control);\n background: var(--fx-color-surface-inset);\n color: var(--fx-color-text-secondary);\n}\n.cb-address {\n display: flex;\n align-items: center;\n padding: 0 var(--fx-ref-space-8);\n overflow: hidden;\n cursor: text;\n}\n.cb-address-crumb {\n display: flex;\n flex: 0 1 auto;\n align-items: center;\n min-width: 0;\n overflow: hidden;\n}\n.cb-root .cb-address:focus-visible,\n.cb-root .cb-address-input:focus,\n.cb-root .cb-address-input:focus-visible {\n outline: none;\n border-color: var(--fx-color-border-essential);\n}\n.cb-address-input {\n margin: 0;\n padding: 0 var(--fx-ref-space-8);\n font: inherit;\n color: var(--fx-color-text-primary);\n appearance: none;\n outline: none;\n}\n.cb-address-input::placeholder {\n color: var(--fx-color-text-muted);\n}\n.cb-crumb-segment {\n display: inline-flex;\n align-items: center;\n min-width: 0;\n color: var(--fx-color-text-muted);\n}\n.cb-crumb-item {\n min-width: 0;\n padding: var(--fx-ref-space-2) var(--fx-ref-space-4);\n border: 0;\n border-radius: var(--fx-ref-radius-4);\n background: transparent;\n color: var(--fx-color-text-muted);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n cursor: pointer;\n}\n.cb-crumb-item:hover {\n background: var(--fx-color-surface-hover);\n color: var(--fx-color-text-primary);\n}\n.cb-crumb-current {\n color: var(--fx-color-text-primary);\n font-weight: var(--fx-ref-font-weight-600);\n}\n.cb-crumb-chevron {\n display: inline-flex;\n align-items: center;\n flex-shrink: 0;\n color: var(--fx-color-text-muted);\n}\n.cb-crumb-chevron-btn {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: var(--fx-ref-space-16);\n height: var(--fx-component-control-height-compact);\n padding: 0;\n border: 0;\n border-radius: var(--fx-ref-radius-4);\n background: transparent;\n color: var(--fx-color-text-muted);\n cursor: pointer;\n appearance: none;\n}\n.cb-crumb-chevron-btn > svg {\n transition: transform 0.12s ease;\n}\n.cb-crumb-chevron-btn:hover {\n background: var(--fx-color-surface-hover);\n color: var(--fx-color-text-primary);\n}\n.cb-crumb-chevron-btn[aria-expanded=true] {\n color: var(--fx-color-text-primary);\n}\n.cb-crumb-chevron-btn[aria-expanded=true] > svg {\n transform: rotate(90deg);\n}\n.cb-crumb-chevron .fx-menu-dropdown__anchor {\n display: inline-flex;\n}\n.cb-crumb-menu .fx-menu {\n max-height: 320px;\n overflow-y: auto;\n}\n.cb-crumb-menu .fx-menu__item[data-active] {\n color: var(--fx-color-text-primary);\n font-weight: var(--fx-ref-font-weight-600);\n}\n.cb-content-body {\n display: flex;\n flex: 1;\n min-width: 0;\n min-height: 0;\n overflow: hidden;\n}\n.cb-grid-column {\n display: flex;\n flex: 1;\n flex-direction: column;\n min-width: 0;\n min-height: var(--cb-grid-min-height);\n overflow: hidden;\n}\n.cb-filter-bar {\n position: relative;\n flex: 0 0 var(--fx-component-panel-header-height);\n gap: var(--fx-ref-space-6);\n padding: var(--fx-ref-space-6) var(--fx-ref-space-8);\n border-bottom: var(--fx-border-width) solid var(--fx-color-border-subtle);\n}\n.cb-filter-bar .is-active {\n color: var(--fx-color-brand-text);\n background: var(--fx-color-brand-soft);\n}\n.cb-search-box {\n flex: 0 0 auto;\n width: var(--fx-component-menu-min-width);\n max-width: 100%;\n}\n.cb-search-box .fx-input {\n height: var(--fx-component-control-height-compact);\n}\n.cb-pop {\n position: absolute;\n z-index: var(--fx-layer-popover);\n}\n.cb-pop-create {\n top: var(--fx-component-panel-header-height);\n left: var(--fx-ref-space-8);\n}\n.cb-pop-import {\n top: var(--fx-component-panel-header-height);\n left: var(--cb-import-pop-left);\n}\n.cb-settings-menu {\n min-width: var(--fx-component-menu-min-width);\n padding: var(--fx-ref-space-6);\n border: var(--fx-border-width) solid var(--fx-color-border-default);\n border-radius: var(--fx-radius-popover);\n background: var(--fx-color-surface-raised);\n color: var(--fx-color-text-primary);\n box-shadow: var(--fx-shadow-floating);\n}\n.cb-settings-menu > strong {\n display: block;\n padding: var(--fx-ref-space-6) var(--fx-ref-space-8);\n color: var(--fx-color-text-muted);\n font-size: var(--fx-type-caption-font-size);\n}\n.cb-menu-title {\n display: inline-flex;\n align-items: center;\n gap: var(--fx-ref-space-6);\n}\n.cb-menu-icon-placeholder {\n width: var(--fx-component-control-icon-size);\n}\n.cb-layout-switch {\n padding: var(--fx-ref-space-2) var(--fx-ref-space-8) var(--fx-ref-space-6);\n}\n.cb-settings-row {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: var(--fx-ref-space-12);\n padding: var(--fx-ref-space-8);\n}\n.cb-settings-label {\n color: var(--fx-color-text-secondary);\n white-space: nowrap;\n}\n.cb-settings-range {\n flex: 0 0 auto;\n}\n.cb-settings-switch-row {\n margin: 0 var(--fx-ref-space-2);\n}\n.cb-grid-view {\n position: relative;\n flex: 1;\n min-width: 0;\n min-height: 0;\n overflow-x: hidden;\n overflow-y: auto;\n}\n.cb-fe-grid {\n display: grid;\n width: 100%;\n max-width: 100%;\n min-width: 0;\n grid-template-columns: repeat(auto-fill, minmax(0, var(--cb-thumb, 88px)));\n grid-auto-rows: max-content;\n align-content: start;\n justify-content: start;\n gap: calc(var(--fx-ref-space-8) + var(--cb-group-stack));\n padding: var(--fx-ref-space-12);\n overflow-x: hidden;\n}\n.cb-grid-item {\n position: relative;\n display: flex;\n flex-direction: column;\n align-items: center;\n width: 100%;\n max-width: 100%;\n min-width: 0;\n overflow: hidden;\n padding: var(--fx-ref-space-4);\n border: var(--fx-border-width) solid transparent;\n border-radius: var(--fx-radius-control);\n background: var(--fx-color-surface-raised);\n color: var(--fx-color-text-secondary);\n cursor: pointer;\n}\n.cb-grid-folder {\n background: transparent;\n}\n.cb-grid-item:hover {\n background: var(--fx-color-surface-hover);\n}\n.cb-grid-item.sel {\n border-color: var(--fx-color-selection-indicator);\n background: var(--fx-color-selection-bg);\n box-shadow: 0 0 0 var(--fx-border-width) var(--fx-color-selection-indicator);\n}\n.cb-grid-item:focus-visible {\n outline: var(--fx-border-focus-width) solid var(--fx-color-border-focus);\n outline-offset: var(--fx-border-focus-offset);\n}\n.cb-grid-item.is-busy,\n.cb-details-row.is-busy {\n cursor: progress;\n}\n.cb-item-busy-veil {\n position: absolute;\n inset: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n background: color-mix(in srgb, var(--fx-color-surface-raised) 55%, transparent);\n pointer-events: none;\n}\n.cb-item-busy-veil .fx-spinner,\n.cb-item-busy-inline {\n width: 14px;\n height: 14px;\n flex: 0 0 14px;\n}\n.cb-grid-view.cb-layout-list .cb-item-busy-inline {\n margin-left: auto;\n}\n.cb-grid-thumb {\n position: relative;\n display: flex;\n align-items: center;\n justify-content: center;\n width: 100%;\n aspect-ratio: 1;\n overflow: hidden;\n border-radius: var(--fx-radius-control);\n background: var(--fx-color-surface-inset);\n}\n.cb-grid-icon {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 100%;\n height: 100%;\n color: var(--fx-color-text-muted);\n}\n.cb-grid-icon svg {\n width: 46%;\n height: 46%;\n}\n.cb-folder-icon {\n color: var(--cb-folder-icon);\n}\n.cb-preview-ico.cb-folder-icon,\n.cb-preview-list-ico.cb-folder-icon,\n.cb-details-icon.cb-folder-icon,\n.cb-filter-option-icon.cb-folder-icon {\n color: var(--cb-folder-icon);\n}\n.cb-grid-thumb .cb-folder-icon {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 100%;\n height: 100%;\n}\n.cb-grid-thumb .cb-folder-icon svg {\n width: 86%;\n height: 86%;\n color: currentColor;\n}\n.cb-grid-label {\n width: 100%;\n margin-top: var(--fx-ref-space-4);\n overflow: hidden;\n text-align: center;\n}\n.cb-fe-label {\n display: flex;\n flex-direction: column;\n justify-content: flex-start;\n width: 100%;\n flex: 0 0 auto;\n height: calc(var(--cb-card-line) * 4);\n overflow: hidden;\n}\n.cb-fe-name {\n display: -webkit-box;\n margin-top: 0;\n overflow: hidden;\n color: var(--fx-color-text-primary);\n font-size: var(--fx-type-caption-font-size);\n line-height: var(--cb-card-line);\n text-align: center;\n white-space: normal;\n word-break: normal;\n overflow-wrap: anywhere;\n -webkit-box-orient: vertical;\n -webkit-line-clamp: 4;\n}\n.cb-fe-label.has-kind .cb-fe-name {\n min-height: calc(var(--cb-card-line) * 3);\n -webkit-line-clamp: 3;\n}\n.cb-card-meta,\n.cb-card-kind {\n width: 100%;\n flex: 0 0 auto;\n margin-top: auto;\n overflow: hidden;\n color: var(--fx-color-text-muted);\n font-size: var(--fx-type-caption-font-size);\n line-height: var(--cb-card-line);\n text-align: center;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.cb-fe-grid.cb-layout-list {\n grid-template-columns: minmax(0, 1fr);\n grid-auto-rows: auto;\n gap: var(--fx-ref-space-2);\n padding: var(--fx-ref-space-4) var(--fx-ref-space-6);\n overflow-x: hidden;\n}\n.cb-grid-view.cb-layout-list .cb-grid-item {\n flex-direction: row;\n align-items: center;\n width: 100%;\n min-width: 0;\n min-height: 40px;\n padding: var(--fx-ref-space-4) var(--fx-ref-space-8);\n gap: var(--fx-ref-space-8);\n overflow: hidden;\n box-shadow: none;\n}\n.cb-grid-view.cb-layout-list .cb-grid-item.sel {\n box-shadow: none;\n}\n.cb-grid-view.cb-layout-list .cb-grid-thumb {\n width: 32px;\n height: 32px;\n flex: 0 0 32px;\n aspect-ratio: auto;\n overflow: visible;\n}\n.cb-grid-view.cb-layout-list .cb-file-thumb {\n position: static;\n}\n.cb-grid-view.cb-layout-list .cb-grid-thumb svg {\n width: 20px;\n height: 20px;\n}\n.cb-layout-list .cb-fe-label {\n flex: 1 1 auto;\n min-width: 0;\n height: auto;\n overflow: hidden;\n flex-direction: row;\n align-items: center;\n text-align: left;\n}\n.cb-layout-list .cb-fe-name,\n.cb-layout-list .cb-fe-label.has-kind .cb-fe-name {\n display: block;\n flex: 1;\n min-width: 0;\n min-height: 0;\n overflow: hidden;\n text-align: left;\n white-space: nowrap;\n text-overflow: ellipsis;\n -webkit-line-clamp: unset;\n}\n.cb-layout-list .cb-card-meta,\n.cb-layout-list .cb-card-kind {\n margin-top: 0;\n}\n.cb-layout-list .cb-card-meta {\n display: none;\n}\n.cb-grid-view.cb-layout-list .cb-group-card:not(.cb-pack-expanded),\n.cb-grid-view.cb-layout-list .cb-group-card.sel:not(.cb-pack-expanded) {\n box-shadow: none;\n}\n.cb-grid-view.cb-layout-list .cb-group-member:not(.sel) {\n background: transparent;\n}\n.cb-grid-view.cb-layout-list .cb-group-member:not(.sel):hover {\n background: var(--fx-color-surface-hover);\n}\n.cb-grid-view.cb-layout-list .cb-group-card,\n.cb-grid-view.cb-layout-list .cb-pack-expanded {\n padding-right: calc(var(--fx-ref-space-8) + 44px);\n}\n.cb-grid-view.cb-layout-list .cb-group-badge {\n top: 50%;\n right: var(--fx-ref-space-8);\n bottom: auto;\n transform: translateY(-50%);\n}\n.cb-details-view {\n display: flex;\n flex: 1;\n flex-direction: column;\n min-height: 0;\n overflow: auto;\n padding: 0 var(--fx-ref-space-6) var(--fx-ref-space-8);\n --cb-details-cols: minmax(160px, 1fr) 160px 90px 130px;\n}\n.cb-details-header,\n.cb-details-row {\n display: grid;\n grid-template-columns: var(--cb-details-cols);\n align-items: center;\n}\n.cb-details-header {\n position: sticky;\n z-index: var(--fx-layer-sticky);\n top: 0;\n min-height: var(--fx-component-editor-row-height);\n border-bottom: var(--fx-border-width) solid var(--fx-color-border-default);\n background: var(--fx-color-surface-canvas);\n color: var(--fx-color-text-muted);\n font-size: var(--fx-type-caption-font-size);\n}\n.cb-details-th {\n display: flex;\n align-items: center;\n gap: var(--fx-ref-space-4);\n height: 100%;\n padding: var(--fx-ref-space-4) var(--fx-ref-space-8);\n border: 0;\n background: transparent;\n color: inherit;\n text-align: left;\n cursor: pointer;\n}\n.cb-details-th:hover {\n color: var(--fx-color-text-primary);\n}\n.cb-details-th.active,\n.cb-details-th[data-active=true] {\n color: var(--fx-color-brand-text);\n}\n.cb-details-sort-arrow {\n font-size: 9px;\n}\n.cb-details-body {\n display: flex;\n flex-direction: column;\n}\n.cb-details-row {\n position: relative;\n width: 100%;\n border-radius: var(--fx-ref-radius-4);\n color: var(--fx-color-text-secondary);\n cursor: pointer;\n}\n.cb-details-row:hover {\n background: var(--fx-color-surface-hover);\n}\n.cb-details-row.sel {\n background: var(--fx-color-selection-bg);\n box-shadow: inset var(--fx-border-focus-width) 0 0 var(--fx-color-selection-indicator);\n}\n.cb-details-row:focus-visible {\n outline: var(--fx-border-focus-width) solid var(--fx-color-border-focus);\n outline-offset: -2px;\n}\n.cb-details-cell {\n min-width: 0;\n padding: var(--fx-ref-space-4) var(--fx-ref-space-8);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.cb-details-name {\n display: flex;\n align-items: center;\n gap: var(--fx-ref-space-6);\n}\n.cb-details-icon {\n display: inline-flex;\n width: 16px;\n height: 16px;\n flex: 0 0 16px;\n}\n.cb-details-icon svg {\n width: 16px;\n height: 16px;\n}\n.cb-details-type,\n.cb-details-size,\n.cb-details-modified {\n color: var(--fx-color-text-muted);\n}\n.cb-empty {\n grid-column: 1 / -1;\n color: var(--fx-color-text-muted);\n}\n.cb-status {\n display: flex;\n align-items: center;\n justify-content: space-between;\n flex: 0 0 var(--fx-component-editor-row-height);\n min-height: var(--fx-component-editor-row-height);\n padding: var(--fx-ref-space-4) var(--fx-ref-space-8);\n border-top: var(--fx-border-width) solid var(--fx-color-border-subtle);\n color: var(--fx-color-text-muted);\n font-size: var(--fx-type-caption-font-size);\n}\n.cb-file-thumb {\n position: relative;\n}\n.cb-group-card:not(.cb-pack-expanded) {\n box-shadow:\n 3px 3px 0 0 var(--fx-color-surface-raised),\n 3px 3px 0 1px var(--fx-color-border-subtle),\n 6px 6px 0 0 var(--fx-color-surface-raised),\n 6px 6px 0 1px var(--fx-color-border-subtle);\n}\n.cb-group-card.sel:not(.cb-pack-expanded) {\n box-shadow:\n 0 0 0 var(--fx-border-width) var(--fx-color-selection-indicator),\n 3px 3px 0 0 var(--fx-color-surface-raised),\n 3px 3px 0 1px var(--fx-color-border-subtle),\n 6px 6px 0 0 var(--fx-color-surface-raised),\n 6px 6px 0 1px var(--fx-color-border-subtle);\n}\n.cb-group-badge {\n position: absolute;\n right: 3px;\n bottom: 3px;\n z-index: 2;\n display: flex;\n align-items: center;\n gap: 3px;\n height: 22px;\n padding: 0 8px;\n border: 0;\n border-radius: 11px;\n background: color-mix(in srgb, var(--fx-color-surface-canvas) 62%, transparent);\n color: var(--fx-color-text-inverse);\n font-size: 11px;\n font-weight: var(--fx-ref-font-weight-600);\n cursor: pointer;\n}\n.cb-group-badge:hover {\n background: rgb(0 0 0 / 62%);\n color: #fff;\n}\n.cb-group-badge svg {\n width: 11px;\n height: 11px;\n transition: transform var(--fx-motion-hover) var(--fx-motion-ease);\n}\n.cb-group-backdrops {\n position: absolute;\n inset: 0;\n z-index: 0;\n pointer-events: none;\n}\n.cb-group-backdrop {\n position: absolute;\n background: rgb(0 0 0 / 10%);\n}\n.cb-group-member {\n z-index: 1;\n}\n.cb-group-badge.open svg {\n transform: rotate(180deg);\n}\n.cb-preview-panel {\n display: flex;\n flex: 0 0 var(--cb-preview-w, 280px);\n flex-direction: column;\n width: var(--cb-preview-w, 280px);\n min-width: 180px;\n max-width: 560px;\n min-height: 0;\n overflow: hidden;\n border-left: var(--fx-border-width) solid var(--fx-color-border-subtle);\n background: var(--fx-color-surface-canvas);\n}\n.cb-preview-head {\n display: flex;\n align-items: center;\n gap: var(--fx-ref-space-8);\n padding: var(--fx-ref-space-8) var(--fx-ref-space-8);\n border-bottom: var(--fx-border-width) solid var(--fx-color-border-subtle);\n flex-shrink: 0;\n}\n.cb-preview-mode-bar {\n display: flex;\n gap: var(--fx-ref-space-4);\n padding: var(--fx-ref-space-6) var(--fx-ref-space-8);\n border-bottom: var(--fx-border-width) solid var(--fx-color-border-subtle);\n flex-shrink: 0;\n}\n.cb-preview-mode-btn {\n flex: 1 1 0;\n min-width: 0;\n height: 24px;\n padding: 0 var(--fx-ref-space-8);\n overflow: hidden;\n border: var(--fx-border-width) solid var(--fx-color-border-subtle);\n border-radius: var(--fx-radius-control);\n background: transparent;\n color: var(--fx-color-text-muted);\n text-overflow: ellipsis;\n white-space: nowrap;\n cursor: pointer;\n}\n.cb-preview-mode-btn:hover {\n color: var(--fx-color-text-primary);\n background: var(--fx-color-surface-hover);\n}\n.cb-preview-mode-btn.is-active {\n color: var(--fx-color-text-primary);\n border-color: var(--fx-color-border-strong);\n background: var(--fx-color-surface-raised);\n}\n.cb-preview-ico,\n.cb-preview-list-ico {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n flex: 0 0 28px;\n width: 28px;\n height: 28px;\n border-radius: var(--fx-radius-control);\n background: var(--fx-color-surface-raised);\n color: var(--fx-color-text-muted);\n}\n.cb-preview-list-ico {\n flex-basis: 16px;\n width: 16px;\n height: 16px;\n background: transparent;\n}\n.cb-preview-title {\n flex: 1;\n min-width: 0;\n}\n.cb-preview-title .name {\n overflow: hidden;\n color: var(--fx-color-text-primary);\n font-weight: var(--fx-ref-font-weight-600);\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.cb-preview-title .meta {\n overflow: hidden;\n color: var(--fx-color-text-muted);\n font: var(--fx-type-code-font-weight) var(--fx-type-caption-font-size)/var(--fx-type-caption-line-height) var(--fx-type-code-font-family);\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.cb-preview-close {\n width: 24px;\n height: 24px;\n}\n.cb-preview-body {\n flex: 1;\n min-height: 0;\n overflow: auto;\n padding: var(--fx-ref-space-8);\n}\n.cb-preview-empty .cb-preview-body {\n display: flex;\n align-items: center;\n justify-content: center;\n text-align: center;\n color: var(--fx-color-text-muted);\n}\n.cb-preview-list,\n.cb-preview-asset-list {\n display: flex;\n flex-direction: column;\n gap: var(--fx-ref-space-4);\n}\n.cb-preview-list-item,\n.cb-preview-asset-row {\n display: flex;\n align-items: center;\n gap: var(--fx-ref-space-8);\n min-width: 0;\n padding: var(--fx-ref-space-4) var(--fx-ref-space-6);\n border-radius: var(--fx-radius-control);\n color: var(--fx-color-text-secondary);\n}\n.cb-preview-list-item:hover,\n.cb-preview-asset-row:hover {\n background: var(--fx-color-surface-hover);\n}\n.cb-preview-list-item > span:nth-of-type(2) {\n flex: 1 1 0;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.cb-preview-list-item .sub,\n.cb-preview-asset-row .guid,\n.cb-preview-asset-row .kind {\n color: var(--fx-color-text-muted);\n font: var(--fx-type-code-font-weight) var(--fx-type-caption-font-size)/var(--fx-type-caption-line-height) var(--fx-type-code-font-family);\n}\n.cb-preview-list-item .sub {\n flex: 0 1 38%;\n min-width: 0;\n margin-left: auto;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.cb-preview-asset-row > .cb-preview-asset-main {\n flex: 1 1 0;\n min-width: 0;\n}\n.cb-preview-asset-row > .cb-preview-asset-main > div {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.cb-preview-asset-row .kind {\n margin-left: 0;\n}\n.cb-preview-asset-row .guid {\n flex: 0 1 auto;\n max-width: 42%;\n min-width: 0;\n margin-left: auto;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.cb-preview-media {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: var(--fx-ref-space-8);\n min-height: 0;\n}\n.cb-preview-image {\n display: block;\n max-width: 100%;\n max-height: min(360px, 50vh);\n object-fit: contain;\n border-radius: var(--fx-radius-control);\n background: var(--fx-color-surface-inset);\n}\n.cb-preview-audio,\n.cb-preview-video {\n width: 100%;\n max-width: 100%;\n}\n.cb-preview-video {\n max-height: min(360px, 50vh);\n border-radius: var(--fx-radius-control);\n background: #000;\n}\n.cb-preview-font-sample {\n margin: 0;\n color: var(--fx-color-text-primary);\n font-size: 1.35rem;\n line-height: 1.4;\n text-align: center;\n}\n.cb-preview-font-meta {\n margin: 0;\n max-width: 100%;\n overflow: hidden;\n color: var(--fx-color-text-muted);\n font: var(--fx-type-caption-font-size)/var(--fx-type-caption-line-height) var(--fx-type-code-font-family);\n text-align: center;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.cb-preview-asset-hero {\n display: flex;\n align-items: center;\n justify-content: center;\n padding: var(--fx-ref-space-16) 0 var(--fx-ref-space-8);\n}\n.cb-preview-hero-icon {\n color: var(--fx-color-text-muted);\n}\n.cb-preview-note {\n padding: var(--fx-ref-space-8) var(--fx-ref-space-8);\n overflow: hidden;\n border: var(--fx-border-width) solid var(--fx-color-border-subtle);\n border-radius: var(--fx-radius-control);\n background: var(--fx-color-surface-raised);\n color: var(--fx-color-text-muted);\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.cb-preview-source {\n margin: 0;\n padding: var(--fx-ref-space-8);\n overflow: auto;\n border: var(--fx-border-width) solid var(--fx-color-border-subtle);\n border-radius: var(--fx-radius-control);\n background: var(--fx-color-surface-inset);\n color: var(--fx-color-text-secondary);\n font: var(--fx-type-code-font-weight) var(--fx-type-code-font-size)/var(--fx-type-code-line-height) var(--fx-type-code-font-family);\n white-space: pre-wrap;\n}\n.cb-preview-code {\n display: flex;\n flex-direction: column;\n gap: var(--fx-ref-space-6);\n min-height: 0;\n}\n.cb-preview-code-head {\n display: flex;\n align-items: center;\n gap: var(--fx-ref-space-8);\n}\n.cb-preview-code-badge {\n padding: var(--fx-ref-space-2) var(--fx-ref-space-8);\n border-radius: var(--fx-radius-pill);\n background: var(--fx-color-surface-hover);\n color: var(--fx-color-text-muted);\n font: var(--fx-type-code-font-weight) var(--fx-type-caption-font-size)/var(--fx-type-caption-line-height) var(--fx-type-code-font-family);\n letter-spacing: 0.03em;\n text-transform: uppercase;\n}\n.cb-preview-code-hint {\n color: var(--fx-color-text-disabled);\n font-size: var(--fx-type-caption-font-size);\n}\n.cb-preview-code-plain,\n.cb-preview-code-shiki pre.shiki {\n margin: 0;\n white-space: pre-wrap;\n word-break: break-word;\n font: var(--fx-type-code-font-weight) var(--fx-type-code-font-size)/var(--fx-type-code-line-height) var(--fx-type-code-font-family);\n}\n.cb-preview-code-plain {\n color: var(--fx-color-text-secondary);\n}\n.cb-preview-code-shiki pre.shiki {\n background: transparent !important;\n}\n.cb-preview-code-shiki pre.shiki code {\n background: transparent;\n padding: 0;\n border-radius: 0;\n color: inherit;\n font-size: inherit;\n}\n.cb-filter-menu-body {\n min-width: 220px;\n padding: var(--fx-ref-space-4);\n border: var(--fx-border-width) solid var(--fx-color-border-default);\n border-radius: var(--fx-radius-popover);\n background: var(--fx-color-surface-raised);\n box-shadow: var(--fx-shadow-floating);\n}\n.cb-filter-section {\n padding: var(--fx-ref-space-6) var(--fx-ref-space-8) var(--fx-ref-space-4);\n color: var(--fx-color-text-muted);\n font-size: var(--fx-type-caption-font-size);\n font-weight: var(--fx-ref-font-weight-600);\n}\n.cb-filter-separator {\n height: var(--fx-border-width);\n margin: var(--fx-ref-space-4) 0;\n background: var(--fx-color-border-subtle);\n}\n.cb-filter-option {\n display: flex;\n align-items: center;\n gap: var(--fx-ref-space-8);\n width: 100%;\n min-height: var(--fx-component-editor-row-height);\n padding: var(--fx-ref-space-4) var(--fx-ref-space-8);\n border: 0;\n border-radius: var(--fx-radius-control);\n background: transparent;\n color: var(--fx-color-text-secondary);\n text-align: left;\n cursor: pointer;\n}\n.cb-filter-option:hover {\n background: var(--fx-color-surface-hover);\n color: var(--fx-color-text-primary);\n}\n.cb-filter-option:disabled {\n color: var(--fx-color-text-disabled);\n cursor: default;\n}\n.cb-filter-option-icon {\n flex: 0 0 14px;\n width: 14px;\n color: var(--fx-color-text-muted);\n}\n.cb-filter-check {\n flex: 0 0 var(--fx-component-choice-size);\n pointer-events: none;\n}\n.cb-filter-check.fx-choice {\n align-items: center;\n gap: 0;\n min-height: 0;\n margin: 0;\n}\n.cb-filter-check .fx-choice__text {\n display: none;\n}\n.cb-radio-menu {\n width: 14px;\n height: 14px;\n flex: 0 0 14px;\n border: var(--fx-border-width) solid var(--fx-color-border-control);\n border-radius: 999px;\n}\n.cb-radio-menu[data-checked=true] {\n border-color: var(--fx-color-choice-indicator);\n background:\n radial-gradient(\n circle at center,\n var(--fx-color-choice-indicator) 4px,\n transparent 5px);\n}\n@container (max-width: 660px) {\n .cb-toolbar-group .fx-button {\n width: var(--fx-component-control-height-compact);\n padding: 0;\n font-size: 0;\n }\n}\n';
|
|
2365
|
+
if (typeof document !== "undefined" && !document.querySelector('style[data-forgeax-css="L2RhdGEvaG9tZS9nYWhvdWxpYW8vYWN0aW9ucy1ydW5uZXIvX3dvcmsvZm9yZ2VheC12aWV3L2ZvcmdlYXgtdmlldy9wYWNrYWdlcy92aWV3LXBsdWdpbi1jb250ZW50LWJyb3dzZXIvc3JjL3VpL2NvbnRlbnQtYnJvd3Nlci5jc3M"]')) {
|
|
2366
|
+
const style = document.createElement("style");
|
|
2367
|
+
style.dataset.forgeaxCss = "L2RhdGEvaG9tZS9nYWhvdWxpYW8vYWN0aW9ucy1ydW5uZXIvX3dvcmsvZm9yZ2VheC12aWV3L2ZvcmdlYXgtdmlldy9wYWNrYWdlcy92aWV3LXBsdWdpbi1jb250ZW50LWJyb3dzZXIvc3JjL3VpL2NvbnRlbnQtYnJvd3Nlci5jc3M";
|
|
2368
|
+
style.textContent = css;
|
|
2369
|
+
document.head.append(style);
|
|
2370
|
+
}
|
|
2371
|
+
|
|
2372
|
+
// packages/view-plugin-content-browser/src/ui/mount.tsx
|
|
2373
|
+
import { jsx as jsx10 } from "react/jsx-runtime";
|
|
2374
|
+
async function mountContentBrowserPanel(props) {
|
|
2375
|
+
if (!props.mountElement) throw new TypeError("mountContentBrowserPanel requires mountElement");
|
|
2376
|
+
const root = createRoot(props.mountElement);
|
|
2377
|
+
root.render(
|
|
2378
|
+
/* @__PURE__ */ jsx10(OverlayRootProvider, { root: props.overlayRoot ?? props.mountElement, children: /* @__PURE__ */ jsx10(
|
|
2379
|
+
ContentBrowserPanel,
|
|
2380
|
+
{
|
|
2381
|
+
client: props.client,
|
|
2382
|
+
demo: props.demo
|
|
2383
|
+
}
|
|
2384
|
+
) })
|
|
2385
|
+
);
|
|
2386
|
+
return async () => root.unmount();
|
|
2387
|
+
}
|
|
2388
|
+
|
|
2389
|
+
export {
|
|
2390
|
+
mountContentBrowserPanel
|
|
2391
|
+
};
|
|
2392
|
+
//# sourceMappingURL=chunk-I5BFP7SS.mjs.map
|