eidos-ui 3.6.3 → 3.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +11 -0
- package/dist/{Avatar.types-BY-C09Ke.d.cts → Avatar.types-DkRznn-7.d.cts} +6 -1
- package/dist/{Avatar.types-BY-C09Ke.d.ts → Avatar.types-DkRznn-7.d.ts} +6 -1
- package/dist/{Breadcrumb.types-DaykU-C8.d.cts → Breadcrumb.types-C3uADbKU.d.cts} +4 -1
- package/dist/{Breadcrumb.types-DaykU-C8.d.ts → Breadcrumb.types-C3uADbKU.d.ts} +4 -1
- package/dist/Button.types-BCIK8Qlk.d.ts +59 -0
- package/dist/Button.types-DkgWjFsk.d.cts +59 -0
- package/dist/Chip.types-BM-UZOCv.d.ts +33 -0
- package/dist/Chip.types-_1bhyKz4.d.cts +33 -0
- package/dist/{Header.types-Ce5Cj301.d.cts → Header.types-a6p0-ZHx.d.cts} +24 -8
- package/dist/{Header.types-0XovUp0T.d.ts → Header.types-zbhURbg7.d.ts} +24 -8
- package/dist/{Input.types-D7-sWq-q.d.cts → Input.types--K0t_3L2.d.cts} +1 -1
- package/dist/{Input.types-CSDMaZNe.d.ts → Input.types--UjucBDd.d.ts} +1 -1
- package/dist/{Menu.types-CTnUijv5.d.cts → Menu.types-D6VoK9T9.d.cts} +1 -1
- package/dist/{Menu.types-BN4g1-3A.d.ts → Menu.types-tUEhXn52.d.ts} +1 -1
- package/dist/{Navigation.types-By5HfPTi.d.ts → Navigation.types-CJRzo9Zo.d.ts} +1 -1
- package/dist/{Navigation.types-_MrYqqUI.d.cts → Navigation.types-D95oHZEJ.d.cts} +1 -1
- package/dist/{SegmentedControl.types-cjLwwBAm.d.ts → SegmentedControl.types-CHtjABQM.d.ts} +1 -1
- package/dist/{SegmentedControl.types-BofrEYyd.d.cts → SegmentedControl.types-D_gHYL9X.d.cts} +1 -1
- package/dist/{Select.types-ok-03rLo.d.cts → Select.types-8CGZBgT-.d.cts} +2 -2
- package/dist/{Select.types-C2tGy1vj.d.ts → Select.types-CAVh9Gvd.d.ts} +2 -2
- package/dist/{Table.types-D8pmgxKA.d.ts → Table.types-BFDE-hhF.d.ts} +2 -2
- package/dist/{Table.types-D-9tC0kJ.d.cts → Table.types-Tai7_MTz.d.cts} +2 -2
- package/dist/{Toolbar.types-CKnQC_TW.d.ts → Toolbar.types-BqBrPVww.d.ts} +8 -6
- package/dist/{Toolbar.types-DUz2mxct.d.cts → Toolbar.types-GCUgzuKW.d.cts} +8 -6
- package/dist/alert/index.cjs +8 -5
- package/dist/alert/index.cjs.map +1 -1
- package/dist/alert/index.d.cts +1 -1
- package/dist/alert/index.d.ts +1 -1
- package/dist/alert/index.js +7 -4
- package/dist/avatar/index.d.cts +2 -2
- package/dist/avatar/index.d.ts +2 -2
- package/dist/breadcrumb/index.cjs +4 -2
- package/dist/breadcrumb/index.cjs.map +1 -1
- package/dist/breadcrumb/index.d.cts +2 -2
- package/dist/breadcrumb/index.d.ts +2 -2
- package/dist/breadcrumb/index.js +3 -1
- package/dist/button/index.cjs +7 -4
- package/dist/button/index.cjs.map +1 -1
- package/dist/button/index.d.cts +5 -5
- package/dist/button/index.d.ts +5 -5
- package/dist/button/index.js +6 -3
- package/dist/button-group/index.d.cts +2 -2
- package/dist/button-group/index.d.ts +2 -2
- package/dist/chip/index.cjs +7 -4
- package/dist/chip/index.cjs.map +1 -1
- package/dist/chip/index.d.cts +5 -23
- package/dist/chip/index.d.ts +5 -23
- package/dist/chip/index.js +6 -3
- package/dist/{chunk-DRXPTACG.js → chunk-26PRBZA6.js} +6 -2
- package/dist/chunk-26PRBZA6.js.map +1 -0
- package/dist/chunk-2IXCEKLI.js +82 -0
- package/dist/chunk-2IXCEKLI.js.map +1 -0
- package/dist/{chunk-GWHZFX2H.js → chunk-2TIMJD4K.js} +29 -6
- package/dist/chunk-2TIMJD4K.js.map +1 -0
- package/dist/{chunk-RHFD2Z5V.js → chunk-3TF2GZSG.js} +7 -7
- package/dist/{chunk-TC5IC6OP.cjs → chunk-3VXUOAIJ.cjs} +3 -3
- package/dist/{chunk-TC5IC6OP.cjs.map → chunk-3VXUOAIJ.cjs.map} +1 -1
- package/dist/{chunk-JHX6JK3M.js → chunk-3X6QVHTD.js} +2 -2
- package/dist/{chunk-7VJCGKVP.cjs → chunk-4HZIXRAJ.cjs} +11 -11
- package/dist/{chunk-7VJCGKVP.cjs.map → chunk-4HZIXRAJ.cjs.map} +1 -1
- package/dist/{chunk-MQAOXZD4.js → chunk-4S57PE43.js} +4 -4
- package/dist/{chunk-JT4KVXJK.js → chunk-4V2XYUQL.js} +2 -2
- package/dist/{chunk-PMSENLOA.cjs → chunk-544RAXWO.cjs} +19 -19
- package/dist/{chunk-PMSENLOA.cjs.map → chunk-544RAXWO.cjs.map} +1 -1
- package/dist/{chunk-4JSTBA4F.cjs → chunk-6CW5QSYV.cjs} +7 -7
- package/dist/{chunk-4JSTBA4F.cjs.map → chunk-6CW5QSYV.cjs.map} +1 -1
- package/dist/{chunk-AR2ZOO6L.js → chunk-6FXFKMJ5.js} +3 -3
- package/dist/{chunk-KREHT4AQ.cjs → chunk-6IB27I5K.cjs} +8 -8
- package/dist/{chunk-KREHT4AQ.cjs.map → chunk-6IB27I5K.cjs.map} +1 -1
- package/dist/{chunk-LGDODZHI.js → chunk-6LTZV6HN.js} +4 -4
- package/dist/{chunk-YP4HUBKN.js → chunk-6NAOAKII.js} +2 -2
- package/dist/chunk-75Q5OS7L.cjs +10 -0
- package/dist/chunk-75Q5OS7L.cjs.map +1 -0
- package/dist/{chunk-LQXFXXMJ.cjs → chunk-7FV2X62W.cjs} +7 -7
- package/dist/{chunk-LQXFXXMJ.cjs.map → chunk-7FV2X62W.cjs.map} +1 -1
- package/dist/{chunk-2T7ZMMH5.cjs → chunk-7NUVLVSL.cjs} +5 -5
- package/dist/{chunk-2T7ZMMH5.cjs.map → chunk-7NUVLVSL.cjs.map} +1 -1
- package/dist/chunk-ACH7SYQ2.js +47 -0
- package/dist/chunk-ACH7SYQ2.js.map +1 -0
- package/dist/{chunk-HNGFRRVZ.cjs → chunk-AUNDBUHM.cjs} +3 -3
- package/dist/{chunk-HNGFRRVZ.cjs.map → chunk-AUNDBUHM.cjs.map} +1 -1
- package/dist/{chunk-XZLSHEHE.cjs → chunk-B2OHBIAL.cjs} +10 -10
- package/dist/{chunk-XZLSHEHE.cjs.map → chunk-B2OHBIAL.cjs.map} +1 -1
- package/dist/chunk-BDH2MXJW.js +46 -0
- package/dist/chunk-BDH2MXJW.js.map +1 -0
- package/dist/{chunk-D7SQ7LHJ.js → chunk-BO3KK3ZQ.js} +2 -2
- package/dist/{chunk-NOQF7UQ5.cjs → chunk-CFVUUMQA.cjs} +6 -6
- package/dist/{chunk-NOQF7UQ5.cjs.map → chunk-CFVUUMQA.cjs.map} +1 -1
- package/dist/chunk-CJT7L764.cjs +21 -0
- package/dist/chunk-CJT7L764.cjs.map +1 -0
- package/dist/{chunk-5XH2PHT2.js → chunk-CNTG7OOO.js} +14 -14
- package/dist/{chunk-I6M6CVI2.cjs → chunk-DG3O5NV4.cjs} +3 -3
- package/dist/{chunk-I6M6CVI2.cjs.map → chunk-DG3O5NV4.cjs.map} +1 -1
- package/dist/{chunk-WNDDS367.js → chunk-DPTTDHZ5.js} +3 -3
- package/dist/{chunk-35LGEPLP.cjs → chunk-ENMDOQQO.cjs} +29 -14
- package/dist/chunk-ENMDOQQO.cjs.map +1 -0
- package/dist/{chunk-V4BZWBZT.cjs → chunk-F5IRMMZ2.cjs} +7 -7
- package/dist/{chunk-V4BZWBZT.cjs.map → chunk-F5IRMMZ2.cjs.map} +1 -1
- package/dist/{chunk-WE2SBWZ6.js → chunk-FE7S4RSK.js} +10 -10
- package/dist/chunk-FE7S4RSK.js.map +1 -0
- package/dist/{chunk-BFKPJ627.js → chunk-FHOD3FUN.js} +4 -4
- package/dist/{chunk-SNRRF64M.js → chunk-GDRLVX2A.js} +31 -10
- package/dist/chunk-GDRLVX2A.js.map +1 -0
- package/dist/{chunk-5O73AALP.cjs → chunk-GP6EEZH5.cjs} +7 -3
- package/dist/chunk-GP6EEZH5.cjs.map +1 -0
- package/dist/{chunk-SDUGYJGW.js → chunk-H3C6YECZ.js} +6 -6
- package/dist/{chunk-RJVHR45I.cjs → chunk-H46ZLPNJ.cjs} +7 -7
- package/dist/{chunk-RJVHR45I.cjs.map → chunk-H46ZLPNJ.cjs.map} +1 -1
- package/dist/{chunk-66UQTF57.cjs → chunk-HLI4SOH3.cjs} +45 -45
- package/dist/{chunk-66UQTF57.cjs.map → chunk-HLI4SOH3.cjs.map} +1 -1
- package/dist/{chunk-ZMRINZIO.cjs → chunk-HR5MWA3B.cjs} +5 -5
- package/dist/{chunk-ZMRINZIO.cjs.map → chunk-HR5MWA3B.cjs.map} +1 -1
- package/dist/{chunk-MPIVBAMY.js → chunk-HYRLK462.js} +2 -2
- package/dist/{chunk-FIVMMCGM.js → chunk-IHPSRTVW.js} +4 -4
- package/dist/{chunk-THCTUBX6.js → chunk-IKXXXVUO.js} +3 -3
- package/dist/{chunk-JPYJQ4TF.cjs → chunk-JFV56ISS.cjs} +6 -6
- package/dist/{chunk-JPYJQ4TF.cjs.map → chunk-JFV56ISS.cjs.map} +1 -1
- package/dist/{chunk-75GFIQRU.js → chunk-JY77VJAZ.js} +30 -15
- package/dist/chunk-JY77VJAZ.js.map +1 -0
- package/dist/chunk-KXDGW6LJ.cjs +46 -0
- package/dist/chunk-KXDGW6LJ.cjs.map +1 -0
- package/dist/{chunk-24HKKSKX.js → chunk-L6ERHCQ2.js} +3 -3
- package/dist/{chunk-4LNTZPSQ.js → chunk-L6YJ6QTZ.js} +2 -2
- package/dist/{chunk-KBQD4JLK.cjs → chunk-LUDK44NZ.cjs} +3 -3
- package/dist/{chunk-KBQD4JLK.cjs.map → chunk-LUDK44NZ.cjs.map} +1 -1
- package/dist/chunk-LWCFT5SP.cjs +82 -0
- package/dist/chunk-LWCFT5SP.cjs.map +1 -0
- package/dist/{chunk-JNY7TUDS.js → chunk-MCPGI6EI.js} +2 -2
- package/dist/{chunk-DU5JKTHK.cjs → chunk-MKC6V3SY.cjs} +6 -6
- package/dist/{chunk-DU5JKTHK.cjs.map → chunk-MKC6V3SY.cjs.map} +1 -1
- package/dist/{chunk-J76JHN7J.cjs → chunk-N5NXKVFJ.cjs} +10 -10
- package/dist/{chunk-J76JHN7J.cjs.map → chunk-N5NXKVFJ.cjs.map} +1 -1
- package/dist/{chunk-XERBOFYZ.cjs → chunk-NERASTO2.cjs} +3 -3
- package/dist/{chunk-XERBOFYZ.cjs.map → chunk-NERASTO2.cjs.map} +1 -1
- package/dist/{chunk-3KBBJZHK.cjs → chunk-NFD7MPX4.cjs} +16 -14
- package/dist/chunk-NFD7MPX4.cjs.map +1 -0
- package/dist/{chunk-3ZRFOKDM.cjs → chunk-NNAEQR3Y.cjs} +30 -30
- package/dist/{chunk-3ZRFOKDM.cjs.map → chunk-NNAEQR3Y.cjs.map} +1 -1
- package/dist/{chunk-36JFXFM2.cjs → chunk-OGGZIFTI.cjs} +38 -38
- package/dist/chunk-OGGZIFTI.cjs.map +1 -0
- package/dist/{chunk-2PCCGQOH.js → chunk-P6OJQ2RN.js} +6 -6
- package/dist/{chunk-3RWZC6OW.cjs → chunk-PE2SLXUS.cjs} +5 -5
- package/dist/{chunk-3RWZC6OW.cjs.map → chunk-PE2SLXUS.cjs.map} +1 -1
- package/dist/chunk-QD32IMMH.js +13 -0
- package/dist/chunk-QD32IMMH.js.map +1 -0
- package/dist/{chunk-HEXAY6DE.cjs → chunk-QUSO4GFA.cjs} +7 -7
- package/dist/{chunk-HEXAY6DE.cjs.map → chunk-QUSO4GFA.cjs.map} +1 -1
- package/dist/{chunk-OOCCSMWM.js → chunk-RHWZX7PB.js} +9 -7
- package/dist/chunk-RHWZX7PB.js.map +1 -0
- package/dist/{chunk-YXRKBKFB.js → chunk-S5CMZFX6.js} +3 -3
- package/dist/{chunk-4AO5RKV5.cjs → chunk-SLHIVEFW.cjs} +7 -7
- package/dist/{chunk-4AO5RKV5.cjs.map → chunk-SLHIVEFW.cjs.map} +1 -1
- package/dist/{chunk-HEX4IMLO.js → chunk-TJQNGJHP.js} +4 -4
- package/dist/{chunk-JCKGAAPZ.cjs → chunk-TNQ2ZZ7W.cjs} +9 -9
- package/dist/{chunk-JCKGAAPZ.cjs.map → chunk-TNQ2ZZ7W.cjs.map} +1 -1
- package/dist/chunk-U32K2H3N.js +10 -0
- package/dist/chunk-U32K2H3N.js.map +1 -0
- package/dist/{chunk-RHHZRTWM.js → chunk-U34INRFO.js} +28 -13
- package/dist/chunk-U34INRFO.js.map +1 -0
- package/dist/{chunk-SFFKQQ5Z.js → chunk-U4SVBE2M.js} +5 -5
- package/dist/{chunk-O3QM3BFE.js → chunk-UC4NYF6T.js} +2 -2
- package/dist/{chunk-6JHVXWDV.cjs → chunk-ULKWUKD2.cjs} +22 -22
- package/dist/{chunk-6JHVXWDV.cjs.map → chunk-ULKWUKD2.cjs.map} +1 -1
- package/dist/{chunk-BEOECPVJ.cjs → chunk-UTYY35QX.cjs} +3 -3
- package/dist/{chunk-BEOECPVJ.cjs.map → chunk-UTYY35QX.cjs.map} +1 -1
- package/dist/{chunk-7BFODYNL.cjs → chunk-UUT2VEN5.cjs} +7 -7
- package/dist/{chunk-7BFODYNL.cjs.map → chunk-UUT2VEN5.cjs.map} +1 -1
- package/dist/chunk-V3T7RO4F.js +21 -0
- package/dist/chunk-V3T7RO4F.js.map +1 -0
- package/dist/{chunk-GIEDIAPD.js → chunk-V5CM5TH3.js} +3 -3
- package/dist/{chunk-L65MHFMD.js → chunk-V64DICJK.js} +3 -3
- package/dist/{chunk-KIZVY57H.cjs → chunk-VXC7Z7XB.cjs} +5 -5
- package/dist/{chunk-KIZVY57H.cjs.map → chunk-VXC7Z7XB.cjs.map} +1 -1
- package/dist/chunk-VYF7WV4K.cjs +47 -0
- package/dist/chunk-VYF7WV4K.cjs.map +1 -0
- package/dist/{chunk-P4XZH3OR.js → chunk-WHQGJHMD.js} +4 -4
- package/dist/{chunk-TTLFY76J.cjs → chunk-WR77IZUU.cjs} +32 -9
- package/dist/chunk-WR77IZUU.cjs.map +1 -0
- package/dist/{chunk-O2BECFXJ.cjs → chunk-WTFEMOV5.cjs} +43 -22
- package/dist/chunk-WTFEMOV5.cjs.map +1 -0
- package/dist/{chunk-YAKTVIVK.js → chunk-XIUZT4TO.js} +3 -3
- package/dist/chunk-XPG56DLQ.cjs +103 -0
- package/dist/chunk-XPG56DLQ.cjs.map +1 -0
- package/dist/{chunk-GPVGGBIR.js → chunk-XWMXEJVZ.js} +2 -2
- package/dist/chunk-XZILHRKG.cjs +13 -0
- package/dist/chunk-XZILHRKG.cjs.map +1 -0
- package/dist/{chunk-VQGLVBPL.cjs → chunk-YIOHKQ6Y.cjs} +11 -4
- package/dist/chunk-YIOHKQ6Y.cjs.map +1 -0
- package/dist/{chunk-A3LMUPG3.js → chunk-Z3IJWYUD.js} +2 -2
- package/dist/{chunk-4J25XZDI.js → chunk-ZJWQPZ7E.js} +9 -2
- package/dist/chunk-ZJWQPZ7E.js.map +1 -0
- package/dist/color-picker/index.cjs +5 -4
- package/dist/color-picker/index.cjs.map +1 -1
- package/dist/color-picker/index.js +4 -3
- package/dist/combobox/index.cjs +7 -6
- package/dist/combobox/index.cjs.map +1 -1
- package/dist/combobox/index.js +6 -5
- package/dist/command-palette/index.cjs +4 -3
- package/dist/command-palette/index.cjs.map +1 -1
- package/dist/command-palette/index.js +3 -2
- package/dist/context-menu/index.cjs +7 -6
- package/dist/context-menu/index.cjs.map +1 -1
- package/dist/context-menu/index.d.cts +2 -2
- package/dist/context-menu/index.d.ts +2 -2
- package/dist/context-menu/index.js +6 -5
- package/dist/conversation/index.cjs +11 -8
- package/dist/conversation/index.cjs.map +1 -1
- package/dist/conversation/index.d.cts +3 -3
- package/dist/conversation/index.d.ts +3 -3
- package/dist/conversation/index.js +10 -7
- package/dist/data-grid/index.cjs +18 -15
- package/dist/data-grid/index.cjs.map +1 -1
- package/dist/data-grid/index.d.cts +8 -8
- package/dist/data-grid/index.d.ts +8 -8
- package/dist/data-grid/index.js +17 -14
- package/dist/date-picker/index.cjs +11 -8
- package/dist/date-picker/index.cjs.map +1 -1
- package/dist/date-picker/index.d.cts +2 -2
- package/dist/date-picker/index.d.ts +2 -2
- package/dist/date-picker/index.js +10 -7
- package/dist/drawer/index.cjs +8 -5
- package/dist/drawer/index.cjs.map +1 -1
- package/dist/drawer/index.d.cts +5 -4
- package/dist/drawer/index.d.ts +5 -4
- package/dist/drawer/index.js +7 -4
- package/dist/dropdown/index.cjs +4 -3
- package/dist/dropdown/index.cjs.map +1 -1
- package/dist/dropdown/index.js +3 -2
- package/dist/header/index.cjs +9 -6
- package/dist/header/index.cjs.map +1 -1
- package/dist/header/index.d.cts +10 -10
- package/dist/header/index.d.ts +10 -10
- package/dist/header/index.js +8 -5
- package/dist/index.cjs +59 -42
- package/dist/index.cjs.map +1 -1
- package/dist/index.css +107 -34
- package/dist/index.d.cts +16 -13
- package/dist/index.d.ts +16 -13
- package/dist/index.js +65 -48
- package/dist/inline-edit/index.cjs +6 -5
- package/dist/inline-edit/index.cjs.map +1 -1
- package/dist/inline-edit/index.js +5 -4
- package/dist/input/index.cjs +5 -4
- package/dist/input/index.cjs.map +1 -1
- package/dist/input/index.d.cts +3 -3
- package/dist/input/index.d.ts +3 -3
- package/dist/input/index.js +4 -3
- package/dist/link-provider/index.cjs +12 -0
- package/dist/link-provider/index.cjs.map +1 -0
- package/dist/link-provider/index.d.cts +43 -0
- package/dist/link-provider/index.d.ts +43 -0
- package/dist/link-provider/index.js +12 -0
- package/dist/link-provider/index.js.map +1 -0
- package/dist/lucide-icons/index.cjs +9 -0
- package/dist/lucide-icons/index.cjs.map +1 -0
- package/dist/lucide-icons/index.d.cts +2 -0
- package/dist/lucide-icons/index.d.ts +2 -0
- package/dist/lucide-icons/index.js +9 -0
- package/dist/lucide-icons/index.js.map +1 -0
- package/dist/menu/index.cjs +6 -5
- package/dist/menu/index.cjs.map +1 -1
- package/dist/menu/index.d.cts +3 -3
- package/dist/menu/index.d.ts +3 -3
- package/dist/menu/index.js +5 -4
- package/dist/modal/index.cjs +8 -5
- package/dist/modal/index.cjs.map +1 -1
- package/dist/modal/index.d.cts +2 -2
- package/dist/modal/index.d.ts +2 -2
- package/dist/modal/index.js +7 -4
- package/dist/navigation/index.cjs +8 -5
- package/dist/navigation/index.cjs.map +1 -1
- package/dist/navigation/index.d.cts +3 -3
- package/dist/navigation/index.d.ts +3 -3
- package/dist/navigation/index.js +7 -4
- package/dist/number-input/index.cjs +4 -3
- package/dist/number-input/index.cjs.map +1 -1
- package/dist/number-input/index.js +3 -2
- package/dist/page-layout/index.cjs +16 -13
- package/dist/page-layout/index.cjs.map +1 -1
- package/dist/page-layout/index.d.cts +8 -8
- package/dist/page-layout/index.d.ts +8 -8
- package/dist/page-layout/index.js +15 -12
- package/dist/pagination/index.cjs +11 -8
- package/dist/pagination/index.cjs.map +1 -1
- package/dist/pagination/index.js +10 -7
- package/dist/popover/index.cjs +4 -3
- package/dist/popover/index.cjs.map +1 -1
- package/dist/popover/index.d.cts +1 -1
- package/dist/popover/index.d.ts +1 -1
- package/dist/popover/index.js +3 -2
- package/dist/renderIcon-BW3PUtg8.d.cts +50 -0
- package/dist/renderIcon-BW3PUtg8.d.ts +50 -0
- package/dist/segmented-control/index.cjs +5 -4
- package/dist/segmented-control/index.cjs.map +1 -1
- package/dist/segmented-control/index.d.cts +3 -3
- package/dist/segmented-control/index.d.ts +3 -3
- package/dist/segmented-control/index.js +4 -3
- package/dist/select/index.cjs +7 -6
- package/dist/select/index.cjs.map +1 -1
- package/dist/select/index.d.cts +4 -4
- package/dist/select/index.d.ts +4 -4
- package/dist/select/index.js +6 -5
- package/dist/snackbar/index.cjs +8 -5
- package/dist/snackbar/index.cjs.map +1 -1
- package/dist/snackbar/index.js +7 -4
- package/dist/split-button/index.cjs +7 -6
- package/dist/split-button/index.cjs.map +1 -1
- package/dist/split-button/index.d.cts +2 -2
- package/dist/split-button/index.d.ts +2 -2
- package/dist/split-button/index.js +6 -5
- package/dist/split-chip/index.cjs +14 -0
- package/dist/split-chip/index.cjs.map +1 -0
- package/dist/split-chip/index.d.cts +67 -0
- package/dist/split-chip/index.d.ts +67 -0
- package/dist/split-chip/index.js +14 -0
- package/dist/split-chip/index.js.map +1 -0
- package/dist/table/index.cjs +16 -13
- package/dist/table/index.cjs.map +1 -1
- package/dist/table/index.d.cts +4 -4
- package/dist/table/index.d.ts +4 -4
- package/dist/table/index.js +15 -12
- package/dist/tabs/index.cjs +4 -3
- package/dist/tabs/index.cjs.map +1 -1
- package/dist/tabs/index.d.cts +1 -1
- package/dist/tabs/index.d.ts +1 -1
- package/dist/tabs/index.js +3 -2
- package/dist/tag-input/index.cjs +9 -6
- package/dist/tag-input/index.cjs.map +1 -1
- package/dist/tag-input/index.js +8 -5
- package/dist/textarea/index.cjs +5 -4
- package/dist/textarea/index.cjs.map +1 -1
- package/dist/textarea/index.d.cts +1 -1
- package/dist/textarea/index.d.ts +1 -1
- package/dist/textarea/index.js +4 -3
- package/dist/theme-editor/index.cjs +14 -11
- package/dist/theme-editor/index.cjs.map +1 -1
- package/dist/theme-editor/index.js +13 -10
- package/dist/theme-provider/index.cjs +4 -3
- package/dist/theme-provider/index.cjs.map +1 -1
- package/dist/theme-provider/index.js +3 -2
- package/dist/timeline/index.cjs +2 -2
- package/dist/timeline/index.d.cts +18 -3
- package/dist/timeline/index.d.ts +18 -3
- package/dist/timeline/index.js +1 -1
- package/dist/toolbar/index.cjs +12 -9
- package/dist/toolbar/index.cjs.map +1 -1
- package/dist/toolbar/index.d.cts +7 -7
- package/dist/toolbar/index.d.ts +7 -7
- package/dist/toolbar/index.js +11 -8
- package/dist/tooltip/index.cjs +4 -3
- package/dist/tooltip/index.cjs.map +1 -1
- package/dist/tooltip/index.js +3 -2
- package/package.json +4 -2
- package/dist/Button.types-BH0CPyPx.d.ts +0 -33
- package/dist/Button.types-DZRCVqyN.d.cts +0 -33
- package/dist/chunk-35LGEPLP.cjs.map +0 -1
- package/dist/chunk-36JFXFM2.cjs.map +0 -1
- package/dist/chunk-3KBBJZHK.cjs.map +0 -1
- package/dist/chunk-4J25XZDI.js.map +0 -1
- package/dist/chunk-5O73AALP.cjs.map +0 -1
- package/dist/chunk-75GFIQRU.js.map +0 -1
- package/dist/chunk-DA375AI6.cjs +0 -88
- package/dist/chunk-DA375AI6.cjs.map +0 -1
- package/dist/chunk-DRXPTACG.js.map +0 -1
- package/dist/chunk-GWHZFX2H.js.map +0 -1
- package/dist/chunk-NEQXEVHM.js +0 -34
- package/dist/chunk-NEQXEVHM.js.map +0 -1
- package/dist/chunk-O2BECFXJ.cjs.map +0 -1
- package/dist/chunk-OOCCSMWM.js.map +0 -1
- package/dist/chunk-RHHZRTWM.js.map +0 -1
- package/dist/chunk-SNRRF64M.js.map +0 -1
- package/dist/chunk-TTLFY76J.cjs.map +0 -1
- package/dist/chunk-VQGLVBPL.cjs.map +0 -1
- package/dist/chunk-WE2SBWZ6.js.map +0 -1
- package/dist/chunk-ZMDZGL5A.cjs +0 -34
- package/dist/chunk-ZMDZGL5A.cjs.map +0 -1
- package/dist/renderIcon-C2lEMMzb.d.cts +0 -30
- package/dist/renderIcon-C2lEMMzb.d.ts +0 -30
- /package/dist/{chunk-RHFD2Z5V.js.map → chunk-3TF2GZSG.js.map} +0 -0
- /package/dist/{chunk-JHX6JK3M.js.map → chunk-3X6QVHTD.js.map} +0 -0
- /package/dist/{chunk-MQAOXZD4.js.map → chunk-4S57PE43.js.map} +0 -0
- /package/dist/{chunk-JT4KVXJK.js.map → chunk-4V2XYUQL.js.map} +0 -0
- /package/dist/{chunk-AR2ZOO6L.js.map → chunk-6FXFKMJ5.js.map} +0 -0
- /package/dist/{chunk-LGDODZHI.js.map → chunk-6LTZV6HN.js.map} +0 -0
- /package/dist/{chunk-YP4HUBKN.js.map → chunk-6NAOAKII.js.map} +0 -0
- /package/dist/{chunk-D7SQ7LHJ.js.map → chunk-BO3KK3ZQ.js.map} +0 -0
- /package/dist/{chunk-5XH2PHT2.js.map → chunk-CNTG7OOO.js.map} +0 -0
- /package/dist/{chunk-WNDDS367.js.map → chunk-DPTTDHZ5.js.map} +0 -0
- /package/dist/{chunk-BFKPJ627.js.map → chunk-FHOD3FUN.js.map} +0 -0
- /package/dist/{chunk-SDUGYJGW.js.map → chunk-H3C6YECZ.js.map} +0 -0
- /package/dist/{chunk-MPIVBAMY.js.map → chunk-HYRLK462.js.map} +0 -0
- /package/dist/{chunk-FIVMMCGM.js.map → chunk-IHPSRTVW.js.map} +0 -0
- /package/dist/{chunk-THCTUBX6.js.map → chunk-IKXXXVUO.js.map} +0 -0
- /package/dist/{chunk-24HKKSKX.js.map → chunk-L6ERHCQ2.js.map} +0 -0
- /package/dist/{chunk-4LNTZPSQ.js.map → chunk-L6YJ6QTZ.js.map} +0 -0
- /package/dist/{chunk-JNY7TUDS.js.map → chunk-MCPGI6EI.js.map} +0 -0
- /package/dist/{chunk-2PCCGQOH.js.map → chunk-P6OJQ2RN.js.map} +0 -0
- /package/dist/{chunk-YXRKBKFB.js.map → chunk-S5CMZFX6.js.map} +0 -0
- /package/dist/{chunk-HEX4IMLO.js.map → chunk-TJQNGJHP.js.map} +0 -0
- /package/dist/{chunk-SFFKQQ5Z.js.map → chunk-U4SVBE2M.js.map} +0 -0
- /package/dist/{chunk-O3QM3BFE.js.map → chunk-UC4NYF6T.js.map} +0 -0
- /package/dist/{chunk-GIEDIAPD.js.map → chunk-V5CM5TH3.js.map} +0 -0
- /package/dist/{chunk-L65MHFMD.js.map → chunk-V64DICJK.js.map} +0 -0
- /package/dist/{chunk-P4XZH3OR.js.map → chunk-WHQGJHMD.js.map} +0 -0
- /package/dist/{chunk-YAKTVIVK.js.map → chunk-XIUZT4TO.js.map} +0 -0
- /package/dist/{chunk-GPVGGBIR.js.map → chunk-XWMXEJVZ.js.map} +0 -0
- /package/dist/{chunk-A3LMUPG3.js.map → chunk-Z3IJWYUD.js.map} +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/home/runner/work/eidos-ui/eidos-ui/dist/chunk-
|
|
1
|
+
{"version":3,"sources":["/home/runner/work/eidos-ui/eidos-ui/dist/chunk-DG3O5NV4.cjs","../src/components/InlineEdit/InlineEdit.component.tsx"],"names":[],"mappings":"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","file":"/home/runner/work/eidos-ui/eidos-ui/dist/chunk-DG3O5NV4.cjs","sourcesContent":[null,"import React, { useState, useRef, useCallback } from 'react';\nimport { Pencil } from 'lucide-react';\nimport { Input } from '../Input/Input.component';\nimport type { InlineEditProps } from './InlineEdit.types';\nimport './InlineEdit.scss';\n\nexport const InlineEdit: React.FC<InlineEditProps> = ({\n value,\n onChange,\n onConfirm,\n onCancel,\n editing: editingProp,\n onEditingChange,\n type = 'text',\n placeholder,\n trigger = 'click',\n size = 'md',\n fullWidth = false,\n disabled = false,\n confirmOnBlur = true,\n renderDisplay,\n showEditIcon = true,\n inputVariant = 'outlined',\n className = '',\n}) => {\n const isControlled = editingProp !== undefined;\n const [internalEditing, setInternalEditing] = useState(false);\n const editing = isControlled ? editingProp : internalEditing;\n\n // Track the value at the moment editing begins so Esc can revert to it.\n const valueAtEditStart = useRef(value);\n\n // Local draft while editing - keeps Input value in sync without forcing the\n // parent to wire `onChange` just to see live keystrokes.\n const [draft, setDraft] = useState(value);\n\n // ------------------------------------------------------------------\n // Editing state helpers\n // ------------------------------------------------------------------\n\n const openEdit = useCallback(() => {\n if (disabled) return;\n valueAtEditStart.current = value;\n setDraft(value);\n if (!isControlled) setInternalEditing(true);\n onEditingChange?.(true);\n }, [disabled, isControlled, onEditingChange, value]);\n\n const closeEdit = useCallback(() => {\n if (!isControlled) setInternalEditing(false);\n onEditingChange?.(false);\n }, [isControlled, onEditingChange]);\n\n const confirm = useCallback(() => {\n closeEdit();\n onConfirm?.(draft);\n }, [closeEdit, draft, onConfirm]);\n\n const cancel = useCallback(() => {\n // Revert the draft AND propagate the original value so the parent stays in\n // sync when `onChange` is used to maintain external state.\n setDraft(valueAtEditStart.current);\n onChange?.(valueAtEditStart.current);\n closeEdit();\n onCancel?.();\n }, [closeEdit, onChange, onCancel]);\n\n // ------------------------------------------------------------------\n // Input handlers\n // ------------------------------------------------------------------\n\n const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n setDraft(e.target.value);\n onChange?.(e.target.value);\n };\n\n const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {\n if (e.key === 'Enter') {\n e.preventDefault();\n // Stop propagation so parent grids/tables don't double-handle Enter.\n e.stopPropagation();\n confirm();\n } else if (e.key === 'Escape') {\n e.preventDefault();\n e.stopPropagation();\n cancel();\n }\n // Tab and Arrow keys intentionally bubble - consumers like DataGrid own\n // Tab-to-next-cell and arrow-key navigation at the container level.\n };\n\n const handleBlur = () => {\n if (confirmOnBlur) confirm();\n };\n\n // ------------------------------------------------------------------\n // Trigger props for display mode\n // ------------------------------------------------------------------\n\n const displayTriggerProps =\n trigger === 'doubleClick' ? { onDoubleClick: openEdit } : { onClick: openEdit };\n\n // ------------------------------------------------------------------\n // Render: edit mode\n // ------------------------------------------------------------------\n\n if (editing) {\n return (\n <Input\n type={type}\n variant={inputVariant}\n size={size}\n value={draft}\n onChange={handleChange}\n onKeyDown={handleKeyDown}\n onBlur={handleBlur}\n placeholder={placeholder}\n fullWidth={fullWidth}\n clearable={false}\n autoFocus\n className={`eidos-inline-edit eidos-inline-edit--editing ${className}`}\n />\n );\n }\n\n // ------------------------------------------------------------------\n // Render: display mode\n // ------------------------------------------------------------------\n\n const isEmpty = !value;\n\n return (\n <span\n role=\"button\"\n tabIndex={disabled ? undefined : 0}\n // The visible text has to be *in* the name (SC 2.5.3 Label in Name).\n //\n // This was a flat \"Click to edit\", which shares nothing with the value\n // on screen - so a speech-input user saying what they can see (\"Page\n // title\") matched nothing, and a screen reader announced an edit\n // affordance without ever saying what it edits. Every `InlineEdit` on\n // a page was also announced identically.\n //\n // Left off entirely when there is no value: the placeholder is then\n // the visible text and `textContent` already provides the name.\n aria-label={disabled || isEmpty ? undefined : `${value}, click to edit`}\n className={[\n 'eidos-inline-edit',\n `eidos-inline-edit--${size}`,\n fullWidth ? 'eidos-inline-edit--full-width' : '',\n disabled ? 'eidos-inline-edit--disabled' : '',\n isEmpty ? 'eidos-inline-edit--empty' : '',\n className,\n ]\n .filter(Boolean)\n .join(' ')}\n {...(disabled ? {} : displayTriggerProps)}\n onKeyDown={\n disabled\n ? undefined\n : (e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n openEdit();\n }\n }\n }\n >\n <span className=\"eidos-inline-edit__text\">\n {renderDisplay\n ? renderDisplay(value)\n : value || <span className=\"eidos-inline-edit__placeholder\">{placeholder}</span>}\n </span>\n {!disabled && showEditIcon && (\n <span className=\"eidos-inline-edit__icon\" aria-hidden>\n <Pencil />\n </span>\n )}\n </span>\n );\n};\n"]}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
Select
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-4S57PE43.js";
|
|
4
4
|
import {
|
|
5
5
|
Button
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-JY77VJAZ.js";
|
|
7
7
|
|
|
8
8
|
// src/components/Pagination/Pagination.component.tsx
|
|
9
9
|
import { useState, useEffect, useId } from "react";
|
|
@@ -209,4 +209,4 @@ Pagination.displayName = "Pagination";
|
|
|
209
209
|
export {
|
|
210
210
|
Pagination
|
|
211
211
|
};
|
|
212
|
-
//# sourceMappingURL=chunk-
|
|
212
|
+
//# sourceMappingURL=chunk-DPTTDHZ5.js.map
|
|
@@ -1,12 +1,37 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
var _chunkCJT7L764cjs = require('./chunk-CJT7L764.cjs');
|
|
5
|
+
|
|
6
|
+
// src/utils/renderIcon.tsx
|
|
2
7
|
var _lucidereact = require('lucide-react');
|
|
8
|
+
|
|
9
|
+
// src/utils/devWarn.ts
|
|
10
|
+
var warned = /* @__PURE__ */ new Set();
|
|
11
|
+
function devWarn(key, message) {
|
|
12
|
+
const nodeEnv = _optionalChain([globalThis, 'access', _ => _.process, 'optionalAccess', _2 => _2.env, 'optionalAccess', _3 => _3.NODE_ENV]);
|
|
13
|
+
if (nodeEnv === "production") return;
|
|
14
|
+
if (warned.has(key)) return;
|
|
15
|
+
warned.add(key);
|
|
16
|
+
console.warn(`[eidos-ui] ${message}`);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
// src/utils/renderIcon.tsx
|
|
3
20
|
var _jsxruntime = require('react/jsx-runtime');
|
|
4
21
|
var renderIcon = (icon, className) => {
|
|
5
22
|
if (!icon) return null;
|
|
6
23
|
if (typeof icon === "string") {
|
|
7
|
-
const
|
|
24
|
+
const Registered = _chunkCJT7L764cjs.resolveRegisteredIcon.call(void 0, icon);
|
|
25
|
+
if (Registered) {
|
|
26
|
+
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, Registered, { className, "aria-hidden": "true" });
|
|
27
|
+
}
|
|
28
|
+
const iconName = _chunkCJT7L764cjs.toIconKey.call(void 0, icon);
|
|
8
29
|
const LucideIcon = _lucidereact.icons[iconName];
|
|
9
30
|
if (LucideIcon) {
|
|
31
|
+
devWarn(
|
|
32
|
+
`icon-string-fallback-${iconName}`,
|
|
33
|
+
`Icon "${icon}" was resolved by name from the full Lucide icon set. That lookup is deprecated and is removed in 4.0, because it bundles every Lucide icon. Pass the component instead (\`import { ${iconName} } from 'lucide-react'\`), register it once with \`registerIcons({ ${iconName} })\`, or \`import 'eidos-ui/lucide-icons'\` to register them all.`
|
|
34
|
+
);
|
|
10
35
|
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, LucideIcon, { className, "aria-hidden": "true" });
|
|
11
36
|
}
|
|
12
37
|
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "i", { className: `${icon} ${className || ""}`, "aria-hidden": "true" });
|
|
@@ -15,16 +40,6 @@ var renderIcon = (icon, className) => {
|
|
|
15
40
|
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, IconComponent, { className, "aria-hidden": "true" });
|
|
16
41
|
};
|
|
17
42
|
|
|
18
|
-
// src/utils/devWarn.ts
|
|
19
|
-
var warned = /* @__PURE__ */ new Set();
|
|
20
|
-
function devWarn(key, message) {
|
|
21
|
-
const nodeEnv = _optionalChain([globalThis, 'access', _ => _.process, 'optionalAccess', _2 => _2.env, 'optionalAccess', _3 => _3.NODE_ENV]);
|
|
22
|
-
if (nodeEnv === "production") return;
|
|
23
|
-
if (warned.has(key)) return;
|
|
24
|
-
warned.add(key);
|
|
25
|
-
console.warn(`[eidos-ui] ${message}`);
|
|
26
|
-
}
|
|
27
|
-
|
|
28
43
|
// src/utils/dualModifier.ts
|
|
29
44
|
var dualModifier = (block, canonical, legacy) => `${block}--${canonical} ${block}--${legacy}`;
|
|
30
45
|
var fullWidthModifier = (block) => dualModifier(block, "full-width", "fullWidth");
|
|
@@ -130,5 +145,5 @@ var useIsClient = () => {
|
|
|
130
145
|
|
|
131
146
|
|
|
132
147
|
|
|
133
|
-
exports.
|
|
134
|
-
//# sourceMappingURL=chunk-
|
|
148
|
+
exports.devWarn = devWarn; exports.renderIcon = renderIcon; exports.dualModifier = dualModifier; exports.fullWidthModifier = fullWidthModifier; exports.FOCUSABLE_SELECTOR = FOCUSABLE_SELECTOR; exports.useDialogFocus = useDialogFocus; exports.useIsClient = useIsClient;
|
|
149
|
+
//# sourceMappingURL=chunk-ENMDOQQO.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["/home/runner/work/eidos-ui/eidos-ui/dist/chunk-ENMDOQQO.cjs","../src/utils/renderIcon.tsx","../src/utils/devWarn.ts","../src/utils/dualModifier.ts","../src/utils/useDialogFocus.ts","../src/utils/useIsClient.ts"],"names":[],"mappings":"AAAA;AACE;AACA;AACF,wDAA6B;AAC7B;AACA;ACJA,2CAAsB;ADMtB;AACA;AEOA,IAAM,OAAA,kBAAS,IAAI,GAAA,CAAY,CAAA;AAExB,SAAS,OAAA,CAAQ,GAAA,EAAa,OAAA,EAAuB;AAC1D,EAAA,MAAM,QAAA,kBAAW,UAAA,mBAA6D,OAAA,6BAAS,GAAA,6BACnF,UAAA;AACJ,EAAA,GAAA,CAAI,QAAA,IAAY,YAAA,EAAc,MAAA;AAC9B,EAAA,GAAA,CAAI,MAAA,CAAO,GAAA,CAAI,GAAG,CAAA,EAAG,MAAA;AACrB,EAAA,MAAA,CAAO,GAAA,CAAI,GAAG,CAAA;AACd,EAAA,OAAA,CAAQ,IAAA,CAAK,CAAA,WAAA,EAAc,OAAO,CAAA,CAAA;AACpC;AFPqC;AACA;ACiBxB;AAN0C;AACnC,EAAA;AAEY,EAAA;AACT,IAAA;AACH,IAAA;AACN,MAAA;AACV,IAAA;AAQ+B,IAAA;AACwB,IAAA;AAEvC,IAAA;AACd,MAAA;AAC0B,QAAA;AACX,QAAA;AACf,MAAA;AACQ,MAAA;AACV,IAAA;AAGQ,IAAA;AACV,EAAA;AAGsB,EAAA;AACd,EAAA;AACV;ADrBqC;AACA;AGdO;AAK1C;AHYmC;AACA;AI9CK;AA+CR;AAChC,EAAA;AACA,EAAA;AACA,EAAA;AACA,EAAA;AACA,EAAA;AACA,EAAA;AACA,EAAA;AACA,EAAA;AACA,EAAA;AACA,EAAA;AACA,EAAA;AACA,EAAA;AACQ;AASA;AAGR;AACqC,EAAA;AACrC;AAGgC;AAqBhC;AAGgB,EAAA;AACiB,IAAA;AACJ,IAAA;AAMD,IAAA;AAEF,IAAA;AAeL,IAAA;AACP,IAAA;AACG,IAAA;AAEQ,IAAA;AACQ,MAAA;AACjB,MAAA;AACG,QAAA;AACR,MAAA;AAIuB,QAAA;AACZ,QAAA;AAClB,MAAA;AAEwB,MAAA;AACV,QAAA;AACJ,QAAA;AACV,MAAA;AACF,IAAA;AAES,IAAA;AAEmC,IAAA;AACjB,MAAA;AAED,MAAA;AAKO,MAAA;AACH,MAAA;AACL,QAAA;AACrB,QAAA;AACF,MAAA;AAEyB,MAAA;AACF,MAAA;AACQ,MAAA;AAIR,MAAA;AACA,QAAA;AACI,QAAA;AACzB,QAAA;AACF,MAAA;AAEsB,MAAA;AACC,QAAA;AACV,QAAA;AACiB,MAAA;AACP,QAAA;AACT,QAAA;AACd,MAAA;AACF,IAAA;AAEsB,IAAA;AAET,IAAA;AACe,MAAA;AACG,MAAA;AAEL,MAAA;AACI,MAAA;AAeJ,MAAA;AACM,MAAA;AAEV,MAAA;AACM,QAAA;AAC1B,MAAA;AACF,IAAA;AACwB,EAAA;AAC5B;AJvFqC;AACA;AKjIjB;AA4CsB;AACR,EAAA;AAEhB,EAAA;AACE,IAAA;AACb,EAAA;AAEE,EAAA;AACT;ALsFqC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA","file":"/home/runner/work/eidos-ui/eidos-ui/dist/chunk-ENMDOQQO.cjs","sourcesContent":[null,"import React from 'react';\nimport { icons } from 'lucide-react';\nimport { devWarn } from './devWarn';\nimport { resolveRegisteredIcon, toIconKey, type IconComponent } from './iconRegistry';\n\nexport type IconType = IconComponent | string;\n\n/**\n * Renders an icon prop.\n *\n * @param icon - An icon component, or a string: a name registered with\n * `registerIcons`, or CSS classes for an icon font.\n * @param className - Optional CSS class name to apply to the icon.\n * @returns React node representing the icon, or null if no icon provided.\n *\n * @example\n * // Component - the recommended form; only the icons you import are bundled\n * import { Heart } from 'lucide-react';\n * renderIcon(Heart, 'my-icon-class');\n *\n * @example\n * // Registered name\n * registerIcons({ Heart });\n * renderIcon('heart', 'my-icon-class');\n *\n * @example\n * // CSS classes for an icon font (Font Awesome, Remixicon, ...)\n * renderIcon('fas fa-heart', 'my-icon-class');\n */\nexport const renderIcon = (icon: IconType | undefined, className?: string): React.ReactNode => {\n if (!icon) return null;\n\n if (typeof icon === 'string') {\n const Registered = resolveRegisteredIcon(icon);\n if (Registered) {\n return <Registered className={className} aria-hidden=\"true\" />;\n }\n\n // Deprecated fallback, removed in 4.0: resolving an unregistered name\n // against Lucide's full `icons` map. Referencing that map is what puts\n // every Lucide icon (~1,800 modules) into a consumer's bundle, however\n // few they use - no bundler can tree-shake a lookup by a runtime string.\n // It stays for one minor so existing string names keep working while\n // the warning below points at the migration.\n const iconName = toIconKey(icon);\n const LucideIcon = icons[iconName as keyof typeof icons] as IconComponent | undefined;\n\n if (LucideIcon) {\n devWarn(\n `icon-string-fallback-${iconName}`,\n `Icon \"${icon}\" was resolved by name from the full Lucide icon set. That lookup is deprecated and is removed in 4.0, because it bundles every Lucide icon. Pass the component instead (\\`import { ${iconName} } from 'lucide-react'\\`), register it once with \\`registerIcons({ ${iconName} })\\`, or \\`import 'eidos-ui/lucide-icons'\\` to register them all.`,\n );\n return <LucideIcon className={className} aria-hidden=\"true\" />;\n }\n\n // Fallback: render as a CSS class (for Font Awesome, Remixicon, etc.)\n return <i className={`${icon} ${className || ''}`} aria-hidden=\"true\" />;\n }\n\n // It's a React component\n const IconComponent = icon;\n return <IconComponent className={className} aria-hidden=\"true\" />;\n};\n","/**\n * Logs a misconfiguration warning, once per `key`, and never in production.\n *\n * Deliberately reads `process.env.NODE_ENV` off `globalThis` behind a cast\n * rather than referencing `process` directly: this is a browser library, and\n * a bare `process` reference fails the `tsup` dts build (its worker resolves\n * without node types, so `npm run typecheck` passing is not enough) as well\n * as throwing at runtime anywhere a bundler hasn't substituted it. The\n * optional chaining covers every case - no `process`, no `env`, no value.\n *\n * Because the check is dynamic rather than a statically replaceable\n * `process.env.NODE_ENV` expression, the message text stays in production\n * bundles; only the logging is skipped. That is the trade for not shipping a\n * `process` reference at all, and these strings are small.\n */\nconst warned = new Set<string>();\n\nexport function devWarn(key: string, message: string): void {\n const nodeEnv = (globalThis as { process?: { env?: { NODE_ENV?: string } } }).process?.env\n ?.NODE_ENV;\n if (nodeEnv === 'production') return;\n if (warned.has(key)) return;\n warned.add(key);\n console.warn(`[eidos-ui] ${message}`);\n}\n","/**\n * Emits a BEM modifier in both its canonical kebab-case spelling and a legacy\n * camelCase one.\n *\n * The library shipped two conventions for the same idea: eight components\n * used `--fullWidth` while four used `--full-width`, and `Tabs` had\n * `--hideScrollbar`. Kebab-case is the canonical form - every block name\n * (`eidos-date-picker-trigger`) and every design token (`--font-size-sm`) is\n * already kebab, so a camelCase modifier was inconsistent with the very\n * selector it hung off.\n *\n * Renaming outright would be a **breaking** change: `README.md` presents the\n * `eidos-*` class names as things consumers may target, so a stylesheet out\n * there is matching the old spelling. Emitting both keeps every existing\n * selector working while new code has one spelling to learn.\n *\n * Deliberately a helper rather than a duplicated string literal at each call\n * site: two near-identical classes in a `className` read as a copy-paste slip\n * and invite exactly the \"tidy up\" that would silently break those consumer\n * stylesheets. It also makes dropping the aliases at the next major a change\n * to this one file rather than an edit in every component.\n *\n * Internal only - deliberately not re-exported from `src/index.ts`.\n *\n * @example\n * dualModifier('eidos-input', 'full-width', 'fullWidth');\n * // 'eidos-input--full-width eidos-input--fullWidth'\n */\nexport const dualModifier = (block: string, canonical: string, legacy: string): string =>\n `${block}--${canonical} ${block}--${legacy}`;\n\n/** `dualModifier` preset for the library's most widespread split modifier. */\nexport const fullWidthModifier = (block: string): string =>\n dualModifier(block, 'full-width', 'fullWidth');\n","import { useEffect, type RefObject } from 'react';\n\n/**\n * Focus management for a dialog: move focus in on open, optionally trap Tab\n * inside it, and restore focus to the opener on close.\n *\n * Named for the job rather than the mechanism because the trap is optional.\n * `Popover` declares `aria-modal=\"false\"` - an honest non-modal dialog - so\n * trapping Tab in it would be wrong, but it still needs the other two: its\n * panel is portaled to `document.body`, so without moving focus in, Tab from\n * the trigger goes to whatever follows it in the page and the panel's own\n * controls are unreachable by keyboard entirely.\n *\n * ## Why this exists\n *\n * `Modal`, `Drawer` and `CommandPalette` all rendered\n * `role=\"dialog\" aria-modal=\"true\"` with no focus management whatsoever. That\n * attribute is a **promise to assistive technology that the rest of the page\n * is inert**, and it was false: measured in a browser, focus never entered the\n * dialog, and Tab moved to the page behind the scrim on the first press\n * (Drawer on the second). Drawer additionally dropped focus onto `<body>` when\n * it closed, so a keyboard user was returned to the top of the document.\n *\n * That is WCAG 2.4.3 Focus Order (Level A), and it is invisible to axe - a\n * static snapshot of the DOM looks perfectly correct.\n *\n * ## Nesting\n *\n * Traps register on a module-level stack and only the innermost one acts, so a\n * dialog opened from a dialog behaves correctly. Without this, both listeners\n * fire for the same Tab and fight over where focus lands.\n *\n * ## What this does *not* do\n *\n * It does not mark the background `inert`. A trap plus `aria-modal` is the\n * widely-supported approach and is what screen readers act on; `inert` on\n * every sibling of the portal root would be stronger, but it needs the\n * component to know about DOM it does not own. Worth revisiting if a\n * consumer reports a screen reader escaping the dialog in browse mode.\n */\n\n/**\n * Deliberately not `[tabindex]` in general - that would match `tabindex=\"-1\"`,\n * which is programmatically focusable but explicitly removed from the Tab\n * sequence, so including it would make Tab stop somewhere the user cannot\n * reach by tabbing in the first place.\n */\nexport const FOCUSABLE_SELECTOR = [\n 'a[href]',\n 'area[href]',\n 'button:not([disabled])',\n 'input:not([disabled]):not([type=\"hidden\"])',\n 'select:not([disabled])',\n 'textarea:not([disabled])',\n 'details > summary:first-of-type',\n 'iframe',\n 'audio[controls]',\n 'video[controls]',\n '[contenteditable]:not([contenteditable=\"false\"])',\n '[tabindex]:not([tabindex^=\"-\"])',\n].join(',');\n\n/**\n * `offsetParent === null` is the usual visibility check and is wrong here: it\n * is also null for `position: fixed` elements, which is exactly what a modal\n * is. `getClientRects()` is empty only when the element genuinely does not\n * render.\n */\nconst isVisible = (element: HTMLElement): boolean =>\n element.getClientRects().length > 0 && getComputedStyle(element).visibility !== 'hidden';\n\nconst getFocusable = (container: HTMLElement): HTMLElement[] =>\n Array.from(container.querySelectorAll<HTMLElement>(FOCUSABLE_SELECTOR)).filter(\n (element) => isVisible(element) && element.closest('[aria-hidden=\"true\"]') === null,\n );\n\n/** Innermost trap last. Only the last entry responds to Tab. */\nconst trapStack: HTMLElement[] = [];\n\nexport interface UseDialogFocusOptions {\n /** Focused when the trap activates. Defaults to the first focusable child. */\n initialFocus?: RefObject<HTMLElement | null>;\n /**\n * Whether to return focus to whatever had it when the trap activated.\n * Defaults to `true`; pass `false` when the caller restores focus itself.\n */\n restoreFocus?: boolean;\n /**\n * Whether Tab is confined to the container. Defaults to `true`.\n *\n * Set `false` for a non-modal dialog (`aria-modal=\"false\"`), where the rest\n * of the page stays available and trapping would strand the user.\n */\n trapTab?: boolean;\n}\n\nexport const useDialogFocus = (\n active: boolean,\n containerRef: RefObject<HTMLElement | null>,\n { initialFocus, restoreFocus = true, trapTab = true }: UseDialogFocusOptions = {},\n): void => {\n useEffect(() => {\n const container = containerRef.current;\n if (!active || !container) return;\n\n // Captured before focus moves. The caller must only flip `active` to true\n // once the container is in the DOM - for the animated overlays that means\n // `isOpen && isMounted`, since `isMounted` is set in an effect one render\n // later and the container does not exist before it.\n const previouslyFocused = document.activeElement as HTMLElement | null;\n\n trapStack.push(container);\n\n // Moving focus in is retried across a few frames rather than attempted\n // once.\n //\n // These overlays animate open, and `.focus()` on an element that is still\n // `visibility: hidden` is a silent no-op - it does not throw, it just\n // leaves focus where it was. `Modal` sets its `--is-open` class two\n // animation frames after mounting, and the computed style has not caught\n // up at the moment the effect runs, so a single attempt focused nothing\n // and the trap looked broken.\n //\n // Retrying is better than keying off any particular animation: the hook\n // stays ignorant of each component's transition duration, and simply\n // stops as soon as focus has actually landed inside.\n const MAX_FRAMES = 10;\n let frame = 0;\n let attempts = 0;\n\n const tryFocus = () => {\n const target = initialFocus?.current ?? getFocusable(container)[0];\n if (target) {\n target.focus();\n } else {\n // A dialog with nothing focusable in it still must not leave focus on\n // the page behind, so the container takes it. `tabindex=\"-1\"` keeps\n // it out of the Tab sequence while allowing `.focus()`.\n if (!container.hasAttribute('tabindex')) container.setAttribute('tabindex', '-1');\n container.focus();\n }\n\n if (!container.contains(document.activeElement) && attempts < MAX_FRAMES) {\n attempts += 1;\n frame = requestAnimationFrame(tryFocus);\n }\n };\n\n tryFocus();\n\n const onKeyDown = (event: KeyboardEvent) => {\n if (event.key !== 'Tab') return;\n // Only the innermost trap acts.\n if (trapStack[trapStack.length - 1] !== container) return;\n\n // Re-queried on every Tab rather than cached: dialog contents change\n // (a disabled Confirm button becoming enabled, a list filtering down),\n // and a stale list sends focus to an element that is no longer there.\n const focusable = getFocusable(container);\n if (focusable.length === 0) {\n event.preventDefault();\n return;\n }\n\n const first = focusable[0];\n const last = focusable[focusable.length - 1];\n const activeElement = document.activeElement as HTMLElement | null;\n\n // Focus outside the container - e.g. a click landed on the backdrop.\n // Pull it back in rather than letting Tab continue through the page.\n if (!activeElement || !container.contains(activeElement)) {\n event.preventDefault();\n (event.shiftKey ? last : first).focus();\n return;\n }\n\n if (event.shiftKey && activeElement === first) {\n event.preventDefault();\n last.focus();\n } else if (!event.shiftKey && activeElement === last) {\n event.preventDefault();\n first.focus();\n }\n };\n\n if (trapTab) document.addEventListener('keydown', onKeyDown, true);\n\n return () => {\n cancelAnimationFrame(frame);\n document.removeEventListener('keydown', onKeyDown, true);\n\n const index = trapStack.lastIndexOf(container);\n if (index !== -1) trapStack.splice(index, 1);\n\n // Restore only if focus still belongs to the closing dialog.\n //\n // Two cases count as \"belongs\":\n //\n // 1. Focus is still inside the container.\n // 2. Focus has been lost to `<body>`. When the overlay hides, the\n // browser blurs whatever was focused inside it, so by the time this\n // cleanup runs `activeElement` is often already `<body>` - checking\n // only case 1 meant `CommandPalette` never restored at all.\n //\n // Anything else means something took focus deliberately - a confirm\n // action moving to a new region, say - and stealing it back would be\n // worse than doing nothing.\n const active = document.activeElement;\n const focusIsOurs = container.contains(active) || active === document.body || active === null;\n\n if (restoreFocus && focusIsOurs && previouslyFocused?.isConnected) {\n previouslyFocused.focus();\n }\n };\n }, [active, containerRef, initialFocus, restoreFocus, trapTab]);\n};\n","import { useEffect, useState } from 'react';\n\n/**\n * `false` on the server and on the very first client render, `true` from the\n * first effect onwards.\n *\n * ## Why this exists\n *\n * Every overlay in this library renders through `createPortal(…,\n * document.body)`. A portal is a client-only construct: there is no\n * `document` during `renderToString`, so any overlay that is *already open on\n * its first render* does not merely render oddly - it throws, and takes the\n * whole server render down with it. Measured against the built package:\n *\n * ```\n * renderToString(<Modal isOpen>) ReferenceError: document is not defined\n * renderToString(<Dropdown defaultOpen>) ReferenceError: DOMRect is not defined\n * renderToString(<Select autoOpen>) ReferenceError: DOMRect is not defined\n * ```\n *\n * `Modal`, `Drawer` and `CommandPalette` each keep an `isMounted` flag, which\n * looks like it would prevent this and does not: it is initialised to\n * `useState(isOpen)`, so it is already `true` on the first render. It exists\n * to sequence the open/close *animation*, not to defer the portal.\n *\n * With this hook the server renders nothing for the panel, and the portal\n * appears on the client after mount.\n *\n * ## Why a state flag rather than `typeof document !== 'undefined'`\n *\n * That check is `true` during hydration, so the client's first render would\n * produce the portal while the server's produced nothing - a hydration\n * mismatch, which React resolves by discarding and re-rendering the subtree.\n * A state flag set in an effect makes the first client render agree with the\n * server by construction, and the portal arrive one render later.\n *\n * ## Scope\n *\n * Only for components that can be open on their first render - `Dropdown`\n * (`defaultOpen`), `Popover`, `Modal`, `Drawer`, `CommandPalette`. `Tooltip`,\n * `ContextMenu` and `Snackbar` can only open in response to an event, which\n * cannot happen during a server render, so they need nothing. `check-ssr.js`\n * asserts all of them either way.\n */\nexport const useIsClient = (): boolean => {\n const [isClient, setIsClient] = useState(false);\n\n useEffect(() => {\n setIsClient(true);\n }, []);\n\n return isClient;\n};\n"]}
|
|
@@ -3,13 +3,13 @@
|
|
|
3
3
|
var _chunkQ3GNKF74cjs = require('./chunk-Q3GNKF74.cjs');
|
|
4
4
|
|
|
5
5
|
|
|
6
|
-
var
|
|
6
|
+
var _chunkXPG56DLQcjs = require('./chunk-XPG56DLQ.cjs');
|
|
7
7
|
|
|
8
8
|
|
|
9
|
-
var
|
|
9
|
+
var _chunkUTYY35QXcjs = require('./chunk-UTYY35QX.cjs');
|
|
10
10
|
|
|
11
11
|
|
|
12
|
-
var
|
|
12
|
+
var _chunkENMDOQQOcjs = require('./chunk-ENMDOQQO.cjs');
|
|
13
13
|
|
|
14
14
|
// src/components/Navigation/Navigation.component.tsx
|
|
15
15
|
var _react = require('react');
|
|
@@ -88,7 +88,7 @@ var Navigation = ({
|
|
|
88
88
|
] })
|
|
89
89
|
}
|
|
90
90
|
),
|
|
91
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "ul", { className: "eidos-navigation__items", children: items.map((item) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "li", { className: "eidos-navigation__item-wrapper", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
91
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "ul", { className: "eidos-navigation__items", children: items.map((item) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "li", { className: "eidos-navigation__item-wrapper", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkUTYY35QXcjs.Tooltip, { message: item.label, placement: "right", disabled: !collapsed, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
92
92
|
"button",
|
|
93
93
|
{
|
|
94
94
|
type: "button",
|
|
@@ -101,14 +101,14 @@ var Navigation = ({
|
|
|
101
101
|
"aria-current": item.active ? "page" : void 0,
|
|
102
102
|
"aria-label": collapsed ? item.label : void 0,
|
|
103
103
|
children: [
|
|
104
|
-
item.icon &&
|
|
104
|
+
item.icon && _chunkENMDOQQOcjs.renderIcon.call(void 0, item.icon, "eidos-navigation__item-icon"),
|
|
105
105
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "eidos-navigation__item-label", "aria-hidden": collapsed || void 0, children: item.label })
|
|
106
106
|
]
|
|
107
107
|
}
|
|
108
108
|
) }) }, item.id)) }),
|
|
109
109
|
footer && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "eidos-navigation__footer", children: footer }),
|
|
110
110
|
collapsible && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "eidos-navigation__toggle", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
111
|
-
|
|
111
|
+
_chunkXPG56DLQcjs.IconButton,
|
|
112
112
|
{
|
|
113
113
|
icon: collapsed ? _lucidereact.SquareChevronRight : _lucidereact.SquareChevronLeft,
|
|
114
114
|
variant: "text",
|
|
@@ -126,4 +126,4 @@ Navigation.displayName = "Navigation";
|
|
|
126
126
|
|
|
127
127
|
|
|
128
128
|
exports.Navigation = Navigation;
|
|
129
|
-
//# sourceMappingURL=chunk-
|
|
129
|
+
//# sourceMappingURL=chunk-F5IRMMZ2.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/home/runner/work/eidos-ui/eidos-ui/dist/chunk-V4BZWBZT.cjs","../src/components/Navigation/Navigation.component.tsx"],"names":[],"mappings":"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","file":"/home/runner/work/eidos-ui/eidos-ui/dist/chunk-V4BZWBZT.cjs","sourcesContent":[null,"import React, { useCallback, useEffect, useRef, useState } from 'react';\nimport { SquareChevronLeft, SquareChevronRight } from 'lucide-react';\nimport type { NavigationLogo, NavigationProps } from './Navigation.types';\nimport { Avatar } from '../Avatar';\nimport { IconButton } from '../Button';\nimport { Tooltip } from '../Tooltip';\nimport { renderIcon } from '../../utils';\nimport './Navigation.scss';\n\n/**\n * Renders a custom brand logo, guaranteeing correct aspect-ratio rendering\n * regardless of whether the source image is vertical, horizontal, or square\n * - and regardless of how much width is actually available, expanded or\n * collapsed. Deliberately no JS sizing/measurement at all: a fixed `height`,\n * `width: auto` (derived from the image's own intrinsic ratio), a `max-width`\n * expressed as `min(72px, 100%)` (see `.eidos-navigation__brand-logo` in\n * Navigation.scss) so it never renders wider than whatever space its\n * container - the rail, expanded or collapsed - actually has, and\n * `object-fit: contain` so it's letterboxed rather than distorted if that\n * ever clamps it below its natural width-at-32px-tall. Centering is handled\n * separately, at the row level - see `&__brand--logo-only` in Navigation.scss.\n */\nconst NavigationBrandLogo: React.FC<{ logo: NavigationLogo }> = ({ logo }) => (\n <img src={logo.src} alt={logo.alt} className=\"eidos-navigation__brand-logo\" />\n);\n\nexport const Navigation: React.FC<NavigationProps> = ({\n brand,\n items,\n footer,\n collapsed: collapsedProp,\n defaultCollapsed = false,\n onCollapsedChange,\n collapseBelow = 768,\n collapsible = true,\n className = '',\n}) => {\n // ── Controlled / uncontrolled collapsed state ─────────────────────────────\n // Mirrors CommandPalette's `open`/`defaultOpen` pattern - omitting\n // `collapsed` lets Navigation own its state entirely, while passing it\n // (+ `onCollapsedChange`) keeps full external control for consumers who\n // need to persist the preference or drive it from a responsive breakpoint.\n const isControlled = collapsedProp !== undefined;\n const [internalCollapsed, setInternalCollapsed] = useState(defaultCollapsed);\n const collapsed = isControlled ? collapsedProp : internalCollapsed;\n\n // Shared by the manual toggle button and `collapseBelow` below - uncontrolled\n // flips the internal state directly, controlled defers to `onCollapsedChange`\n // since Navigation can't change `collapsed` itself.\n const applyCollapsed = useCallback(\n (next: boolean) => {\n if (!isControlled) setInternalCollapsed(next);\n onCollapsedChange?.(next);\n },\n [isControlled, onCollapsedChange],\n );\n\n const toggleCollapsed = useCallback(() => {\n applyCollapsed(!collapsed);\n }, [applyCollapsed, collapsed]);\n\n // Read by the breakpoint effect below so it does not depend on\n // `applyCollapsed`'s identity. A consumer passing an inline\n // `onCollapsedChange` gives that callback a new identity every render,\n // which would re-run the effect - and re-apply the media query's answer -\n // on every render, overriding any manual toggle made in between crossings.\n // That is the one thing `collapseBelow` is documented not to do.\n const applyCollapsedRef = useRef(applyCollapsed);\n useEffect(() => {\n applyCollapsedRef.current = applyCollapsed;\n });\n\n // Auto-collapse/expand at a viewport breakpoint. `matchMedia`'s `change`\n // event only fires exactly at the crossing point, not on every resize\n // tick, so a manual toggle in between crossings is left alone until the\n // viewport actually crosses the breakpoint again.\n useEffect(() => {\n // `0` opts out, as documented - and it has to be checked here rather\n // than relying on `(max-width: 0px)` never matching, because the mount\n // pass below would otherwise still run.\n if (!collapseBelow) return;\n if (typeof window === 'undefined' || !window.matchMedia) return;\n\n const query = window.matchMedia(`(max-width: ${collapseBelow}px)`);\n\n // On mount this may only *collapse*, never expand. `defaultCollapsed`\n // (or a controlled `collapsed`) is the consumer's stated starting point,\n // and applying `query.matches` unconditionally threw it away one commit\n // after the first paint: on any viewport wider than the breakpoint the\n // rail visibly started collapsed and then sprang open. Crossings below\n // still drive both directions, which is what \"collapses and re-expands\"\n // refers to.\n if (query.matches) applyCollapsedRef.current(true);\n\n const handleChange = (event: MediaQueryListEvent) => applyCollapsedRef.current(event.matches);\n query.addEventListener('change', handleChange);\n return () => query.removeEventListener('change', handleChange);\n }, [collapseBelow]);\n\n const classes = ['eidos-navigation', collapsed && 'eidos-navigation--collapsed', className]\n .filter(Boolean)\n .join(' ');\n\n // A `logo` brand has no `name` text alongside it (see the discriminated\n // union in Navigation.types.ts), so there's never a second, variable-width\n // sibling competing for space - unlike the `name` variant, it's always\n // safe to just center it outright, in both expanded and collapsed states,\n // with nothing further to compute. See `&__brand--logo-only` in\n // Navigation.scss.\n const brandClasses = [\n 'eidos-navigation__brand',\n brand.logo && 'eidos-navigation__brand--logo-only',\n brand.onClick && 'eidos-navigation__brand--clickable',\n ]\n .filter(Boolean)\n .join(' ');\n\n const brandAccessibleName = brand.logo ? brand.logo.alt : brand.name;\n\n return (\n <nav className={classes} aria-label=\"Main\">\n <div\n className={brandClasses}\n onClick={brand.onClick}\n role={brand.onClick ? 'button' : undefined}\n tabIndex={brand.onClick ? 0 : undefined}\n // Only a real interactive control (role=\"button\") reliably exposes\n // `aria-label` as its accessible name - a plain, non-interactive div\n // doesn't, so the visible (if currently faded) text remains the only\n // way assistive tech gets the brand name in that case.\n aria-label={brand.onClick ? brandAccessibleName : undefined}\n onKeyDown={\n brand.onClick\n ? (e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n brand.onClick?.();\n }\n }\n : undefined\n }\n >\n {brand.logo ? (\n <NavigationBrandLogo logo={brand.logo} />\n ) : (\n <>\n <Avatar name={brand.name} shape=\"square\" size=\"sm\" />\n {/* Only redundant with the wrapper's own `aria-label` when\n `brand.onClick` is set (see the note on it above) - otherwise\n this is the only accessible text for the brand at all. */}\n <span\n className=\"eidos-navigation__brand-name\"\n aria-hidden={brand.onClick ? true : undefined}\n >\n {brand.name}\n </span>\n </>\n )}\n </div>\n\n <ul className=\"eidos-navigation__items\">\n {items.map((item) => (\n <li key={item.id} className=\"eidos-navigation__item-wrapper\">\n {/* Always wrapped (disabled rather than omitted while expanded)\n so the button underneath is never unmounted/remounted across\n a collapse toggle - that would otherwise reset its own CSS\n transitions (gap, padding, justify-content) partway through\n the rail's width animation, snapping instead of easing. */}\n <Tooltip message={item.label} placement=\"right\" disabled={!collapsed}>\n <button\n type=\"button\"\n className={[\n 'eidos-navigation__item',\n item.active && 'eidos-navigation__item--active',\n ]\n .filter(Boolean)\n .join(' ')}\n disabled={item.disabled}\n onClick={item.onClick}\n aria-current={item.active ? 'page' : undefined}\n // The label fades out visually while collapsed (see\n // `.eidos-navigation__item-label` in Navigation.scss) but\n // isn't removed from the DOM, so it's given directly as the\n // accessible name here instead of relying on the (also\n // fading) visible text, and hidden from assistive tech below\n // to avoid it being announced twice alongside the `Tooltip`.\n aria-label={collapsed ? item.label : undefined}\n >\n {item.icon && renderIcon(item.icon, 'eidos-navigation__item-icon')}\n <span className=\"eidos-navigation__item-label\" aria-hidden={collapsed || undefined}>\n {item.label}\n </span>\n </button>\n </Tooltip>\n </li>\n ))}\n </ul>\n\n {footer && <div className=\"eidos-navigation__footer\">{footer}</div>}\n\n {/* Floats half in/half out of the rail's right edge (see `&__toggle`\n in Navigation.scss) rather than sitting in its own row - a\n dedicated row reserved space in the flex column even when there\n were too few items to need it.\n\n The positioning has to live on this wrapping `<span>`, not on the\n `IconButton` itself: its `tooltip` prop makes `Button` wrap it in\n `Tooltip`'s own `.eidos-tooltip-trigger` div, which - not the\n button - is the actual flex child of `.eidos-navigation`. Removing\n only the inner button from flow left that outer wrapper still\n in-flow, still consuming space and still getting `gap` applied\n around it, which is exactly why a gap remained. */}\n {collapsible && (\n <span className=\"eidos-navigation__toggle\">\n <IconButton\n icon={collapsed ? SquareChevronRight : SquareChevronLeft}\n variant=\"text\"\n color=\"secondary\"\n size=\"sm\"\n tooltip={collapsed ? 'Expand navigation' : 'Collapse navigation'}\n aria-label={collapsed ? 'Expand navigation' : 'Collapse navigation'}\n onClick={toggleCollapsed}\n />\n </span>\n )}\n </nav>\n );\n};\n\nNavigation.displayName = 'Navigation';\n"]}
|
|
1
|
+
{"version":3,"sources":["/home/runner/work/eidos-ui/eidos-ui/dist/chunk-F5IRMMZ2.cjs","../src/components/Navigation/Navigation.component.tsx"],"names":[],"mappings":"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","file":"/home/runner/work/eidos-ui/eidos-ui/dist/chunk-F5IRMMZ2.cjs","sourcesContent":[null,"import React, { useCallback, useEffect, useRef, useState } from 'react';\nimport { SquareChevronLeft, SquareChevronRight } from 'lucide-react';\nimport type { NavigationLogo, NavigationProps } from './Navigation.types';\nimport { Avatar } from '../Avatar';\nimport { IconButton } from '../Button';\nimport { Tooltip } from '../Tooltip';\nimport { renderIcon } from '../../utils';\nimport './Navigation.scss';\n\n/**\n * Renders a custom brand logo, guaranteeing correct aspect-ratio rendering\n * regardless of whether the source image is vertical, horizontal, or square\n * - and regardless of how much width is actually available, expanded or\n * collapsed. Deliberately no JS sizing/measurement at all: a fixed `height`,\n * `width: auto` (derived from the image's own intrinsic ratio), a `max-width`\n * expressed as `min(72px, 100%)` (see `.eidos-navigation__brand-logo` in\n * Navigation.scss) so it never renders wider than whatever space its\n * container - the rail, expanded or collapsed - actually has, and\n * `object-fit: contain` so it's letterboxed rather than distorted if that\n * ever clamps it below its natural width-at-32px-tall. Centering is handled\n * separately, at the row level - see `&__brand--logo-only` in Navigation.scss.\n */\nconst NavigationBrandLogo: React.FC<{ logo: NavigationLogo }> = ({ logo }) => (\n <img src={logo.src} alt={logo.alt} className=\"eidos-navigation__brand-logo\" />\n);\n\nexport const Navigation: React.FC<NavigationProps> = ({\n brand,\n items,\n footer,\n collapsed: collapsedProp,\n defaultCollapsed = false,\n onCollapsedChange,\n collapseBelow = 768,\n collapsible = true,\n className = '',\n}) => {\n // ── Controlled / uncontrolled collapsed state ─────────────────────────────\n // Mirrors CommandPalette's `open`/`defaultOpen` pattern - omitting\n // `collapsed` lets Navigation own its state entirely, while passing it\n // (+ `onCollapsedChange`) keeps full external control for consumers who\n // need to persist the preference or drive it from a responsive breakpoint.\n const isControlled = collapsedProp !== undefined;\n const [internalCollapsed, setInternalCollapsed] = useState(defaultCollapsed);\n const collapsed = isControlled ? collapsedProp : internalCollapsed;\n\n // Shared by the manual toggle button and `collapseBelow` below - uncontrolled\n // flips the internal state directly, controlled defers to `onCollapsedChange`\n // since Navigation can't change `collapsed` itself.\n const applyCollapsed = useCallback(\n (next: boolean) => {\n if (!isControlled) setInternalCollapsed(next);\n onCollapsedChange?.(next);\n },\n [isControlled, onCollapsedChange],\n );\n\n const toggleCollapsed = useCallback(() => {\n applyCollapsed(!collapsed);\n }, [applyCollapsed, collapsed]);\n\n // Read by the breakpoint effect below so it does not depend on\n // `applyCollapsed`'s identity. A consumer passing an inline\n // `onCollapsedChange` gives that callback a new identity every render,\n // which would re-run the effect - and re-apply the media query's answer -\n // on every render, overriding any manual toggle made in between crossings.\n // That is the one thing `collapseBelow` is documented not to do.\n const applyCollapsedRef = useRef(applyCollapsed);\n useEffect(() => {\n applyCollapsedRef.current = applyCollapsed;\n });\n\n // Auto-collapse/expand at a viewport breakpoint. `matchMedia`'s `change`\n // event only fires exactly at the crossing point, not on every resize\n // tick, so a manual toggle in between crossings is left alone until the\n // viewport actually crosses the breakpoint again.\n useEffect(() => {\n // `0` opts out, as documented - and it has to be checked here rather\n // than relying on `(max-width: 0px)` never matching, because the mount\n // pass below would otherwise still run.\n if (!collapseBelow) return;\n if (typeof window === 'undefined' || !window.matchMedia) return;\n\n const query = window.matchMedia(`(max-width: ${collapseBelow}px)`);\n\n // On mount this may only *collapse*, never expand. `defaultCollapsed`\n // (or a controlled `collapsed`) is the consumer's stated starting point,\n // and applying `query.matches` unconditionally threw it away one commit\n // after the first paint: on any viewport wider than the breakpoint the\n // rail visibly started collapsed and then sprang open. Crossings below\n // still drive both directions, which is what \"collapses and re-expands\"\n // refers to.\n if (query.matches) applyCollapsedRef.current(true);\n\n const handleChange = (event: MediaQueryListEvent) => applyCollapsedRef.current(event.matches);\n query.addEventListener('change', handleChange);\n return () => query.removeEventListener('change', handleChange);\n }, [collapseBelow]);\n\n const classes = ['eidos-navigation', collapsed && 'eidos-navigation--collapsed', className]\n .filter(Boolean)\n .join(' ');\n\n // A `logo` brand has no `name` text alongside it (see the discriminated\n // union in Navigation.types.ts), so there's never a second, variable-width\n // sibling competing for space - unlike the `name` variant, it's always\n // safe to just center it outright, in both expanded and collapsed states,\n // with nothing further to compute. See `&__brand--logo-only` in\n // Navigation.scss.\n const brandClasses = [\n 'eidos-navigation__brand',\n brand.logo && 'eidos-navigation__brand--logo-only',\n brand.onClick && 'eidos-navigation__brand--clickable',\n ]\n .filter(Boolean)\n .join(' ');\n\n const brandAccessibleName = brand.logo ? brand.logo.alt : brand.name;\n\n return (\n <nav className={classes} aria-label=\"Main\">\n <div\n className={brandClasses}\n onClick={brand.onClick}\n role={brand.onClick ? 'button' : undefined}\n tabIndex={brand.onClick ? 0 : undefined}\n // Only a real interactive control (role=\"button\") reliably exposes\n // `aria-label` as its accessible name - a plain, non-interactive div\n // doesn't, so the visible (if currently faded) text remains the only\n // way assistive tech gets the brand name in that case.\n aria-label={brand.onClick ? brandAccessibleName : undefined}\n onKeyDown={\n brand.onClick\n ? (e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n brand.onClick?.();\n }\n }\n : undefined\n }\n >\n {brand.logo ? (\n <NavigationBrandLogo logo={brand.logo} />\n ) : (\n <>\n <Avatar name={brand.name} shape=\"square\" size=\"sm\" />\n {/* Only redundant with the wrapper's own `aria-label` when\n `brand.onClick` is set (see the note on it above) - otherwise\n this is the only accessible text for the brand at all. */}\n <span\n className=\"eidos-navigation__brand-name\"\n aria-hidden={brand.onClick ? true : undefined}\n >\n {brand.name}\n </span>\n </>\n )}\n </div>\n\n <ul className=\"eidos-navigation__items\">\n {items.map((item) => (\n <li key={item.id} className=\"eidos-navigation__item-wrapper\">\n {/* Always wrapped (disabled rather than omitted while expanded)\n so the button underneath is never unmounted/remounted across\n a collapse toggle - that would otherwise reset its own CSS\n transitions (gap, padding, justify-content) partway through\n the rail's width animation, snapping instead of easing. */}\n <Tooltip message={item.label} placement=\"right\" disabled={!collapsed}>\n <button\n type=\"button\"\n className={[\n 'eidos-navigation__item',\n item.active && 'eidos-navigation__item--active',\n ]\n .filter(Boolean)\n .join(' ')}\n disabled={item.disabled}\n onClick={item.onClick}\n aria-current={item.active ? 'page' : undefined}\n // The label fades out visually while collapsed (see\n // `.eidos-navigation__item-label` in Navigation.scss) but\n // isn't removed from the DOM, so it's given directly as the\n // accessible name here instead of relying on the (also\n // fading) visible text, and hidden from assistive tech below\n // to avoid it being announced twice alongside the `Tooltip`.\n aria-label={collapsed ? item.label : undefined}\n >\n {item.icon && renderIcon(item.icon, 'eidos-navigation__item-icon')}\n <span className=\"eidos-navigation__item-label\" aria-hidden={collapsed || undefined}>\n {item.label}\n </span>\n </button>\n </Tooltip>\n </li>\n ))}\n </ul>\n\n {footer && <div className=\"eidos-navigation__footer\">{footer}</div>}\n\n {/* Floats half in/half out of the rail's right edge (see `&__toggle`\n in Navigation.scss) rather than sitting in its own row - a\n dedicated row reserved space in the flex column even when there\n were too few items to need it.\n\n The positioning has to live on this wrapping `<span>`, not on the\n `IconButton` itself: its `tooltip` prop makes `Button` wrap it in\n `Tooltip`'s own `.eidos-tooltip-trigger` div, which - not the\n button - is the actual flex child of `.eidos-navigation`. Removing\n only the inner button from flow left that outer wrapper still\n in-flow, still consuming space and still getting `gap` applied\n around it, which is exactly why a gap remained. */}\n {collapsible && (\n <span className=\"eidos-navigation__toggle\">\n <IconButton\n icon={collapsed ? SquareChevronRight : SquareChevronLeft}\n variant=\"text\"\n color=\"secondary\"\n size=\"sm\"\n tooltip={collapsed ? 'Expand navigation' : 'Collapse navigation'}\n aria-label={collapsed ? 'Expand navigation' : 'Collapse navigation'}\n onClick={toggleCollapsed}\n />\n </span>\n )}\n </nav>\n );\n};\n\nNavigation.displayName = 'Navigation';\n"]}
|
|
@@ -13,33 +13,33 @@ import {
|
|
|
13
13
|
subscribeToFontLoads,
|
|
14
14
|
toFontStack,
|
|
15
15
|
useTheme
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-Z3IJWYUD.js";
|
|
17
17
|
import {
|
|
18
18
|
Slider
|
|
19
19
|
} from "./chunk-2BC4M4QZ.js";
|
|
20
20
|
import {
|
|
21
21
|
Select
|
|
22
|
-
} from "./chunk-
|
|
22
|
+
} from "./chunk-4S57PE43.js";
|
|
23
23
|
import {
|
|
24
24
|
Card
|
|
25
25
|
} from "./chunk-EF4Y6Q35.js";
|
|
26
26
|
import {
|
|
27
27
|
ColorPicker
|
|
28
|
-
} from "./chunk-
|
|
28
|
+
} from "./chunk-L6YJ6QTZ.js";
|
|
29
29
|
import {
|
|
30
30
|
Alert
|
|
31
|
-
} from "./chunk-
|
|
31
|
+
} from "./chunk-6FXFKMJ5.js";
|
|
32
32
|
import {
|
|
33
33
|
Button,
|
|
34
34
|
IconButton
|
|
35
|
-
} from "./chunk-
|
|
35
|
+
} from "./chunk-JY77VJAZ.js";
|
|
36
36
|
import {
|
|
37
37
|
Tooltip
|
|
38
|
-
} from "./chunk-
|
|
38
|
+
} from "./chunk-MCPGI6EI.js";
|
|
39
39
|
|
|
40
40
|
// src/components/ThemeEditor/ThemeEditor.component.tsx
|
|
41
41
|
import { useCallback, useEffect, useMemo, useReducer, useRef, useState } from "react";
|
|
42
|
-
import { CircleCheck, CircleX, TriangleAlert } from "lucide-react";
|
|
42
|
+
import { CircleCheck, CircleX, RotateCcw, TriangleAlert, Upload } from "lucide-react";
|
|
43
43
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
44
44
|
var PAGE_SURFACE = CONTRAST_LIGHT;
|
|
45
45
|
var EDGE_MIN_RATIO = 1.5;
|
|
@@ -184,7 +184,7 @@ var FontRow = ({
|
|
|
184
184
|
variant: "text",
|
|
185
185
|
color: "secondary",
|
|
186
186
|
size: "sm",
|
|
187
|
-
preIcon:
|
|
187
|
+
preIcon: Upload,
|
|
188
188
|
onClick: () => inputRef.current?.click(),
|
|
189
189
|
tooltip: "Load a font file to use it right away. Not saved - see onFontUpload to persist it.",
|
|
190
190
|
children: "Upload"
|
|
@@ -307,7 +307,7 @@ var ThemeEditor = ({
|
|
|
307
307
|
/* @__PURE__ */ jsx("div", { className: "eidos-theme-editor-row__actions", children: /* @__PURE__ */ jsx(
|
|
308
308
|
IconButton,
|
|
309
309
|
{
|
|
310
|
-
icon:
|
|
310
|
+
icon: RotateCcw,
|
|
311
311
|
variant: "text",
|
|
312
312
|
color: "secondary",
|
|
313
313
|
size: "sm",
|
|
@@ -398,4 +398,4 @@ ThemeEditor.displayName = "ThemeEditor";
|
|
|
398
398
|
export {
|
|
399
399
|
ThemeEditor
|
|
400
400
|
};
|
|
401
|
-
//# sourceMappingURL=chunk-
|
|
401
|
+
//# sourceMappingURL=chunk-FE7S4RSK.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/ThemeEditor/ThemeEditor.component.tsx"],"sourcesContent":["import React, { useCallback, useEffect, useMemo, useReducer, useRef, useState } from 'react';\nimport { CircleCheck, CircleX, RotateCcw, TriangleAlert, Upload } from 'lucide-react';\nimport { Alert } from '../Alert';\nimport { Button, IconButton } from '../Button';\nimport { Card } from '../Card';\nimport { ColorPicker } from '../ColorPicker';\nimport { Select } from '../Select';\nimport { Slider } from '../Slider';\nimport { Tooltip } from '../Tooltip';\nimport { useTheme } from '../ThemeProvider';\nimport type { ThemeColorKey, ThemeFontOption } from '../ThemeProvider';\nimport {\n THEME_COLOR_KEYS,\n FONT_SCALE_MAX,\n FONT_SCALE_MIN,\n defaultTheme,\n} from '../ThemeProvider/ThemeProvider.tokens';\nimport {\n CONTRAST_DARK,\n CONTRAST_LIGHT,\n contrastRatio,\n pickContrast,\n} from '../ThemeProvider/ThemeProvider.color';\nimport {\n FONT_ACCEPT,\n isFontStackAvailable,\n registerFontFile,\n subscribeToFontLoads,\n toFontStack,\n} from '../ThemeProvider/ThemeProvider.fonts';\nimport type { ThemeEditorProps } from './ThemeEditor.types';\n\n/** The page surface every diagnostic is measured against - `--white`. */\nconst PAGE_SURFACE = CONTRAST_LIGHT;\n\n/** Below this, a fill is effectively invisible against the page behind it. */\nconst EDGE_MIN_RATIO = 1.5;\n\nconst COLOR_LABELS: Record<ThemeColorKey, string> = {\n primary: 'Primary',\n secondary: 'Secondary',\n success: 'Success',\n danger: 'Danger',\n warning: 'Warning',\n info: 'Info',\n hyperlink: 'Hyperlink',\n};\n\n/** `hyperlink` is only ever text on a surface, so it is graded differently. */\nconst isFill = (key: ThemeColorKey): boolean => key !== 'hyperlink';\n\n/**\n * Built-in stacks, deliberately limited to fonts that can be relied on.\n *\n * A dropdown implies its entries are available, but a font stack is only a list\n * of *names* - nothing here can install a font. So the list is restricted to\n * generic families (guaranteed by CSS), `system-ui` (whatever the OS provides),\n * and the handful of genuinely web-safe faces. Fonts like Inter, which are not\n * installed anywhere by default, were removed: offering one is offering a\n * choice that silently does nothing on most machines.\n *\n * The preset is included because it is the shipped default and therefore has to\n * be representable - and note that `eidos-ui` does not ship the Plus Jakarta\n * Sans file either, so it renders only where the consumer provides it. That is\n * exactly why unavailable options are labelled as such.\n *\n * Anything beyond this belongs to the consuming app, via `fontOptions`.\n */\nconst FONT_STACKS: ThemeFontOption[] = [\n // Taken from the preset rather than retyped, so the shipped default always\n // matches an option exactly. A hand-copied shorter stack did not match, and\n // the row fell back to showing a synthetic \"custom\" entry instead of the\n // name of the font actually in use.\n { label: 'Plus Jakarta Sans (theme default)', value: defaultTheme.typography.fontFamily! },\n { label: 'System UI', value: \"system-ui, -apple-system, 'Segoe UI', sans-serif\" },\n { label: 'Helvetica / Arial', value: 'Helvetica, Arial, sans-serif' },\n { label: 'Georgia', value: \"Georgia, 'Times New Roman', serif\" },\n { label: 'Sans-serif (generic)', value: 'sans-serif' },\n { label: 'Serif (generic)', value: 'serif' },\n];\n\nconst MONO_STACKS: ThemeFontOption[] = [\n { label: 'JetBrains Mono (theme default)', value: defaultTheme.typography.monoFamily! },\n { label: 'Menlo / Consolas', value: 'Menlo, Consolas, monospace' },\n { label: 'Courier New', value: \"'Courier New', Courier, monospace\" },\n { label: 'Monospace (generic)', value: 'monospace' },\n];\n\ntype Grade = 'aa' | 'aa-large' | 'fail';\n\nconst gradeFor = (ratio: number): Grade => (ratio >= 4.5 ? 'aa' : ratio >= 3 ? 'aa-large' : 'fail');\n\n/** Spelled out for the middle grade, which is the one that misleads. */\nconst GRADE_CAVEAT: Partial<Record<Grade, string>> = {\n 'aa-large':\n ' WCAG AA needs 4.5:1 for normal text and allows 3:1 only at 24px or larger - button and label text here is around 12px, so this does not pass.',\n fail: ' Below 3:1, which fails WCAG AA at every text size.',\n};\n\n/**\n * Severity is carried by an icon and the label text, not by colour.\n *\n * These badges cannot use `Pill`, or any themed `--x-color`: the theme being\n * edited also styles this editor, so a washed-out `success` colour would render\n * the \"passes AA\" badge illegible at precisely the moment it is reporting that\n * a colour is illegible. The badge styling comes from the gray ramp, which is\n * deliberately not themeable.\n *\n * Not relying on colour alone also satisfies WCAG 1.4.1 (Use of Colour).\n */\nconst GRADE_BADGE: Record<\n Grade,\n { label: string; icon: React.ComponentType<{ className?: string }> }\n> = {\n aa: { label: 'AA', icon: CircleCheck },\n // Named for what it means in practice, not just for the threshold it clears.\n // WCAG's relaxed 3:1 tier applies only to text at 24px (or 18.7px bold) and\n // above, and nothing in this library is that large - `--font-size-sm` is\n // ~12.25px at the default root size. A bare \"AA large only\" reads as a pass\n // when for every component here it is a fail.\n 'aa-large': { label: 'Too low for body text', icon: TriangleAlert },\n fail: { label: 'Fails AA', icon: CircleX },\n};\n\ninterface Diagnostic {\n grade: Grade;\n ratio: number;\n /** What the ratio describes, for the tooltip. */\n detail: string;\n /** Set when the fill is too close to the page surface to be seen. */\n edgeWarning?: string;\n}\n\nconst diagnose = (key: ThemeColorKey, base: string, explicitContrast?: string): Diagnostic => {\n if (!isFill(key)) {\n // Link text sits on the page, so the page is what it must contrast with.\n const ratio = contrastRatio(base, PAGE_SURFACE);\n const grade = gradeFor(ratio);\n return {\n grade,\n ratio,\n detail: `Link text on the page background: ${ratio.toFixed(2)}:1 against white.${GRADE_CAVEAT[grade] ?? ''}`,\n };\n }\n\n const foreground = explicitContrast ?? pickContrast(base);\n const ratio = contrastRatio(base, foreground);\n const name = foreground.toLowerCase() === CONTRAST_DARK ? 'dark' : 'white';\n const edge = contrastRatio(base, PAGE_SURFACE);\n\n const grade = gradeFor(ratio);\n\n return {\n grade,\n ratio,\n detail: `${name === 'white' ? 'White' : 'Near-black'} text on this fill is ${ratio.toFixed(2)}:1.${\n explicitContrast ? ' Foreground pinned via the theme.' : ''\n }${GRADE_CAVEAT[grade] ?? ''}`,\n edgeWarning:\n edge < EDGE_MIN_RATIO\n ? `Only ${edge.toFixed(2)}:1 against the page background - this fill is barely distinguishable from the page it sits on.`\n : undefined,\n };\n};\n\ninterface FontRowProps {\n label: string;\n /** Stack currently applied, used to pick the matching option. */\n value: string;\n options: ThemeFontOption[];\n mono: boolean;\n allowUpload: boolean;\n onChange: (stack: string) => void;\n onUploaded: (option: ThemeFontOption, file: File, family: string) => void;\n}\n\n/** Pulls the first family out of a stack, unquoted. */\nconst firstFamily = (stack: string): string =>\n stack\n .split(',')[0]\n ?.trim()\n .replace(/^['\"]|['\"]$/g, '') || 'Custom';\n\n/**\n * One font row: a `Select` over the known stacks, an optional upload, and an\n * availability warning.\n *\n * Uses `Select` rather than `Combobox` deliberately. `Combobox` filters its\n * options against the text in the field, and the field holds a full font stack\n * (`'Plus Jakarta Sans', -apple-system, …`) which matches no option label - so\n * the list read \"No results found\" until the text was cleared by hand. A font\n * is a choice from a known set, not a search.\n */\nconst FontRow: React.FC<FontRowProps> = ({\n label,\n value,\n options,\n mono,\n allowUpload,\n onChange,\n onUploaded,\n}) => {\n const inputRef = useRef<HTMLInputElement>(null);\n const [error, setError] = useState<string | null>(null);\n\n // Web fonts load asynchronously, so the first render always sees them as\n // unavailable. Without re-checking once they arrive, the row would sit on a\n // stale \"not installed\" warning for a font that is rendering perfectly.\n // The reducer exists only to schedule that re-render; its value is unused.\n const [, onFontsLoaded] = useReducer((count: number) => count + 1, 0);\n useEffect(() => subscribeToFontLoads(onFontsLoaded), [onFontsLoaded]);\n\n const baseOptions = useMemo(() => {\n // A stack the theme carries but that isn't in the list (loaded by the host\n // app, or set programmatically) still needs to be selectable, labelled with\n // its own first family so the row names the font actually in use.\n const known = options.some((o) => o.value === value);\n return known ? options : [...options, { label: `${firstFamily(value)} (custom)`, value }];\n }, [options, value]);\n\n // Probed on every render rather than memoised: availability changes over time\n // as fonts load, so a cached answer is a wrong answer. Four canvas\n // measurements are far cheaper than getting this wrong.\n //\n // Availability is annotated per option rather than filtered or disabled. A\n // theme is shared across machines, so a font present here may be absent for\n // the next user - and vice versa, which would mean hiding a font someone\n // legitimately wants. Annotating keeps every choice selectable while making\n // the list stop implying that a name is a guarantee.\n const selectOptions = baseOptions.map((option) => ({\n id: option.value,\n label: isFontStackAvailable(option.value) ? option.label : `${option.label} - not installed`,\n value: option.value,\n }));\n\n const handleFile = useCallback(\n async (file: File | undefined) => {\n if (!file) return;\n setError(null);\n try {\n const family = await registerFontFile(file);\n const stack = toFontStack(family, mono);\n onUploaded({ label: `${family} (this session)`, value: stack }, file, family);\n onChange(stack);\n } catch (cause) {\n setError(\n cause instanceof Error ? cause.message : 'That file could not be loaded as a font.',\n );\n }\n },\n [mono, onChange, onUploaded],\n );\n\n const unavailable = !isFontStackAvailable(value);\n\n return (\n <div className=\"eidos-theme-editor-row eidos-theme-editor-row--wide\">\n <span className=\"eidos-theme-editor-row__label\">{label}</span>\n\n <div className=\"eidos-theme-editor-row__control\">\n <Select\n options={selectOptions}\n value={value}\n onChange={(next) => onChange(Array.isArray(next) ? next[0] : next)}\n fullWidth\n // The row's visible label is a `<span>`, not a `<label htmlFor>`,\n // so nothing associates it with the control. Naming the input\n // directly keeps the two in step without restructuring the row.\n inputProps={{ 'aria-label': label }}\n />\n </div>\n\n {/* Occasional - lives before the action so it can never displace it. */}\n <div className=\"eidos-theme-editor-row__diagnostics\">\n {unavailable && (\n <Tooltip\n message={`${firstFamily(value)} isn't available here, so the browser is rendering the next family in the stack instead. Upload the file, or have your app serve it, to use it.`}\n >\n <span className=\"eidos-theme-editor-badge eidos-theme-editor-badge--aa-large\">\n <TriangleAlert className=\"eidos-theme-editor-badge__icon\" />\n Not installed\n </span>\n </Tooltip>\n )}\n {error && (\n <Tooltip message={error}>\n <span className=\"eidos-theme-editor-badge eidos-theme-editor-badge--fail\">\n <CircleX className=\"eidos-theme-editor-badge__icon\" />\n Upload failed\n </span>\n </Tooltip>\n )}\n </div>\n\n {allowUpload && (\n <div className=\"eidos-theme-editor-row__actions\">\n <Button\n variant=\"text\"\n color=\"secondary\"\n size=\"sm\"\n preIcon={Upload}\n onClick={() => inputRef.current?.click()}\n tooltip=\"Load a font file to use it right away. Not saved - see onFontUpload to persist it.\"\n >\n Upload\n </Button>\n {/* Plain input rather than FileUpload: this is a single inline\n action in a dense row, not a drop zone. */}\n <input\n ref={inputRef}\n type=\"file\"\n accept={FONT_ACCEPT}\n // Same proxy pattern as `MessageComposer` - see the note there.\n className=\"eidos-theme-editor-file\"\n tabIndex={-1}\n aria-hidden=\"true\"\n onChange={(event) => {\n void handleFile(event.target.files?.[0]);\n // Allow re-picking the same file after a failure.\n event.target.value = '';\n }}\n />\n </div>\n )}\n </div>\n );\n};\n\n/**\n * Live editor for the active `ThemeProvider` theme.\n *\n * Renders no preview of its own: the provider writes tokens to\n * `document.documentElement`, so the surrounding page is the preview.\n *\n * Contrast readouts are diagnostics only - a colour that fails is still\n * applied. Automatically \"correcting\" a chosen colour would mean silently\n * rendering something other than what was picked.\n */\nexport const ThemeEditor: React.FC<ThemeEditorProps> = ({\n colors = THEME_COLOR_KEYS as ThemeColorKey[],\n fontOptions = FONT_STACKS,\n monoFontOptions = MONO_STACKS,\n allowFontUpload = true,\n onFontUpload,\n hideTypography = false,\n hideReset = false,\n hideCssExport = false,\n className,\n}) => {\n const { theme, resolvedTheme, setTheme, updateTheme, resetTheme, isDefault, toCss } = useTheme();\n const [copied, setCopied] = useState(false);\n\n // Fonts registered through the upload control this session. Kept local\n // because font *data* cannot live in a ThemeConfig - see the .mdx.\n const [uploaded, setUploaded] = useState<ThemeFontOption[]>([]);\n const [monoUploaded, setMonoUploaded] = useState<ThemeFontOption[]>([]);\n\n const setColor = useCallback(\n (key: ThemeColorKey, hex: string) => {\n const current = theme.colors?.[key];\n // Only the base is written here. A `contrast` pinned in the theme is\n // preserved rather than dropped, since the editor never sets one.\n const pinned = typeof current === 'object' ? current.contrast : undefined;\n updateTheme({ colors: { [key]: pinned ? { base: hex, contrast: pinned } : hex } });\n },\n [theme.colors, updateTheme],\n );\n\n const resetColor = useCallback(\n (key: ThemeColorKey) => {\n // Must go through setTheme, not updateTheme: updateTheme merges, so a key\n // left out of the patch keeps its existing value instead of being removed.\n // Removal is what restores the preset, since resolveTheme fills gaps.\n const nextColors = { ...theme.colors };\n delete nextColors[key];\n setTheme({ ...theme, colors: nextColors });\n },\n [theme, setTheme],\n );\n\n const diagnostics = useMemo(\n () =>\n colors.map((key) => {\n const { base, contrast } = resolvedTheme.colors[key];\n return { key, base, ...diagnose(key, base, contrast) };\n }),\n [colors, resolvedTheme],\n );\n\n const failing = diagnostics.filter((d) => d.grade === 'fail');\n const invisible = diagnostics.filter((d) => d.edgeWarning);\n\n const copyCss = useCallback(() => {\n const css = toCss();\n const done = () => {\n setCopied(true);\n setTimeout(() => setCopied(false), 1600);\n };\n if (navigator.clipboard?.writeText) {\n navigator.clipboard.writeText(css).then(done, done);\n return;\n }\n done();\n }, [toCss]);\n\n return (\n <div className={['eidos-theme-editor', className].filter(Boolean).join(' ')}>\n {(failing.length > 0 || invisible.length > 0) && (\n <Alert variant=\"warning\" title=\"Contrast issues\">\n {failing.length > 0 && (\n <p>\n Cannot reach WCAG AA (4.5:1) with either foreground:{' '}\n {failing.map((d) => COLOR_LABELS[d.key]).join(', ')}.\n </p>\n )}\n {invisible.length > 0 && (\n <p>\n Too close to the page background to read as a filled surface:{' '}\n {invisible.map((d) => COLOR_LABELS[d.key]).join(', ')}.\n </p>\n )}\n </Alert>\n )}\n\n <Card variant=\"outlined\" padding=\"lg\" className=\"eidos-theme-editor-section\">\n <div className=\"eidos-theme-editor-section__header\">\n <span className=\"eidos-theme-editor-section__title\">Colours</span>\n <span className=\"eidos-theme-editor-section__hint\">\n Shades, tints and foregrounds are derived from each base colour.\n </span>\n </div>\n\n <div className=\"eidos-theme-editor-rows\">\n {diagnostics.map(({ key, base, grade, ratio, detail, edgeWarning }) => {\n const badge = GRADE_BADGE[grade];\n const overridden = theme.colors?.[key] !== undefined;\n return (\n <div className=\"eidos-theme-editor-row\" key={key}>\n <span className=\"eidos-theme-editor-row__label\">{COLOR_LABELS[key]}</span>\n\n {/* `md` rather than `sm`: the size drives the panel's\n saturation/brightness canvas, and 120px is cramped for\n picking a lightness precisely. */}\n <ColorPicker\n value={base}\n onChange={(hex) => setColor(key, hex)}\n size=\"md\"\n // The row draws its own visible label, so the picker must\n // not draw a second one - but without a name of its own\n // every picker here announced as \"Open colour picker\" and\n // they were indistinguishable.\n ariaLabel={COLOR_LABELS[key]}\n />\n\n <div className=\"eidos-theme-editor-row__diagnostics\">\n <Tooltip message={detail}>\n <span className={`eidos-theme-editor-badge eidos-theme-editor-badge--${grade}`}>\n <badge.icon className=\"eidos-theme-editor-badge__icon\" />\n {`${ratio.toFixed(2)}:1 ${badge.label}`}\n </span>\n </Tooltip>\n {edgeWarning && (\n <Tooltip message={edgeWarning}>\n <span className=\"eidos-theme-editor-badge eidos-theme-editor-badge--fail\">\n <CircleX className=\"eidos-theme-editor-badge__icon\" />\n Invisible on page\n </span>\n </Tooltip>\n )}\n </div>\n\n <div className=\"eidos-theme-editor-row__actions\">\n <IconButton\n icon={RotateCcw}\n variant=\"text\"\n color=\"secondary\"\n size=\"sm\"\n disabled={!overridden}\n onClick={() => resetColor(key)}\n tooltip={overridden ? `Reset ${COLOR_LABELS[key]} to the preset` : 'Unchanged'}\n aria-label={`Reset ${COLOR_LABELS[key]}`}\n />\n </div>\n </div>\n );\n })}\n </div>\n </Card>\n\n {!hideTypography && (\n <Card variant=\"outlined\" padding=\"lg\" className=\"eidos-theme-editor-section\">\n <div className=\"eidos-theme-editor-section__header\">\n <span className=\"eidos-theme-editor-section__title\">Typography</span>\n <span className=\"eidos-theme-editor-section__hint\">\n A stack only names a font - upload the file to use one the browser doesn't\n already have. Spacing is declared in <code>em</code>, so the scale moves padding with\n the text.\n </span>\n </div>\n\n <div className=\"eidos-theme-editor-rows\">\n <FontRow\n label=\"Body font\"\n value={resolvedTheme.typography.fontFamily}\n options={[...fontOptions, ...uploaded]}\n mono={false}\n allowUpload={allowFontUpload}\n onChange={(fontFamily) => updateTheme({ typography: { fontFamily } })}\n onUploaded={(option, file, family) => {\n setUploaded((prev) => [...prev, option]);\n onFontUpload?.(file, family, false);\n }}\n />\n\n <FontRow\n label=\"Mono font\"\n value={resolvedTheme.typography.monoFamily}\n options={[...monoFontOptions, ...monoUploaded]}\n mono\n allowUpload={allowFontUpload}\n onChange={(monoFamily) => updateTheme({ typography: { monoFamily } })}\n onUploaded={(option, file, family) => {\n setMonoUploaded((prev) => [...prev, option]);\n onFontUpload?.(file, family, true);\n }}\n />\n\n <div className=\"eidos-theme-editor-row eidos-theme-editor-row--wide\">\n <span className=\"eidos-theme-editor-row__label\">Scale</span>\n <div className=\"eidos-theme-editor-row__control\">\n <Slider\n value={resolvedTheme.typography.fontScale}\n min={FONT_SCALE_MIN}\n max={FONT_SCALE_MAX}\n step={0.025}\n showValue\n showMinMax\n unit=\"×\"\n onChange={(value) => updateTheme({ typography: { fontScale: value } })}\n />\n </div>\n </div>\n </div>\n </Card>\n )}\n\n {(!hideReset || !hideCssExport) && (\n <div className=\"eidos-theme-editor-actions\">\n {!hideReset && (\n <Button variant=\"outlined\" color=\"secondary\" disabled={isDefault} onClick={resetTheme}>\n Reset all\n </Button>\n )}\n {!hideCssExport && (\n <Button\n variant=\"outlined\"\n preIcon={copied ? 'Check' : 'Clipboard'}\n onClick={copyCss}\n tooltip=\"Copy the resolved tokens as a :root block you can paste into your own stylesheet\"\n >\n {copied ? 'Copied' : 'Copy as CSS'}\n </Button>\n )}\n </div>\n )}\n </div>\n );\n};\n\nThemeEditor.displayName = 'ThemeEditor';\n"],"mappings":"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","names":["ratio","grade"]}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
2
|
MenuPanel
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-WHQGJHMD.js";
|
|
4
4
|
import {
|
|
5
5
|
Dropdown
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-3X6QVHTD.js";
|
|
7
7
|
import {
|
|
8
8
|
renderIcon
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-U34INRFO.js";
|
|
10
10
|
|
|
11
11
|
// src/components/SplitButton/SplitButton.component.tsx
|
|
12
12
|
import { useCallback } from "react";
|
|
@@ -95,4 +95,4 @@ var SplitButton = ({
|
|
|
95
95
|
export {
|
|
96
96
|
SplitButton
|
|
97
97
|
};
|
|
98
|
-
//# sourceMappingURL=chunk-
|
|
98
|
+
//# sourceMappingURL=chunk-FHOD3FUN.js.map
|
|
@@ -12,16 +12,16 @@ import {
|
|
|
12
12
|
} from "./chunk-3TUCQAYL.js";
|
|
13
13
|
import {
|
|
14
14
|
Chip
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-2TIMJD4K.js";
|
|
16
16
|
import {
|
|
17
17
|
Menu
|
|
18
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-WHQGJHMD.js";
|
|
19
19
|
import {
|
|
20
20
|
Avatar
|
|
21
21
|
} from "./chunk-XJBWFDDE.js";
|
|
22
22
|
import {
|
|
23
23
|
Button
|
|
24
|
-
} from "./chunk-
|
|
24
|
+
} from "./chunk-JY77VJAZ.js";
|
|
25
25
|
|
|
26
26
|
// src/components/Conversation/Chat.component.tsx
|
|
27
27
|
import { useCallback as useCallback3, useMemo } from "react";
|
|
@@ -55,9 +55,11 @@ var useNewMessageIds = (messages, enabled) => {
|
|
|
55
55
|
var BOTTOM_THRESHOLD_PX = 48;
|
|
56
56
|
var useStickToBottom = (messages) => {
|
|
57
57
|
const scrollRef = useRef(null);
|
|
58
|
+
const contentRef = useRef(null);
|
|
58
59
|
const [atBottom, setAtBottom] = useState(true);
|
|
59
60
|
const atBottomRef = useRef(true);
|
|
60
61
|
const lastCount = useRef(messages.length);
|
|
62
|
+
const lastScrollTop = useRef(0);
|
|
61
63
|
const scrollToBottom = useCallback((behavior = "smooth") => {
|
|
62
64
|
const node = scrollRef.current;
|
|
63
65
|
if (!node) return;
|
|
@@ -67,7 +69,11 @@ var useStickToBottom = (messages) => {
|
|
|
67
69
|
const node = scrollRef.current;
|
|
68
70
|
if (!node) return;
|
|
69
71
|
const distance = node.scrollHeight - node.scrollTop - node.clientHeight;
|
|
70
|
-
const
|
|
72
|
+
const movedUp = node.scrollTop < lastScrollTop.current;
|
|
73
|
+
lastScrollTop.current = node.scrollTop;
|
|
74
|
+
let next = atBottomRef.current;
|
|
75
|
+
if (distance <= BOTTOM_THRESHOLD_PX) next = true;
|
|
76
|
+
else if (movedUp) next = false;
|
|
71
77
|
atBottomRef.current = next;
|
|
72
78
|
setAtBottom((current) => current === next ? current : next);
|
|
73
79
|
}, []);
|
|
@@ -80,7 +86,22 @@ var useStickToBottom = (messages) => {
|
|
|
80
86
|
}
|
|
81
87
|
lastCount.current = messages.length;
|
|
82
88
|
}, [messages.length, scrollToBottom]);
|
|
83
|
-
|
|
89
|
+
useEffect(() => {
|
|
90
|
+
const content = contentRef.current;
|
|
91
|
+
if (!content || typeof ResizeObserver === "undefined") return;
|
|
92
|
+
let lastHeight = content.getBoundingClientRect().height;
|
|
93
|
+
let observedCount = lastCount.current;
|
|
94
|
+
const observer = new ResizeObserver(() => {
|
|
95
|
+
const height = content.getBoundingClientRect().height;
|
|
96
|
+
const countChanged = observedCount !== lastCount.current;
|
|
97
|
+
observedCount = lastCount.current;
|
|
98
|
+
if (height > lastHeight && !countChanged && atBottomRef.current) scrollToBottom("auto");
|
|
99
|
+
lastHeight = height;
|
|
100
|
+
});
|
|
101
|
+
observer.observe(content);
|
|
102
|
+
return () => observer.disconnect();
|
|
103
|
+
}, [scrollToBottom]);
|
|
104
|
+
return { scrollRef, contentRef, atBottom, scrollToBottom, handleScroll };
|
|
84
105
|
};
|
|
85
106
|
var useScrollAnchor = (scrollRef, messages) => {
|
|
86
107
|
const previous = useRef({ height: 0, firstId: "", count: 0 });
|
|
@@ -609,7 +630,7 @@ var Chat = ({
|
|
|
609
630
|
ariaLabel = "Conversation",
|
|
610
631
|
className = ""
|
|
611
632
|
}) => {
|
|
612
|
-
const { scrollRef, atBottom, scrollToBottom, handleScroll } = useStickToBottom(messages);
|
|
633
|
+
const { scrollRef, contentRef, atBottom, scrollToBottom, handleScroll } = useStickToBottom(messages);
|
|
613
634
|
const newIds = useNewMessageIds(messages, animateNewMessages);
|
|
614
635
|
useScrollAnchor(scrollRef, messages);
|
|
615
636
|
const loadMoreOnScroll = useLoadMoreOnScrollTop(scrollRef, { hasMore, loadingMore, onLoadMore });
|
|
@@ -669,7 +690,7 @@ var Chat = ({
|
|
|
669
690
|
return nodes;
|
|
670
691
|
};
|
|
671
692
|
return /* @__PURE__ */ jsxs3("div", { className: classNames("eidos-chat", className), children: [
|
|
672
|
-
/* @__PURE__ */
|
|
693
|
+
/* @__PURE__ */ jsx3(
|
|
673
694
|
"div",
|
|
674
695
|
{
|
|
675
696
|
ref: scrollRef,
|
|
@@ -681,7 +702,7 @@ var Chat = ({
|
|
|
681
702
|
"aria-busy": loading,
|
|
682
703
|
"aria-label": ariaLabel,
|
|
683
704
|
tabIndex: 0,
|
|
684
|
-
children: [
|
|
705
|
+
children: /* @__PURE__ */ jsxs3("div", { ref: contentRef, className: "eidos-chat-scroll-content", children: [
|
|
685
706
|
hasMore && /* @__PURE__ */ jsx3("div", { className: "eidos-chat-load-more", children: loadingMore ? /* @__PURE__ */ jsxs3("span", { className: "eidos-chat-loading-more", children: [
|
|
686
707
|
/* @__PURE__ */ jsx3(Spinner, { size: "sm", color: "secondary" }),
|
|
687
708
|
"Loading earlier messages\u2026"
|
|
@@ -705,7 +726,7 @@ var Chat = ({
|
|
|
705
726
|
] }),
|
|
706
727
|
typing.length === 1 ? `${typing[0].name} is typing\u2026` : `${typing.length} people are typing\u2026`
|
|
707
728
|
] })
|
|
708
|
-
]
|
|
729
|
+
] })
|
|
709
730
|
}
|
|
710
731
|
),
|
|
711
732
|
!atBottom && messages.length > 0 && /* @__PURE__ */ jsx3("div", { className: "eidos-chat-jump", children: /* @__PURE__ */ jsx3(
|
|
@@ -886,4 +907,4 @@ export {
|
|
|
886
907
|
Chat,
|
|
887
908
|
CommentThread
|
|
888
909
|
};
|
|
889
|
-
//# sourceMappingURL=chunk-
|
|
910
|
+
//# sourceMappingURL=chunk-GDRLVX2A.js.map
|