eidos-ui 3.3.0 → 3.4.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 +17 -5
- package/dist/{Input.types-XrJTI0JC.d.ts → Input.types-CSDMaZNe.d.ts} +10 -0
- package/dist/{Input.types-DFZNyJGF.d.cts → Input.types-D7-sWq-q.d.cts} +10 -0
- package/dist/{Select.types-CAkT2ACt.d.cts → Select.types-2p-mpaBL.d.cts} +1 -1
- package/dist/{Select.types-B4kDpkGB.d.ts → Select.types-BqaD7bmB.d.ts} +1 -1
- package/dist/alert/index.cjs +5 -5
- package/dist/alert/index.js +4 -4
- package/dist/button/index.cjs +4 -4
- package/dist/button/index.js +3 -3
- package/dist/checkbox/index.cjs +2 -2
- package/dist/checkbox/index.js +1 -1
- package/dist/chip/index.cjs +4 -4
- package/dist/chip/index.js +3 -3
- package/dist/{chunk-RYOQYYDO.js → chunk-22EKNTWJ.js} +9 -5
- package/dist/chunk-22EKNTWJ.js.map +1 -0
- package/dist/{chunk-3E7TKBQI.cjs → chunk-27UANGPW.cjs} +14 -6
- package/dist/chunk-27UANGPW.cjs.map +1 -0
- package/dist/{chunk-CJGFRPAS.cjs → chunk-3QQKWXMV.cjs} +4 -4
- package/dist/chunk-3QQKWXMV.cjs.map +1 -0
- package/dist/{chunk-Q5KQVBQP.cjs → chunk-3S33BIN2.cjs} +18 -16
- package/dist/chunk-3S33BIN2.cjs.map +1 -0
- package/dist/{chunk-ZPDETHQ7.js → chunk-3WV6RTXX.js} +3 -3
- package/dist/{chunk-ZPDETHQ7.js.map → chunk-3WV6RTXX.js.map} +1 -1
- package/dist/chunk-44T4HMFU.js +88 -0
- package/dist/chunk-44T4HMFU.js.map +1 -0
- package/dist/{chunk-3EPND5M2.cjs → chunk-4LET2PEX.cjs} +12 -12
- package/dist/chunk-4LET2PEX.cjs.map +1 -0
- package/dist/{chunk-R4M6SNUU.cjs → chunk-5E4DYTZ3.cjs} +48 -37
- package/dist/chunk-5E4DYTZ3.cjs.map +1 -0
- package/dist/{chunk-I5XR2V4A.cjs → chunk-5V7DXZWT.cjs} +79 -76
- package/dist/chunk-5V7DXZWT.cjs.map +1 -0
- package/dist/{chunk-6CPCNQKV.js → chunk-67EXHO4T.js} +2 -2
- package/dist/{chunk-K7T25Y3A.cjs → chunk-6LCYO2HG.cjs} +10 -9
- package/dist/chunk-6LCYO2HG.cjs.map +1 -0
- package/dist/{chunk-ZNWIHUHZ.cjs → chunk-7KVXXHFX.cjs} +9 -3
- package/dist/chunk-7KVXXHFX.cjs.map +1 -0
- package/dist/{chunk-55J4LEKT.cjs → chunk-AHVDTWVM.cjs} +11 -8
- package/dist/chunk-AHVDTWVM.cjs.map +1 -0
- package/dist/{chunk-OAPOGYA5.cjs → chunk-AXPEJ5IG.cjs} +7 -4
- package/dist/chunk-AXPEJ5IG.cjs.map +1 -0
- package/dist/{chunk-GDQWSCJQ.js → chunk-BBU7QG7L.js} +4 -4
- package/dist/{chunk-T2KB3DJJ.js → chunk-BGBAZMFE.js} +9 -3
- package/dist/chunk-BGBAZMFE.js.map +1 -0
- package/dist/{chunk-EH42ND5Q.cjs → chunk-BIANFFJL.cjs} +5 -5
- package/dist/{chunk-EH42ND5Q.cjs.map → chunk-BIANFFJL.cjs.map} +1 -1
- package/dist/{chunk-O2AACVSF.js → chunk-BO4LTIJI.js} +3 -3
- package/dist/{chunk-G5N3C6AU.cjs → chunk-CBT3TTQR.cjs} +36 -36
- package/dist/{chunk-G5N3C6AU.cjs.map → chunk-CBT3TTQR.cjs.map} +1 -1
- package/dist/{chunk-JRLUZDKA.js → chunk-CEC3GO4R.js} +20 -7
- package/dist/chunk-CEC3GO4R.js.map +1 -0
- package/dist/{chunk-BNVQ34FD.js → chunk-CP335H4Q.js} +4 -4
- package/dist/{chunk-H6CWTMAH.js → chunk-DGXHR6FV.js} +5 -2
- package/dist/chunk-DGXHR6FV.js.map +1 -0
- package/dist/{chunk-OU7DCYIA.js → chunk-DMOZURHV.js} +2 -2
- package/dist/{chunk-L5W2XC6M.js → chunk-EWTMX4DK.js} +8 -8
- package/dist/{chunk-SXGCRHBZ.js → chunk-FDMYDIGI.js} +8 -6
- package/dist/chunk-FDMYDIGI.js.map +1 -0
- package/dist/{chunk-AOGNTG3W.cjs → chunk-FODRHCRP.cjs} +5 -4
- package/dist/chunk-FODRHCRP.cjs.map +1 -0
- package/dist/{chunk-E7FGY7BJ.js → chunk-FPLX5FIK.js} +4 -4
- package/dist/{chunk-NEYLNRVG.cjs → chunk-FXMRDNR6.cjs} +21 -16
- package/dist/chunk-FXMRDNR6.cjs.map +1 -0
- package/dist/{chunk-VXO2MYYH.cjs → chunk-G74DHVHV.cjs} +9 -9
- package/dist/{chunk-VXO2MYYH.cjs.map → chunk-G74DHVHV.cjs.map} +1 -1
- package/dist/{chunk-O3LG7B2J.cjs → chunk-GMDVW76A.cjs} +13 -5
- package/dist/chunk-GMDVW76A.cjs.map +1 -0
- package/dist/{chunk-NQ4L6PYW.js → chunk-GOF6A4M4.js} +2 -2
- package/dist/{chunk-NQ4L6PYW.js.map → chunk-GOF6A4M4.js.map} +1 -1
- package/dist/{chunk-TQGO5WK6.js → chunk-GPK2THIG.js} +7 -6
- package/dist/chunk-GPK2THIG.js.map +1 -0
- package/dist/{chunk-HYDNZXPU.js → chunk-H2RS6Z6Q.js} +41 -25
- package/dist/{chunk-HYDNZXPU.js.map → chunk-H2RS6Z6Q.js.map} +1 -1
- package/dist/{chunk-OJDYTCMO.cjs → chunk-H5D3ZFBM.cjs} +68 -61
- package/dist/chunk-H5D3ZFBM.cjs.map +1 -0
- package/dist/{chunk-MHZIBV2C.js → chunk-IXVM2XNS.js} +7 -6
- package/dist/chunk-IXVM2XNS.js.map +1 -0
- package/dist/{chunk-MCWTQT3M.cjs → chunk-JKBBHAIC.cjs} +21 -20
- package/dist/chunk-JKBBHAIC.cjs.map +1 -0
- package/dist/{chunk-QQIALSTX.cjs → chunk-KPMIIGHH.cjs} +27 -17
- package/dist/chunk-KPMIIGHH.cjs.map +1 -0
- package/dist/{chunk-QJRKXT54.cjs → chunk-KWDOOMHR.cjs} +7 -7
- package/dist/{chunk-QJRKXT54.cjs.map → chunk-KWDOOMHR.cjs.map} +1 -1
- package/dist/{chunk-HALVTKW7.js → chunk-LH5A2SIX.js} +78 -75
- package/dist/{chunk-HALVTKW7.js.map → chunk-LH5A2SIX.js.map} +1 -1
- package/dist/{chunk-27ZWUEPE.js → chunk-LIKSLFX6.js} +20 -9
- package/dist/chunk-LIKSLFX6.js.map +1 -0
- package/dist/{chunk-Z5U4NJTW.cjs → chunk-MLUHM3VG.cjs} +48 -19
- package/dist/chunk-MLUHM3VG.cjs.map +1 -0
- package/dist/{chunk-M7PF4FKQ.js → chunk-MP7LN5CW.js} +6 -3
- package/dist/chunk-MP7LN5CW.js.map +1 -0
- package/dist/{chunk-ACNTH2OQ.cjs → chunk-MW4YZVP5.cjs} +96 -97
- package/dist/chunk-MW4YZVP5.cjs.map +1 -0
- package/dist/{chunk-ZXJU3TQD.cjs → chunk-N5ZWQJTM.cjs} +11 -10
- package/dist/chunk-N5ZWQJTM.cjs.map +1 -0
- package/dist/{chunk-OGC44JFZ.cjs → chunk-N77VOYCK.cjs} +7 -7
- package/dist/{chunk-OGC44JFZ.cjs.map → chunk-N77VOYCK.cjs.map} +1 -1
- package/dist/{chunk-OAK7HFOJ.js → chunk-NACA72XI.js} +21 -16
- package/dist/chunk-NACA72XI.js.map +1 -0
- package/dist/{chunk-TEVZHN5I.cjs → chunk-NCZUQFKL.cjs} +28 -15
- package/dist/chunk-NCZUQFKL.cjs.map +1 -0
- package/dist/{chunk-NZO2I5AL.cjs → chunk-NF55JG2V.cjs} +7 -7
- package/dist/{chunk-NZO2I5AL.cjs.map → chunk-NF55JG2V.cjs.map} +1 -1
- package/dist/{chunk-ZWAFL2B3.cjs → chunk-O46UJUZM.cjs} +21 -19
- package/dist/chunk-O46UJUZM.cjs.map +1 -0
- package/dist/{chunk-25PSIDPC.js → chunk-OIXPYXR6.js} +79 -21
- package/dist/chunk-OIXPYXR6.js.map +1 -0
- package/dist/chunk-OWWPHXAF.cjs +88 -0
- package/dist/chunk-OWWPHXAF.cjs.map +1 -0
- package/dist/{chunk-65PC3YDT.cjs → chunk-OZQKWDFH.cjs} +7 -7
- package/dist/{chunk-65PC3YDT.cjs.map → chunk-OZQKWDFH.cjs.map} +1 -1
- package/dist/{chunk-P2JM22BF.cjs → chunk-P7J6WZTO.cjs} +3 -3
- package/dist/{chunk-P2JM22BF.cjs.map → chunk-P7J6WZTO.cjs.map} +1 -1
- package/dist/{chunk-KQJ3IAFT.js → chunk-PG2EII6U.js} +2 -2
- package/dist/{chunk-E6SE552P.cjs → chunk-RUDXHT76.cjs} +41 -25
- package/dist/chunk-RUDXHT76.cjs.map +1 -0
- package/dist/{chunk-S4S4LB63.js → chunk-SCLFJHN2.js} +11 -3
- package/dist/chunk-SCLFJHN2.js.map +1 -0
- package/dist/{chunk-WKDT2XFQ.js → chunk-SFRILDXY.js} +4 -4
- package/dist/{chunk-J5RMLZ4P.cjs → chunk-SKBKTNEQ.cjs} +80 -22
- package/dist/chunk-SKBKTNEQ.cjs.map +1 -0
- package/dist/{chunk-YW65NAKH.cjs → chunk-SKLMBE3Z.cjs} +7 -7
- package/dist/{chunk-YW65NAKH.cjs.map → chunk-SKLMBE3Z.cjs.map} +1 -1
- package/dist/{chunk-PY2376XI.js → chunk-SVCWSW2F.js} +8 -8
- package/dist/chunk-SVCWSW2F.js.map +1 -0
- package/dist/{chunk-2RXQMQYW.js → chunk-SXL4DMZ7.js} +27 -17
- package/dist/{chunk-2RXQMQYW.js.map → chunk-SXL4DMZ7.js.map} +1 -1
- package/dist/{chunk-7SVDYEKM.js → chunk-TLECMA3B.js} +5 -4
- package/dist/{chunk-7SVDYEKM.js.map → chunk-TLECMA3B.js.map} +1 -1
- package/dist/{chunk-FXZJL2AM.cjs → chunk-TWXZKUCG.cjs} +9 -5
- package/dist/chunk-TWXZKUCG.cjs.map +1 -0
- package/dist/{chunk-GG5YGESX.js → chunk-TYGVKSL6.js} +4 -3
- package/dist/chunk-TYGVKSL6.js.map +1 -0
- package/dist/{chunk-TTO7JXDB.cjs → chunk-TYSNOPMQ.cjs} +3 -3
- package/dist/{chunk-TTO7JXDB.cjs.map → chunk-TYSNOPMQ.cjs.map} +1 -1
- package/dist/{chunk-ZZSPQFMX.js → chunk-U233KQZX.js} +2 -1
- package/dist/{chunk-ZZSPQFMX.js.map → chunk-U233KQZX.js.map} +1 -1
- package/dist/{chunk-5HUZYY54.js → chunk-UDRAM6JU.js} +13 -5
- package/dist/chunk-UDRAM6JU.js.map +1 -0
- package/dist/{chunk-3EUTXQDB.js → chunk-UGTKZ7HP.js} +30 -23
- package/dist/chunk-UGTKZ7HP.js.map +1 -0
- package/dist/{chunk-FKXKBJUI.cjs → chunk-VHO6JPRR.cjs} +2 -1
- package/dist/chunk-VHO6JPRR.cjs.map +1 -0
- package/dist/chunk-VHSTB7GB.cjs +123 -0
- package/dist/chunk-VHSTB7GB.cjs.map +1 -0
- package/dist/{chunk-VPRUHE35.js → chunk-VRNCXYEP.js} +4 -4
- package/dist/{chunk-ITXDSQT2.js → chunk-WGCGSM5P.js} +96 -97
- package/dist/chunk-WGCGSM5P.js.map +1 -0
- package/dist/chunk-WT4WBHBR.js +123 -0
- package/dist/chunk-WT4WBHBR.js.map +1 -0
- package/dist/{chunk-L23WWO3D.js → chunk-X6UKU3C3.js} +2 -2
- package/dist/{chunk-5WH3JMR5.js → chunk-XK5USBHB.js} +7 -4
- package/dist/chunk-XK5USBHB.js.map +1 -0
- package/dist/{chunk-ND526PMG.cjs → chunk-XMXL6NVJ.cjs} +11 -11
- package/dist/{chunk-ND526PMG.cjs.map → chunk-XMXL6NVJ.cjs.map} +1 -1
- package/dist/{chunk-YV57RSPD.js → chunk-XO7WTE6O.js} +47 -18
- package/dist/chunk-XO7WTE6O.js.map +1 -0
- package/dist/{chunk-3CXULV4G.cjs → chunk-XRVRGRC3.cjs} +2 -2
- package/dist/{chunk-3CXULV4G.cjs.map → chunk-XRVRGRC3.cjs.map} +1 -1
- package/dist/{chunk-GPRJYPIG.js → chunk-Y7VSWZWM.js} +6 -4
- package/dist/chunk-Y7VSWZWM.js.map +1 -0
- package/dist/{chunk-2QEKSRVX.js → chunk-YIBPOLNN.js} +4 -4
- package/dist/{chunk-IJ4DXG7D.cjs → chunk-YJNQLH2L.cjs} +5 -2
- package/dist/chunk-YJNQLH2L.cjs.map +1 -0
- package/dist/{chunk-6CSUUQ5M.cjs → chunk-YUH56CJI.cjs} +6 -6
- package/dist/{chunk-6CSUUQ5M.cjs.map → chunk-YUH56CJI.cjs.map} +1 -1
- package/dist/color-picker/index.cjs +4 -4
- package/dist/color-picker/index.d.cts +8 -0
- package/dist/color-picker/index.d.ts +8 -0
- package/dist/color-picker/index.js +3 -3
- package/dist/combobox/index.cjs +6 -6
- package/dist/combobox/index.js +5 -5
- package/dist/command-palette/index.cjs +3 -2
- package/dist/command-palette/index.cjs.map +1 -1
- package/dist/command-palette/index.js +2 -1
- package/dist/context-menu/index.cjs +6 -6
- package/dist/context-menu/index.js +5 -5
- package/dist/conversation/index.cjs +8 -8
- package/dist/conversation/index.js +7 -7
- package/dist/data-grid/index.cjs +16 -16
- package/dist/data-grid/index.d.cts +2 -2
- package/dist/data-grid/index.d.ts +2 -2
- package/dist/data-grid/index.js +15 -15
- package/dist/date-picker/index.cjs +8 -8
- package/dist/date-picker/index.d.cts +1 -1
- package/dist/date-picker/index.d.ts +1 -1
- package/dist/date-picker/index.js +7 -7
- package/dist/drawer/index.cjs +5 -5
- package/dist/drawer/index.js +4 -4
- package/dist/dropdown/index.cjs +3 -3
- package/dist/dropdown/index.js +2 -2
- package/dist/file-upload/index.cjs +2 -2
- package/dist/file-upload/index.js +1 -1
- package/dist/header/index.cjs +6 -6
- package/dist/header/index.js +5 -5
- package/dist/index.cjs +42 -42
- package/dist/index.css +93 -38
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +41 -41
- package/dist/inline-edit/index.cjs +5 -5
- package/dist/inline-edit/index.js +4 -4
- package/dist/input/index.cjs +4 -4
- package/dist/input/index.d.cts +2 -2
- package/dist/input/index.d.ts +2 -2
- package/dist/input/index.js +3 -3
- package/dist/menu/index.cjs +5 -5
- package/dist/menu/index.js +4 -4
- package/dist/modal/index.cjs +5 -5
- package/dist/modal/index.js +4 -4
- package/dist/navigation/index.cjs +5 -5
- package/dist/navigation/index.js +4 -4
- package/dist/number-input/index.cjs +3 -3
- package/dist/number-input/index.js +2 -2
- package/dist/o-t-p-input/index.cjs +2 -2
- package/dist/o-t-p-input/index.js +1 -1
- package/dist/page-layout/index.cjs +12 -12
- package/dist/page-layout/index.js +11 -11
- package/dist/pagination/index.cjs +8 -8
- package/dist/pagination/index.js +7 -7
- package/dist/popover/index.cjs +3 -2
- package/dist/popover/index.cjs.map +1 -1
- package/dist/popover/index.js +2 -1
- package/dist/radio/index.cjs +2 -2
- package/dist/radio/index.js +1 -1
- package/dist/segmented-control/index.cjs +4 -4
- package/dist/segmented-control/index.js +3 -3
- package/dist/select/index.cjs +6 -6
- package/dist/select/index.d.cts +3 -3
- package/dist/select/index.d.ts +3 -3
- package/dist/select/index.js +5 -5
- package/dist/snackbar/index.cjs +5 -5
- package/dist/snackbar/index.d.cts +4 -0
- package/dist/snackbar/index.d.ts +4 -0
- package/dist/snackbar/index.js +4 -4
- package/dist/split-button/index.cjs +6 -6
- package/dist/split-button/index.js +5 -5
- package/dist/table/index.cjs +14 -14
- package/dist/table/index.js +13 -13
- package/dist/tabs/index.cjs +3 -3
- package/dist/tabs/index.js +2 -2
- package/dist/tag-input/index.cjs +6 -6
- package/dist/tag-input/index.js +5 -5
- package/dist/textarea/index.cjs +4 -4
- package/dist/textarea/index.js +3 -3
- package/dist/theme-editor/index.cjs +11 -11
- package/dist/theme-editor/index.js +10 -10
- package/dist/theme-provider/index.cjs +3 -3
- package/dist/theme-provider/index.js +2 -2
- package/dist/toolbar/index.cjs +8 -8
- package/dist/toolbar/index.js +7 -7
- package/dist/tooltip/index.cjs +3 -2
- package/dist/tooltip/index.cjs.map +1 -1
- package/dist/tooltip/index.js +2 -1
- package/dist/virtual-list/index.cjs +2 -2
- package/dist/virtual-list/index.js +1 -1
- package/package.json +7 -2
- package/dist/chunk-25PSIDPC.js.map +0 -1
- package/dist/chunk-27ZWUEPE.js.map +0 -1
- package/dist/chunk-3E7TKBQI.cjs.map +0 -1
- package/dist/chunk-3EPND5M2.cjs.map +0 -1
- package/dist/chunk-3EUTXQDB.js.map +0 -1
- package/dist/chunk-55J4LEKT.cjs.map +0 -1
- package/dist/chunk-5HUZYY54.js.map +0 -1
- package/dist/chunk-5WH3JMR5.js.map +0 -1
- package/dist/chunk-ACNTH2OQ.cjs.map +0 -1
- package/dist/chunk-AOGNTG3W.cjs.map +0 -1
- package/dist/chunk-CJGFRPAS.cjs.map +0 -1
- package/dist/chunk-CUJBNRJJ.cjs +0 -38
- package/dist/chunk-CUJBNRJJ.cjs.map +0 -1
- package/dist/chunk-E6SE552P.cjs.map +0 -1
- package/dist/chunk-EAJHEYZM.js +0 -38
- package/dist/chunk-EAJHEYZM.js.map +0 -1
- package/dist/chunk-FKXKBJUI.cjs.map +0 -1
- package/dist/chunk-FXZJL2AM.cjs.map +0 -1
- package/dist/chunk-GG5YGESX.js.map +0 -1
- package/dist/chunk-GPRJYPIG.js.map +0 -1
- package/dist/chunk-H6CWTMAH.js.map +0 -1
- package/dist/chunk-I5XR2V4A.cjs.map +0 -1
- package/dist/chunk-IJ4DXG7D.cjs.map +0 -1
- package/dist/chunk-ITXDSQT2.js.map +0 -1
- package/dist/chunk-J5RMLZ4P.cjs.map +0 -1
- package/dist/chunk-JRLUZDKA.js.map +0 -1
- package/dist/chunk-K7T25Y3A.cjs.map +0 -1
- package/dist/chunk-L5Q6UDY3.js +0 -69
- package/dist/chunk-L5Q6UDY3.js.map +0 -1
- package/dist/chunk-M7PF4FKQ.js.map +0 -1
- package/dist/chunk-MCWTQT3M.cjs.map +0 -1
- package/dist/chunk-MHZIBV2C.js.map +0 -1
- package/dist/chunk-NEYLNRVG.cjs.map +0 -1
- package/dist/chunk-O3LG7B2J.cjs.map +0 -1
- package/dist/chunk-OAK7HFOJ.js.map +0 -1
- package/dist/chunk-OAPOGYA5.cjs.map +0 -1
- package/dist/chunk-OJDYTCMO.cjs.map +0 -1
- package/dist/chunk-PY2376XI.js.map +0 -1
- package/dist/chunk-Q5KQVBQP.cjs.map +0 -1
- package/dist/chunk-QQIALSTX.cjs.map +0 -1
- package/dist/chunk-R4M6SNUU.cjs.map +0 -1
- package/dist/chunk-RYOQYYDO.js.map +0 -1
- package/dist/chunk-S4S4LB63.js.map +0 -1
- package/dist/chunk-SXGCRHBZ.js.map +0 -1
- package/dist/chunk-T2KB3DJJ.js.map +0 -1
- package/dist/chunk-TEVZHN5I.cjs.map +0 -1
- package/dist/chunk-TQGO5WK6.js.map +0 -1
- package/dist/chunk-WWYJNWJY.cjs +0 -69
- package/dist/chunk-WWYJNWJY.cjs.map +0 -1
- package/dist/chunk-YV57RSPD.js.map +0 -1
- package/dist/chunk-Z5U4NJTW.cjs.map +0 -1
- package/dist/chunk-ZNWIHUHZ.cjs.map +0 -1
- package/dist/chunk-ZWAFL2B3.cjs.map +0 -1
- package/dist/chunk-ZXJU3TQD.cjs.map +0 -1
- /package/dist/{chunk-6CPCNQKV.js.map → chunk-67EXHO4T.js.map} +0 -0
- /package/dist/{chunk-GDQWSCJQ.js.map → chunk-BBU7QG7L.js.map} +0 -0
- /package/dist/{chunk-O2AACVSF.js.map → chunk-BO4LTIJI.js.map} +0 -0
- /package/dist/{chunk-BNVQ34FD.js.map → chunk-CP335H4Q.js.map} +0 -0
- /package/dist/{chunk-OU7DCYIA.js.map → chunk-DMOZURHV.js.map} +0 -0
- /package/dist/{chunk-L5W2XC6M.js.map → chunk-EWTMX4DK.js.map} +0 -0
- /package/dist/{chunk-E7FGY7BJ.js.map → chunk-FPLX5FIK.js.map} +0 -0
- /package/dist/{chunk-KQJ3IAFT.js.map → chunk-PG2EII6U.js.map} +0 -0
- /package/dist/{chunk-WKDT2XFQ.js.map → chunk-SFRILDXY.js.map} +0 -0
- /package/dist/{chunk-VPRUHE35.js.map → chunk-VRNCXYEP.js.map} +0 -0
- /package/dist/{chunk-L23WWO3D.js.map → chunk-X6UKU3C3.js.map} +0 -0
- /package/dist/{chunk-2QEKSRVX.js.map → chunk-YIBPOLNN.js.map} +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
Button
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-44T4HMFU.js";
|
|
4
4
|
|
|
5
5
|
// src/components/Snackbar/Snackbar.context.tsx
|
|
6
6
|
import { createContext, useContext, useState, useCallback, useRef } from "react";
|
|
@@ -17,21 +17,48 @@ var SnackbarProvider = ({ children }) => {
|
|
|
17
17
|
const [snackbars, setSnackbars] = useState([]);
|
|
18
18
|
const snackbarsRef = useRef([]);
|
|
19
19
|
snackbarsRef.current = snackbars;
|
|
20
|
+
const timers = useRef(
|
|
21
|
+
/* @__PURE__ */ new Map()
|
|
22
|
+
);
|
|
23
|
+
const clearTimer = useCallback((id) => {
|
|
24
|
+
const timer = timers.current.get(id);
|
|
25
|
+
if (timer) {
|
|
26
|
+
window.clearTimeout(timer.timeout);
|
|
27
|
+
timers.current.delete(id);
|
|
28
|
+
}
|
|
29
|
+
}, []);
|
|
30
|
+
const removeSnackbarRef = useRef(() => {
|
|
31
|
+
});
|
|
20
32
|
const generateId = useCallback(() => {
|
|
21
33
|
return `snackbar-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
|
|
22
34
|
}, []);
|
|
23
|
-
const removeSnackbar = useCallback(
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
snackbar.
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
+
const removeSnackbar = useCallback(
|
|
36
|
+
(id) => {
|
|
37
|
+
clearTimer(id);
|
|
38
|
+
const snackbar = snackbarsRef.current.find((item) => item.id === id);
|
|
39
|
+
if (snackbar?.onClose) {
|
|
40
|
+
snackbar.onClose(id);
|
|
41
|
+
}
|
|
42
|
+
setSnackbars(
|
|
43
|
+
(prev) => prev.map((item) => item.id === id ? { ...item, state: "exiting" } : item)
|
|
44
|
+
);
|
|
45
|
+
setTimeout(() => {
|
|
46
|
+
setSnackbars((prev) => prev.filter((item) => item.id !== id));
|
|
47
|
+
}, 300);
|
|
48
|
+
},
|
|
49
|
+
[clearTimer]
|
|
50
|
+
);
|
|
51
|
+
const startTimer = useCallback(
|
|
52
|
+
(id, ms) => {
|
|
53
|
+
clearTimer(id);
|
|
54
|
+
timers.current.set(id, {
|
|
55
|
+
timeout: window.setTimeout(() => removeSnackbarRef.current(id), ms),
|
|
56
|
+
remaining: ms,
|
|
57
|
+
startedAt: Date.now()
|
|
58
|
+
});
|
|
59
|
+
},
|
|
60
|
+
[clearTimer]
|
|
61
|
+
);
|
|
35
62
|
const addSnackbar = useCallback(
|
|
36
63
|
(snackbar) => {
|
|
37
64
|
const id = generateId();
|
|
@@ -50,14 +77,32 @@ var SnackbarProvider = ({ children }) => {
|
|
|
50
77
|
});
|
|
51
78
|
});
|
|
52
79
|
if (snackbar.duration && snackbar.duration > 0) {
|
|
53
|
-
|
|
54
|
-
removeSnackbar(id);
|
|
55
|
-
}, snackbar.duration);
|
|
80
|
+
startTimer(id, snackbar.duration);
|
|
56
81
|
}
|
|
57
82
|
return id;
|
|
58
83
|
},
|
|
59
|
-
[generateId,
|
|
84
|
+
[generateId, startTimer]
|
|
85
|
+
);
|
|
86
|
+
const pauseSnackbar = useCallback((id) => {
|
|
87
|
+
const timer = timers.current.get(id);
|
|
88
|
+
if (!timer) return;
|
|
89
|
+
window.clearTimeout(timer.timeout);
|
|
90
|
+
timers.current.set(id, {
|
|
91
|
+
...timer,
|
|
92
|
+
// What is left of the countdown at the moment of pausing, floored at 0
|
|
93
|
+
// so a timer that was already due does not resume with a negative delay.
|
|
94
|
+
remaining: Math.max(0, timer.remaining - (Date.now() - timer.startedAt))
|
|
95
|
+
});
|
|
96
|
+
}, []);
|
|
97
|
+
const resumeSnackbar = useCallback(
|
|
98
|
+
(id) => {
|
|
99
|
+
const timer = timers.current.get(id);
|
|
100
|
+
if (!timer) return;
|
|
101
|
+
startTimer(id, timer.remaining);
|
|
102
|
+
},
|
|
103
|
+
[startTimer]
|
|
60
104
|
);
|
|
105
|
+
removeSnackbarRef.current = removeSnackbar;
|
|
61
106
|
const clearAllSnackbars = useCallback(() => {
|
|
62
107
|
setSnackbars((prev) => prev.map((item) => ({ ...item, state: "exiting" })));
|
|
63
108
|
setTimeout(() => {
|
|
@@ -68,7 +113,9 @@ var SnackbarProvider = ({ children }) => {
|
|
|
68
113
|
snackbars,
|
|
69
114
|
addSnackbar,
|
|
70
115
|
removeSnackbar,
|
|
71
|
-
clearAllSnackbars
|
|
116
|
+
clearAllSnackbars,
|
|
117
|
+
pauseSnackbar,
|
|
118
|
+
resumeSnackbar
|
|
72
119
|
};
|
|
73
120
|
return /* @__PURE__ */ jsx(SnackbarContext.Provider, { value: contextValue, children });
|
|
74
121
|
};
|
|
@@ -144,12 +191,23 @@ SnackbarComponent.displayName = "SnackbarComponent";
|
|
|
144
191
|
// src/components/Snackbar/SnackbarContainer.component.tsx
|
|
145
192
|
import { jsx as jsx3 } from "react/jsx-runtime";
|
|
146
193
|
var SnackbarContainer = () => {
|
|
147
|
-
const { snackbars, removeSnackbar } = useSnackbarContext();
|
|
194
|
+
const { snackbars, removeSnackbar, pauseSnackbar, resumeSnackbar } = useSnackbarContext();
|
|
148
195
|
if (snackbars.length === 0) {
|
|
149
196
|
return null;
|
|
150
197
|
}
|
|
151
198
|
return createPortal(
|
|
152
|
-
/* @__PURE__ */ jsx3("div", { className: "eidos-snackbar-container", children: snackbars.map((snackbar) => /* @__PURE__ */ jsx3(
|
|
199
|
+
/* @__PURE__ */ jsx3("div", { className: "eidos-snackbar-container", children: snackbars.map((snackbar) => /* @__PURE__ */ jsx3(
|
|
200
|
+
"div",
|
|
201
|
+
{
|
|
202
|
+
className: "eidos-snackbar-wrapper",
|
|
203
|
+
onMouseEnter: () => pauseSnackbar(snackbar.id),
|
|
204
|
+
onMouseLeave: () => resumeSnackbar(snackbar.id),
|
|
205
|
+
onFocus: () => pauseSnackbar(snackbar.id),
|
|
206
|
+
onBlur: () => resumeSnackbar(snackbar.id),
|
|
207
|
+
children: /* @__PURE__ */ jsx3(SnackbarComponent, { snackbar, onClose: removeSnackbar })
|
|
208
|
+
},
|
|
209
|
+
snackbar.id
|
|
210
|
+
)) }),
|
|
153
211
|
document.body
|
|
154
212
|
);
|
|
155
213
|
};
|
|
@@ -235,4 +293,4 @@ export {
|
|
|
235
293
|
SnackbarContainer,
|
|
236
294
|
useSnackbar
|
|
237
295
|
};
|
|
238
|
-
//# sourceMappingURL=chunk-
|
|
296
|
+
//# sourceMappingURL=chunk-OIXPYXR6.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/Snackbar/Snackbar.context.tsx","../src/components/Snackbar/SnackbarContainer.component.tsx","../src/components/Snackbar/Snackbar.component.tsx","../src/components/Snackbar/Snackbar.hooks.ts"],"sourcesContent":["import React, { createContext, useContext, useState, useCallback, useRef } from 'react';\nimport type { SnackbarContextValue, SnackbarItem, SnackbarProps } from './Snackbar.types';\n\nconst SnackbarContext = createContext<SnackbarContextValue | undefined>(undefined);\n\nexport const useSnackbarContext = (): SnackbarContextValue => {\n const context = useContext(SnackbarContext);\n if (!context) {\n throw new Error('useSnackbarContext must be used within a SnackbarProvider');\n }\n return context;\n};\n\ninterface SnackbarProviderProps {\n children: React.ReactNode;\n}\n\nexport const SnackbarProvider: React.FC<SnackbarProviderProps> = ({ children }) => {\n const [snackbars, setSnackbars] = useState<SnackbarItem[]>([]);\n // Mirror state in a ref so removeSnackbar can read current items synchronously\n // without placing side-effects inside a setState updater (which StrictMode calls twice).\n const snackbarsRef = useRef<SnackbarItem[]>([]);\n snackbarsRef.current = snackbars;\n\n // ── Pausable auto-dismiss timers (SC 2.2.1 Timing Adjustable) ─────────────\n //\n // Auto-dismiss used to be a bare `setTimeout` that nothing could stop. That\n // is a Level A failure: a time limit the user can neither turn off, adjust\n // nor extend. It bites hardest exactly where a snackbar is most useful -\n // `action` puts a control (typically \"Undo\") inside something that deletes\n // itself on a stopwatch, so anyone reading slowly, using a screen reader,\n // or driving by keyboard can lose it mid-reach.\n //\n // Each timer therefore records when it started and how long is left, so it\n // can be cancelled on hover or focus and restarted with the remainder.\n const timers = useRef(\n new Map<string, { timeout: number; remaining: number; startedAt: number }>(),\n );\n\n const clearTimer = useCallback((id: string): void => {\n const timer = timers.current.get(id);\n if (timer) {\n window.clearTimeout(timer.timeout);\n timers.current.delete(id);\n }\n }, []);\n\n // `startTimer` needs `removeSnackbar`, and `removeSnackbar` needs\n // `clearTimer`. A ref breaks the cycle without reordering the file or\n // making every callback depend on the others' identity.\n const removeSnackbarRef = useRef<(id: string) => void>(() => {});\n\n const generateId = useCallback((): string => {\n return `snackbar-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;\n }, []);\n\n const removeSnackbar = useCallback(\n (id: string): void => {\n // Read from ref - safe to call outside a setState updater.\n // Calling side-effects inside a setState updater is wrong: React StrictMode\n // deliberately invokes updaters twice, which would fire onClose 2× from here\n // plus 1× from SnackbarComponent.handleClose = 3× total.\n clearTimer(id);\n\n const snackbar = snackbarsRef.current.find((item) => item.id === id);\n if (snackbar?.onClose) {\n snackbar.onClose(id);\n }\n\n // Transition to exiting state, then remove after the CSS animation (300ms).\n setSnackbars((prev) =>\n prev.map((item) => (item.id === id ? { ...item, state: 'exiting' } : item)),\n );\n\n setTimeout(() => {\n setSnackbars((prev) => prev.filter((item) => item.id !== id));\n }, 300);\n },\n [clearTimer],\n );\n\n const startTimer = useCallback(\n (id: string, ms: number): void => {\n clearTimer(id);\n timers.current.set(id, {\n timeout: window.setTimeout(() => removeSnackbarRef.current(id), ms),\n remaining: ms,\n startedAt: Date.now(),\n });\n },\n [clearTimer],\n );\n\n const addSnackbar = useCallback(\n (snackbar: Omit<SnackbarProps, 'id'>): string => {\n const id = generateId();\n const newSnackbar: SnackbarItem = {\n ...snackbar,\n id,\n state: 'entering',\n createdAt: Date.now(),\n };\n\n setSnackbars((prev) => [newSnackbar, ...prev]); // Add to beginning (newest on top)\n\n // Use requestAnimationFrame to ensure DOM is rendered before animation\n requestAnimationFrame(() => {\n requestAnimationFrame(() => {\n setSnackbars((prev) =>\n prev.map((item) => (item.id === id ? { ...item, state: 'entered' } : item)),\n );\n });\n });\n\n // Auto-close if duration is set\n if (snackbar.duration && snackbar.duration > 0) {\n startTimer(id, snackbar.duration);\n }\n\n return id;\n },\n [generateId, startTimer],\n );\n\n // Pause on hover or focus, resume on leave or blur. Wired up by\n // `SnackbarContainer` - see the handlers there.\n const pauseSnackbar = useCallback((id: string): void => {\n const timer = timers.current.get(id);\n if (!timer) return;\n window.clearTimeout(timer.timeout);\n timers.current.set(id, {\n ...timer,\n // What is left of the countdown at the moment of pausing, floored at 0\n // so a timer that was already due does not resume with a negative delay.\n remaining: Math.max(0, timer.remaining - (Date.now() - timer.startedAt)),\n });\n }, []);\n\n const resumeSnackbar = useCallback(\n (id: string): void => {\n const timer = timers.current.get(id);\n if (!timer) return;\n startTimer(id, timer.remaining);\n },\n [startTimer],\n );\n\n removeSnackbarRef.current = removeSnackbar;\n\n const clearAllSnackbars = useCallback((): void => {\n // Transition all to exiting state\n setSnackbars((prev) => prev.map((item) => ({ ...item, state: 'exiting' })));\n\n // Remove all after animation completes (300ms to match CSS animation)\n setTimeout(() => {\n setSnackbars([]);\n }, 300);\n }, []);\n\n const contextValue: SnackbarContextValue = {\n snackbars,\n addSnackbar,\n removeSnackbar,\n clearAllSnackbars,\n pauseSnackbar,\n resumeSnackbar,\n };\n\n return <SnackbarContext.Provider value={contextValue}>{children}</SnackbarContext.Provider>;\n};\n\nSnackbarProvider.displayName = 'SnackbarProvider';\n","import React from 'react';\nimport { createPortal } from 'react-dom';\nimport { useSnackbarContext } from './Snackbar.context';\nimport { SnackbarComponent } from './Snackbar.component';\n\nexport const SnackbarContainer: React.FC = () => {\n const { snackbars, removeSnackbar, pauseSnackbar, resumeSnackbar } = useSnackbarContext();\n\n if (snackbars.length === 0) {\n return null;\n }\n\n return createPortal(\n <div className={'eidos-snackbar-container'}>\n {snackbars.map((snackbar) => (\n <div\n key={snackbar.id}\n className={'eidos-snackbar-wrapper'}\n // Holds the auto-dismiss countdown while the user is engaged with\n // this snackbar, which is what makes the time limit adjustable\n // (SC 2.2.1). Hover covers reading it; focus covers reaching its\n // action by keyboard - `onFocus`/`onBlur` bubble in React, so a\n // focused \"Undo\" button inside pauses the whole snackbar.\n onMouseEnter={() => pauseSnackbar(snackbar.id)}\n onMouseLeave={() => resumeSnackbar(snackbar.id)}\n onFocus={() => pauseSnackbar(snackbar.id)}\n onBlur={() => resumeSnackbar(snackbar.id)}\n >\n <SnackbarComponent snackbar={snackbar} onClose={removeSnackbar} />\n </div>\n ))}\n </div>,\n document.body,\n );\n};\n\nSnackbarContainer.displayName = 'SnackbarContainer';\n","import React from 'react';\nimport { X } from 'lucide-react';\nimport { Button } from '../Button/Button.component';\nimport type { SnackbarItem } from './Snackbar.types';\n\ninterface SnackbarComponentProps {\n snackbar: SnackbarItem;\n onClose: (id: string) => void;\n}\n\nexport const SnackbarComponent: React.FC<SnackbarComponentProps> = ({ snackbar, onClose }) => {\n const {\n id,\n variant = 'info',\n message,\n component: Component,\n componentProps,\n action,\n state,\n } = snackbar;\n\n const handleClose = () => {\n // onClose callback is fired by removeSnackbar (context) to cover both\n // manual and auto-close paths without duplication.\n onClose(id);\n };\n\n const handleActionClick = () => {\n if (action?.onClick) {\n action.onClick();\n }\n };\n\n // Render content based on type\n const renderContent = () => {\n if (message) {\n return <span className={'eidos-snackbar-message'}>{message}</span>;\n }\n if (Component) {\n return <Component {...(componentProps || {})} />;\n }\n return null;\n };\n\n return (\n <div\n className={`eidos-snackbar eidos-snackbar--${variant} eidos-snackbar--${state} ${snackbar.className || ''}`}\n role=\"alert\"\n aria-live=\"polite\"\n >\n <div className={'eidos-snackbar-content'}>{renderContent()}</div>\n\n {action && (\n <div className={'eidos-snackbar-actions'}>\n <Button\n variant={action.variant === 'primary' ? 'filled' : 'text'}\n size=\"sm\"\n onClick={handleActionClick}\n className={'eidos-snackbar-action-button'}\n >\n {action.label}\n </Button>\n </div>\n )}\n\n <button\n className={'eidos-snackbar-close-button'}\n onClick={handleClose}\n aria-label=\"Close notification\"\n type=\"button\"\n >\n <X className={'eidos-snackbar-close-icon'} />\n </button>\n </div>\n );\n};\n\nSnackbarComponent.displayName = 'SnackbarComponent';\n","import { useCallback } from 'react';\nimport { useSnackbarContext } from './Snackbar.context';\nimport type { UseSnackbarReturn, SnackbarProps } from './Snackbar.types';\n\nexport const useSnackbar = (): UseSnackbarReturn => {\n const { addSnackbar, removeSnackbar, clearAllSnackbars } = useSnackbarContext();\n\n const showSnackbar = useCallback(\n (snackbar: Omit<SnackbarProps, 'id'>): string => {\n return addSnackbar(snackbar);\n },\n [addSnackbar],\n );\n\n const hideSnackbar = useCallback(\n (id: string): void => {\n removeSnackbar(id);\n },\n [removeSnackbar],\n );\n\n const clearAll = useCallback((): void => {\n clearAllSnackbars();\n }, [clearAllSnackbars]);\n\n const showSuccess = useCallback(\n (message: string, options?: Partial<Omit<SnackbarProps, 'id' | 'message' | 'variant'>>) => {\n return showSnackbar({\n message,\n variant: 'success',\n duration: 5000,\n ...options,\n });\n },\n [showSnackbar],\n );\n\n const showError = useCallback(\n (message: string, options?: Partial<Omit<SnackbarProps, 'id' | 'message' | 'variant'>>) => {\n return showSnackbar({\n message,\n variant: 'danger',\n duration: 5000,\n ...options,\n });\n },\n [showSnackbar],\n );\n\n const showWarning = useCallback(\n (message: string, options?: Partial<Omit<SnackbarProps, 'id' | 'message' | 'variant'>>) => {\n return showSnackbar({\n message,\n variant: 'warning',\n duration: 5000,\n ...options,\n });\n },\n [showSnackbar],\n );\n\n const showInfo = useCallback(\n (message: string, options?: Partial<Omit<SnackbarProps, 'id' | 'message' | 'variant'>>) => {\n return showSnackbar({\n message,\n variant: 'info',\n duration: 5000,\n ...options,\n });\n },\n [showSnackbar],\n );\n\n return {\n showSnackbar,\n hideSnackbar,\n clearAll,\n showSuccess,\n showError,\n showWarning,\n showInfo,\n };\n};\n\nexport default useSnackbar;\n"],"mappings":"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","names":["jsx","jsx","useCallback","useCallback"]}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } }
|
|
2
|
+
|
|
3
|
+
var _chunkMLUHM3VGcjs = require('./chunk-MLUHM3VG.cjs');
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
var _chunkVHSTB7GBcjs = require('./chunk-VHSTB7GB.cjs');
|
|
8
|
+
|
|
9
|
+
// src/components/Button/Button.component.tsx
|
|
10
|
+
var _lucidereact = require('lucide-react');
|
|
11
|
+
var _jsxruntime = require('react/jsx-runtime');
|
|
12
|
+
var Button = ({
|
|
13
|
+
variant = "filled",
|
|
14
|
+
color = "primary",
|
|
15
|
+
size = "md",
|
|
16
|
+
disabled = false,
|
|
17
|
+
loading = false,
|
|
18
|
+
loadingText = "Loading...",
|
|
19
|
+
tooltip,
|
|
20
|
+
className = "",
|
|
21
|
+
preIcon,
|
|
22
|
+
posIcon,
|
|
23
|
+
icon,
|
|
24
|
+
children,
|
|
25
|
+
...buttonProps
|
|
26
|
+
}) => {
|
|
27
|
+
const isIconOnly = !!icon;
|
|
28
|
+
if (isIconOnly) {
|
|
29
|
+
if (children) {
|
|
30
|
+
throw new Error("Icon-only buttons cannot have children");
|
|
31
|
+
}
|
|
32
|
+
if (preIcon) {
|
|
33
|
+
throw new Error("Icon-only buttons cannot have preIcon");
|
|
34
|
+
}
|
|
35
|
+
if (posIcon) {
|
|
36
|
+
throw new Error("Icon-only buttons cannot have posIcon");
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
const suppliedLabel = _nullishCoalesce(buttonProps["aria-label"], () => ( buttonProps["aria-labelledby"]));
|
|
40
|
+
const iconOnlyLabel = isIconOnly && !suppliedLabel ? tooltip : void 0;
|
|
41
|
+
if (isIconOnly && !suppliedLabel && !tooltip) {
|
|
42
|
+
_chunkVHSTB7GBcjs.devWarn.call(void 0,
|
|
43
|
+
"button-icon-only-name",
|
|
44
|
+
'Button: an icon-only button needs an accessible name. Pass `tooltip` (which now also names it) or `aria-label`, otherwise it is announced as just "button".'
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
const buttonClasses = [
|
|
48
|
+
"eidos-button",
|
|
49
|
+
`eidos-button--${variant}`,
|
|
50
|
+
`eidos-button--${color}`,
|
|
51
|
+
`eidos-button--${size}`,
|
|
52
|
+
isIconOnly && "eidos-button--icon-only",
|
|
53
|
+
disabled && "eidos-button--disabled",
|
|
54
|
+
loading && "eidos-button--loading",
|
|
55
|
+
className
|
|
56
|
+
].filter(Boolean).join(" ");
|
|
57
|
+
const buttonContent = /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
58
|
+
"button",
|
|
59
|
+
{
|
|
60
|
+
type: "button",
|
|
61
|
+
...buttonProps,
|
|
62
|
+
"aria-label": _nullishCoalesce(iconOnlyLabel, () => ( buttonProps["aria-label"])),
|
|
63
|
+
className: buttonClasses,
|
|
64
|
+
disabled: disabled || loading,
|
|
65
|
+
children: loading ? /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
|
|
66
|
+
!isIconOnly && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
|
|
67
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "eidos-button--loading-spinner", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.LoaderCircle, { className: "eidos-button--spinner-icon" }) }),
|
|
68
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "eidos-button--copy", children: loadingText })
|
|
69
|
+
] }),
|
|
70
|
+
isIconOnly && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "eidos-button--loading-spinner", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.LoaderCircle, { className: "eidos-button--spinner-icon" }) })
|
|
71
|
+
] }) : /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
|
|
72
|
+
preIcon && _chunkVHSTB7GBcjs.renderIcon.call(void 0, preIcon, "eidos-button--pre-icon"),
|
|
73
|
+
isIconOnly && icon ? _chunkVHSTB7GBcjs.renderIcon.call(void 0, icon, "eidos-button--icon") : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "eidos-button--copy", children }),
|
|
74
|
+
posIcon && _chunkVHSTB7GBcjs.renderIcon.call(void 0, posIcon, "eidos-button--pos-icon")
|
|
75
|
+
] })
|
|
76
|
+
}
|
|
77
|
+
);
|
|
78
|
+
return tooltip ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkMLUHM3VGcjs.Tooltip, { message: tooltip, children: buttonContent }) : buttonContent;
|
|
79
|
+
};
|
|
80
|
+
var IconButton = (props) => {
|
|
81
|
+
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, Button, { ...props });
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
exports.Button = Button; exports.IconButton = IconButton;
|
|
88
|
+
//# sourceMappingURL=chunk-OWWPHXAF.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["/home/runner/work/eidos-ui/eidos-ui/dist/chunk-OWWPHXAF.cjs","../src/components/Button/Button.component.tsx"],"names":[],"mappings":"AAAA;AACE;AACF,wDAA6B;AAC7B;AACE;AACA;AACF,wDAA6B;AAC7B;AACA;ACPA,2CAA6B;AAkFjB,+CAAA;AA7EL,IAAM,OAAA,EAAgC,CAAC;AAAA,EAC5C,QAAA,EAAU,QAAA;AAAA,EACV,MAAA,EAAQ,SAAA;AAAA,EACR,KAAA,EAAO,IAAA;AAAA,EACP,SAAA,EAAW,KAAA;AAAA,EACX,QAAA,EAAU,KAAA;AAAA,EACV,YAAA,EAAc,YAAA;AAAA,EACd,OAAA;AAAA,EACA,UAAA,EAAY,EAAA;AAAA,EACZ,OAAA;AAAA,EACA,OAAA;AAAA,EACA,IAAA;AAAA,EACA,QAAA;AAAA,EACA,GAAG;AACL,CAAA,EAAA,GAAM;AACJ,EAAA,MAAM,WAAA,EAAa,CAAC,CAAC,IAAA;AAErB,EAAA,GAAA,CAAI,UAAA,EAAY;AACd,IAAA,GAAA,CAAI,QAAA,EAAU;AACZ,MAAA,MAAM,IAAI,KAAA,CAAM,wCAAwC,CAAA;AAAA,IAC1D;AACA,IAAA,GAAA,CAAI,OAAA,EAAS;AACX,MAAA,MAAM,IAAI,KAAA,CAAM,uCAAuC,CAAA;AAAA,IACzD;AACA,IAAA,GAAA,CAAI,OAAA,EAAS;AACX,MAAA,MAAM,IAAI,KAAA,CAAM,uCAAuC,CAAA;AAAA,IACzD;AAAA,EACF;AAgBA,EAAA,MAAM,cAAA,mBAAgB,WAAA,CAAY,YAAY,CAAA,UAAK,WAAA,CAAY,iBAAiB,GAAA;AAChF,EAAA,MAAM,cAAA,EAAgB,WAAA,GAAc,CAAC,cAAA,EAAgB,QAAA,EAAU,KAAA,CAAA;AAE/D,EAAA,GAAA,CAAI,WAAA,GAAc,CAAC,cAAA,GAAiB,CAAC,OAAA,EAAS;AAC5C,IAAA,uCAAA;AAAA,MACE,uBAAA;AAAA,MACA;AAAA,IACF,CAAA;AAAA,EACF;AAEA,EAAA,MAAM,cAAA,EAAgB;AAAA,IACpB,cAAA;AAAA,IACA,CAAA,cAAA,EAAiB,OAAO,CAAA,CAAA;AACF,IAAA;AACD,IAAA;AACP,IAAA;AACF,IAAA;AACD,IAAA;AACX,IAAA;AAGS,EAAA;AAGT,EAAA;AAAC,IAAA;AAAA,IAAA;AACM,MAAA;AACD,MAAA;AACQ,MAAA;AACD,MAAA;AACW,MAAA;AAGpB,MAAA;AAEI,QAAA;AACE,0BAAA;AAGA,0BAAA;AACF,QAAA;AAGA,QAAA;AAMJ,MAAA;AACc,QAAA;AAGV,QAAA;AAKU,QAAA;AACd,MAAA;AAAA,IAAA;AAEJ,EAAA;AAGe,EAAA;AACnB;AAagE;AACtD,EAAA;AACV;AD9C6B;AACA;AACA;AACA;AACA","file":"/home/runner/work/eidos-ui/eidos-ui/dist/chunk-OWWPHXAF.cjs","sourcesContent":[null,"import React from 'react';\nimport { LoaderCircle } from 'lucide-react';\nimport { Tooltip } from '../Tooltip';\nimport { ButtonProps, IconButtonProps } from './Button.types';\nimport { renderIcon, devWarn } from '../../utils';\n\nexport const Button: React.FC<ButtonProps> = ({\n variant = 'filled',\n color = 'primary',\n size = 'md',\n disabled = false,\n loading = false,\n loadingText = 'Loading...',\n tooltip,\n className = '',\n preIcon,\n posIcon,\n icon,\n children,\n ...buttonProps\n}) => {\n const isIconOnly = !!icon;\n\n if (isIconOnly) {\n if (children) {\n throw new Error('Icon-only buttons cannot have children');\n }\n if (preIcon) {\n throw new Error('Icon-only buttons cannot have preIcon');\n }\n if (posIcon) {\n throw new Error('Icon-only buttons cannot have posIcon');\n }\n }\n\n // ── Accessible name for icon-only buttons ──────────────────────────────\n //\n // An icon-only button has no text, so without `aria-label` it is announced\n // as just \"button\". `tooltip` alone did NOT fix this: `Tooltip` renders a\n // floating panel and adds no naming attributes to its child, so the\n // library's own documented example - `<IconButton icon={Plus}\n // tooltip=\"Add item\" />` - shipped a nameless control.\n //\n // Falling back to `tooltip` makes that documented pattern correct without\n // asking anyone to change their code: if you already described the button\n // for sighted users, that description now names it for everyone.\n //\n // Only ever a fallback - an explicit `aria-label` or `aria-labelledby`\n // always wins, since the caller may want a longer name than the tooltip.\n const suppliedLabel = buttonProps['aria-label'] ?? buttonProps['aria-labelledby'];\n const iconOnlyLabel = isIconOnly && !suppliedLabel ? tooltip : undefined;\n\n if (isIconOnly && !suppliedLabel && !tooltip) {\n devWarn(\n 'button-icon-only-name',\n 'Button: an icon-only button needs an accessible name. Pass `tooltip` (which now also names it) or `aria-label`, otherwise it is announced as just \"button\".',\n );\n }\n\n const buttonClasses = [\n 'eidos-button',\n `eidos-button--${variant}`,\n `eidos-button--${color}`,\n `eidos-button--${size}`,\n isIconOnly && 'eidos-button--icon-only',\n disabled && 'eidos-button--disabled',\n loading && 'eidos-button--loading',\n className,\n ]\n .filter(Boolean)\n .join(' ');\n\n const buttonContent = (\n <button\n type=\"button\"\n {...buttonProps}\n aria-label={iconOnlyLabel ?? buttonProps['aria-label']}\n className={buttonClasses}\n disabled={disabled || loading}\n >\n {loading ? (\n <>\n {!isIconOnly && (\n <>\n <span className=\"eidos-button--loading-spinner\">\n <LoaderCircle className=\"eidos-button--spinner-icon\" />\n </span>\n <span className=\"eidos-button--copy\">{loadingText}</span>\n </>\n )}\n {isIconOnly && (\n <span className=\"eidos-button--loading-spinner\">\n <LoaderCircle className=\"eidos-button--spinner-icon\" />\n </span>\n )}\n </>\n ) : (\n <>\n {preIcon && renderIcon(preIcon, 'eidos-button--pre-icon')}\n\n {isIconOnly && icon ? (\n renderIcon(icon, 'eidos-button--icon')\n ) : (\n <span className=\"eidos-button--copy\">{children}</span>\n )}\n\n {posIcon && renderIcon(posIcon, 'eidos-button--pos-icon')}\n </>\n )}\n </button>\n );\n\n return tooltip ? <Tooltip message={tooltip}>{buttonContent}</Tooltip> : buttonContent;\n};\n\n/**\n * IconButton - Convenience wrapper for icon-only buttons\n *\n * @example\n * ```tsx\n * import { IconButton } from 'eidos-ui';\n * import { Plus } from 'lucide-react';\n *\n * <IconButton icon={Plus} tooltip=\"Add item\" />\n * ```\n */\nexport const IconButton: React.FC<IconButtonProps> = (props) => {\n return <Button {...props} />;\n};\n"]}
|
|
@@ -3,13 +3,13 @@
|
|
|
3
3
|
var _chunkQ3GNKF74cjs = require('./chunk-Q3GNKF74.cjs');
|
|
4
4
|
|
|
5
5
|
|
|
6
|
-
var
|
|
6
|
+
var _chunkOWWPHXAFcjs = require('./chunk-OWWPHXAF.cjs');
|
|
7
7
|
|
|
8
8
|
|
|
9
|
-
var
|
|
9
|
+
var _chunkMLUHM3VGcjs = require('./chunk-MLUHM3VG.cjs');
|
|
10
10
|
|
|
11
11
|
|
|
12
|
-
var
|
|
12
|
+
var _chunkVHSTB7GBcjs = require('./chunk-VHSTB7GB.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, _chunkMLUHM3VGcjs.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 && _chunkVHSTB7GBcjs.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
|
+
_chunkOWWPHXAFcjs.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-OZQKWDFH.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/home/runner/work/eidos-ui/eidos-ui/dist/chunk-65PC3YDT.cjs","../src/components/Navigation/Navigation.component.tsx"],"names":[],"mappings":"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","file":"/home/runner/work/eidos-ui/eidos-ui/dist/chunk-65PC3YDT.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-OZQKWDFH.cjs","../src/components/Navigation/Navigation.component.tsx"],"names":[],"mappings":"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","file":"/home/runner/work/eidos-ui/eidos-ui/dist/chunk-OZQKWDFH.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,6 +1,6 @@
|
|
|
1
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
2
|
|
|
3
|
-
var
|
|
3
|
+
var _chunkVHSTB7GBcjs = require('./chunk-VHSTB7GB.cjs');
|
|
4
4
|
|
|
5
5
|
// src/components/Dropdown/Dropdown.context.types.ts
|
|
6
6
|
var _react = require('react');
|
|
@@ -360,7 +360,7 @@ var DropdownInternal = ({
|
|
|
360
360
|
{
|
|
361
361
|
ref: triggerRef,
|
|
362
362
|
onClick: handleTriggerClick,
|
|
363
|
-
className: `eidos-dropdown-trigger ${fullWidth ?
|
|
363
|
+
className: `eidos-dropdown-trigger ${fullWidth ? _chunkVHSTB7GBcjs.fullWidthModifier.call(void 0, "eidos-dropdown-trigger") : ""} ${triggerClassName}`,
|
|
364
364
|
children: trigger
|
|
365
365
|
}
|
|
366
366
|
),
|
|
@@ -400,4 +400,4 @@ Dropdown.displayName = "Dropdown";
|
|
|
400
400
|
|
|
401
401
|
|
|
402
402
|
exports.DropdownProvider = DropdownProvider; exports.useDropdownContext = useDropdownContext; exports.Dropdown = Dropdown;
|
|
403
|
-
//# sourceMappingURL=chunk-
|
|
403
|
+
//# sourceMappingURL=chunk-P7J6WZTO.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/home/runner/work/eidos-ui/eidos-ui/dist/chunk-P2JM22BF.cjs","../src/components/Dropdown/Dropdown.context.types.ts","../src/components/Dropdown/Dropdown.context.tsx","../src/components/Dropdown/Dropdown.hooks.ts","../src/components/Dropdown/Dropdown.component.tsx"],"names":["jsx"],"mappings":"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","file":"/home/runner/work/eidos-ui/eidos-ui/dist/chunk-P2JM22BF.cjs","sourcesContent":[null,"import { createContext } from 'react';\n\nexport interface DropdownContextValue {\n level: number;\n}\n\nexport const DropdownContext = createContext<DropdownContextValue>({ level: 0 });\n","import React from 'react';\nimport { DropdownContext } from './Dropdown.context.types';\n\nexport const DropdownProvider: React.FC<{ children: React.ReactNode; level?: number }> = ({\n children,\n level = 0,\n}) => {\n return <DropdownContext.Provider value={{ level }}>{children}</DropdownContext.Provider>;\n};\n","import { useContext } from 'react';\nimport { DropdownContext } from './Dropdown.context.types';\n\nexport const useDropdownContext = () => {\n return useContext(DropdownContext);\n};\n","import React, { useState, useRef, useCallback, useEffect } from 'react';\nimport { createPortal } from 'react-dom';\nimport { fullWidthModifier } from '../../utils';\nimport type { DropdownProps, DropdownState } from './Dropdown.types';\nimport { DropdownProvider } from './Dropdown.context';\nimport { useDropdownContext } from './Dropdown.hooks';\n\nconst DropdownInternal: React.FC<DropdownProps> = ({\n trigger,\n content,\n placement: preferredPlacement = 'bottom',\n align = 'start',\n delay = 0,\n disabled = false,\n defaultOpen = false,\n triggerClassName = '',\n contentClassName = '',\n closeOnClickOutside = true,\n closeOnEscape = true,\n minWidth,\n maxWidth,\n minHeight,\n maxHeight,\n autoWidth = true,\n fullWidth = false,\n triggerRef: externalTriggerRef,\n isNested = false,\n dropdownLevel,\n dropdownGroup,\n}) => {\n const context = useDropdownContext();\n const actualLevel = dropdownLevel !== undefined ? dropdownLevel : context.level;\n const [dropdownState, setDropdownState] = useState<DropdownState>({\n isVisible: defaultOpen,\n isPositioned: false,\n position: { top: 0, left: 0, placement: preferredPlacement },\n });\n const triggerRef = useRef<HTMLDivElement>(null);\n const contentRef = useRef<HTMLDivElement>(null);\n const timeoutRef = useRef<ReturnType<typeof setTimeout> | undefined>(undefined);\n const animationFrameRef = useRef<number | undefined>(undefined);\n const isScrollingRef = useRef(false);\n\n // The element to actually measure/anchor against. When a consumer passes\n // `triggerRef`, that's an explicit statement of \"this is what I want the\n // dropdown positioned relative to\" - it must win over the internal wrapper\n // div, not just inform sizing. Consumers occasionally need `trigger` to be\n // a small anchor node (e.g. a 0-height span) sitting inside a larger,\n // variable-content field (chips, wrapped text); anchoring position to the\n // wrapper instead of that field silently drifts as soon as the field's\n // internal layout changes, since the wrapper only ever contains `trigger`\n // itself, never the field around it.\n const getTriggerElement = useCallback(\n (): HTMLElement | null => externalTriggerRef?.current ?? triggerRef.current,\n [externalTriggerRef],\n );\n\n const calculateDynamicSizing = useCallback(\n (triggerRect: DOMRect) => {\n // Shrink the panel to its content by default. This prevents the\n // position:fixed element from expanding to viewport width when children\n // use `width:100%` or `flex:1`. `minWidth` (set below) still wins when\n // the trigger is wider than the content, as CSS min-width overrides width.\n const styles: Record<string, string | number> = { width: 'max-content' };\n\n if (autoWidth && (externalTriggerRef?.current || triggerRef.current)) {\n const triggerWidth = triggerRect.width;\n styles.minWidth = triggerWidth;\n }\n\n if (minWidth !== undefined) {\n styles.minWidth = typeof minWidth === 'number' ? `${minWidth}px` : minWidth;\n }\n if (maxWidth !== undefined) {\n if (maxWidth === 'auto') {\n styles.maxWidth = 'none';\n } else {\n styles.maxWidth = typeof maxWidth === 'number' ? `${maxWidth}px` : maxWidth;\n }\n }\n if (minHeight !== undefined) {\n styles.minHeight = typeof minHeight === 'number' ? `${minHeight}px` : minHeight;\n }\n if (maxHeight !== undefined) {\n if (maxHeight === 'auto') {\n styles.maxHeight = 'none';\n } else {\n styles.maxHeight = typeof maxHeight === 'number' ? `${maxHeight}px` : maxHeight;\n }\n }\n\n const hasHeightConstraint = minHeight !== undefined || maxHeight !== undefined;\n if (hasHeightConstraint) {\n styles.overflowY = 'auto';\n } else {\n styles.overflowY = 'visible';\n }\n\n return styles;\n },\n [autoWidth, externalTriggerRef, minWidth, maxWidth, minHeight, maxHeight],\n );\n\n const calculateOptimalPosition = useCallback(\n (triggerRect: DOMRect, contentRect: DOMRect) => {\n const viewportWidth = window.innerWidth;\n const viewportHeight = window.innerHeight;\n const gap = 8;\n\n let placement: 'top' | 'bottom' | 'left' | 'right' = preferredPlacement;\n let top = 0;\n let left = 0;\n\n // Helpers for cross-axis alignment\n const alignedLeft = (() => {\n switch (align) {\n case 'end':\n return triggerRect.right - contentRect.width;\n case 'center':\n return triggerRect.left + (triggerRect.width - contentRect.width) / 2;\n default:\n return triggerRect.left; // \"start\"\n }\n })();\n const alignedTop = (() => {\n switch (align) {\n case 'end':\n return triggerRect.bottom - contentRect.height;\n case 'center':\n return triggerRect.top + (triggerRect.height - contentRect.height) / 2;\n default:\n return triggerRect.top; // \"start\"\n }\n })();\n\n switch (preferredPlacement) {\n case 'top':\n top = triggerRect.top - contentRect.height - gap;\n left = alignedLeft;\n break;\n case 'bottom':\n top = triggerRect.bottom + gap;\n left = alignedLeft;\n break;\n case 'left':\n top = alignedTop;\n left = triggerRect.left - contentRect.width - gap;\n break;\n case 'right':\n top = alignedTop;\n left = triggerRect.right + gap;\n break;\n }\n\n if (placement === 'top' && top < gap) {\n placement = 'bottom';\n top = triggerRect.bottom + gap;\n } else if (placement === 'bottom' && top + contentRect.height > viewportHeight - gap) {\n placement = 'top';\n top = triggerRect.top - contentRect.height - gap;\n } else if (placement === 'left' && left < gap) {\n placement = 'right';\n left = triggerRect.right + gap;\n } else if (placement === 'right' && left + contentRect.width > viewportWidth - gap) {\n placement = 'left';\n left = triggerRect.left - contentRect.width - gap;\n }\n\n // Always clamp to both viewport edges - not just the near one - regardless\n // of whether an explicit min/max size was passed. `autoWidth` consumers\n // (Combobox, Select, TagInput suggestions, Menu, ...) never set\n // minWidth/maxWidth, so gating this on those props left the far edge\n // (right/bottom) completely unclamped and let content overflow the\n // viewport whenever it rendered wider/taller than its trigger.\n top = Math.max(gap, Math.min(top, viewportHeight - contentRect.height - gap));\n\n left = Math.max(gap, Math.min(left, viewportWidth - contentRect.width - gap));\n\n return { top, left, placement };\n },\n [preferredPlacement, align],\n );\n\n const handleScroll = useCallback(() => {\n if (!dropdownState.isVisible || !dropdownState.isPositioned || isScrollingRef.current) return;\n\n isScrollingRef.current = true;\n\n animationFrameRef.current = requestAnimationFrame(() => {\n const triggerElement = getTriggerElement();\n if (triggerElement && contentRef.current) {\n const triggerRect = triggerElement.getBoundingClientRect();\n const contentRect = contentRef.current.getBoundingClientRect();\n\n const { top, left, placement } = calculateOptimalPosition(triggerRect, contentRect);\n\n setDropdownState((prev) => ({\n ...prev,\n position: { top, left, placement },\n }));\n }\n\n isScrollingRef.current = false;\n });\n }, [\n dropdownState.isVisible,\n dropdownState.isPositioned,\n calculateOptimalPosition,\n getTriggerElement,\n ]);\n\n const handleTriggerClick = useCallback(() => {\n if (disabled) return;\n\n if (dropdownState.isVisible) {\n setDropdownState((prev) => ({\n ...prev,\n isVisible: false,\n isPositioned: false,\n }));\n } else {\n if (dropdownGroup) {\n const siblingDropdowns = document.querySelectorAll(\n `[data-dropdown-group=\"${dropdownGroup}\"][data-dropdown-content]`,\n );\n siblingDropdowns.forEach((dropdown) => {\n const dropdownElement = dropdown as HTMLElement;\n\n dropdownElement.dispatchEvent(new CustomEvent('closeSibling'));\n });\n }\n\n if (delay > 0) {\n timeoutRef.current = setTimeout(() => {\n setDropdownState((prev) => ({\n ...prev,\n isVisible: true,\n isPositioned: false,\n }));\n }, delay);\n } else {\n setDropdownState((prev) => ({\n ...prev,\n isVisible: true,\n isPositioned: false,\n }));\n }\n }\n }, [disabled, dropdownState.isVisible, delay, dropdownGroup]);\n\n useEffect(() => {\n const handleCloseSibling = () => {\n if (dropdownState.isVisible) {\n setDropdownState((prev) => ({\n ...prev,\n isVisible: false,\n isPositioned: false,\n }));\n }\n };\n\n const currentContentRef = contentRef.current;\n if (currentContentRef) {\n currentContentRef.addEventListener('closeSibling', handleCloseSibling);\n }\n\n return () => {\n if (currentContentRef) {\n currentContentRef.removeEventListener('closeSibling', handleCloseSibling);\n }\n };\n }, [dropdownState.isVisible]);\n\n const handleClickOutside = useCallback(\n (event: MouseEvent) => {\n if (!closeOnClickOutside || !dropdownState.isVisible) return;\n\n const target = event.target as Node;\n\n if (contentRef.current?.contains(target)) {\n return;\n }\n\n if (getTriggerElement()?.contains(target)) {\n return;\n }\n\n const allDropdowns = document.querySelectorAll('[data-dropdown-content]');\n for (const dropdown of allDropdowns) {\n if (dropdown === contentRef.current) continue;\n\n if (dropdown.contains(target)) {\n const clickedDropdownLevel = parseInt(\n dropdown.getAttribute('data-dropdown-level') || '0',\n );\n\n if (clickedDropdownLevel > actualLevel) {\n return;\n }\n }\n }\n\n setDropdownState((prev) => ({\n ...prev,\n isVisible: false,\n isPositioned: false,\n }));\n },\n [closeOnClickOutside, dropdownState.isVisible, actualLevel, getTriggerElement],\n );\n\n const handleEscapeKey = useCallback(\n (event: KeyboardEvent) => {\n if (closeOnEscape && event.key === 'Escape' && dropdownState.isVisible) {\n setDropdownState((prev) => ({\n ...prev,\n isVisible: false,\n isPositioned: false,\n }));\n }\n },\n [closeOnEscape, dropdownState.isVisible],\n );\n\n useEffect(() => {\n const triggerElement = getTriggerElement();\n if (\n dropdownState.isVisible &&\n !dropdownState.isPositioned &&\n contentRef.current &&\n triggerElement\n ) {\n const triggerRect = triggerElement.getBoundingClientRect();\n const contentRect = contentRef.current.getBoundingClientRect();\n\n const { top, left, placement } = calculateOptimalPosition(triggerRect, contentRect);\n\n setDropdownState((prev) => ({\n ...prev,\n position: { top, left, placement },\n isPositioned: true,\n }));\n }\n }, [\n dropdownState.isVisible,\n dropdownState.isPositioned,\n calculateOptimalPosition,\n getTriggerElement,\n ]);\n\n useEffect(() => {\n const handleResize = () => {\n const triggerElement = getTriggerElement();\n if (\n dropdownState.isVisible &&\n dropdownState.isPositioned &&\n contentRef.current &&\n triggerElement\n ) {\n const triggerRect = triggerElement.getBoundingClientRect();\n const contentRect = contentRef.current.getBoundingClientRect();\n\n const { top, left, placement } = calculateOptimalPosition(triggerRect, contentRect);\n\n setDropdownState((prev) => ({\n ...prev,\n position: { top, left, placement },\n }));\n }\n };\n\n window.addEventListener('resize', handleResize);\n return () => window.removeEventListener('resize', handleResize);\n }, [\n dropdownState.isVisible,\n dropdownState.isPositioned,\n calculateOptimalPosition,\n getTriggerElement,\n ]);\n\n useEffect(() => {\n if (dropdownState.isVisible) {\n window.addEventListener('scroll', handleScroll, { passive: true });\n\n document.body.addEventListener('scroll', handleScroll, { passive: true });\n }\n\n return () => {\n window.removeEventListener('scroll', handleScroll);\n document.body.removeEventListener('scroll', handleScroll);\n };\n }, [dropdownState.isVisible, handleScroll]);\n\n useEffect(() => {\n if (dropdownState.isVisible) {\n document.addEventListener('mousedown', handleClickOutside);\n document.addEventListener('keydown', handleEscapeKey);\n }\n\n return () => {\n document.removeEventListener('mousedown', handleClickOutside);\n document.removeEventListener('keydown', handleEscapeKey);\n };\n }, [dropdownState.isVisible, handleClickOutside, handleEscapeKey]);\n\n useEffect(() => {\n return () => {\n if (timeoutRef.current) {\n clearTimeout(timeoutRef.current);\n }\n if (animationFrameRef.current) {\n cancelAnimationFrame(animationFrameRef.current);\n }\n };\n }, []);\n\n return (\n <>\n {/*\n A positioning and click-capturing wrapper, and nothing more - it\n deliberately carries no `role` and no `tabIndex`.\n\n It used to be `role=\"button\" tabIndex={-1}`, which was wrong in both\n directions at once. `tabIndex={-1}` with no key handler meant the\n wrapper was never keyboard-operable, so the button role it advertised\n could not be activated by anyone using a keyboard - it promised a\n control that did not exist. Meanwhile, because `trigger` is virtually\n always a real control (Select and Combobox pass an `<input>`, Menu and\n SplitButton a `<button>`, ...), the role wrapped an interactive element\n in another interactive element: invalid ARIA, flagged by axe as\n `nested-interactive`, and announced by screen readers as a button\n inside a button. One attribute did this across every component built\n on Dropdown - Select, Combobox, Menu, Popover, ContextMenu,\n ColorPicker and TagInput - 212 violations in a single axe run.\n\n Semantics belong to whatever is passed as `trigger`, which is the only\n element that can actually own them. A consumer passing a\n non-interactive node should pass a `<button>` instead; it was never\n keyboard-accessible under the old markup either.\n */}\n <div\n ref={triggerRef}\n onClick={handleTriggerClick}\n className={`eidos-dropdown-trigger ${fullWidth ? fullWidthModifier('eidos-dropdown-trigger') : ''} ${triggerClassName}`}\n >\n {trigger}\n </div>\n {dropdownState.isVisible &&\n createPortal(\n <div\n ref={contentRef}\n data-dropdown-content\n data-dropdown-level={actualLevel}\n data-dropdown-group={dropdownGroup || ''}\n className={`eidos-dropdown-content eidos-dropdown-content--${dropdownState.position.placement} ${isNested ? 'eidos-dropdown-content--nested' : ''} ${dropdownState.isPositioned ? 'eidos-dropdown-content--positioned' : ''} ${contentClassName || ''}`}\n style={{\n top: dropdownState.position.top,\n left: dropdownState.position.left,\n ...calculateDynamicSizing(\n getTriggerElement()?.getBoundingClientRect() || new DOMRect(),\n ),\n }}\n role=\"menu\"\n >\n {content}\n </div>,\n document.body,\n )}\n </>\n );\n};\n\nexport const Dropdown: React.FC<DropdownProps> = (props) => {\n const context = useDropdownContext();\n const nextLevel = props.dropdownLevel !== undefined ? props.dropdownLevel : context.level + 1;\n\n return (\n <DropdownProvider level={nextLevel}>\n <DropdownInternal {...props} />\n </DropdownProvider>\n );\n};\n\nDropdown.displayName = 'Dropdown';\n"]}
|
|
1
|
+
{"version":3,"sources":["/home/runner/work/eidos-ui/eidos-ui/dist/chunk-P7J6WZTO.cjs","../src/components/Dropdown/Dropdown.context.types.ts","../src/components/Dropdown/Dropdown.context.tsx","../src/components/Dropdown/Dropdown.hooks.ts","../src/components/Dropdown/Dropdown.component.tsx"],"names":["jsx"],"mappings":"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","file":"/home/runner/work/eidos-ui/eidos-ui/dist/chunk-P7J6WZTO.cjs","sourcesContent":[null,"import { createContext } from 'react';\n\nexport interface DropdownContextValue {\n level: number;\n}\n\nexport const DropdownContext = createContext<DropdownContextValue>({ level: 0 });\n","import React from 'react';\nimport { DropdownContext } from './Dropdown.context.types';\n\nexport const DropdownProvider: React.FC<{ children: React.ReactNode; level?: number }> = ({\n children,\n level = 0,\n}) => {\n return <DropdownContext.Provider value={{ level }}>{children}</DropdownContext.Provider>;\n};\n","import { useContext } from 'react';\nimport { DropdownContext } from './Dropdown.context.types';\n\nexport const useDropdownContext = () => {\n return useContext(DropdownContext);\n};\n","import React, { useState, useRef, useCallback, useEffect } from 'react';\nimport { createPortal } from 'react-dom';\nimport { fullWidthModifier } from '../../utils';\nimport type { DropdownProps, DropdownState } from './Dropdown.types';\nimport { DropdownProvider } from './Dropdown.context';\nimport { useDropdownContext } from './Dropdown.hooks';\n\nconst DropdownInternal: React.FC<DropdownProps> = ({\n trigger,\n content,\n placement: preferredPlacement = 'bottom',\n align = 'start',\n delay = 0,\n disabled = false,\n defaultOpen = false,\n triggerClassName = '',\n contentClassName = '',\n closeOnClickOutside = true,\n closeOnEscape = true,\n minWidth,\n maxWidth,\n minHeight,\n maxHeight,\n autoWidth = true,\n fullWidth = false,\n triggerRef: externalTriggerRef,\n isNested = false,\n dropdownLevel,\n dropdownGroup,\n}) => {\n const context = useDropdownContext();\n const actualLevel = dropdownLevel !== undefined ? dropdownLevel : context.level;\n const [dropdownState, setDropdownState] = useState<DropdownState>({\n isVisible: defaultOpen,\n isPositioned: false,\n position: { top: 0, left: 0, placement: preferredPlacement },\n });\n const triggerRef = useRef<HTMLDivElement>(null);\n const contentRef = useRef<HTMLDivElement>(null);\n const timeoutRef = useRef<ReturnType<typeof setTimeout> | undefined>(undefined);\n const animationFrameRef = useRef<number | undefined>(undefined);\n const isScrollingRef = useRef(false);\n\n // The element to actually measure/anchor against. When a consumer passes\n // `triggerRef`, that's an explicit statement of \"this is what I want the\n // dropdown positioned relative to\" - it must win over the internal wrapper\n // div, not just inform sizing. Consumers occasionally need `trigger` to be\n // a small anchor node (e.g. a 0-height span) sitting inside a larger,\n // variable-content field (chips, wrapped text); anchoring position to the\n // wrapper instead of that field silently drifts as soon as the field's\n // internal layout changes, since the wrapper only ever contains `trigger`\n // itself, never the field around it.\n const getTriggerElement = useCallback(\n (): HTMLElement | null => externalTriggerRef?.current ?? triggerRef.current,\n [externalTriggerRef],\n );\n\n const calculateDynamicSizing = useCallback(\n (triggerRect: DOMRect) => {\n // Shrink the panel to its content by default. This prevents the\n // position:fixed element from expanding to viewport width when children\n // use `width:100%` or `flex:1`. `minWidth` (set below) still wins when\n // the trigger is wider than the content, as CSS min-width overrides width.\n const styles: Record<string, string | number> = { width: 'max-content' };\n\n if (autoWidth && (externalTriggerRef?.current || triggerRef.current)) {\n const triggerWidth = triggerRect.width;\n styles.minWidth = triggerWidth;\n }\n\n if (minWidth !== undefined) {\n styles.minWidth = typeof minWidth === 'number' ? `${minWidth}px` : minWidth;\n }\n if (maxWidth !== undefined) {\n if (maxWidth === 'auto') {\n styles.maxWidth = 'none';\n } else {\n styles.maxWidth = typeof maxWidth === 'number' ? `${maxWidth}px` : maxWidth;\n }\n }\n if (minHeight !== undefined) {\n styles.minHeight = typeof minHeight === 'number' ? `${minHeight}px` : minHeight;\n }\n if (maxHeight !== undefined) {\n if (maxHeight === 'auto') {\n styles.maxHeight = 'none';\n } else {\n styles.maxHeight = typeof maxHeight === 'number' ? `${maxHeight}px` : maxHeight;\n }\n }\n\n const hasHeightConstraint = minHeight !== undefined || maxHeight !== undefined;\n if (hasHeightConstraint) {\n styles.overflowY = 'auto';\n } else {\n styles.overflowY = 'visible';\n }\n\n return styles;\n },\n [autoWidth, externalTriggerRef, minWidth, maxWidth, minHeight, maxHeight],\n );\n\n const calculateOptimalPosition = useCallback(\n (triggerRect: DOMRect, contentRect: DOMRect) => {\n const viewportWidth = window.innerWidth;\n const viewportHeight = window.innerHeight;\n const gap = 8;\n\n let placement: 'top' | 'bottom' | 'left' | 'right' = preferredPlacement;\n let top = 0;\n let left = 0;\n\n // Helpers for cross-axis alignment\n const alignedLeft = (() => {\n switch (align) {\n case 'end':\n return triggerRect.right - contentRect.width;\n case 'center':\n return triggerRect.left + (triggerRect.width - contentRect.width) / 2;\n default:\n return triggerRect.left; // \"start\"\n }\n })();\n const alignedTop = (() => {\n switch (align) {\n case 'end':\n return triggerRect.bottom - contentRect.height;\n case 'center':\n return triggerRect.top + (triggerRect.height - contentRect.height) / 2;\n default:\n return triggerRect.top; // \"start\"\n }\n })();\n\n switch (preferredPlacement) {\n case 'top':\n top = triggerRect.top - contentRect.height - gap;\n left = alignedLeft;\n break;\n case 'bottom':\n top = triggerRect.bottom + gap;\n left = alignedLeft;\n break;\n case 'left':\n top = alignedTop;\n left = triggerRect.left - contentRect.width - gap;\n break;\n case 'right':\n top = alignedTop;\n left = triggerRect.right + gap;\n break;\n }\n\n if (placement === 'top' && top < gap) {\n placement = 'bottom';\n top = triggerRect.bottom + gap;\n } else if (placement === 'bottom' && top + contentRect.height > viewportHeight - gap) {\n placement = 'top';\n top = triggerRect.top - contentRect.height - gap;\n } else if (placement === 'left' && left < gap) {\n placement = 'right';\n left = triggerRect.right + gap;\n } else if (placement === 'right' && left + contentRect.width > viewportWidth - gap) {\n placement = 'left';\n left = triggerRect.left - contentRect.width - gap;\n }\n\n // Always clamp to both viewport edges - not just the near one - regardless\n // of whether an explicit min/max size was passed. `autoWidth` consumers\n // (Combobox, Select, TagInput suggestions, Menu, ...) never set\n // minWidth/maxWidth, so gating this on those props left the far edge\n // (right/bottom) completely unclamped and let content overflow the\n // viewport whenever it rendered wider/taller than its trigger.\n top = Math.max(gap, Math.min(top, viewportHeight - contentRect.height - gap));\n\n left = Math.max(gap, Math.min(left, viewportWidth - contentRect.width - gap));\n\n return { top, left, placement };\n },\n [preferredPlacement, align],\n );\n\n const handleScroll = useCallback(() => {\n if (!dropdownState.isVisible || !dropdownState.isPositioned || isScrollingRef.current) return;\n\n isScrollingRef.current = true;\n\n animationFrameRef.current = requestAnimationFrame(() => {\n const triggerElement = getTriggerElement();\n if (triggerElement && contentRef.current) {\n const triggerRect = triggerElement.getBoundingClientRect();\n const contentRect = contentRef.current.getBoundingClientRect();\n\n const { top, left, placement } = calculateOptimalPosition(triggerRect, contentRect);\n\n setDropdownState((prev) => ({\n ...prev,\n position: { top, left, placement },\n }));\n }\n\n isScrollingRef.current = false;\n });\n }, [\n dropdownState.isVisible,\n dropdownState.isPositioned,\n calculateOptimalPosition,\n getTriggerElement,\n ]);\n\n const handleTriggerClick = useCallback(() => {\n if (disabled) return;\n\n if (dropdownState.isVisible) {\n setDropdownState((prev) => ({\n ...prev,\n isVisible: false,\n isPositioned: false,\n }));\n } else {\n if (dropdownGroup) {\n const siblingDropdowns = document.querySelectorAll(\n `[data-dropdown-group=\"${dropdownGroup}\"][data-dropdown-content]`,\n );\n siblingDropdowns.forEach((dropdown) => {\n const dropdownElement = dropdown as HTMLElement;\n\n dropdownElement.dispatchEvent(new CustomEvent('closeSibling'));\n });\n }\n\n if (delay > 0) {\n timeoutRef.current = setTimeout(() => {\n setDropdownState((prev) => ({\n ...prev,\n isVisible: true,\n isPositioned: false,\n }));\n }, delay);\n } else {\n setDropdownState((prev) => ({\n ...prev,\n isVisible: true,\n isPositioned: false,\n }));\n }\n }\n }, [disabled, dropdownState.isVisible, delay, dropdownGroup]);\n\n useEffect(() => {\n const handleCloseSibling = () => {\n if (dropdownState.isVisible) {\n setDropdownState((prev) => ({\n ...prev,\n isVisible: false,\n isPositioned: false,\n }));\n }\n };\n\n const currentContentRef = contentRef.current;\n if (currentContentRef) {\n currentContentRef.addEventListener('closeSibling', handleCloseSibling);\n }\n\n return () => {\n if (currentContentRef) {\n currentContentRef.removeEventListener('closeSibling', handleCloseSibling);\n }\n };\n }, [dropdownState.isVisible]);\n\n const handleClickOutside = useCallback(\n (event: MouseEvent) => {\n if (!closeOnClickOutside || !dropdownState.isVisible) return;\n\n const target = event.target as Node;\n\n if (contentRef.current?.contains(target)) {\n return;\n }\n\n if (getTriggerElement()?.contains(target)) {\n return;\n }\n\n const allDropdowns = document.querySelectorAll('[data-dropdown-content]');\n for (const dropdown of allDropdowns) {\n if (dropdown === contentRef.current) continue;\n\n if (dropdown.contains(target)) {\n const clickedDropdownLevel = parseInt(\n dropdown.getAttribute('data-dropdown-level') || '0',\n );\n\n if (clickedDropdownLevel > actualLevel) {\n return;\n }\n }\n }\n\n setDropdownState((prev) => ({\n ...prev,\n isVisible: false,\n isPositioned: false,\n }));\n },\n [closeOnClickOutside, dropdownState.isVisible, actualLevel, getTriggerElement],\n );\n\n const handleEscapeKey = useCallback(\n (event: KeyboardEvent) => {\n if (closeOnEscape && event.key === 'Escape' && dropdownState.isVisible) {\n setDropdownState((prev) => ({\n ...prev,\n isVisible: false,\n isPositioned: false,\n }));\n }\n },\n [closeOnEscape, dropdownState.isVisible],\n );\n\n useEffect(() => {\n const triggerElement = getTriggerElement();\n if (\n dropdownState.isVisible &&\n !dropdownState.isPositioned &&\n contentRef.current &&\n triggerElement\n ) {\n const triggerRect = triggerElement.getBoundingClientRect();\n const contentRect = contentRef.current.getBoundingClientRect();\n\n const { top, left, placement } = calculateOptimalPosition(triggerRect, contentRect);\n\n setDropdownState((prev) => ({\n ...prev,\n position: { top, left, placement },\n isPositioned: true,\n }));\n }\n }, [\n dropdownState.isVisible,\n dropdownState.isPositioned,\n calculateOptimalPosition,\n getTriggerElement,\n ]);\n\n useEffect(() => {\n const handleResize = () => {\n const triggerElement = getTriggerElement();\n if (\n dropdownState.isVisible &&\n dropdownState.isPositioned &&\n contentRef.current &&\n triggerElement\n ) {\n const triggerRect = triggerElement.getBoundingClientRect();\n const contentRect = contentRef.current.getBoundingClientRect();\n\n const { top, left, placement } = calculateOptimalPosition(triggerRect, contentRect);\n\n setDropdownState((prev) => ({\n ...prev,\n position: { top, left, placement },\n }));\n }\n };\n\n window.addEventListener('resize', handleResize);\n return () => window.removeEventListener('resize', handleResize);\n }, [\n dropdownState.isVisible,\n dropdownState.isPositioned,\n calculateOptimalPosition,\n getTriggerElement,\n ]);\n\n useEffect(() => {\n if (dropdownState.isVisible) {\n window.addEventListener('scroll', handleScroll, { passive: true });\n\n document.body.addEventListener('scroll', handleScroll, { passive: true });\n }\n\n return () => {\n window.removeEventListener('scroll', handleScroll);\n document.body.removeEventListener('scroll', handleScroll);\n };\n }, [dropdownState.isVisible, handleScroll]);\n\n useEffect(() => {\n if (dropdownState.isVisible) {\n document.addEventListener('mousedown', handleClickOutside);\n document.addEventListener('keydown', handleEscapeKey);\n }\n\n return () => {\n document.removeEventListener('mousedown', handleClickOutside);\n document.removeEventListener('keydown', handleEscapeKey);\n };\n }, [dropdownState.isVisible, handleClickOutside, handleEscapeKey]);\n\n useEffect(() => {\n return () => {\n if (timeoutRef.current) {\n clearTimeout(timeoutRef.current);\n }\n if (animationFrameRef.current) {\n cancelAnimationFrame(animationFrameRef.current);\n }\n };\n }, []);\n\n return (\n <>\n {/*\n A positioning and click-capturing wrapper, and nothing more - it\n deliberately carries no `role` and no `tabIndex`.\n\n It used to be `role=\"button\" tabIndex={-1}`, which was wrong in both\n directions at once. `tabIndex={-1}` with no key handler meant the\n wrapper was never keyboard-operable, so the button role it advertised\n could not be activated by anyone using a keyboard - it promised a\n control that did not exist. Meanwhile, because `trigger` is virtually\n always a real control (Select and Combobox pass an `<input>`, Menu and\n SplitButton a `<button>`, ...), the role wrapped an interactive element\n in another interactive element: invalid ARIA, flagged by axe as\n `nested-interactive`, and announced by screen readers as a button\n inside a button. One attribute did this across every component built\n on Dropdown - Select, Combobox, Menu, Popover, ContextMenu,\n ColorPicker and TagInput - 212 violations in a single axe run.\n\n Semantics belong to whatever is passed as `trigger`, which is the only\n element that can actually own them. A consumer passing a\n non-interactive node should pass a `<button>` instead; it was never\n keyboard-accessible under the old markup either.\n */}\n <div\n ref={triggerRef}\n onClick={handleTriggerClick}\n className={`eidos-dropdown-trigger ${fullWidth ? fullWidthModifier('eidos-dropdown-trigger') : ''} ${triggerClassName}`}\n >\n {trigger}\n </div>\n {dropdownState.isVisible &&\n createPortal(\n <div\n ref={contentRef}\n data-dropdown-content\n data-dropdown-level={actualLevel}\n data-dropdown-group={dropdownGroup || ''}\n className={`eidos-dropdown-content eidos-dropdown-content--${dropdownState.position.placement} ${isNested ? 'eidos-dropdown-content--nested' : ''} ${dropdownState.isPositioned ? 'eidos-dropdown-content--positioned' : ''} ${contentClassName || ''}`}\n style={{\n top: dropdownState.position.top,\n left: dropdownState.position.left,\n ...calculateDynamicSizing(\n getTriggerElement()?.getBoundingClientRect() || new DOMRect(),\n ),\n }}\n role=\"menu\"\n >\n {content}\n </div>,\n document.body,\n )}\n </>\n );\n};\n\nexport const Dropdown: React.FC<DropdownProps> = (props) => {\n const context = useDropdownContext();\n const nextLevel = props.dropdownLevel !== undefined ? props.dropdownLevel : context.level + 1;\n\n return (\n <DropdownProvider level={nextLevel}>\n <DropdownInternal {...props} />\n </DropdownProvider>\n );\n};\n\nDropdown.displayName = 'Dropdown';\n"]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
devWarn
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-WT4WBHBR.js";
|
|
4
4
|
|
|
5
5
|
// src/components/ThemeProvider/ThemeProvider.component.tsx
|
|
6
6
|
import { useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from "react";
|
|
@@ -521,4 +521,4 @@ export {
|
|
|
521
521
|
isFontAvailable,
|
|
522
522
|
isFontStackAvailable
|
|
523
523
|
};
|
|
524
|
-
//# sourceMappingURL=chunk-
|
|
524
|
+
//# sourceMappingURL=chunk-PG2EII6U.js.map
|