@mieweb/ui 0.11.0-dev.30 → 0.11.0-dev.32
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/agent/README.md +7 -7
- package/agent/agents/mieweb-ui-design.agent.md +8 -3
- package/agent/agents/mieweb-ui-i18n.agent.md +91 -0
- package/agent/agents/mieweb-ui-styling.agent.md +1 -1
- package/agent/skills/mieweb-ui-catalog/SKILL.md +15 -10
- package/agent/skills/mieweb-ui-catalog/selection-guidance.md +14 -7
- package/agent/skills/mieweb-ui-i18n-checklist/SKILL.md +133 -0
- package/dist/CsvBlock-AV4VM7JT.cjs +18 -0
- package/dist/{CsvBlock-RGO7JXHJ.cjs.map → CsvBlock-AV4VM7JT.cjs.map} +1 -1
- package/dist/CsvBlock-XBNYCEMP.js +9 -0
- package/dist/{CsvBlock-CFXSDPBI.js.map → CsvBlock-XBNYCEMP.js.map} +1 -1
- package/dist/HtmlPreviewBlock-DQAVD6IO.cjs +18 -0
- package/dist/{HtmlPreviewBlock-VBYXCXVT.cjs.map → HtmlPreviewBlock-DQAVD6IO.cjs.map} +1 -1
- package/dist/HtmlPreviewBlock-QQHRNLIY.js +9 -0
- package/dist/{HtmlPreviewBlock-Z2GCK325.js.map → HtmlPreviewBlock-QQHRNLIY.js.map} +1 -1
- package/dist/MermaidBlock-LHGYKC23.cjs +18 -0
- package/dist/{MermaidBlock-I2R2BQOX.cjs.map → MermaidBlock-LHGYKC23.cjs.map} +1 -1
- package/dist/MermaidBlock-QPKMIP3B.js +9 -0
- package/dist/{MermaidBlock-XCAK7IA5.js.map → MermaidBlock-QPKMIP3B.js.map} +1 -1
- package/dist/SurveyBlock-6DPTWHKI.js +9 -0
- package/dist/{SurveyBlock-KI5JOWCL.js.map → SurveyBlock-6DPTWHKI.js.map} +1 -1
- package/dist/SurveyBlock-6IXNVHS5.cjs +18 -0
- package/dist/{SurveyBlock-UKSGISRT.cjs.map → SurveyBlock-6IXNVHS5.cjs.map} +1 -1
- package/dist/{chunk-7XKM6V2K.cjs → chunk-2OXNJJHJ.cjs} +8 -8
- package/dist/{chunk-7XKM6V2K.cjs.map → chunk-2OXNJJHJ.cjs.map} +1 -1
- package/dist/{chunk-AJPFQF3H.cjs → chunk-2R3ILG4Y.cjs} +11 -11
- package/dist/{chunk-AJPFQF3H.cjs.map → chunk-2R3ILG4Y.cjs.map} +1 -1
- package/dist/{chunk-XQHDQ64G.cjs → chunk-2Z2GFDRS.cjs} +4 -4
- package/dist/{chunk-XQHDQ64G.cjs.map → chunk-2Z2GFDRS.cjs.map} +1 -1
- package/dist/{chunk-GM32IDVL.cjs → chunk-32ZILZ2T.cjs} +6 -6
- package/dist/{chunk-GM32IDVL.cjs.map → chunk-32ZILZ2T.cjs.map} +1 -1
- package/dist/{chunk-VOEXGDL5.js → chunk-33Y3KQWL.js} +3 -3
- package/dist/{chunk-VOEXGDL5.js.map → chunk-33Y3KQWL.js.map} +1 -1
- package/dist/{chunk-GYXSF6BJ.cjs → chunk-3IKIRGHI.cjs} +6 -6
- package/dist/{chunk-GYXSF6BJ.cjs.map → chunk-3IKIRGHI.cjs.map} +1 -1
- package/dist/{chunk-5HKZR6UG.js → chunk-43L4KGLU.js} +4 -4
- package/dist/{chunk-5HKZR6UG.js.map → chunk-43L4KGLU.js.map} +1 -1
- package/dist/{chunk-6BNZLN4B.cjs → chunk-4I5V6SXP.cjs} +10 -10
- package/dist/{chunk-6BNZLN4B.cjs.map → chunk-4I5V6SXP.cjs.map} +1 -1
- package/dist/{chunk-NUFUV43P.cjs → chunk-4UDEMJE4.cjs} +2 -2
- package/dist/chunk-4UDEMJE4.cjs.map +1 -0
- package/dist/{chunk-L5Y52F2E.cjs → chunk-4VSK3EE5.cjs} +4 -4
- package/dist/{chunk-L5Y52F2E.cjs.map → chunk-4VSK3EE5.cjs.map} +1 -1
- package/dist/{chunk-Y7ZJZLJY.js → chunk-566FIEPE.js} +4 -4
- package/dist/{chunk-Y7ZJZLJY.js.map → chunk-566FIEPE.js.map} +1 -1
- package/dist/{chunk-UTIPENPW.cjs → chunk-67SD6VPF.cjs} +5 -5
- package/dist/{chunk-UTIPENPW.cjs.map → chunk-67SD6VPF.cjs.map} +1 -1
- package/dist/{chunk-6CGM5H4J.js → chunk-6LIC3DKE.js} +2 -2
- package/dist/chunk-6LIC3DKE.js.map +1 -0
- package/dist/{chunk-6N7NMOSV.js → chunk-76ECYE5G.js} +3 -3
- package/dist/{chunk-6N7NMOSV.js.map → chunk-76ECYE5G.js.map} +1 -1
- package/dist/{chunk-56VTM4OX.js → chunk-7LKTIZLR.js} +3 -3
- package/dist/{chunk-56VTM4OX.js.map → chunk-7LKTIZLR.js.map} +1 -1
- package/dist/{chunk-7C5W744U.cjs → chunk-ARRJRFPD.cjs} +8 -8
- package/dist/{chunk-7C5W744U.cjs.map → chunk-ARRJRFPD.cjs.map} +1 -1
- package/dist/{chunk-5KGYTNOA.cjs → chunk-BP4LXRC6.cjs} +9 -9
- package/dist/{chunk-5KGYTNOA.cjs.map → chunk-BP4LXRC6.cjs.map} +1 -1
- package/dist/{chunk-UNFDIBKJ.js → chunk-CLNTWFEB.js} +3 -3
- package/dist/{chunk-UNFDIBKJ.js.map → chunk-CLNTWFEB.js.map} +1 -1
- package/dist/{chunk-X5JOEZVR.js → chunk-CRSJRWN2.js} +4 -4
- package/dist/{chunk-X5JOEZVR.js.map → chunk-CRSJRWN2.js.map} +1 -1
- package/dist/{chunk-FIKO4WR6.js → chunk-CVMD2A3J.js} +3 -3
- package/dist/{chunk-FIKO4WR6.js.map → chunk-CVMD2A3J.js.map} +1 -1
- package/dist/{chunk-SMPLM6K3.js → chunk-DG3CXR24.js} +5 -5
- package/dist/{chunk-SMPLM6K3.js.map → chunk-DG3CXR24.js.map} +1 -1
- package/dist/{chunk-LRAAJRE7.cjs → chunk-DO7EED3B.cjs} +154 -154
- package/dist/{chunk-LRAAJRE7.cjs.map → chunk-DO7EED3B.cjs.map} +1 -1
- package/dist/{chunk-UJDWFDKE.js → chunk-DXKE4YZT.js} +3 -3
- package/dist/{chunk-UJDWFDKE.js.map → chunk-DXKE4YZT.js.map} +1 -1
- package/dist/{chunk-KQ6GLYFZ.cjs → chunk-ECKIFQSD.cjs} +6 -6
- package/dist/{chunk-KQ6GLYFZ.cjs.map → chunk-ECKIFQSD.cjs.map} +1 -1
- package/dist/{chunk-4P27Y52M.js → chunk-EPKPHWIL.js} +4 -4
- package/dist/{chunk-4P27Y52M.js.map → chunk-EPKPHWIL.js.map} +1 -1
- package/dist/{chunk-RIUQP2QS.cjs → chunk-FNSFMM4F.cjs} +5 -5
- package/dist/{chunk-RIUQP2QS.cjs.map → chunk-FNSFMM4F.cjs.map} +1 -1
- package/dist/{chunk-3Y3ZCDNF.cjs → chunk-FQUSSPXX.cjs} +19 -19
- package/dist/{chunk-3Y3ZCDNF.cjs.map → chunk-FQUSSPXX.cjs.map} +1 -1
- package/dist/{chunk-ANMX7YDL.cjs → chunk-FSARTLUE.cjs} +4 -4
- package/dist/{chunk-ANMX7YDL.cjs.map → chunk-FSARTLUE.cjs.map} +1 -1
- package/dist/{chunk-ERACGSDY.cjs → chunk-G42V64UW.cjs} +8 -8
- package/dist/{chunk-ERACGSDY.cjs.map → chunk-G42V64UW.cjs.map} +1 -1
- package/dist/{chunk-UUI7WXI5.js → chunk-GAI6SRJ3.js} +3 -3
- package/dist/{chunk-UUI7WXI5.js.map → chunk-GAI6SRJ3.js.map} +1 -1
- package/dist/{chunk-4I6BW3FB.js → chunk-GLRKXJCR.js} +3 -3
- package/dist/{chunk-4I6BW3FB.js.map → chunk-GLRKXJCR.js.map} +1 -1
- package/dist/{chunk-NPKPCYAT.cjs → chunk-GM376OD6.cjs} +17 -17
- package/dist/{chunk-NPKPCYAT.cjs.map → chunk-GM376OD6.cjs.map} +1 -1
- package/dist/{chunk-DXEPYK3I.cjs → chunk-HGJHWI7W.cjs} +5 -3
- package/dist/chunk-HGJHWI7W.cjs.map +1 -0
- package/dist/{chunk-6ZA574PU.cjs → chunk-IIV5GNSK.cjs} +5 -5
- package/dist/{chunk-6ZA574PU.cjs.map → chunk-IIV5GNSK.cjs.map} +1 -1
- package/dist/{chunk-XPVQI3MM.cjs → chunk-INMDLVUB.cjs} +17 -2
- package/dist/chunk-INMDLVUB.cjs.map +1 -0
- package/dist/{chunk-RZSSQ7AT.js → chunk-JATLYCS4.js} +3 -3
- package/dist/{chunk-RZSSQ7AT.js.map → chunk-JATLYCS4.js.map} +1 -1
- package/dist/{chunk-4NB4WOGU.cjs → chunk-JCO62XMU.cjs} +6 -6
- package/dist/{chunk-4NB4WOGU.cjs.map → chunk-JCO62XMU.cjs.map} +1 -1
- package/dist/{chunk-QR7B6UPR.js → chunk-JN2CL7MK.js} +3 -3
- package/dist/{chunk-QR7B6UPR.js.map → chunk-JN2CL7MK.js.map} +1 -1
- package/dist/{chunk-FBCDYTWM.js → chunk-JNSSA4YN.js} +3 -3
- package/dist/{chunk-FBCDYTWM.js.map → chunk-JNSSA4YN.js.map} +1 -1
- package/dist/{chunk-BIQIE3VW.js → chunk-JQAGNAY2.js} +5 -5
- package/dist/{chunk-BIQIE3VW.js.map → chunk-JQAGNAY2.js.map} +1 -1
- package/dist/{chunk-TOJ56HKQ.cjs → chunk-KD7YD6US.cjs} +8 -8
- package/dist/{chunk-TOJ56HKQ.cjs.map → chunk-KD7YD6US.cjs.map} +1 -1
- package/dist/{chunk-5LNLB2XT.js → chunk-KSQQBFDQ.js} +3 -3
- package/dist/{chunk-5LNLB2XT.js.map → chunk-KSQQBFDQ.js.map} +1 -1
- package/dist/{chunk-3NOVISM6.js → chunk-L52HKEUD.js} +3 -3
- package/dist/{chunk-3NOVISM6.js.map → chunk-L52HKEUD.js.map} +1 -1
- package/dist/{chunk-IXUIOR4K.cjs → chunk-M42FTWY2.cjs} +6 -6
- package/dist/{chunk-IXUIOR4K.cjs.map → chunk-M42FTWY2.cjs.map} +1 -1
- package/dist/{chunk-32ZCJOSR.cjs → chunk-N7AIZWQS.cjs} +4 -4
- package/dist/{chunk-32ZCJOSR.cjs.map → chunk-N7AIZWQS.cjs.map} +1 -1
- package/dist/{chunk-P7D7BYFE.js → chunk-NA3NRLX2.js} +4 -4
- package/dist/{chunk-P7D7BYFE.js.map → chunk-NA3NRLX2.js.map} +1 -1
- package/dist/{chunk-Y424YL55.js → chunk-OLA7OYAS.js} +3 -3
- package/dist/{chunk-Y424YL55.js.map → chunk-OLA7OYAS.js.map} +1 -1
- package/dist/{chunk-F6W62K4J.js → chunk-OWYWRBED.js} +3 -3
- package/dist/{chunk-F6W62K4J.js.map → chunk-OWYWRBED.js.map} +1 -1
- package/dist/{chunk-RSJGTWLM.js → chunk-OYLZ5PF2.js} +3 -3
- package/dist/{chunk-RSJGTWLM.js.map → chunk-OYLZ5PF2.js.map} +1 -1
- package/dist/{chunk-7XC6E4BT.cjs → chunk-PJN4HM2X.cjs} +37 -37
- package/dist/{chunk-7XC6E4BT.cjs.map → chunk-PJN4HM2X.cjs.map} +1 -1
- package/dist/{chunk-NIO3XVUV.js → chunk-PLBWZW4F.js} +4 -4
- package/dist/{chunk-NIO3XVUV.js.map → chunk-PLBWZW4F.js.map} +1 -1
- package/dist/{chunk-XI74P5F2.cjs → chunk-PW2E7YBD.cjs} +5 -5
- package/dist/{chunk-XI74P5F2.cjs.map → chunk-PW2E7YBD.cjs.map} +1 -1
- package/dist/{chunk-HDY7YQFX.js → chunk-Q5APDRMO.js} +3 -3
- package/dist/{chunk-HDY7YQFX.js.map → chunk-Q5APDRMO.js.map} +1 -1
- package/dist/{chunk-FGLIP6YR.js → chunk-QATEO4KC.js} +4 -4
- package/dist/{chunk-FGLIP6YR.js.map → chunk-QATEO4KC.js.map} +1 -1
- package/dist/{chunk-254QK722.cjs → chunk-QHCAWDMG.cjs} +18 -7
- package/dist/chunk-QHCAWDMG.cjs.map +1 -0
- package/dist/{chunk-7HFZL5V5.js → chunk-QNJEDBIN.js} +4 -4
- package/dist/{chunk-7HFZL5V5.js.map → chunk-QNJEDBIN.js.map} +1 -1
- package/dist/{chunk-AIJYZP7M.js → chunk-R3MJKY63.js} +6 -6
- package/dist/{chunk-AIJYZP7M.js.map → chunk-R3MJKY63.js.map} +1 -1
- package/dist/{chunk-N54FYWG6.js → chunk-R5P7NAJQ.js} +4 -4
- package/dist/{chunk-N54FYWG6.js.map → chunk-R5P7NAJQ.js.map} +1 -1
- package/dist/{chunk-BWSZ2BHJ.cjs → chunk-S6457ZNC.cjs} +5 -5
- package/dist/{chunk-BWSZ2BHJ.cjs.map → chunk-S6457ZNC.cjs.map} +1 -1
- package/dist/{chunk-Z2OOJGHL.cjs → chunk-SCYLVQWA.cjs} +53 -53
- package/dist/{chunk-Z2OOJGHL.cjs.map → chunk-SCYLVQWA.cjs.map} +1 -1
- package/dist/{chunk-7IRTD4JT.cjs → chunk-SGDNEIJM.cjs} +4 -4
- package/dist/{chunk-7IRTD4JT.cjs.map → chunk-SGDNEIJM.cjs.map} +1 -1
- package/dist/{chunk-4JXO5JTE.js → chunk-SNAMNKFH.js} +17 -2
- package/dist/chunk-SNAMNKFH.js.map +1 -0
- package/dist/{chunk-GW4RFJZ5.js → chunk-TUYWCUKH.js} +18 -7
- package/dist/chunk-TUYWCUKH.js.map +1 -0
- package/dist/{chunk-CLQW724U.cjs → chunk-TXB3UHIO.cjs} +9 -9
- package/dist/{chunk-CLQW724U.cjs.map → chunk-TXB3UHIO.cjs.map} +1 -1
- package/dist/{chunk-4RI3CQGE.js → chunk-ULEX7OOJ.js} +4 -4
- package/dist/{chunk-4RI3CQGE.js.map → chunk-ULEX7OOJ.js.map} +1 -1
- package/dist/{chunk-KDW6BD4O.cjs → chunk-UVVZD3AS.cjs} +4 -4
- package/dist/{chunk-KDW6BD4O.cjs.map → chunk-UVVZD3AS.cjs.map} +1 -1
- package/dist/{chunk-MA3Y6AYA.cjs → chunk-V2KSJLUL.cjs} +8 -8
- package/dist/{chunk-MA3Y6AYA.cjs.map → chunk-V2KSJLUL.cjs.map} +1 -1
- package/dist/{chunk-SW2E7XKY.cjs → chunk-VIVS44IG.cjs} +9 -9
- package/dist/{chunk-SW2E7XKY.cjs.map → chunk-VIVS44IG.cjs.map} +1 -1
- package/dist/{chunk-GVM6DTR5.js → chunk-VP3XNLUL.js} +5 -3
- package/dist/chunk-VP3XNLUL.js.map +1 -0
- package/dist/{chunk-IGDO62KR.cjs → chunk-VVKUYQER.cjs} +5 -5
- package/dist/{chunk-IGDO62KR.cjs.map → chunk-VVKUYQER.cjs.map} +1 -1
- package/dist/{chunk-BJ6ABRSQ.cjs → chunk-WG2ANSDG.cjs} +6 -6
- package/dist/{chunk-BJ6ABRSQ.cjs.map → chunk-WG2ANSDG.cjs.map} +1 -1
- package/dist/{chunk-WFBUBT54.js → chunk-WX2XB6FP.js} +3 -3
- package/dist/{chunk-WFBUBT54.js.map → chunk-WX2XB6FP.js.map} +1 -1
- package/dist/{chunk-7QW6TU4X.js → chunk-YCPWQWQQ.js} +3 -3
- package/dist/{chunk-7QW6TU4X.js.map → chunk-YCPWQWQQ.js.map} +1 -1
- package/dist/{chunk-DSQCYX7L.js → chunk-YSIFPHLX.js} +7 -7
- package/dist/{chunk-DSQCYX7L.js.map → chunk-YSIFPHLX.js.map} +1 -1
- package/dist/{chunk-2X54ZLT6.js → chunk-ZFJJMDV3.js} +4 -4
- package/dist/{chunk-2X54ZLT6.js.map → chunk-ZFJJMDV3.js.map} +1 -1
- package/dist/{chunk-PYI2IWNX.cjs → chunk-ZOSM6D7F.cjs} +4 -4
- package/dist/{chunk-PYI2IWNX.cjs.map → chunk-ZOSM6D7F.cjs.map} +1 -1
- package/dist/components/ActionPlan/index.cjs +6 -6
- package/dist/components/ActionPlan/index.js +4 -4
- package/dist/components/ActivityFeed/index.cjs +6 -6
- package/dist/components/ActivityFeed/index.js +4 -4
- package/dist/components/AlertDialog/index.cjs +7 -7
- package/dist/components/AlertDialog/index.js +3 -3
- package/dist/components/AssociationList/index.cjs +6 -6
- package/dist/components/AssociationList/index.js +4 -4
- package/dist/components/Button/index.cjs +4 -4
- package/dist/components/Button/index.d.cts +1 -1
- package/dist/components/Button/index.d.ts +1 -1
- package/dist/components/Button/index.js +2 -2
- package/dist/components/CalendarView/index.cjs +5 -5
- package/dist/components/CalendarView/index.js +3 -3
- package/dist/components/CustomizableDashboard/index.cjs +10 -10
- package/dist/components/CustomizableDashboard/index.js +3 -3
- package/dist/components/EmailEditor/index.cjs +14 -14
- package/dist/components/EmailEditor/index.js +5 -5
- package/dist/components/FieldHistory/index.cjs +6 -6
- package/dist/components/FieldHistory/index.js +4 -4
- package/dist/components/FloatingWindow/index.cjs +5 -5
- package/dist/components/FloatingWindow/index.js +3 -3
- package/dist/components/ListView/index.cjs +5 -5
- package/dist/components/ListView/index.js +3 -3
- package/dist/components/Markdown/index.cjs +17 -17
- package/dist/components/Markdown/index.js +8 -8
- package/dist/components/MediaEditor/index.cjs +12 -12
- package/dist/components/MediaEditor/index.d.cts +13 -0
- package/dist/components/MediaEditor/index.d.ts +13 -0
- package/dist/components/MediaEditor/index.js +7 -7
- package/dist/components/MediaFeed/index.cjs +6 -6
- package/dist/components/MediaFeed/index.js +5 -5
- package/dist/components/MediaPlayer/index.cjs +7 -7
- package/dist/components/MediaPlayer/index.js +4 -4
- package/dist/components/MegaMenu/index.cjs +6 -6
- package/dist/components/MegaMenu/index.js +3 -3
- package/dist/components/RadialExplorer/index.cjs +4 -4
- package/dist/components/RadialExplorer/index.js +3 -3
- package/dist/components/RecordHeader/index.cjs +5 -5
- package/dist/components/RecordHeader/index.d.cts +1 -1
- package/dist/components/RecordHeader/index.d.ts +1 -1
- package/dist/components/RecordHeader/index.js +3 -3
- package/dist/components/RichTextEditor/index.cjs +6 -6
- package/dist/components/RichTextEditor/index.js +3 -3
- package/dist/components/SectionSpyNav/index.cjs +4 -4
- package/dist/components/SectionSpyNav/index.js +3 -3
- package/dist/components/SuperChat/index.cjs +9 -9
- package/dist/components/SuperChat/index.js +5 -5
- package/dist/components/Textarea/index.cjs +7 -7
- package/dist/components/Textarea/index.js +4 -4
- package/dist/components/TranscriptView/index.cjs +2 -2
- package/dist/components/TranscriptView/index.d.cts +14 -1
- package/dist/components/TranscriptView/index.d.ts +14 -1
- package/dist/components/TranscriptView/index.js +1 -1
- package/dist/components/ViewSet/index.cjs +6 -6
- package/dist/components/ViewSet/index.js +5 -5
- package/dist/datavis.cjs +3 -3
- package/dist/datavis.js +2 -2
- package/dist/deck.cjs +15 -15
- package/dist/deck.js +2 -2
- package/dist/esheet.cjs +130 -130
- package/dist/esheet.js +8 -8
- package/dist/hooks/index.cjs +12 -12
- package/dist/hooks/index.d.cts +15 -2
- package/dist/hooks/index.d.ts +15 -2
- package/dist/hooks/index.js +3 -3
- package/dist/index.cjs +2056 -418
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +178 -87
- package/dist/index.d.ts +178 -87
- package/dist/index.js +1693 -55
- package/dist/index.js.map +1 -1
- package/dist/{model-Y7WRIGGA.cjs → model-NPW2JMHZ.cjs} +20 -20
- package/dist/{model-Y7WRIGGA.cjs.map → model-NPW2JMHZ.cjs.map} +1 -1
- package/dist/{model-WFFZRQMY.js → model-SG5H3TCJ.js} +6 -6
- package/dist/{model-WFFZRQMY.js.map → model-SG5H3TCJ.js.map} +1 -1
- package/dist/org-chart.cjs +4 -4
- package/dist/org-chart.js +2 -2
- package/dist/styles.css +1 -1
- package/dist/tailwind-preset.cjs +4 -4
- package/dist/tailwind-preset.js +1 -1
- package/dist/templates.cjs +38 -38
- package/dist/templates.js +3 -3
- package/package.json +1 -1
- package/dist/CsvBlock-CFXSDPBI.js +0 -9
- package/dist/CsvBlock-RGO7JXHJ.cjs +0 -18
- package/dist/HtmlPreviewBlock-VBYXCXVT.cjs +0 -18
- package/dist/HtmlPreviewBlock-Z2GCK325.js +0 -9
- package/dist/MermaidBlock-I2R2BQOX.cjs +0 -18
- package/dist/MermaidBlock-XCAK7IA5.js +0 -9
- package/dist/SurveyBlock-KI5JOWCL.js +0 -9
- package/dist/SurveyBlock-UKSGISRT.cjs +0 -18
- package/dist/chunk-254QK722.cjs.map +0 -1
- package/dist/chunk-4JXO5JTE.js.map +0 -1
- package/dist/chunk-6CGM5H4J.js.map +0 -1
- package/dist/chunk-DXEPYK3I.cjs.map +0 -1
- package/dist/chunk-GVM6DTR5.js.map +0 -1
- package/dist/chunk-GW4RFJZ5.js.map +0 -1
- package/dist/chunk-NUFUV43P.cjs.map +0 -1
- package/dist/chunk-XPVQI3MM.cjs.map +0 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { defaultViewLabels, accentClasses } from './chunk-3YBS4WUQ.js';
|
|
2
2
|
import { Spinner } from './chunk-UA7E7PDS.js';
|
|
3
3
|
import { ChevronRight, ChevronDown } from './chunk-BKSPDTX4.js';
|
|
4
|
-
import { Button } from './chunk-
|
|
4
|
+
import { Button } from './chunk-WX2XB6FP.js';
|
|
5
5
|
import { cn } from './chunk-TQONQSJO.js';
|
|
6
6
|
import * as React from 'react';
|
|
7
7
|
import { cva } from 'class-variance-authority';
|
|
@@ -254,5 +254,5 @@ function ListView({
|
|
|
254
254
|
}
|
|
255
255
|
|
|
256
256
|
export { ListView, itemVariants };
|
|
257
|
-
//# sourceMappingURL=chunk-
|
|
258
|
-
//# sourceMappingURL=chunk-
|
|
257
|
+
//# sourceMappingURL=chunk-CLNTWFEB.js.map
|
|
258
|
+
//# sourceMappingURL=chunk-CLNTWFEB.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/ListView/ListView.tsx"],"names":[],"mappings":"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","file":"chunk-UNFDIBKJ.js","sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { cn } from '../../utils/cn';\nimport { Button } from '../Button';\nimport { Spinner } from '../Spinner';\nimport { ChevronDownIcon, ChevronRightIcon } from '../Icons';\nimport {\n accentClasses,\n defaultViewLabels,\n type Stage,\n type ViewBaseProps,\n} from '../../views/types';\n\n// =============================================================================\n// Types\n// =============================================================================\n\nexport type ListViewSlot =\n | 'group'\n | 'groupHeader'\n | 'item'\n | 'selectedItem'\n | 'state';\n\nexport interface ListViewProps<T>\n extends ViewBaseProps<T>, VariantProps<typeof itemVariants> {\n /**\n * Group rows by `accessors.getStatus`, using these stages for order and\n * labels. Items whose status matches no stage are appended under their own\n * heading rather than dropped.\n */\n stages?: readonly Stage[];\n /** Group by `accessors.getGroup` instead of by stage. */\n groupBy?: 'status' | 'group' | 'none';\n /** Groups that start collapsed. Uncontrolled; the user can reopen them. */\n defaultCollapsedGroups?: readonly string[];\n /** Retries the failed load. Renders the retry action only when provided. */\n onRetry?: () => void;\n classNames?: Partial<Record<ListViewSlot, string>>;\n /** Heading level for group headers, under the page's own heading. */\n headingLevel?: 'h2' | 'h3' | 'h4';\n}\n\ninterface Group<T> {\n id: string;\n label: string;\n accent?: Stage['accent'];\n items: T[];\n}\n\n// =============================================================================\n// Variants\n// =============================================================================\n\nconst itemVariants = cva(\n [\n 'flex w-full items-start gap-3 border-b border-border px-3 text-start',\n 'last:border-b-0',\n 'transition-colors',\n 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-ring',\n ],\n {\n variants: {\n density: {\n comfortable: 'py-3',\n compact: 'py-2',\n },\n interactive: {\n true: 'cursor-pointer hover:bg-muted',\n false: '',\n },\n selected: {\n true: 'bg-primary-500/10',\n false: '',\n },\n },\n defaultVariants: {\n density: 'comfortable',\n interactive: false,\n selected: false,\n },\n }\n);\n\n// =============================================================================\n// Grouping\n// =============================================================================\n\nfunction buildGroups<T>(\n items: T[],\n groupBy: 'status' | 'group' | 'none',\n accessors: ListViewProps<T>['accessors'],\n ungrouped: string,\n stages?: readonly Stage[]\n): Group<T>[] {\n if (groupBy === 'none') return [{ id: '', label: '', items }];\n\n const read = groupBy === 'status' ? accessors.getStatus : accessors.getGroup;\n if (!read) return [{ id: '', label: '', items }];\n\n const buckets = new Map<string, T[]>();\n for (const item of items) {\n const key = read(item) ?? '';\n const bucket = buckets.get(key);\n if (bucket) bucket.push(item);\n else buckets.set(key, [item]);\n }\n\n const groups: Group<T>[] = [];\n // Stages fix the order, and an empty stage still shows — a board column that\n // disappears when it empties hides the fact that the stage exists. This only\n // applies to `groupBy=\"status\"`: stages name statuses, so seeding them under\n // `groupBy=\"group\"` would print an empty \"Backlog\"/\"In progress\" above the\n // real buckets. `ViewSet` always passes its shared stages, so that case is\n // reachable with nothing more than `listProps={{ groupBy: 'group' }}`.\n for (const stage of (groupBy === 'status' ? stages : undefined) ?? []) {\n groups.push({\n id: stage.id,\n label: stage.label,\n accent: stage.accent,\n items: buckets.get(stage.id) ?? [],\n });\n buckets.delete(stage.id);\n }\n for (const [key, bucket] of buckets) {\n groups.push({ id: key, label: key || ungrouped, items: bucket });\n }\n return groups;\n}\n\n// =============================================================================\n// Component\n// =============================================================================\n\n/**\n * Declared `parameters.catalog.collection` — the three load states below are\n * part of this component's API, not decoration.\n */\nexport function ListView<T>({\n items,\n accessors,\n loading = false,\n error = null,\n selectedId = null,\n onOpen,\n getHref,\n renderItem,\n emptyState,\n labels,\n stages,\n groupBy = stages ? 'status' : 'none',\n defaultCollapsedGroups,\n onRetry,\n density,\n className,\n classNames,\n headingLevel: Heading = 'h3',\n}: ListViewProps<T>) {\n const text = { ...defaultViewLabels, ...labels };\n // Ids come from position, not from the status text: two distinct statuses can\n // normalise to the same string, and a duplicate id makes `aria-labelledby`\n // resolve to the wrong heading.\n const baseId = React.useId();\n const [collapsed, setCollapsed] = React.useState<Set<string>>(\n () => new Set(defaultCollapsedGroups ?? [])\n );\n\n const groups = React.useMemo(\n () => buildGroups(items, groupBy, accessors, text.ungrouped, stages),\n [items, groupBy, accessors, text.ungrouped, stages]\n );\n\n const state = (content: React.ReactNode) => (\n <div\n data-slot=\"list-view-state\"\n className={cn(\n 'text-muted-foreground flex flex-col items-center justify-center gap-2 px-4 py-10 text-center text-sm',\n classNames?.state\n )}\n >\n {content}\n </div>\n );\n\n let body: React.ReactNode;\n if (error) {\n body = state(\n <>\n <p role=\"alert\" className=\"text-destructive\">\n {text.error}\n </p>\n {onRetry && (\n <Button variant=\"ghost\" size=\"sm\" onClick={onRetry}>\n {text.retry}\n </Button>\n )}\n </>\n );\n } else if (loading) {\n // Spinner is the status region and carries the accessible name; the visible\n // copy beside it would otherwise be announced twice.\n body = state(\n <span className=\"flex items-center gap-2\">\n <Spinner size=\"sm\" label={text.loading} />\n <span aria-hidden>{text.loading}</span>\n </span>\n );\n } else if (items.length === 0) {\n body = emptyState ?? state(text.empty);\n } else {\n body = groups.map((group, groupIndex) => {\n const isCollapsed = collapsed.has(group.id);\n const headerId = `${baseId}-group-${groupIndex}`;\n return (\n <section\n key={group.id}\n data-slot=\"list-view-group\"\n className={cn(classNames?.group)}\n >\n {group.label && (\n <Heading className=\"sticky top-0 z-10\">\n <button\n type=\"button\"\n id={headerId}\n aria-expanded={!isCollapsed}\n onClick={() =>\n setCollapsed((prev) => {\n const next = new Set(prev);\n if (!next.delete(group.id)) next.add(group.id);\n return next;\n })\n }\n data-slot=\"list-view-group-header\"\n className={cn(\n 'border-border bg-muted text-muted-foreground flex w-full items-center gap-2 border-b px-3 py-2 text-start text-xs font-semibold tracking-wide uppercase',\n 'focus-visible:ring-ring focus-visible:ring-2 focus-visible:outline-none focus-visible:ring-inset',\n classNames?.groupHeader\n )}\n >\n {isCollapsed ? (\n <ChevronRightIcon\n className=\"size-3.5 rtl:rotate-180\"\n aria-hidden\n />\n ) : (\n <ChevronDownIcon className=\"size-3.5\" aria-hidden />\n )}\n {group.accent && (\n <span\n aria-hidden\n className={cn(\n 'size-2 shrink-0 rounded-full',\n accentClasses[group.accent].marker\n )}\n />\n )}\n <span>{group.label}</span>\n <span className=\"ms-auto font-normal tabular-nums\">\n {group.items.length}\n </span>\n </button>\n </Heading>\n )}\n {!isCollapsed && (\n <ul aria-labelledby={group.label ? headerId : undefined}>\n {group.items.map((item) => {\n const id = accessors.getId(item);\n const selected = id === selectedId;\n const accent = accessors.getAccent?.(item);\n const subtitle = accessors.getSubtitle?.(item);\n const content = renderItem?.(item, { view: 'list' }) ?? (\n <>\n {accent && (\n <span\n aria-hidden\n className={cn(\n 'mt-1.5 size-2 shrink-0 rounded-full',\n accentClasses[accent].marker\n )}\n />\n )}\n <span className=\"min-w-0 flex-1\">\n <span className=\"text-foreground block truncate font-medium\">\n {accessors.getTitle(item)}\n </span>\n {subtitle && (\n <span className=\"text-muted-foreground block truncate text-sm\">\n {subtitle}\n </span>\n )}\n </span>\n </>\n );\n const classes = cn(\n itemVariants({\n density,\n interactive: Boolean(onOpen || getHref),\n selected,\n }),\n classNames?.item,\n selected && classNames?.selectedItem\n );\n const href = getHref?.(id, item);\n return (\n <li key={id}>\n {href ? (\n // An anchor, not a handler, so the row is middle-clickable\n // and crawlable; onOpen still runs for router navigation.\n <a\n href={href}\n aria-current={selected ? 'true' : undefined}\n data-slot=\"list-view-item\"\n className={classes}\n onClick={(event) => {\n if (\n !onOpen ||\n event.defaultPrevented ||\n event.metaKey ||\n event.ctrlKey ||\n event.shiftKey ||\n event.button !== 0\n )\n return;\n event.preventDefault();\n onOpen(id, item);\n }}\n >\n {content}\n </a>\n ) : onOpen ? (\n <button\n type=\"button\"\n aria-current={selected ? 'true' : undefined}\n data-slot=\"list-view-item\"\n className={classes}\n onClick={() => onOpen(id, item)}\n >\n {content}\n </button>\n ) : (\n <div data-slot=\"list-view-item\" className={classes}>\n {content}\n </div>\n )}\n </li>\n );\n })}\n {group.items.length === 0 && (\n <li className=\"text-muted-foreground px-3 py-2 text-sm\">\n {text.empty}\n </li>\n )}\n </ul>\n )}\n </section>\n );\n });\n }\n\n return (\n <div\n data-slot=\"list-view\"\n className={cn(\n 'border-border bg-card overflow-hidden rounded-lg border',\n className\n )}\n >\n {body}\n </div>\n );\n}\n\nexport { itemVariants as listViewItemVariants };\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/components/ListView/ListView.tsx"],"names":[],"mappings":"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","file":"chunk-CLNTWFEB.js","sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { cn } from '../../utils/cn';\nimport { Button } from '../Button';\nimport { Spinner } from '../Spinner';\nimport { ChevronDownIcon, ChevronRightIcon } from '../Icons';\nimport {\n accentClasses,\n defaultViewLabels,\n type Stage,\n type ViewBaseProps,\n} from '../../views/types';\n\n// =============================================================================\n// Types\n// =============================================================================\n\nexport type ListViewSlot =\n | 'group'\n | 'groupHeader'\n | 'item'\n | 'selectedItem'\n | 'state';\n\nexport interface ListViewProps<T>\n extends ViewBaseProps<T>, VariantProps<typeof itemVariants> {\n /**\n * Group rows by `accessors.getStatus`, using these stages for order and\n * labels. Items whose status matches no stage are appended under their own\n * heading rather than dropped.\n */\n stages?: readonly Stage[];\n /** Group by `accessors.getGroup` instead of by stage. */\n groupBy?: 'status' | 'group' | 'none';\n /** Groups that start collapsed. Uncontrolled; the user can reopen them. */\n defaultCollapsedGroups?: readonly string[];\n /** Retries the failed load. Renders the retry action only when provided. */\n onRetry?: () => void;\n classNames?: Partial<Record<ListViewSlot, string>>;\n /** Heading level for group headers, under the page's own heading. */\n headingLevel?: 'h2' | 'h3' | 'h4';\n}\n\ninterface Group<T> {\n id: string;\n label: string;\n accent?: Stage['accent'];\n items: T[];\n}\n\n// =============================================================================\n// Variants\n// =============================================================================\n\nconst itemVariants = cva(\n [\n 'flex w-full items-start gap-3 border-b border-border px-3 text-start',\n 'last:border-b-0',\n 'transition-colors',\n 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-ring',\n ],\n {\n variants: {\n density: {\n comfortable: 'py-3',\n compact: 'py-2',\n },\n interactive: {\n true: 'cursor-pointer hover:bg-muted',\n false: '',\n },\n selected: {\n true: 'bg-primary-500/10',\n false: '',\n },\n },\n defaultVariants: {\n density: 'comfortable',\n interactive: false,\n selected: false,\n },\n }\n);\n\n// =============================================================================\n// Grouping\n// =============================================================================\n\nfunction buildGroups<T>(\n items: T[],\n groupBy: 'status' | 'group' | 'none',\n accessors: ListViewProps<T>['accessors'],\n ungrouped: string,\n stages?: readonly Stage[]\n): Group<T>[] {\n if (groupBy === 'none') return [{ id: '', label: '', items }];\n\n const read = groupBy === 'status' ? accessors.getStatus : accessors.getGroup;\n if (!read) return [{ id: '', label: '', items }];\n\n const buckets = new Map<string, T[]>();\n for (const item of items) {\n const key = read(item) ?? '';\n const bucket = buckets.get(key);\n if (bucket) bucket.push(item);\n else buckets.set(key, [item]);\n }\n\n const groups: Group<T>[] = [];\n // Stages fix the order, and an empty stage still shows — a board column that\n // disappears when it empties hides the fact that the stage exists. This only\n // applies to `groupBy=\"status\"`: stages name statuses, so seeding them under\n // `groupBy=\"group\"` would print an empty \"Backlog\"/\"In progress\" above the\n // real buckets. `ViewSet` always passes its shared stages, so that case is\n // reachable with nothing more than `listProps={{ groupBy: 'group' }}`.\n for (const stage of (groupBy === 'status' ? stages : undefined) ?? []) {\n groups.push({\n id: stage.id,\n label: stage.label,\n accent: stage.accent,\n items: buckets.get(stage.id) ?? [],\n });\n buckets.delete(stage.id);\n }\n for (const [key, bucket] of buckets) {\n groups.push({ id: key, label: key || ungrouped, items: bucket });\n }\n return groups;\n}\n\n// =============================================================================\n// Component\n// =============================================================================\n\n/**\n * Declared `parameters.catalog.collection` — the three load states below are\n * part of this component's API, not decoration.\n */\nexport function ListView<T>({\n items,\n accessors,\n loading = false,\n error = null,\n selectedId = null,\n onOpen,\n getHref,\n renderItem,\n emptyState,\n labels,\n stages,\n groupBy = stages ? 'status' : 'none',\n defaultCollapsedGroups,\n onRetry,\n density,\n className,\n classNames,\n headingLevel: Heading = 'h3',\n}: ListViewProps<T>) {\n const text = { ...defaultViewLabels, ...labels };\n // Ids come from position, not from the status text: two distinct statuses can\n // normalise to the same string, and a duplicate id makes `aria-labelledby`\n // resolve to the wrong heading.\n const baseId = React.useId();\n const [collapsed, setCollapsed] = React.useState<Set<string>>(\n () => new Set(defaultCollapsedGroups ?? [])\n );\n\n const groups = React.useMemo(\n () => buildGroups(items, groupBy, accessors, text.ungrouped, stages),\n [items, groupBy, accessors, text.ungrouped, stages]\n );\n\n const state = (content: React.ReactNode) => (\n <div\n data-slot=\"list-view-state\"\n className={cn(\n 'text-muted-foreground flex flex-col items-center justify-center gap-2 px-4 py-10 text-center text-sm',\n classNames?.state\n )}\n >\n {content}\n </div>\n );\n\n let body: React.ReactNode;\n if (error) {\n body = state(\n <>\n <p role=\"alert\" className=\"text-destructive\">\n {text.error}\n </p>\n {onRetry && (\n <Button variant=\"ghost\" size=\"sm\" onClick={onRetry}>\n {text.retry}\n </Button>\n )}\n </>\n );\n } else if (loading) {\n // Spinner is the status region and carries the accessible name; the visible\n // copy beside it would otherwise be announced twice.\n body = state(\n <span className=\"flex items-center gap-2\">\n <Spinner size=\"sm\" label={text.loading} />\n <span aria-hidden>{text.loading}</span>\n </span>\n );\n } else if (items.length === 0) {\n body = emptyState ?? state(text.empty);\n } else {\n body = groups.map((group, groupIndex) => {\n const isCollapsed = collapsed.has(group.id);\n const headerId = `${baseId}-group-${groupIndex}`;\n return (\n <section\n key={group.id}\n data-slot=\"list-view-group\"\n className={cn(classNames?.group)}\n >\n {group.label && (\n <Heading className=\"sticky top-0 z-10\">\n <button\n type=\"button\"\n id={headerId}\n aria-expanded={!isCollapsed}\n onClick={() =>\n setCollapsed((prev) => {\n const next = new Set(prev);\n if (!next.delete(group.id)) next.add(group.id);\n return next;\n })\n }\n data-slot=\"list-view-group-header\"\n className={cn(\n 'border-border bg-muted text-muted-foreground flex w-full items-center gap-2 border-b px-3 py-2 text-start text-xs font-semibold tracking-wide uppercase',\n 'focus-visible:ring-ring focus-visible:ring-2 focus-visible:outline-none focus-visible:ring-inset',\n classNames?.groupHeader\n )}\n >\n {isCollapsed ? (\n <ChevronRightIcon\n className=\"size-3.5 rtl:rotate-180\"\n aria-hidden\n />\n ) : (\n <ChevronDownIcon className=\"size-3.5\" aria-hidden />\n )}\n {group.accent && (\n <span\n aria-hidden\n className={cn(\n 'size-2 shrink-0 rounded-full',\n accentClasses[group.accent].marker\n )}\n />\n )}\n <span>{group.label}</span>\n <span className=\"ms-auto font-normal tabular-nums\">\n {group.items.length}\n </span>\n </button>\n </Heading>\n )}\n {!isCollapsed && (\n <ul aria-labelledby={group.label ? headerId : undefined}>\n {group.items.map((item) => {\n const id = accessors.getId(item);\n const selected = id === selectedId;\n const accent = accessors.getAccent?.(item);\n const subtitle = accessors.getSubtitle?.(item);\n const content = renderItem?.(item, { view: 'list' }) ?? (\n <>\n {accent && (\n <span\n aria-hidden\n className={cn(\n 'mt-1.5 size-2 shrink-0 rounded-full',\n accentClasses[accent].marker\n )}\n />\n )}\n <span className=\"min-w-0 flex-1\">\n <span className=\"text-foreground block truncate font-medium\">\n {accessors.getTitle(item)}\n </span>\n {subtitle && (\n <span className=\"text-muted-foreground block truncate text-sm\">\n {subtitle}\n </span>\n )}\n </span>\n </>\n );\n const classes = cn(\n itemVariants({\n density,\n interactive: Boolean(onOpen || getHref),\n selected,\n }),\n classNames?.item,\n selected && classNames?.selectedItem\n );\n const href = getHref?.(id, item);\n return (\n <li key={id}>\n {href ? (\n // An anchor, not a handler, so the row is middle-clickable\n // and crawlable; onOpen still runs for router navigation.\n <a\n href={href}\n aria-current={selected ? 'true' : undefined}\n data-slot=\"list-view-item\"\n className={classes}\n onClick={(event) => {\n if (\n !onOpen ||\n event.defaultPrevented ||\n event.metaKey ||\n event.ctrlKey ||\n event.shiftKey ||\n event.button !== 0\n )\n return;\n event.preventDefault();\n onOpen(id, item);\n }}\n >\n {content}\n </a>\n ) : onOpen ? (\n <button\n type=\"button\"\n aria-current={selected ? 'true' : undefined}\n data-slot=\"list-view-item\"\n className={classes}\n onClick={() => onOpen(id, item)}\n >\n {content}\n </button>\n ) : (\n <div data-slot=\"list-view-item\" className={classes}>\n {content}\n </div>\n )}\n </li>\n );\n })}\n {group.items.length === 0 && (\n <li className=\"text-muted-foreground px-3 py-2 text-sm\">\n {text.empty}\n </li>\n )}\n </ul>\n )}\n </section>\n );\n });\n }\n\n return (\n <div\n data-slot=\"list-view\"\n className={cn(\n 'border-border bg-card overflow-hidden rounded-lg border',\n className\n )}\n >\n {body}\n </div>\n );\n}\n\nexport { itemVariants as listViewItemVariants };\n"]}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { groupByDay, formatDayLabel, withLocale } from './chunk-YGS2TRMP.js';
|
|
2
2
|
import { usePendingOverrides } from './chunk-FTEZNCRI.js';
|
|
3
|
-
import { RecordState } from './chunk-
|
|
3
|
+
import { RecordState } from './chunk-OLA7OYAS.js';
|
|
4
4
|
import { Avatar } from './chunk-TI3TQQ7F.js';
|
|
5
5
|
import { accentClasses, toDateTime } from './chunk-3YBS4WUQ.js';
|
|
6
6
|
import { useLiveAnnouncement } from './chunk-HNXLLDPN.js';
|
|
7
7
|
import { usePrefersReducedMotion } from './chunk-XDU65GLW.js';
|
|
8
|
-
import { Button } from './chunk-
|
|
8
|
+
import { Button } from './chunk-WX2XB6FP.js';
|
|
9
9
|
import { cn } from './chunk-TQONQSJO.js';
|
|
10
10
|
import * as React from 'react';
|
|
11
11
|
import { DateTime } from 'luxon';
|
|
@@ -521,5 +521,5 @@ var ActivityFeed = React.forwardRef(ActivityFeedInner);
|
|
|
521
521
|
ActivityFeed.displayName = "ActivityFeed";
|
|
522
522
|
|
|
523
523
|
export { ActivityFeed, defaultActivityFeedLabels };
|
|
524
|
-
//# sourceMappingURL=chunk-
|
|
525
|
-
//# sourceMappingURL=chunk-
|
|
524
|
+
//# sourceMappingURL=chunk-CRSJRWN2.js.map
|
|
525
|
+
//# sourceMappingURL=chunk-CRSJRWN2.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/ActivityFeed/ActivityFeed.tsx"],"names":["body"],"mappings":"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","file":"chunk-X5JOEZVR.js","sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport { DateTime } from 'luxon';\nimport { Pin, Rows4, type LucideIcon } from 'lucide-react';\nimport { cn } from '../../utils/cn';\nimport { Avatar } from '../Avatar';\nimport { Button } from '../Button';\nimport { useLiveAnnouncement } from '../../hooks/useLiveAnnouncement';\nimport { usePrefersReducedMotion } from '../../hooks/usePrefersReducedMotion';\nimport { accentClasses, toDateTime, type Accent } from '../../views/types';\nimport { formatDayLabel, groupByDay, withLocale } from './dayGroups';\nimport { RecordState } from './RecordState';\nimport { usePendingOverrides } from './usePendingOverrides';\n\n// =============================================================================\n// Types\n// =============================================================================\n\nexport type ActivityFeedDensity = 'comfortable' | 'compact';\n\nexport interface ActivityFeedCategory {\n id: string;\n label: string;\n icon?: LucideIcon;\n /** Token name, resolved to `--mieweb-*` colours. */\n color?: Accent;\n}\n\nexport interface ActivityFeedActor {\n name: string;\n avatarUrl?: string;\n}\n\nexport interface ActivityFeedLabels {\n loading: string;\n empty: string;\n /** Shown when items exist but the active filters hide all of them. */\n noMatches: string;\n error: string;\n retry: string;\n today: string;\n yesterday: string;\n undated: string;\n pinned: string;\n /** Accessible name of the category filter group. */\n filters: string;\n /** The chip that clears every filter. */\n allCategories: string;\n compact: string;\n pin: string;\n loadMore: string;\n /** Announced politely after a filter change. */\n resultCount: (count: number) => string;\n}\n\nexport const defaultActivityFeedLabels: ActivityFeedLabels = {\n loading: 'Loading activity',\n empty: 'No activity yet',\n noMatches: 'No activity matches these filters',\n error: 'Could not load activity',\n retry: 'Try again',\n today: 'Today',\n yesterday: 'Yesterday',\n undated: 'Undated',\n pinned: 'Pinned',\n filters: 'Filter by category',\n allCategories: 'All',\n compact: 'Compact view',\n pin: 'Pin',\n loadMore: 'Load more',\n resultCount: (count) =>\n count === 1 ? '1 activity shown' : `${count} activities shown`,\n};\n\nexport type ActivityFeedSlot =\n | 'toolbar'\n | 'filter'\n | 'section'\n | 'dayHeader'\n | 'item'\n | 'highlightedItem'\n | 'state'\n | 'loadMore';\n\nexport interface ActivityFeedItemContext {\n density: ActivityFeedDensity;\n pinned: boolean;\n category?: ActivityFeedCategory;\n}\n\nexport interface ActivityFeedProps<T> extends Omit<\n React.HTMLAttributes<HTMLDivElement>,\n 'children'\n> {\n items: T[];\n getId: (item: T) => string;\n /** ISO string or `Date`. Date-only strings are wall dates in `timeZone`. */\n getDate: (item: T) => Date | string | null | undefined;\n /** Matched against `categories[].id`. */\n getCategory?: (item: T) => string | undefined;\n getTitle?: (item: T) => string | undefined;\n getDescription?: (item: T) => string | undefined;\n getActor?: (item: T) => ActivityFeedActor | undefined;\n /** Filter chips, icons and colours, in display order. */\n categories?: readonly ActivityFeedCategory[];\n loading?: boolean;\n error?: Error | null;\n onRetry?: () => void;\n /** BCP 47 locale for day headers and times. Defaults to the runtime's. */\n locale?: string;\n /** IANA zone that decides which day an item falls on. Defaults to local. */\n timeZone?: string;\n /** Pins \"today\" so stories and tests stay deterministic. */\n now?: Date;\n pinnedIds?: readonly string[];\n /** Receives the requested state; the row moves optimistically and restores on rejection. */\n onTogglePin?: (id: string, pinned: boolean) => void | Promise<void>;\n onOpen?: (id: string, item: T) => void;\n getHref?: (id: string, item: T) => string;\n /** Scrolls this row into view and highlights it — for deep links. */\n highlightedId?: string | null;\n hasMore?: boolean;\n /** The button shows pending until the returned promise settles. */\n onLoadMore?: () => void | Promise<void>;\n defaultCategories?: readonly string[];\n defaultDensity?: ActivityFeedDensity;\n /** Persists the selected categories and density in `localStorage` under this key. */\n storageKey?: string;\n /** Replaces the built-in row body. Pinning and opening still wrap it. */\n renderItem?: (item: T, context: ActivityFeedItemContext) => React.ReactNode;\n /** Extra content on the row's meta line (badges, durations, sentiment). */\n renderItemMeta?: (item: T) => React.ReactNode;\n /** Rendered under each day header, e.g. a roll-up of that day's calls. */\n renderDaySummary?: (dayKey: string, items: T[]) => React.ReactNode;\n emptyState?: React.ReactNode;\n labels?: Partial<ActivityFeedLabels>;\n classNames?: Partial<Record<ActivityFeedSlot, string>>;\n headingLevel?: 'h2' | 'h3' | 'h4';\n}\n\ninterface StoredPrefs {\n categories?: string[];\n density?: ActivityFeedDensity;\n}\n\nfunction readPrefs(key: string): StoredPrefs {\n try {\n const raw: unknown = JSON.parse(window.localStorage.getItem(key) ?? '{}');\n if (!raw || typeof raw !== 'object') return {};\n const { categories, density } = raw as Record<string, unknown>;\n return {\n categories:\n Array.isArray(categories) &&\n categories.every((c) => typeof c === 'string')\n ? categories\n : undefined,\n density:\n density === 'compact' || density === 'comfortable'\n ? density\n : undefined,\n };\n } catch {\n return {};\n }\n}\n\nfunction writePrefs(key: string, prefs: StoredPrefs) {\n try {\n window.localStorage.setItem(key, JSON.stringify(prefs));\n } catch {\n // Storage full or blocked: the preference just doesn't persist.\n }\n}\n\nconst chipClasses =\n 'inline-flex items-center gap-1.5 rounded-full border px-3 py-1 text-xs font-medium transition-colors motion-reduce:transition-none focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring';\n\n// =============================================================================\n// Component\n// =============================================================================\n\nfunction ActivityFeedInner<T>(\n {\n items,\n getId,\n getDate,\n getCategory,\n getTitle,\n getDescription,\n getActor,\n categories = [],\n loading = false,\n error = null,\n onRetry,\n locale,\n timeZone = 'local',\n now,\n pinnedIds,\n onTogglePin,\n onOpen,\n getHref,\n highlightedId = null,\n hasMore = false,\n onLoadMore,\n defaultCategories,\n defaultDensity = 'comfortable',\n storageKey,\n renderItem,\n renderItemMeta,\n renderDaySummary,\n emptyState,\n labels,\n classNames,\n headingLevel: Heading = 'h3',\n className,\n ...rest\n }: ActivityFeedProps<T>,\n ref: React.ForwardedRef<HTMLDivElement>\n) {\n const text = { ...defaultActivityFeedLabels, ...labels };\n const baseId = React.useId();\n const reducedMotion = usePrefersReducedMotion();\n const [announcement, announce] = useLiveAnnouncement();\n const [pinOverrides, runPin] = usePendingOverrides<boolean>();\n const [loadingMore, setLoadingMore] = React.useState(false);\n const [selected, setSelected] = React.useState<readonly string[]>(\n defaultCategories ?? []\n );\n const [density, setDensity] =\n React.useState<ActivityFeedDensity>(defaultDensity);\n const rowRefs = React.useRef(new Map<string, HTMLElement>());\n\n // Read after mount so server and first client render agree.\n React.useEffect(() => {\n if (!storageKey) return;\n const stored = readPrefs(storageKey);\n if (stored.categories) setSelected(stored.categories);\n if (stored.density) setDensity(stored.density);\n }, [storageKey]);\n\n React.useEffect(() => {\n if (!highlightedId) return;\n rowRefs.current.get(highlightedId)?.scrollIntoView?.({\n block: 'center',\n behavior: reducedMotion ? 'auto' : 'smooth',\n });\n }, [highlightedId, loading, reducedMotion]);\n\n const categoryById = React.useMemo(\n () => new Map(categories.map((c) => [c.id, c])),\n [categories]\n );\n // Persisted IDs may reference renamed/removed categories; applying them\n // verbatim would filter out everything with no chip shown as active.\n const effectiveFilter = React.useMemo(\n () => selected.filter((id) => categoryById.has(id)),\n [selected, categoryById]\n );\n const pinnedSet = React.useMemo(() => new Set(pinnedIds), [pinnedIds]);\n const isPinned = (id: string) => pinOverrides.get(id) ?? pinnedSet.has(id);\n const matches = (item: T, filter: readonly string[]) =>\n filter.length === 0 || filter.includes(getCategory?.(item) ?? '');\n\n const updateFilters = (next: readonly string[]) => {\n setSelected(next);\n if (storageKey) writePrefs(storageKey, { categories: [...next], density });\n announce(text.resultCount(items.filter((i) => matches(i, next)).length));\n };\n\n const toggleDensity = () => {\n const next = density === 'compact' ? 'comfortable' : 'compact';\n setDensity(next);\n if (storageKey)\n writePrefs(storageKey, { categories: [...selected], density: next });\n };\n\n const loadMore = async () => {\n if (!onLoadMore) return;\n setLoadingMore(true);\n try {\n await onLoadMore();\n } catch {\n // The caller reports the failure; the button becomes usable again.\n } finally {\n setLoadingMore(false);\n }\n };\n\n const zone = timeZone;\n const reference = now ?? new Date();\n const compact = density === 'compact';\n const visible = items.filter((item) => matches(item, effectiveFilter));\n const pinnedItems = groupByDay(\n visible.filter((item) => isPinned(getId(item))),\n getDate,\n zone\n ).flatMap((g) => g.items);\n const days = groupByDay(\n visible.filter((item) => !isPinned(getId(item))),\n getDate,\n zone\n );\n\n let row = 0;\n const renderRow = (item: T) => {\n const id = getId(item);\n const pinned = isPinned(id);\n const pending = pinOverrides.has(id);\n const highlighted = id === highlightedId;\n const category = categoryById.get(getCategory?.(item) ?? '');\n const titleId = `${baseId}-title-${row++}`;\n const accent = accentClasses[category?.color ?? 'neutral'];\n const Icon = category?.icon;\n const dt = toDateTime(getDate(item), zone);\n const localDt = dt && withLocale(dt, locale);\n const actor = getActor?.(item);\n const description = compact ? undefined : getDescription?.(item);\n\n const body = renderItem?.(item, { density, pinned, category }) ?? (\n <>\n <span\n aria-hidden\n className={cn(\n 'flex shrink-0 items-center justify-center rounded-full',\n compact ? 'size-5' : 'mt-0.5 size-7',\n accent.tint\n )}\n >\n {Icon ? (\n <Icon className=\"text-foreground size-3.5\" />\n ) : (\n <span className={cn('size-2 rounded-full', accent.marker)} />\n )}\n </span>\n <span className=\"min-w-0 flex-1\">\n <span\n id={titleId}\n className=\"text-foreground block truncate text-sm font-medium\"\n >\n {getTitle?.(item) ?? category?.label ?? id}\n </span>\n {description && (\n <span className=\"text-muted-foreground line-clamp-2 block text-sm\">\n {description}\n </span>\n )}\n <span className=\"text-muted-foreground mt-0.5 flex flex-wrap items-center gap-x-2 gap-y-1 text-xs\">\n {actor && (\n <span className=\"inline-flex items-center gap-1.5\">\n {!compact && (\n <Avatar\n size=\"xs\"\n name={actor.name}\n src={actor.avatarUrl}\n alt=\"\"\n aria-hidden\n />\n )}\n {actor.name}\n </span>\n )}\n {category && <span>{category.label}</span>}\n {localDt && (\n <time\n dateTime={localDt.toISO() ?? undefined}\n title={localDt.toLocaleString(DateTime.DATETIME_MED)}\n >\n {localDt.toLocaleString(DateTime.TIME_SIMPLE)}\n </time>\n )}\n {renderItemMeta?.(item)}\n </span>\n </span>\n </>\n );\n\n const mainClasses =\n 'flex min-w-0 flex-1 items-start gap-3 rounded-md text-start focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring';\n const href = getHref?.(id, item);\n let main: React.ReactNode;\n if (href) {\n main = (\n <a\n href={href}\n className={mainClasses}\n onClick={(event) => {\n if (\n !onOpen ||\n event.metaKey ||\n event.ctrlKey ||\n event.shiftKey ||\n event.button !== 0\n )\n return;\n event.preventDefault();\n onOpen(id, item);\n }}\n onKeyDown={(event) => {\n // Anchors ignore Space natively; rows open on Enter and Space alike.\n if (event.key !== ' ') return;\n event.preventDefault();\n event.currentTarget.click();\n }}\n >\n {body}\n </a>\n );\n } else if (onOpen) {\n main = (\n <button\n type=\"button\"\n className={mainClasses}\n onClick={() => onOpen(id, item)}\n >\n {body}\n </button>\n );\n } else {\n main = <div className={mainClasses}>{body}</div>;\n }\n\n return (\n <li\n key={id}\n ref={(el) => {\n if (el) rowRefs.current.set(id, el);\n else rowRefs.current.delete(id);\n }}\n data-slot=\"activity-feed-item\"\n data-highlighted={highlighted || undefined}\n aria-busy={pending || undefined}\n className={cn(\n 'flex items-start gap-2 px-3',\n compact ? 'py-1.5' : 'py-3',\n highlighted && 'ring-primary-500 bg-primary-500/10 ring-2 ring-inset',\n classNames?.item,\n highlighted && classNames?.highlightedItem\n )}\n >\n {main}\n {onTogglePin && renderItem && (\n <span id={titleId} hidden>\n {getTitle?.(item) ?? category?.label ?? id}\n </span>\n )}\n {onTogglePin && (\n <button\n type=\"button\"\n aria-pressed={pinned}\n aria-label={text.pin}\n aria-describedby={titleId}\n disabled={pending}\n title={text.pin}\n onClick={() =>\n void runPin(id, !pinned, () => onTogglePin(id, !pinned))\n }\n className={cn(\n 'text-muted-foreground hover:bg-muted hover:text-foreground shrink-0 rounded-md p-1.5',\n 'focus-visible:ring-ring focus-visible:ring-2 focus-visible:outline-none',\n 'disabled:opacity-50',\n pinned && 'text-foreground'\n )}\n >\n <Pin\n className={cn('size-4', pinned && 'fill-current')}\n aria-hidden\n />\n </button>\n )}\n </li>\n );\n };\n\n const section = (\n key: string,\n label: React.ReactNode,\n sectionItems: T[],\n summary?: React.ReactNode\n ) => {\n const headingId = `${baseId}-day-${key || 'none'}`;\n return (\n <section\n key={key}\n aria-labelledby={headingId}\n data-slot=\"activity-feed-section\"\n className={classNames?.section}\n >\n <Heading\n id={headingId}\n data-slot=\"activity-feed-day-header\"\n className={cn(\n 'border-border bg-card text-muted-foreground sticky top-0 z-10 flex items-center gap-1.5 border-b px-3 py-2 text-xs font-semibold tracking-wide uppercase',\n classNames?.dayHeader\n )}\n >\n {label}\n </Heading>\n {summary}\n <ul className=\"divide-border divide-y\">\n {sectionItems.map(renderRow)}\n </ul>\n </section>\n );\n };\n\n let body: React.ReactNode;\n if (error) {\n body = (\n <RecordState\n kind=\"error\"\n slot=\"activity-feed-state\"\n message={text.error}\n retryLabel={text.retry}\n onRetry={onRetry}\n className={classNames?.state}\n />\n );\n } else if (loading) {\n body = (\n <RecordState\n kind=\"loading\"\n slot=\"activity-feed-state\"\n message={text.loading}\n className={classNames?.state}\n />\n );\n } else if (items.length === 0) {\n body = emptyState ?? (\n <RecordState\n kind=\"empty\"\n slot=\"activity-feed-state\"\n message={text.empty}\n className={classNames?.state}\n />\n );\n } else if (visible.length === 0) {\n body = (\n <RecordState\n kind=\"empty\"\n slot=\"activity-feed-state\"\n message={text.noMatches}\n className={classNames?.state}\n >\n <Button variant=\"ghost\" size=\"sm\" onClick={() => updateFilters([])}>\n {text.allCategories}\n </Button>\n </RecordState>\n );\n } else {\n body = (\n <>\n {pinnedItems.length > 0 &&\n section(\n 'pinned',\n <>\n <Pin className=\"size-3.5\" aria-hidden />\n {text.pinned}\n </>,\n pinnedItems\n )}\n {days.map((day) =>\n section(\n day.key,\n formatDayLabel(day.key, {\n now: reference,\n zone,\n locale,\n today: text.today,\n yesterday: text.yesterday,\n undated: text.undated,\n }),\n day.items,\n renderDaySummary?.(day.key, day.items)\n )\n )}\n {hasMore && onLoadMore && (\n <div\n data-slot=\"activity-feed-load-more\"\n className={cn('border-border border-t p-3', classNames?.loadMore)}\n >\n <Button\n variant=\"ghost\"\n size=\"sm\"\n fullWidth\n isLoading={loadingMore}\n onClick={() => void loadMore()}\n >\n {text.loadMore}\n </Button>\n </div>\n )}\n </>\n );\n }\n\n return (\n <div\n ref={ref}\n data-slot=\"activity-feed\"\n className={cn(\n 'border-border bg-card overflow-hidden rounded-lg border',\n className\n )}\n {...rest}\n >\n {(categories.length > 0 || items.length > 0) && (\n <div\n data-slot=\"activity-feed-toolbar\"\n className={cn(\n 'border-border flex items-center gap-2 border-b px-3 py-2',\n classNames?.toolbar\n )}\n >\n {categories.length > 0 && (\n <div\n role=\"group\"\n aria-label={text.filters}\n className=\"flex min-w-0 flex-1 flex-wrap gap-1.5\"\n >\n <button\n type=\"button\"\n aria-pressed={effectiveFilter.length === 0}\n onClick={() => updateFilters([])}\n data-slot=\"activity-feed-filter\"\n className={cn(\n chipClasses,\n effectiveFilter.length === 0\n ? 'border-primary-500/40 bg-primary-500/10 text-foreground'\n : 'border-border text-muted-foreground hover:bg-muted',\n classNames?.filter\n )}\n >\n {text.allCategories}\n </button>\n {categories.map((category) => {\n const active = effectiveFilter.includes(category.id);\n const accent = accentClasses[category.color ?? 'primary'];\n const Icon = category.icon;\n return (\n <button\n key={category.id}\n type=\"button\"\n aria-pressed={active}\n onClick={() =>\n updateFilters(\n active\n ? effectiveFilter.filter((c) => c !== category.id)\n : [...effectiveFilter, category.id]\n )\n }\n data-slot=\"activity-feed-filter\"\n className={cn(\n chipClasses,\n active\n ? cn(accent.tint, accent.border, 'text-foreground')\n : 'border-border text-muted-foreground hover:bg-muted',\n classNames?.filter\n )}\n >\n {Icon && <Icon className=\"size-3.5\" aria-hidden />}\n {category.label}\n </button>\n );\n })}\n </div>\n )}\n <button\n type=\"button\"\n aria-pressed={compact}\n aria-label={text.compact}\n title={text.compact}\n onClick={toggleDensity}\n className={cn(\n 'text-muted-foreground hover:bg-muted ms-auto shrink-0 rounded-md p-1.5',\n 'focus-visible:ring-ring focus-visible:ring-2 focus-visible:outline-none',\n compact && 'bg-muted text-foreground'\n )}\n >\n <Rows4 className=\"size-4\" aria-hidden />\n </button>\n </div>\n )}\n <div aria-live=\"polite\" className=\"sr-only\">\n {announcement}\n </div>\n {body}\n </div>\n );\n}\n\n/**\n * A day-grouped feed of a record's activity. Declared\n * `parameters.catalog.collection` — its load states are part of the API.\n */\nexport const ActivityFeed = React.forwardRef(ActivityFeedInner) as <T>(\n props: ActivityFeedProps<T> & { ref?: React.ForwardedRef<HTMLDivElement> }\n) => React.ReactElement;\n\n(ActivityFeed as React.FC).displayName = 'ActivityFeed';\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/components/ActivityFeed/ActivityFeed.tsx"],"names":["body"],"mappings":"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","file":"chunk-CRSJRWN2.js","sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport { DateTime } from 'luxon';\nimport { Pin, Rows4, type LucideIcon } from 'lucide-react';\nimport { cn } from '../../utils/cn';\nimport { Avatar } from '../Avatar';\nimport { Button } from '../Button';\nimport { useLiveAnnouncement } from '../../hooks/useLiveAnnouncement';\nimport { usePrefersReducedMotion } from '../../hooks/usePrefersReducedMotion';\nimport { accentClasses, toDateTime, type Accent } from '../../views/types';\nimport { formatDayLabel, groupByDay, withLocale } from './dayGroups';\nimport { RecordState } from './RecordState';\nimport { usePendingOverrides } from './usePendingOverrides';\n\n// =============================================================================\n// Types\n// =============================================================================\n\nexport type ActivityFeedDensity = 'comfortable' | 'compact';\n\nexport interface ActivityFeedCategory {\n id: string;\n label: string;\n icon?: LucideIcon;\n /** Token name, resolved to `--mieweb-*` colours. */\n color?: Accent;\n}\n\nexport interface ActivityFeedActor {\n name: string;\n avatarUrl?: string;\n}\n\nexport interface ActivityFeedLabels {\n loading: string;\n empty: string;\n /** Shown when items exist but the active filters hide all of them. */\n noMatches: string;\n error: string;\n retry: string;\n today: string;\n yesterday: string;\n undated: string;\n pinned: string;\n /** Accessible name of the category filter group. */\n filters: string;\n /** The chip that clears every filter. */\n allCategories: string;\n compact: string;\n pin: string;\n loadMore: string;\n /** Announced politely after a filter change. */\n resultCount: (count: number) => string;\n}\n\nexport const defaultActivityFeedLabels: ActivityFeedLabels = {\n loading: 'Loading activity',\n empty: 'No activity yet',\n noMatches: 'No activity matches these filters',\n error: 'Could not load activity',\n retry: 'Try again',\n today: 'Today',\n yesterday: 'Yesterday',\n undated: 'Undated',\n pinned: 'Pinned',\n filters: 'Filter by category',\n allCategories: 'All',\n compact: 'Compact view',\n pin: 'Pin',\n loadMore: 'Load more',\n resultCount: (count) =>\n count === 1 ? '1 activity shown' : `${count} activities shown`,\n};\n\nexport type ActivityFeedSlot =\n | 'toolbar'\n | 'filter'\n | 'section'\n | 'dayHeader'\n | 'item'\n | 'highlightedItem'\n | 'state'\n | 'loadMore';\n\nexport interface ActivityFeedItemContext {\n density: ActivityFeedDensity;\n pinned: boolean;\n category?: ActivityFeedCategory;\n}\n\nexport interface ActivityFeedProps<T> extends Omit<\n React.HTMLAttributes<HTMLDivElement>,\n 'children'\n> {\n items: T[];\n getId: (item: T) => string;\n /** ISO string or `Date`. Date-only strings are wall dates in `timeZone`. */\n getDate: (item: T) => Date | string | null | undefined;\n /** Matched against `categories[].id`. */\n getCategory?: (item: T) => string | undefined;\n getTitle?: (item: T) => string | undefined;\n getDescription?: (item: T) => string | undefined;\n getActor?: (item: T) => ActivityFeedActor | undefined;\n /** Filter chips, icons and colours, in display order. */\n categories?: readonly ActivityFeedCategory[];\n loading?: boolean;\n error?: Error | null;\n onRetry?: () => void;\n /** BCP 47 locale for day headers and times. Defaults to the runtime's. */\n locale?: string;\n /** IANA zone that decides which day an item falls on. Defaults to local. */\n timeZone?: string;\n /** Pins \"today\" so stories and tests stay deterministic. */\n now?: Date;\n pinnedIds?: readonly string[];\n /** Receives the requested state; the row moves optimistically and restores on rejection. */\n onTogglePin?: (id: string, pinned: boolean) => void | Promise<void>;\n onOpen?: (id: string, item: T) => void;\n getHref?: (id: string, item: T) => string;\n /** Scrolls this row into view and highlights it — for deep links. */\n highlightedId?: string | null;\n hasMore?: boolean;\n /** The button shows pending until the returned promise settles. */\n onLoadMore?: () => void | Promise<void>;\n defaultCategories?: readonly string[];\n defaultDensity?: ActivityFeedDensity;\n /** Persists the selected categories and density in `localStorage` under this key. */\n storageKey?: string;\n /** Replaces the built-in row body. Pinning and opening still wrap it. */\n renderItem?: (item: T, context: ActivityFeedItemContext) => React.ReactNode;\n /** Extra content on the row's meta line (badges, durations, sentiment). */\n renderItemMeta?: (item: T) => React.ReactNode;\n /** Rendered under each day header, e.g. a roll-up of that day's calls. */\n renderDaySummary?: (dayKey: string, items: T[]) => React.ReactNode;\n emptyState?: React.ReactNode;\n labels?: Partial<ActivityFeedLabels>;\n classNames?: Partial<Record<ActivityFeedSlot, string>>;\n headingLevel?: 'h2' | 'h3' | 'h4';\n}\n\ninterface StoredPrefs {\n categories?: string[];\n density?: ActivityFeedDensity;\n}\n\nfunction readPrefs(key: string): StoredPrefs {\n try {\n const raw: unknown = JSON.parse(window.localStorage.getItem(key) ?? '{}');\n if (!raw || typeof raw !== 'object') return {};\n const { categories, density } = raw as Record<string, unknown>;\n return {\n categories:\n Array.isArray(categories) &&\n categories.every((c) => typeof c === 'string')\n ? categories\n : undefined,\n density:\n density === 'compact' || density === 'comfortable'\n ? density\n : undefined,\n };\n } catch {\n return {};\n }\n}\n\nfunction writePrefs(key: string, prefs: StoredPrefs) {\n try {\n window.localStorage.setItem(key, JSON.stringify(prefs));\n } catch {\n // Storage full or blocked: the preference just doesn't persist.\n }\n}\n\nconst chipClasses =\n 'inline-flex items-center gap-1.5 rounded-full border px-3 py-1 text-xs font-medium transition-colors motion-reduce:transition-none focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring';\n\n// =============================================================================\n// Component\n// =============================================================================\n\nfunction ActivityFeedInner<T>(\n {\n items,\n getId,\n getDate,\n getCategory,\n getTitle,\n getDescription,\n getActor,\n categories = [],\n loading = false,\n error = null,\n onRetry,\n locale,\n timeZone = 'local',\n now,\n pinnedIds,\n onTogglePin,\n onOpen,\n getHref,\n highlightedId = null,\n hasMore = false,\n onLoadMore,\n defaultCategories,\n defaultDensity = 'comfortable',\n storageKey,\n renderItem,\n renderItemMeta,\n renderDaySummary,\n emptyState,\n labels,\n classNames,\n headingLevel: Heading = 'h3',\n className,\n ...rest\n }: ActivityFeedProps<T>,\n ref: React.ForwardedRef<HTMLDivElement>\n) {\n const text = { ...defaultActivityFeedLabels, ...labels };\n const baseId = React.useId();\n const reducedMotion = usePrefersReducedMotion();\n const [announcement, announce] = useLiveAnnouncement();\n const [pinOverrides, runPin] = usePendingOverrides<boolean>();\n const [loadingMore, setLoadingMore] = React.useState(false);\n const [selected, setSelected] = React.useState<readonly string[]>(\n defaultCategories ?? []\n );\n const [density, setDensity] =\n React.useState<ActivityFeedDensity>(defaultDensity);\n const rowRefs = React.useRef(new Map<string, HTMLElement>());\n\n // Read after mount so server and first client render agree.\n React.useEffect(() => {\n if (!storageKey) return;\n const stored = readPrefs(storageKey);\n if (stored.categories) setSelected(stored.categories);\n if (stored.density) setDensity(stored.density);\n }, [storageKey]);\n\n React.useEffect(() => {\n if (!highlightedId) return;\n rowRefs.current.get(highlightedId)?.scrollIntoView?.({\n block: 'center',\n behavior: reducedMotion ? 'auto' : 'smooth',\n });\n }, [highlightedId, loading, reducedMotion]);\n\n const categoryById = React.useMemo(\n () => new Map(categories.map((c) => [c.id, c])),\n [categories]\n );\n // Persisted IDs may reference renamed/removed categories; applying them\n // verbatim would filter out everything with no chip shown as active.\n const effectiveFilter = React.useMemo(\n () => selected.filter((id) => categoryById.has(id)),\n [selected, categoryById]\n );\n const pinnedSet = React.useMemo(() => new Set(pinnedIds), [pinnedIds]);\n const isPinned = (id: string) => pinOverrides.get(id) ?? pinnedSet.has(id);\n const matches = (item: T, filter: readonly string[]) =>\n filter.length === 0 || filter.includes(getCategory?.(item) ?? '');\n\n const updateFilters = (next: readonly string[]) => {\n setSelected(next);\n if (storageKey) writePrefs(storageKey, { categories: [...next], density });\n announce(text.resultCount(items.filter((i) => matches(i, next)).length));\n };\n\n const toggleDensity = () => {\n const next = density === 'compact' ? 'comfortable' : 'compact';\n setDensity(next);\n if (storageKey)\n writePrefs(storageKey, { categories: [...selected], density: next });\n };\n\n const loadMore = async () => {\n if (!onLoadMore) return;\n setLoadingMore(true);\n try {\n await onLoadMore();\n } catch {\n // The caller reports the failure; the button becomes usable again.\n } finally {\n setLoadingMore(false);\n }\n };\n\n const zone = timeZone;\n const reference = now ?? new Date();\n const compact = density === 'compact';\n const visible = items.filter((item) => matches(item, effectiveFilter));\n const pinnedItems = groupByDay(\n visible.filter((item) => isPinned(getId(item))),\n getDate,\n zone\n ).flatMap((g) => g.items);\n const days = groupByDay(\n visible.filter((item) => !isPinned(getId(item))),\n getDate,\n zone\n );\n\n let row = 0;\n const renderRow = (item: T) => {\n const id = getId(item);\n const pinned = isPinned(id);\n const pending = pinOverrides.has(id);\n const highlighted = id === highlightedId;\n const category = categoryById.get(getCategory?.(item) ?? '');\n const titleId = `${baseId}-title-${row++}`;\n const accent = accentClasses[category?.color ?? 'neutral'];\n const Icon = category?.icon;\n const dt = toDateTime(getDate(item), zone);\n const localDt = dt && withLocale(dt, locale);\n const actor = getActor?.(item);\n const description = compact ? undefined : getDescription?.(item);\n\n const body = renderItem?.(item, { density, pinned, category }) ?? (\n <>\n <span\n aria-hidden\n className={cn(\n 'flex shrink-0 items-center justify-center rounded-full',\n compact ? 'size-5' : 'mt-0.5 size-7',\n accent.tint\n )}\n >\n {Icon ? (\n <Icon className=\"text-foreground size-3.5\" />\n ) : (\n <span className={cn('size-2 rounded-full', accent.marker)} />\n )}\n </span>\n <span className=\"min-w-0 flex-1\">\n <span\n id={titleId}\n className=\"text-foreground block truncate text-sm font-medium\"\n >\n {getTitle?.(item) ?? category?.label ?? id}\n </span>\n {description && (\n <span className=\"text-muted-foreground line-clamp-2 block text-sm\">\n {description}\n </span>\n )}\n <span className=\"text-muted-foreground mt-0.5 flex flex-wrap items-center gap-x-2 gap-y-1 text-xs\">\n {actor && (\n <span className=\"inline-flex items-center gap-1.5\">\n {!compact && (\n <Avatar\n size=\"xs\"\n name={actor.name}\n src={actor.avatarUrl}\n alt=\"\"\n aria-hidden\n />\n )}\n {actor.name}\n </span>\n )}\n {category && <span>{category.label}</span>}\n {localDt && (\n <time\n dateTime={localDt.toISO() ?? undefined}\n title={localDt.toLocaleString(DateTime.DATETIME_MED)}\n >\n {localDt.toLocaleString(DateTime.TIME_SIMPLE)}\n </time>\n )}\n {renderItemMeta?.(item)}\n </span>\n </span>\n </>\n );\n\n const mainClasses =\n 'flex min-w-0 flex-1 items-start gap-3 rounded-md text-start focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring';\n const href = getHref?.(id, item);\n let main: React.ReactNode;\n if (href) {\n main = (\n <a\n href={href}\n className={mainClasses}\n onClick={(event) => {\n if (\n !onOpen ||\n event.metaKey ||\n event.ctrlKey ||\n event.shiftKey ||\n event.button !== 0\n )\n return;\n event.preventDefault();\n onOpen(id, item);\n }}\n onKeyDown={(event) => {\n // Anchors ignore Space natively; rows open on Enter and Space alike.\n if (event.key !== ' ') return;\n event.preventDefault();\n event.currentTarget.click();\n }}\n >\n {body}\n </a>\n );\n } else if (onOpen) {\n main = (\n <button\n type=\"button\"\n className={mainClasses}\n onClick={() => onOpen(id, item)}\n >\n {body}\n </button>\n );\n } else {\n main = <div className={mainClasses}>{body}</div>;\n }\n\n return (\n <li\n key={id}\n ref={(el) => {\n if (el) rowRefs.current.set(id, el);\n else rowRefs.current.delete(id);\n }}\n data-slot=\"activity-feed-item\"\n data-highlighted={highlighted || undefined}\n aria-busy={pending || undefined}\n className={cn(\n 'flex items-start gap-2 px-3',\n compact ? 'py-1.5' : 'py-3',\n highlighted && 'ring-primary-500 bg-primary-500/10 ring-2 ring-inset',\n classNames?.item,\n highlighted && classNames?.highlightedItem\n )}\n >\n {main}\n {onTogglePin && renderItem && (\n <span id={titleId} hidden>\n {getTitle?.(item) ?? category?.label ?? id}\n </span>\n )}\n {onTogglePin && (\n <button\n type=\"button\"\n aria-pressed={pinned}\n aria-label={text.pin}\n aria-describedby={titleId}\n disabled={pending}\n title={text.pin}\n onClick={() =>\n void runPin(id, !pinned, () => onTogglePin(id, !pinned))\n }\n className={cn(\n 'text-muted-foreground hover:bg-muted hover:text-foreground shrink-0 rounded-md p-1.5',\n 'focus-visible:ring-ring focus-visible:ring-2 focus-visible:outline-none',\n 'disabled:opacity-50',\n pinned && 'text-foreground'\n )}\n >\n <Pin\n className={cn('size-4', pinned && 'fill-current')}\n aria-hidden\n />\n </button>\n )}\n </li>\n );\n };\n\n const section = (\n key: string,\n label: React.ReactNode,\n sectionItems: T[],\n summary?: React.ReactNode\n ) => {\n const headingId = `${baseId}-day-${key || 'none'}`;\n return (\n <section\n key={key}\n aria-labelledby={headingId}\n data-slot=\"activity-feed-section\"\n className={classNames?.section}\n >\n <Heading\n id={headingId}\n data-slot=\"activity-feed-day-header\"\n className={cn(\n 'border-border bg-card text-muted-foreground sticky top-0 z-10 flex items-center gap-1.5 border-b px-3 py-2 text-xs font-semibold tracking-wide uppercase',\n classNames?.dayHeader\n )}\n >\n {label}\n </Heading>\n {summary}\n <ul className=\"divide-border divide-y\">\n {sectionItems.map(renderRow)}\n </ul>\n </section>\n );\n };\n\n let body: React.ReactNode;\n if (error) {\n body = (\n <RecordState\n kind=\"error\"\n slot=\"activity-feed-state\"\n message={text.error}\n retryLabel={text.retry}\n onRetry={onRetry}\n className={classNames?.state}\n />\n );\n } else if (loading) {\n body = (\n <RecordState\n kind=\"loading\"\n slot=\"activity-feed-state\"\n message={text.loading}\n className={classNames?.state}\n />\n );\n } else if (items.length === 0) {\n body = emptyState ?? (\n <RecordState\n kind=\"empty\"\n slot=\"activity-feed-state\"\n message={text.empty}\n className={classNames?.state}\n />\n );\n } else if (visible.length === 0) {\n body = (\n <RecordState\n kind=\"empty\"\n slot=\"activity-feed-state\"\n message={text.noMatches}\n className={classNames?.state}\n >\n <Button variant=\"ghost\" size=\"sm\" onClick={() => updateFilters([])}>\n {text.allCategories}\n </Button>\n </RecordState>\n );\n } else {\n body = (\n <>\n {pinnedItems.length > 0 &&\n section(\n 'pinned',\n <>\n <Pin className=\"size-3.5\" aria-hidden />\n {text.pinned}\n </>,\n pinnedItems\n )}\n {days.map((day) =>\n section(\n day.key,\n formatDayLabel(day.key, {\n now: reference,\n zone,\n locale,\n today: text.today,\n yesterday: text.yesterday,\n undated: text.undated,\n }),\n day.items,\n renderDaySummary?.(day.key, day.items)\n )\n )}\n {hasMore && onLoadMore && (\n <div\n data-slot=\"activity-feed-load-more\"\n className={cn('border-border border-t p-3', classNames?.loadMore)}\n >\n <Button\n variant=\"ghost\"\n size=\"sm\"\n fullWidth\n isLoading={loadingMore}\n onClick={() => void loadMore()}\n >\n {text.loadMore}\n </Button>\n </div>\n )}\n </>\n );\n }\n\n return (\n <div\n ref={ref}\n data-slot=\"activity-feed\"\n className={cn(\n 'border-border bg-card overflow-hidden rounded-lg border',\n className\n )}\n {...rest}\n >\n {(categories.length > 0 || items.length > 0) && (\n <div\n data-slot=\"activity-feed-toolbar\"\n className={cn(\n 'border-border flex items-center gap-2 border-b px-3 py-2',\n classNames?.toolbar\n )}\n >\n {categories.length > 0 && (\n <div\n role=\"group\"\n aria-label={text.filters}\n className=\"flex min-w-0 flex-1 flex-wrap gap-1.5\"\n >\n <button\n type=\"button\"\n aria-pressed={effectiveFilter.length === 0}\n onClick={() => updateFilters([])}\n data-slot=\"activity-feed-filter\"\n className={cn(\n chipClasses,\n effectiveFilter.length === 0\n ? 'border-primary-500/40 bg-primary-500/10 text-foreground'\n : 'border-border text-muted-foreground hover:bg-muted',\n classNames?.filter\n )}\n >\n {text.allCategories}\n </button>\n {categories.map((category) => {\n const active = effectiveFilter.includes(category.id);\n const accent = accentClasses[category.color ?? 'primary'];\n const Icon = category.icon;\n return (\n <button\n key={category.id}\n type=\"button\"\n aria-pressed={active}\n onClick={() =>\n updateFilters(\n active\n ? effectiveFilter.filter((c) => c !== category.id)\n : [...effectiveFilter, category.id]\n )\n }\n data-slot=\"activity-feed-filter\"\n className={cn(\n chipClasses,\n active\n ? cn(accent.tint, accent.border, 'text-foreground')\n : 'border-border text-muted-foreground hover:bg-muted',\n classNames?.filter\n )}\n >\n {Icon && <Icon className=\"size-3.5\" aria-hidden />}\n {category.label}\n </button>\n );\n })}\n </div>\n )}\n <button\n type=\"button\"\n aria-pressed={compact}\n aria-label={text.compact}\n title={text.compact}\n onClick={toggleDensity}\n className={cn(\n 'text-muted-foreground hover:bg-muted ms-auto shrink-0 rounded-md p-1.5',\n 'focus-visible:ring-ring focus-visible:ring-2 focus-visible:outline-none',\n compact && 'bg-muted text-foreground'\n )}\n >\n <Rows4 className=\"size-4\" aria-hidden />\n </button>\n </div>\n )}\n <div aria-live=\"polite\" className=\"sr-only\">\n {announcement}\n </div>\n {body}\n </div>\n );\n}\n\n/**\n * A day-grouped feed of a record's activity. Declared\n * `parameters.catalog.collection` — its load states are part of the API.\n */\nexport const ActivityFeed = React.forwardRef(ActivityFeedInner) as <T>(\n props: ActivityFeedProps<T> & { ref?: React.ForwardedRef<HTMLDivElement> }\n) => React.ReactElement;\n\n(ActivityFeed as React.FC).displayName = 'ActivityFeed';\n"]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { useScrollSpy } from './chunk-WBGUYSWY.js';
|
|
2
|
-
import { buttonVariants } from './chunk-
|
|
2
|
+
import { buttonVariants } from './chunk-VP3XNLUL.js';
|
|
3
3
|
import { cn } from './chunk-TQONQSJO.js';
|
|
4
4
|
import * as React from 'react';
|
|
5
5
|
import { ArrowDown, ArrowRight, ArrowUpRight } from 'lucide-react';
|
|
@@ -138,5 +138,5 @@ function SectionSpyNav({
|
|
|
138
138
|
}
|
|
139
139
|
|
|
140
140
|
export { SectionSpyNav };
|
|
141
|
-
//# sourceMappingURL=chunk-
|
|
142
|
-
//# sourceMappingURL=chunk-
|
|
141
|
+
//# sourceMappingURL=chunk-CVMD2A3J.js.map
|
|
142
|
+
//# sourceMappingURL=chunk-CVMD2A3J.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/SectionSpyNav/SectionSpyNav.tsx"],"names":[],"mappings":"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","file":"chunk-FIKO4WR6.js","sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport { ArrowDown, ArrowRight, ArrowUpRight } from 'lucide-react';\nimport { cn } from '../../utils/cn';\nimport { useScrollSpy } from '../../hooks/useScrollSpy';\nimport { buttonVariants } from '../Button';\n\n// =============================================================================\n// Types\n// =============================================================================\n\n/** One section the nav links to. The id must match a `section[id]` on the page. */\nexport interface SectionSpyItem {\n id: string;\n label: string;\n}\n\n/**\n * Funnel intent for the bar's single contextual CTA — drives its visual\n * weight so the in-page strip never out-shouts a page's primary CTA:\n * `explore` (quiet next step) → `evaluate` (sales-ready ask) → `commit`\n * (high-intent action).\n */\nexport type SectionSpyCtaTier = 'explore' | 'evaluate' | 'commit';\n\nexport interface SectionSpyCta {\n label: string;\n href: string;\n tier?: SectionSpyCtaTier;\n}\n\nexport interface SectionSpyNavProps {\n /** Sections to link to, in page order. */\n items: SectionSpyItem[];\n /** Optional single page-specific next-step CTA at the end of the bar. */\n cta?: SectionSpyCta;\n /** Eyebrow before the links (default \"On this page\"). */\n label?: string;\n /**\n * Visual tone: `surface` sits on the page background; `brand` renders the\n * inverted primary band.\n */\n tone?: 'surface' | 'brand';\n /** IntersectionObserver root margin tuning for the scroll spy. */\n rootMargin?: string;\n /** Called with the section id when a nav link is clicked. */\n onItemClick?: (id: string) => void;\n /** Called when the CTA is clicked (e.g. for analytics). */\n onCtaClick?: (cta: SectionSpyCta) => void;\n className?: string;\n}\n\n// =============================================================================\n// Internals\n// =============================================================================\n\n/** Directional glyph inferred from the destination. */\nfunction CtaArrow({ href }: { href: string }) {\n const Icon = href.startsWith('#')\n ? ArrowDown\n : href.startsWith('/')\n ? ArrowRight\n : ArrowUpRight;\n // rtl:-scale-x-100 mirrors ArrowRight and ArrowUpRight for RTL reading\n // direction; ArrowDown is horizontally symmetric so the flip is a no-op.\n return <Icon aria-hidden=\"true\" className=\"h-3.5 w-3.5 rtl:-scale-x-100\" />;\n}\n\nconst CTA_TIER_VARIANT = {\n explore: 'ghost',\n evaluate: 'outline',\n commit: 'primary',\n} as const;\n\n// =============================================================================\n// SectionSpyNav\n// =============================================================================\n\n/**\n * Sticky horizontal in-page wayfinding: jumps between a page's major\n * sections, highlights the one in view with a sliding underline, and can\n * carry a single page-specific next-step CTA. Pure anchor links, so it\n * still works if the scroll spy never runs.\n *\n * The horizontal complement to `TableOfContents` — use that for a sidebar\n * outline, this for a band under the page header. Section elements need\n * matching `id`s.\n *\n * @example\n * ```tsx\n * <SectionSpyNav\n * items={[\n * { id: 'overview', label: 'Overview' },\n * { id: 'pricing', label: 'Pricing' },\n * ]}\n * cta={{ label: 'Book a demo', href: '/demo', tier: 'evaluate' }}\n * />\n * ```\n */\nexport function SectionSpyNav({\n items,\n cta,\n label = 'On this page',\n tone = 'surface',\n rootMargin = '-22% 0px -68% 0px',\n onItemClick,\n onCtaClick,\n className,\n}: SectionSpyNavProps) {\n const ids = React.useMemo(() => items.map((it) => it.id), [items]);\n const { activeId } = useScrollSpy({ ids, rootMargin });\n const active = activeId ?? items[0]?.id ?? '';\n\n const railRef = React.useRef<HTMLDivElement>(null);\n const markRef = React.useRef<HTMLSpanElement>(null);\n\n // Find the active link by dataset rather than a CSS selector, so ids\n // never need escaping and CSS.escape availability doesn't matter.\n const findActiveLink = React.useCallback((): HTMLAnchorElement | null => {\n const links = railRef.current?.querySelectorAll<HTMLAnchorElement>('a');\n if (!links) return null;\n for (const link of links) {\n if (link.dataset.id === active) return link;\n }\n return null;\n }, [active]);\n\n // Slide the underline beneath the active link. offsetLeft/offsetWidth are\n // physical and measured against the rail, so the marker tracks the link\n // in both directions and while the rail is scrolled horizontally.\n const syncMarker = React.useCallback(() => {\n const link = findActiveLink();\n const mark = markRef.current;\n if (!link || !mark) return;\n mark.style.left = `${link.offsetLeft}px`;\n mark.style.width = `${link.offsetWidth}px`;\n }, [findActiveLink]);\n\n React.useEffect(() => {\n const link = findActiveLink();\n link?.scrollIntoView?.({ inline: 'center', block: 'nearest' });\n syncMarker();\n }, [findActiveLink, syncMarker]);\n\n React.useEffect(() => {\n window.addEventListener('resize', syncMarker);\n return () => window.removeEventListener('resize', syncMarker);\n }, [syncMarker]);\n\n const brand = tone === 'brand';\n\n return (\n <nav\n className={cn(\n 'sticky top-0 z-30 w-full',\n brand\n ? 'bg-primary-900 text-white'\n : 'border-border bg-card/95 border-b backdrop-blur',\n className\n )}\n aria-label={label}\n >\n <div className=\"flex items-center gap-4 px-4 py-0.5\">\n <span\n className={cn(\n 'shrink-0 text-[11px] font-semibold tracking-wide uppercase max-md:hidden',\n brand ? 'text-white/85' : 'text-muted-foreground'\n )}\n aria-hidden=\"true\"\n >\n {label}\n </span>\n <div\n ref={railRef}\n className=\"relative flex min-w-0 flex-1 gap-1 overflow-x-auto [scrollbar-width:none] [&::-webkit-scrollbar]:hidden\"\n >\n {items.map((it) => {\n const isActive = active === it.id;\n return (\n <a\n key={it.id}\n href={`#${it.id}`}\n data-id={it.id}\n onClick={() => onItemClick?.(it.id)}\n className={cn(\n 'shrink-0 rounded px-2.5 py-2 text-sm whitespace-nowrap transition-colors',\n brand\n ? isActive\n ? 'font-semibold text-white'\n : 'text-white/85 hover:text-white'\n : isActive\n ? 'text-foreground font-semibold'\n : 'text-muted-foreground hover:text-foreground'\n )}\n aria-current={isActive ? 'location' : undefined}\n >\n {it.label}\n </a>\n );\n })}\n <span\n ref={markRef}\n className={cn(\n 'absolute bottom-0 h-0.5 rounded-full transition-[left,width] duration-300',\n brand ? 'bg-primary-400' : 'bg-primary-500'\n )}\n aria-hidden=\"true\"\n />\n </div>\n {cta && (\n <a\n href={cta.href}\n onClick={() => onCtaClick?.(cta)}\n className={cn(\n buttonVariants({\n variant: CTA_TIER_VARIANT[cta.tier ?? 'explore'],\n size: 'sm',\n }),\n 'shrink-0',\n brand &&\n (cta.tier ?? 'explore') !== 'commit' &&\n 'text-white hover:bg-white/10 hover:text-white'\n )}\n >\n {cta.label}\n <CtaArrow href={cta.href} />\n </a>\n )}\n </div>\n </nav>\n );\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/components/SectionSpyNav/SectionSpyNav.tsx"],"names":[],"mappings":"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","file":"chunk-CVMD2A3J.js","sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport { ArrowDown, ArrowRight, ArrowUpRight } from 'lucide-react';\nimport { cn } from '../../utils/cn';\nimport { useScrollSpy } from '../../hooks/useScrollSpy';\nimport { buttonVariants } from '../Button';\n\n// =============================================================================\n// Types\n// =============================================================================\n\n/** One section the nav links to. The id must match a `section[id]` on the page. */\nexport interface SectionSpyItem {\n id: string;\n label: string;\n}\n\n/**\n * Funnel intent for the bar's single contextual CTA — drives its visual\n * weight so the in-page strip never out-shouts a page's primary CTA:\n * `explore` (quiet next step) → `evaluate` (sales-ready ask) → `commit`\n * (high-intent action).\n */\nexport type SectionSpyCtaTier = 'explore' | 'evaluate' | 'commit';\n\nexport interface SectionSpyCta {\n label: string;\n href: string;\n tier?: SectionSpyCtaTier;\n}\n\nexport interface SectionSpyNavProps {\n /** Sections to link to, in page order. */\n items: SectionSpyItem[];\n /** Optional single page-specific next-step CTA at the end of the bar. */\n cta?: SectionSpyCta;\n /** Eyebrow before the links (default \"On this page\"). */\n label?: string;\n /**\n * Visual tone: `surface` sits on the page background; `brand` renders the\n * inverted primary band.\n */\n tone?: 'surface' | 'brand';\n /** IntersectionObserver root margin tuning for the scroll spy. */\n rootMargin?: string;\n /** Called with the section id when a nav link is clicked. */\n onItemClick?: (id: string) => void;\n /** Called when the CTA is clicked (e.g. for analytics). */\n onCtaClick?: (cta: SectionSpyCta) => void;\n className?: string;\n}\n\n// =============================================================================\n// Internals\n// =============================================================================\n\n/** Directional glyph inferred from the destination. */\nfunction CtaArrow({ href }: { href: string }) {\n const Icon = href.startsWith('#')\n ? ArrowDown\n : href.startsWith('/')\n ? ArrowRight\n : ArrowUpRight;\n // rtl:-scale-x-100 mirrors ArrowRight and ArrowUpRight for RTL reading\n // direction; ArrowDown is horizontally symmetric so the flip is a no-op.\n return <Icon aria-hidden=\"true\" className=\"h-3.5 w-3.5 rtl:-scale-x-100\" />;\n}\n\nconst CTA_TIER_VARIANT = {\n explore: 'ghost',\n evaluate: 'outline',\n commit: 'primary',\n} as const;\n\n// =============================================================================\n// SectionSpyNav\n// =============================================================================\n\n/**\n * Sticky horizontal in-page wayfinding: jumps between a page's major\n * sections, highlights the one in view with a sliding underline, and can\n * carry a single page-specific next-step CTA. Pure anchor links, so it\n * still works if the scroll spy never runs.\n *\n * The horizontal complement to `TableOfContents` — use that for a sidebar\n * outline, this for a band under the page header. Section elements need\n * matching `id`s.\n *\n * @example\n * ```tsx\n * <SectionSpyNav\n * items={[\n * { id: 'overview', label: 'Overview' },\n * { id: 'pricing', label: 'Pricing' },\n * ]}\n * cta={{ label: 'Book a demo', href: '/demo', tier: 'evaluate' }}\n * />\n * ```\n */\nexport function SectionSpyNav({\n items,\n cta,\n label = 'On this page',\n tone = 'surface',\n rootMargin = '-22% 0px -68% 0px',\n onItemClick,\n onCtaClick,\n className,\n}: SectionSpyNavProps) {\n const ids = React.useMemo(() => items.map((it) => it.id), [items]);\n const { activeId } = useScrollSpy({ ids, rootMargin });\n const active = activeId ?? items[0]?.id ?? '';\n\n const railRef = React.useRef<HTMLDivElement>(null);\n const markRef = React.useRef<HTMLSpanElement>(null);\n\n // Find the active link by dataset rather than a CSS selector, so ids\n // never need escaping and CSS.escape availability doesn't matter.\n const findActiveLink = React.useCallback((): HTMLAnchorElement | null => {\n const links = railRef.current?.querySelectorAll<HTMLAnchorElement>('a');\n if (!links) return null;\n for (const link of links) {\n if (link.dataset.id === active) return link;\n }\n return null;\n }, [active]);\n\n // Slide the underline beneath the active link. offsetLeft/offsetWidth are\n // physical and measured against the rail, so the marker tracks the link\n // in both directions and while the rail is scrolled horizontally.\n const syncMarker = React.useCallback(() => {\n const link = findActiveLink();\n const mark = markRef.current;\n if (!link || !mark) return;\n mark.style.left = `${link.offsetLeft}px`;\n mark.style.width = `${link.offsetWidth}px`;\n }, [findActiveLink]);\n\n React.useEffect(() => {\n const link = findActiveLink();\n link?.scrollIntoView?.({ inline: 'center', block: 'nearest' });\n syncMarker();\n }, [findActiveLink, syncMarker]);\n\n React.useEffect(() => {\n window.addEventListener('resize', syncMarker);\n return () => window.removeEventListener('resize', syncMarker);\n }, [syncMarker]);\n\n const brand = tone === 'brand';\n\n return (\n <nav\n className={cn(\n 'sticky top-0 z-30 w-full',\n brand\n ? 'bg-primary-900 text-white'\n : 'border-border bg-card/95 border-b backdrop-blur',\n className\n )}\n aria-label={label}\n >\n <div className=\"flex items-center gap-4 px-4 py-0.5\">\n <span\n className={cn(\n 'shrink-0 text-[11px] font-semibold tracking-wide uppercase max-md:hidden',\n brand ? 'text-white/85' : 'text-muted-foreground'\n )}\n aria-hidden=\"true\"\n >\n {label}\n </span>\n <div\n ref={railRef}\n className=\"relative flex min-w-0 flex-1 gap-1 overflow-x-auto [scrollbar-width:none] [&::-webkit-scrollbar]:hidden\"\n >\n {items.map((it) => {\n const isActive = active === it.id;\n return (\n <a\n key={it.id}\n href={`#${it.id}`}\n data-id={it.id}\n onClick={() => onItemClick?.(it.id)}\n className={cn(\n 'shrink-0 rounded px-2.5 py-2 text-sm whitespace-nowrap transition-colors',\n brand\n ? isActive\n ? 'font-semibold text-white'\n : 'text-white/85 hover:text-white'\n : isActive\n ? 'text-foreground font-semibold'\n : 'text-muted-foreground hover:text-foreground'\n )}\n aria-current={isActive ? 'location' : undefined}\n >\n {it.label}\n </a>\n );\n })}\n <span\n ref={markRef}\n className={cn(\n 'absolute bottom-0 h-0.5 rounded-full transition-[left,width] duration-300',\n brand ? 'bg-primary-400' : 'bg-primary-500'\n )}\n aria-hidden=\"true\"\n />\n </div>\n {cta && (\n <a\n href={cta.href}\n onClick={() => onCtaClick?.(cta)}\n className={cn(\n buttonVariants({\n variant: CTA_TIER_VARIANT[cta.tier ?? 'explore'],\n size: 'sm',\n }),\n 'shrink-0',\n brand &&\n (cta.tier ?? 'explore') !== 'commit' &&\n 'text-white hover:bg-white/10 hover:text-white'\n )}\n >\n {cta.label}\n <CtaArrow href={cta.href} />\n </a>\n )}\n </div>\n </nav>\n );\n}\n"]}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { CodingChips, RowActionToolbar, RowIconButton, currentAssertion } from './chunk-
|
|
1
|
+
import { CodingChips, RowActionToolbar, RowIconButton, currentAssertion } from './chunk-KSQQBFDQ.js';
|
|
2
2
|
import { Tooltip } from './chunk-YFWDS6MX.js';
|
|
3
3
|
import { RadioGroup, Radio } from './chunk-EPSB4WTL.js';
|
|
4
4
|
import { Label } from './chunk-I3WGZPI6.js';
|
|
5
5
|
import { DateInput } from './chunk-I6Y2KLTZ.js';
|
|
6
|
-
import { Textarea } from './chunk-
|
|
6
|
+
import { Textarea } from './chunk-L52HKEUD.js';
|
|
7
7
|
import { useMessages } from './chunk-5YOT4DVH.js';
|
|
8
8
|
import { Select } from './chunk-VCI2Y7ST.js';
|
|
9
9
|
import { Dropdown, DropdownItem, DropdownSeparator } from './chunk-OYUIEJPN.js';
|
|
@@ -22,7 +22,7 @@ import { isStorybookDocsMode } from './chunk-VSQF22GL.js';
|
|
|
22
22
|
import { AlertCircle, Plus, RefreshCw, Pencil, GripVertical, Trash2, StickyNote, Ban, ChevronUp, ChevronDown, Link, MoreVertical, Send, Stethoscope, Scan, TestTube2, Pill, CalendarCheck, ExternalLink, ThumbsUp, HandMetal, ThumbsDown, HelpCircle, AlertTriangle } from './chunk-BKSPDTX4.js';
|
|
23
23
|
import { isRtl } from './chunk-YVKBXNPK.js';
|
|
24
24
|
import { Badge } from './chunk-522WJIVI.js';
|
|
25
|
-
import { Button } from './chunk-
|
|
25
|
+
import { Button } from './chunk-WX2XB6FP.js';
|
|
26
26
|
import { cn } from './chunk-TQONQSJO.js';
|
|
27
27
|
import * as React4 from 'react';
|
|
28
28
|
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
@@ -4103,5 +4103,5 @@ function MedicationReconciliation({
|
|
|
4103
4103
|
}
|
|
4104
4104
|
|
|
4105
4105
|
export { ALLERGY_TYPE_LABELS, AllergyList, AllergyManager, Assessment, CodeLookupContext, CodeLookupProvider, ConditionEditor, DateRangeFilter, DateRangePicker, MEDICATION_STATUS_LABELS, MedicationEditor, MedicationList, MedicationReconciliation, ORDER_TYPE_META, ORDER_TYPE_SEARCH_DOMAINS, calculateDateRange, doseFormToQuantityUnit, getDefaultPresets, getExtendedPresets, isConditionCodetype, labelToMedicationFields, lookupToMedicationFields, normalizeConditionCodingSystem, orderTypeForCodetype, parseMedicationLabel, parseSig, useCodeLookupConfig };
|
|
4106
|
-
//# sourceMappingURL=chunk-
|
|
4107
|
-
//# sourceMappingURL=chunk-
|
|
4106
|
+
//# sourceMappingURL=chunk-DG3CXR24.js.map
|
|
4107
|
+
//# sourceMappingURL=chunk-DG3CXR24.js.map
|