@alfadocs/ui-kit-debug 1.128.0 → 1.129.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/_chunks/{appointment-card-0PebvrOS.js → appointment-card-vbUsDh70.js} +49 -72
- package/dist/_chunks/appointment-card-vbUsDh70.js.map +1 -0
- package/dist/_chunks/{appointment-timeline-Czd4PBkF.js → appointment-timeline-B5pfBl-b.js} +2 -2
- package/dist/_chunks/{appointment-timeline-Czd4PBkF.js.map → appointment-timeline-B5pfBl-b.js.map} +1 -1
- package/dist/_chunks/{appointment-tray-B04zKY7g.js → appointment-tray-BhiXetjs.js} +2 -2
- package/dist/_chunks/{appointment-tray-B04zKY7g.js.map → appointment-tray-BhiXetjs.js.map} +1 -1
- package/dist/_chunks/{calendar-_sgjuH3L.js → calendar-DzR-vdJ5.js} +614 -563
- package/dist/_chunks/calendar-DzR-vdJ5.js.map +1 -0
- package/dist/_chunks/calendar-appointment-editor-dialog-DnPADcj9.js +13438 -0
- package/dist/_chunks/calendar-appointment-editor-dialog-DnPADcj9.js.map +1 -0
- package/dist/_chunks/{calendar-event-card-DXAYWH6k.js → calendar-event-card-BNEzkjm-.js} +142 -132
- package/dist/_chunks/calendar-event-card-BNEzkjm-.js.map +1 -0
- package/dist/_chunks/{care-plan-card-bGTIliXc.js → care-plan-card-CwgkImOD.js} +2 -2
- package/dist/_chunks/{care-plan-card-bGTIliXc.js.map → care-plan-card-CwgkImOD.js.map} +1 -1
- package/dist/_chunks/{care-plan-header-k8FslxsU.js → care-plan-header-Dx5OMkc9.js} +2 -2
- package/dist/_chunks/{care-plan-header-k8FslxsU.js.map → care-plan-header-Dx5OMkc9.js.map} +1 -1
- package/dist/_chunks/{clinical-note-card-DHn5W_bv.js → clinical-note-card-pPaeWWnu.js} +2 -2
- package/dist/_chunks/{clinical-note-card-DHn5W_bv.js.map → clinical-note-card-pPaeWWnu.js.map} +1 -1
- package/dist/_chunks/{contact-card-CGpbYuxl.js → contact-card-BSY2YpLZ.js} +2 -2
- package/dist/_chunks/{contact-card-CGpbYuxl.js.map → contact-card-BSY2YpLZ.js.map} +1 -1
- package/dist/_chunks/{contact-profile-card-CCgf0Ntt.js → contact-profile-card-CsZNMlws.js} +2 -2
- package/dist/_chunks/{contact-profile-card-CCgf0Ntt.js.map → contact-profile-card-CsZNMlws.js.map} +1 -1
- package/dist/_chunks/{default-tabs-DOuHEKI5.js → default-tabs-BnB6FUEW.js} +2 -2
- package/dist/_chunks/{default-tabs-DOuHEKI5.js.map → default-tabs-BnB6FUEW.js.map} +1 -1
- package/dist/_chunks/{entity-summary-BanguTa6.js → entity-summary-Dzk54yom.js} +2 -2
- package/dist/_chunks/{entity-summary-BanguTa6.js.map → entity-summary-Dzk54yom.js.map} +1 -1
- package/dist/_chunks/file-pen-line-k4uMBM3h.js +29 -0
- package/dist/_chunks/file-pen-line-k4uMBM3h.js.map +1 -0
- package/dist/_chunks/{info-tip-C-MPkShR.js → info-tip-B3cn3fY2.js} +2 -2
- package/dist/_chunks/{info-tip-C-MPkShR.js.map → info-tip-B3cn3fY2.js.map} +1 -1
- package/dist/_chunks/{link-DtCfnLnF.js → link-CeV7FoI6.js} +2 -2
- package/dist/_chunks/{link-DtCfnLnF.js.map → link-CeV7FoI6.js.map} +1 -1
- package/dist/_chunks/{nav-grid-D2xVcHTO.js → nav-grid-dEgDAri3.js} +2 -2
- package/dist/_chunks/{nav-grid-D2xVcHTO.js.map → nav-grid-dEgDAri3.js.map} +1 -1
- package/dist/_chunks/{note-attachment-cnj2JRrg.js → note-attachment-MNTIqdSz.js} +2 -2
- package/dist/_chunks/{note-attachment-cnj2JRrg.js.map → note-attachment-MNTIqdSz.js.map} +1 -1
- package/dist/_chunks/{note-timeline-BrjHBQfx.js → note-timeline-BQeW0VZY.js} +2 -2
- package/dist/_chunks/{note-timeline-BrjHBQfx.js.map → note-timeline-BQeW0VZY.js.map} +1 -1
- package/dist/_chunks/{notes-panel-n1JFNQ5u.js → notes-panel-DIY7eNsq.js} +2 -2
- package/dist/_chunks/{notes-panel-n1JFNQ5u.js.map → notes-panel-DIY7eNsq.js.map} +1 -1
- package/dist/_chunks/{patient-details-Cba9HQj_.js → patient-details-DBtEITfE.js} +2 -2
- package/dist/_chunks/{patient-details-Cba9HQj_.js.map → patient-details-DBtEITfE.js.map} +1 -1
- package/dist/_chunks/{patient-field-row-CtDihADs.js → patient-field-row-a5d4QijH.js} +2 -2
- package/dist/_chunks/{patient-field-row-CtDihADs.js.map → patient-field-row-a5d4QijH.js.map} +1 -1
- package/dist/_chunks/{patient-summary-card-DnLdbtsw.js → patient-summary-card-BUcZ-gaL.js} +3 -3
- package/dist/_chunks/{patient-summary-card-DnLdbtsw.js.map → patient-summary-card-BUcZ-gaL.js.map} +1 -1
- package/dist/_chunks/{payment-request-card-CEIalOtr.js → payment-request-card-Dv4WbRBe.js} +2 -2
- package/dist/_chunks/{payment-request-card-CEIalOtr.js.map → payment-request-card-Dv4WbRBe.js.map} +1 -1
- package/dist/_chunks/{product-hub-panel-CqRJlmb7.js → product-hub-panel-a8wdVOUt.js} +2 -2
- package/dist/_chunks/{product-hub-panel-CqRJlmb7.js.map → product-hub-panel-a8wdVOUt.js.map} +1 -1
- package/dist/_chunks/{public-footer-C8UIzqLJ.js → public-footer-D0cqScpz.js} +2 -2
- package/dist/_chunks/{public-footer-C8UIzqLJ.js.map → public-footer-D0cqScpz.js.map} +1 -1
- package/dist/_chunks/{signature-request-Dzs0jZsd.js → signature-request-DW2PSp66.js} +3 -3
- package/dist/_chunks/{signature-request-Dzs0jZsd.js.map → signature-request-DW2PSp66.js.map} +1 -1
- package/dist/_chunks/{signed-out-frame-fUf7tqs3.js → signed-out-frame-Oa2e1yps.js} +2 -2
- package/dist/_chunks/{signed-out-frame-fUf7tqs3.js.map → signed-out-frame-Oa2e1yps.js.map} +1 -1
- package/dist/_chunks/task-editor-CVRrDqpe.js +1256 -0
- package/dist/_chunks/task-editor-CVRrDqpe.js.map +1 -0
- package/dist/_chunks/{treatment-receipt-1VnuinhY.js → treatment-receipt-BZzwvsnY.js} +73 -56
- package/dist/_chunks/treatment-receipt-BZzwvsnY.js.map +1 -0
- package/dist/_chunks/use-appointment-details-read-n7kycxrm.js +2439 -0
- package/dist/_chunks/use-appointment-details-read-n7kycxrm.js.map +1 -0
- package/dist/_chunks/{whatsapp-button-DV9JFmtq.js → whatsapp-button-XbozeDl_.js} +32 -25
- package/dist/_chunks/whatsapp-button-XbozeDl_.js.map +1 -0
- package/dist/agent-catalog.json +49 -16
- package/dist/agent-i18n/en.json +5 -5
- package/dist/browser-support.js +1 -1
- package/dist/components/_shared/patient-picker.d.ts +10 -0
- package/dist/components/_shared/patient-picker.d.ts.map +1 -1
- package/dist/components/appointment-card/index.js +2 -2
- package/dist/components/appointment-details-panel/appointment-details-panel.d.ts +23 -1
- package/dist/components/appointment-details-panel/appointment-details-panel.d.ts.map +1 -1
- package/dist/components/appointment-details-panel/appointment-details-panel.links.d.ts +13 -0
- package/dist/components/appointment-details-panel/appointment-details-panel.links.d.ts.map +1 -0
- package/dist/components/appointment-details-panel/appointment-details-panel.recurrence.d.ts +9 -0
- package/dist/components/appointment-details-panel/appointment-details-panel.recurrence.d.ts.map +1 -0
- package/dist/components/appointment-details-panel/appointment-details-panel.sections.d.ts +8 -3
- package/dist/components/appointment-details-panel/appointment-details-panel.sections.d.ts.map +1 -1
- package/dist/components/appointment-details-panel/appointment-details-panel.types.d.ts +63 -1
- package/dist/components/appointment-details-panel/appointment-details-panel.types.d.ts.map +1 -1
- package/dist/components/appointment-details-panel/index.d.ts +2 -1
- package/dist/components/appointment-details-panel/index.d.ts.map +1 -1
- package/dist/components/appointment-details-panel/index.js +5 -4
- package/dist/components/appointment-timeline/index.js +1 -1
- package/dist/components/bill-table/index.js +1 -1
- package/dist/components/calendar/calendar.d.ts +22 -0
- package/dist/components/calendar/calendar.d.ts.map +1 -1
- package/dist/components/calendar/index.js +1 -1
- package/dist/components/calendar-event-card/calendar-event-card.d.ts +8 -0
- package/dist/components/calendar-event-card/calendar-event-card.d.ts.map +1 -1
- package/dist/components/calendar-event-card/index.js +1 -1
- package/dist/components/care-plan-card/index.js +1 -1
- package/dist/components/care-plan-header/index.js +1 -1
- package/dist/components/clinical-note-card/index.js +1 -1
- package/dist/components/contact-card/index.js +1 -1
- package/dist/components/contact-profile-card/index.js +1 -1
- package/dist/components/entity-summary/index.js +1 -1
- package/dist/components/info-tip/index.js +1 -1
- package/dist/components/link/index.js +1 -1
- package/dist/components/nav-grid/index.js +1 -1
- package/dist/components/note-timeline/index.js +1 -1
- package/dist/components/notes-panel/index.js +1 -1
- package/dist/components/patient-details/index.js +1 -1
- package/dist/components/patient-summary-card/index.js +1 -1
- package/dist/components/payment-card/index.js +1 -1
- package/dist/components/product-hub-tray/index.js +1 -1
- package/dist/components/public-footer/index.js +1 -1
- package/dist/components/task-editor/index.js +1 -1
- package/dist/components/treatment-receipt/index.d.ts +2 -2
- package/dist/components/treatment-receipt/index.d.ts.map +1 -1
- package/dist/components/treatment-receipt/index.js +2 -1
- package/dist/components/treatment-receipt/treatment-receipt.d.ts +11 -1
- package/dist/components/treatment-receipt/treatment-receipt.d.ts.map +1 -1
- package/dist/components/whatsapp-button/index.js +1 -1
- package/dist/components/whatsapp-button/whatsapp-button.d.ts.map +1 -1
- package/dist/core.css +1 -1
- package/dist/fullcalendar.css +5 -1
- package/dist/host-compat.css +4 -1
- package/dist/i18n/locales/ar.d.ts +111 -4
- package/dist/i18n/locales/ar.d.ts.map +1 -1
- package/dist/i18n/locales/ar.js +122 -15
- package/dist/i18n/locales/ar.js.map +1 -1
- package/dist/i18n/locales/de.d.ts +111 -4
- package/dist/i18n/locales/de.d.ts.map +1 -1
- package/dist/i18n/locales/de.js +122 -15
- package/dist/i18n/locales/de.js.map +1 -1
- package/dist/i18n/locales/el.d.ts +111 -4
- package/dist/i18n/locales/el.d.ts.map +1 -1
- package/dist/i18n/locales/el.js +122 -15
- package/dist/i18n/locales/el.js.map +1 -1
- package/dist/i18n/locales/en.d.ts +111 -4
- package/dist/i18n/locales/en.d.ts.map +1 -1
- package/dist/i18n/locales/en.js +114 -10
- package/dist/i18n/locales/en.js.map +1 -1
- package/dist/i18n/locales/es.d.ts +111 -4
- package/dist/i18n/locales/es.d.ts.map +1 -1
- package/dist/i18n/locales/es.js +122 -15
- package/dist/i18n/locales/es.js.map +1 -1
- package/dist/i18n/locales/fr.d.ts +111 -4
- package/dist/i18n/locales/fr.d.ts.map +1 -1
- package/dist/i18n/locales/fr.js +122 -15
- package/dist/i18n/locales/fr.js.map +1 -1
- package/dist/i18n/locales/hi.d.ts +111 -4
- package/dist/i18n/locales/hi.d.ts.map +1 -1
- package/dist/i18n/locales/hi.js +122 -15
- package/dist/i18n/locales/hi.js.map +1 -1
- package/dist/i18n/locales/it.d.ts +111 -4
- package/dist/i18n/locales/it.d.ts.map +1 -1
- package/dist/i18n/locales/it.js +122 -15
- package/dist/i18n/locales/it.js.map +1 -1
- package/dist/i18n/locales/ja.d.ts +111 -4
- package/dist/i18n/locales/ja.d.ts.map +1 -1
- package/dist/i18n/locales/ja.js +122 -15
- package/dist/i18n/locales/ja.js.map +1 -1
- package/dist/i18n/locales/nl.d.ts +111 -4
- package/dist/i18n/locales/nl.d.ts.map +1 -1
- package/dist/i18n/locales/nl.js +122 -15
- package/dist/i18n/locales/nl.js.map +1 -1
- package/dist/i18n/locales/pl.d.ts +111 -4
- package/dist/i18n/locales/pl.d.ts.map +1 -1
- package/dist/i18n/locales/pl.js +122 -15
- package/dist/i18n/locales/pl.js.map +1 -1
- package/dist/i18n/locales/pt.d.ts +111 -4
- package/dist/i18n/locales/pt.d.ts.map +1 -1
- package/dist/i18n/locales/pt.js +122 -15
- package/dist/i18n/locales/pt.js.map +1 -1
- package/dist/i18n/locales/ro.d.ts +111 -4
- package/dist/i18n/locales/ro.d.ts.map +1 -1
- package/dist/i18n/locales/ro.js +122 -15
- package/dist/i18n/locales/ro.js.map +1 -1
- package/dist/i18n/locales/ru.d.ts +111 -4
- package/dist/i18n/locales/ru.d.ts.map +1 -1
- package/dist/i18n/locales/ru.js +122 -15
- package/dist/i18n/locales/ru.js.map +1 -1
- package/dist/i18n/locales/sq.d.ts +111 -4
- package/dist/i18n/locales/sq.d.ts.map +1 -1
- package/dist/i18n/locales/sq.js +122 -15
- package/dist/i18n/locales/sq.js.map +1 -1
- package/dist/i18n/locales/sv.d.ts +111 -4
- package/dist/i18n/locales/sv.d.ts.map +1 -1
- package/dist/i18n/locales/sv.js +122 -15
- package/dist/i18n/locales/sv.js.map +1 -1
- package/dist/i18n/locales/tr.d.ts +111 -4
- package/dist/i18n/locales/tr.d.ts.map +1 -1
- package/dist/i18n/locales/tr.js +122 -15
- package/dist/i18n/locales/tr.js.map +1 -1
- package/dist/i18n/locales/zh.d.ts +111 -4
- package/dist/i18n/locales/zh.d.ts.map +1 -1
- package/dist/i18n/locales/zh.js +122 -15
- package/dist/i18n/locales/zh.js.map +1 -1
- package/dist/index.js +1112 -1107
- package/dist/locales/ar.json +122 -15
- package/dist/locales/de.json +122 -15
- package/dist/locales/el.json +122 -15
- package/dist/locales/en.json +114 -7
- package/dist/locales/es.json +122 -15
- package/dist/locales/fr.json +122 -15
- package/dist/locales/hi.json +122 -15
- package/dist/locales/it.json +122 -15
- package/dist/locales/ja.json +122 -15
- package/dist/locales/nl.json +122 -15
- package/dist/locales/pl.json +122 -15
- package/dist/locales/pt.json +122 -15
- package/dist/locales/ro.json +122 -15
- package/dist/locales/ru.json +122 -15
- package/dist/locales/sq.json +122 -15
- package/dist/locales/sv.json +122 -15
- package/dist/locales/tr.json +122 -15
- package/dist/locales/zh.json +122 -15
- package/dist/patterns/calendar/calendar-appointment-details.d.ts +74 -2
- package/dist/patterns/calendar/calendar-appointment-details.d.ts.map +1 -1
- package/dist/patterns/calendar/calendar-archive.d.ts +12 -0
- package/dist/patterns/calendar/calendar-archive.d.ts.map +1 -0
- package/dist/patterns/calendar/calendar-bookings-panel.d.ts.map +1 -1
- package/dist/patterns/calendar/calendar-care-rules.d.ts +19 -23
- package/dist/patterns/calendar/calendar-care-rules.d.ts.map +1 -1
- package/dist/patterns/calendar/calendar-delete-confirm.d.ts +18 -0
- package/dist/patterns/calendar/calendar-delete-confirm.d.ts.map +1 -0
- package/dist/patterns/calendar/calendar-document-scope-confirm.d.ts +12 -0
- package/dist/patterns/calendar/calendar-document-scope-confirm.d.ts.map +1 -0
- package/dist/patterns/calendar/calendar-editor-guard.d.ts +12 -0
- package/dist/patterns/calendar/calendar-editor-guard.d.ts.map +1 -0
- package/dist/patterns/calendar/calendar-editor-hydration.d.ts +13 -2
- package/dist/patterns/calendar/calendar-editor-hydration.d.ts.map +1 -1
- package/dist/patterns/calendar/calendar-load-error.d.ts +11 -0
- package/dist/patterns/calendar/calendar-load-error.d.ts.map +1 -0
- package/dist/patterns/calendar/calendar-patient-locked.d.ts +13 -0
- package/dist/patterns/calendar/calendar-patient-locked.d.ts.map +1 -0
- package/dist/patterns/calendar/calendar-patient-picker.d.ts +6 -1
- package/dist/patterns/calendar/calendar-patient-picker.d.ts.map +1 -1
- package/dist/patterns/calendar/calendar-prompts.d.ts +11 -0
- package/dist/patterns/calendar/calendar-prompts.d.ts.map +1 -0
- package/dist/patterns/calendar/calendar-settings-ical.d.ts +11 -0
- package/dist/patterns/calendar/calendar-settings-ical.d.ts.map +1 -0
- package/dist/patterns/calendar/calendar-settings-overlay.d.ts +73 -0
- package/dist/patterns/calendar/calendar-settings-overlay.d.ts.map +1 -0
- package/dist/patterns/calendar/calendar-settings-panel.d.ts +62 -0
- package/dist/patterns/calendar/calendar-settings-panel.d.ts.map +1 -0
- package/dist/patterns/calendar/calendar-settings-practice.d.ts +20 -0
- package/dist/patterns/calendar/calendar-settings-practice.d.ts.map +1 -0
- package/dist/patterns/calendar/calendar-status-colours.d.ts +18 -0
- package/dist/patterns/calendar/calendar-status-colours.d.ts.map +1 -0
- package/dist/patterns/calendar/calendar-upcoming-panel.d.ts.map +1 -1
- package/dist/patterns/calendar/calendar-waiting-list-panel.d.ts +17 -2
- package/dist/patterns/calendar/calendar-waiting-list-panel.d.ts.map +1 -1
- package/dist/patterns/calendar/calendar-workspace.d.ts +258 -6
- package/dist/patterns/calendar/calendar-workspace.d.ts.map +1 -1
- package/dist/patterns/calendar/calendar-workspace.model.d.ts +98 -11
- package/dist/patterns/calendar/calendar-workspace.model.d.ts.map +1 -1
- package/dist/patterns/calendar/calendar.data.d.ts +9 -3
- package/dist/patterns/calendar/calendar.data.d.ts.map +1 -1
- package/dist/patterns/calendar/calendar.journey.d.ts +69 -5
- package/dist/patterns/calendar/calendar.journey.d.ts.map +1 -1
- package/dist/patterns/calendar/calendar.model.d.ts +72 -14
- package/dist/patterns/calendar/calendar.model.d.ts.map +1 -1
- package/dist/patterns/calendar/calendar.preferences.d.ts +4 -0
- package/dist/patterns/calendar/calendar.preferences.d.ts.map +1 -1
- package/dist/patterns/calendar/calendar.sheets.d.ts +85 -17
- package/dist/patterns/calendar/calendar.sheets.d.ts.map +1 -1
- package/dist/patterns/calendar/calendar.surface.d.ts +64 -6
- package/dist/patterns/calendar/calendar.surface.d.ts.map +1 -1
- package/dist/patterns/calendar/calendar.types.d.ts +223 -6
- package/dist/patterns/calendar/calendar.types.d.ts.map +1 -1
- package/dist/patterns/calendar/index.d.ts +9 -6
- package/dist/patterns/calendar/index.d.ts.map +1 -1
- package/dist/patterns/calendar/index.js +18 -15
- package/dist/patterns/signature-request/index.js +1 -1
- package/dist/patterns/signed-out-frame/index.js +1 -1
- package/dist/tokens.css +5 -1
- package/package.json +1 -1
- package/dist/_chunks/appointment-card-0PebvrOS.js.map +0 -1
- package/dist/_chunks/calendar-_sgjuH3L.js.map +0 -1
- package/dist/_chunks/calendar-appointment-editor-dialog-CGDDGMdo.js +0 -10974
- package/dist/_chunks/calendar-appointment-editor-dialog-CGDDGMdo.js.map +0 -1
- package/dist/_chunks/calendar-event-card-DXAYWH6k.js.map +0 -1
- package/dist/_chunks/task-editor-C05yx7JJ.js +0 -1218
- package/dist/_chunks/task-editor-C05yx7JJ.js.map +0 -1
- package/dist/_chunks/treatment-receipt-1VnuinhY.js.map +0 -1
- package/dist/_chunks/use-appointment-details-read-Bm408XzX.js +0 -2198
- package/dist/_chunks/use-appointment-details-read-Bm408XzX.js.map +0 -1
- package/dist/_chunks/whatsapp-button-DV9JFmtq.js.map +0 -1
|
@@ -6,7 +6,7 @@ import { A as H } from "./avatar-Dp5apm1d.js";
|
|
|
6
6
|
import { B as $ } from "./button-DohK_Ak_.js";
|
|
7
7
|
import { I as O } from "./icon-button-S8_weU3g.js";
|
|
8
8
|
import { C } from "./card-n6W6LW-N.js";
|
|
9
|
-
import { L as F } from "./link-
|
|
9
|
+
import { L as F } from "./link-CeV7FoI6.js";
|
|
10
10
|
import { P as G } from "./panel-header-CbtlTe85.js";
|
|
11
11
|
import { T as W } from "./timestamp-DPLDWdxA.js";
|
|
12
12
|
import { u as X } from "./registry-DvAUVLHh.js";
|
|
@@ -274,4 +274,4 @@ function ae({ section: t }) {
|
|
|
274
274
|
export {
|
|
275
275
|
be as E
|
|
276
276
|
};
|
|
277
|
-
//# sourceMappingURL=entity-summary-
|
|
277
|
+
//# sourceMappingURL=entity-summary-Dzk54yom.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"entity-summary-BanguTa6.js","sources":["../../node_modules/lucide-react/dist/esm/icons/contact-round.mjs","../../src/components/entity-summary/entity-summary.agent.ts","../../src/components/entity-summary/entity-summary.tsx"],"sourcesContent":["/**\n * @license lucide-react v1.22.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\"path\", { d: \"M16 2v2\", key: \"scm5qe\" }],\n [\"path\", { d: \"M17.915 22a6 6 0 0 0-12 0\", key: \"suqz9p\" }],\n [\"path\", { d: \"M8 2v2\", key: \"pbkmx\" }],\n [\"circle\", { cx: \"12\", cy: \"12\", r: \"4\", key: \"4exip2\" }],\n [\"rect\", { x: \"3\", y: \"4\", width: \"18\", height: \"18\", rx: \"2\", key: \"12vinp\" }]\n];\nconst ContactRound = createLucideIcon(\"contact-round\", __iconNode);\n\nexport { __iconNode, ContactRound as default };\n//# sourceMappingURL=contact-round.mjs.map\n","/* -------------------------------------------------------------------- */\n/* Agent adapter — EntitySummary. */\n/* */\n/* The AI narrative brief (\"Sintesi IA\") for an entity. The agent can */\n/* read the brief's STRUCTURE (generated-at + section ids / headings / */\n/* tone / item counts — fixed category labels, never the entity name or */\n/* the bullet items, both PHI) and drive the two affordances: regenerate */\n/* the brief and dismiss the panel. Generation itself is gated upstream */\n/* by AiConsentBanner; this adapter only re-requests an already-consented */\n/* brief. */\n/* -------------------------------------------------------------------- */\n\nimport type { AgentAdapter } from '../../agent/types';\nimport type { EntitySummaryHandle } from './entity-summary';\n\nexport const entitySummaryAgent: AgentAdapter<EntitySummaryHandle> = {\n id: 'entity-summary',\n // 'close' backs close; regenerate is a host-driven refresh with no\n // dedicated capability in the closed vocabulary.\n capabilities: ['close'],\n state: {\n sections: {\n type: 'Array<{ id: string; heading: string; tone: \"default\" | \"attention\"; itemCount: number }>',\n descriptionKey: 'ui.agent.entitySummary.state.sections',\n description:\n 'Structural section list — ids, fixed category headings, tone and item counts. Never the entity name or the bullet items (both PHI).',\n read: (handle) => handle.getState().sections,\n },\n generatedAtIso: {\n type: 'string | undefined',\n descriptionKey: 'ui.agent.entitySummary.state.generatedAtIso',\n description: 'ISO-8601 instant the brief was generated, when known.',\n read: (handle) => handle.getState().generatedAtIso,\n },\n },\n actions: {\n regenerate: {\n // Re-requests a fresh brief from the model — reaches an external system.\n safety: 'write',\n openWorld: true,\n descriptionKey: 'ui.agent.entitySummary.actions.regenerate',\n description:\n 'Request the host to regenerate the AI brief. No-op when the regenerate affordance is not available.',\n invoke: (handle) => {\n if (handle.canRegenerate()) handle.regenerate();\n },\n },\n close: {\n // Ephemeral panel-visibility change — read.\n safety: 'read',\n idempotent: true,\n descriptionKey: 'ui.agent.entitySummary.actions.close',\n description:\n 'Dismiss the summary panel. No-op when the close affordance is not available (e.g. docked in the rail).',\n invoke: (handle) => {\n if (handle.canClose()) handle.close();\n },\n },\n },\n domHooks: {\n root: {\n attr: 'data-component',\n value: 'entity-summary',\n description: 'Marks the EntitySummary panel region.',\n },\n instanceId: {\n attr: 'data-component-id',\n sourceProp: 'id',\n description:\n 'Sourced from the id prop. Required to address a specific summary panel from the agent.',\n },\n },\n};\n","import {\n forwardRef,\n useId,\n useImperativeHandle,\n useMemo,\n useRef,\n type HTMLAttributes,\n type ReactNode,\n} from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { ContactRound, Clock, RefreshCw, X } from 'lucide-react';\nimport { Alert } from '../alert';\nimport { Avatar } from '../avatar';\nimport { Button } from '../button';\nimport { Card } from '../card';\nimport { IconButton } from '../button/icon-button';\nimport { Link } from '../link';\nimport { PanelHeader } from '../panel-header';\nimport { Timestamp } from '../timestamp';\nimport { useAgentRegistration } from '../../agent/registry';\nimport { entitySummaryAgent } from './entity-summary.agent';\n\n/* ------------------------------------------------------------------ */\n/* EntitySummary — the AI narrative brief for an entity. */\n/* */\n/* The kit form of platform's \"Sintesi IA\": a generated, sectioned */\n/* brief of a patient / care plan — header (entity · generated-at · */\n/* regenerate · corpus stats), N labelled sections of bullet items */\n/* (with inline entity links), and a BETA disclaimer. The `attention` */\n/* section tone carries the clinically valuable risk flags. */\n/* */\n/* The kit owns the layout, i18n and theming; the consumer passes */\n/* structured `sections` (data-in) so the brief re-themes and */\n/* localises rather than rendering a model HTML blob. Gate generation */\n/* behind `AiConsentBanner` upstream. */\n/* ------------------------------------------------------------------ */\n\n/** A corpus stat shown in the header (e.g. `{ value: 5, label: 'care plans' }`). */\nexport interface EntitySummaryStat {\n value: string | number;\n label: string;\n}\n\n/** One narrative section — a heading over a list of bullet items. */\nexport interface EntitySummarySection {\n id: string;\n heading: string;\n /**\n * Leading glyph for the section. On default sections it's the scannability\n * anchor shown in a `--primary`-tinted medallion beside the heading (e.g. a\n * calendar for \"Scheduled\", a wallet for \"Financial\"); omit it to render no\n * medallion. On `attention` sections it overrides the warning Alert's icon\n * (which defaults to an alert triangle).\n */\n icon?: ReactNode;\n /**\n * `attention` renders the section as the kit's warning `Alert` — the\n * standard risk-flag treatment (border, warning surface, alert glyph,\n * `--warning-foreground` text) — for clinically important callouts.\n */\n tone?: 'default' | 'attention';\n /** Bullet items — `ReactNode` so consumers compose inline entity links. */\n items: ReactNode[];\n}\n\n/**\n * Curated agent handle for EntitySummary. Exposes structural state only —\n * never the entity name or the section items (both PHI). See\n * `entity-summary.agent.ts`.\n */\nexport interface EntitySummaryHandle {\n /** Structural snapshot — generated-at + section ids/headings/tone/count. No PHI. */\n getState: () => {\n generatedAtIso?: string;\n sections: Array<{\n id: string;\n heading: string;\n tone: 'default' | 'attention';\n itemCount: number;\n }>;\n };\n /** Whether the regenerate affordance is available. */\n canRegenerate: () => boolean;\n /** Request the host to regenerate the brief (mirrors onRegenerate). */\n regenerate: () => void;\n /** Whether the close affordance is available. */\n canClose: () => boolean;\n /** Dismiss the panel (mirrors onClose). */\n close: () => void;\n}\n\nexport interface EntitySummaryProps extends Omit<\n HTMLAttributes<HTMLElement>,\n 'title' | 'children'\n> {\n /**\n * Stable instance id. Surfaced on the root as `data-component-id` so an\n * agent / MCP UI bridge can address this specific summary panel.\n */\n id?: string;\n /** Panel title. Defaults to the localised \"AI summary\". */\n title?: string;\n /** Entity name shown beside its avatar in the header (links when `entityHref` is set). */\n entityName?: string;\n /** Entity href for the name link. */\n entityHref?: string;\n /** Avatar image URL for the entity. Falls back to initials derived from `entityName`. */\n entityAvatarSrc?: string;\n /** ISO-8601 instant the brief was generated. */\n generatedAtIso?: string;\n /** Corpus the brief was built from, shown as a compact KPI card. */\n stats?: EntitySummaryStat[];\n /** The narrative sections, in order. */\n sections: EntitySummarySection[];\n /** Regenerate the brief. Omit to hide the affordance. */\n onRegenerate?: () => void;\n /** Regenerate-button label. */\n regenerateLabel?: string;\n /**\n * Dismiss the panel. Renders a close button in the panel header for\n * STANDALONE use (outside the rail). When docked in `ControlRoomRail`, omit\n * this — the rail injects its own close via `PanelHeaderActionsProvider`\n * (passing it while docked would render a duplicate close control).\n */\n onClose?: () => void;\n /** Footer disclaimer. Defaults to the BETA clinical-judgement note. */\n disclaimer?: ReactNode;\n /** BCP-47 locale for the generated-at timestamp. */\n locale?: string;\n /** Accessible name for the panel region (defaults to `title`). */\n 'aria-label'?: string;\n}\n\n/* ------------------------------------------------------------------ */\n/* Section presentation. The `attention` tone renders a different */\n/* element tree (the kit's warning Alert) rather than a class variant, */\n/* so the branch lives in `Section`; these constants carry the shared */\n/* class sets for the default (prose) sections. */\n/* ------------------------------------------------------------------ */\n\n// The default section's leading icon chip — a --primary-tinted medallion\n// that anchors the heading. No tone variants: the attention tone is owned\n// by the Alert primitive, so this stays a plain class set.\nconst MEDALLION_CLASSES =\n 'ds:flex ds:size-7 ds:shrink-0 ds:items-center ds:justify-center ds:rounded-[var(--radius-md)] ds:[&_svg]:size-4 ds:bg-primary/10 ds:text-[color:var(--primary)]';\n\n// The bullet list shared by every section — indented disc items.\nconst ITEMS_CLASSES =\n 'ds:m-0 ds:flex ds:list-disc ds:flex-col ds:gap-[var(--spacing-2xs)] ds:ps-[var(--spacing-md)] type-body-sm';\n\nexport const EntitySummary = forwardRef<HTMLElement, EntitySummaryProps>(\n function EntitySummary(\n {\n id,\n title,\n entityName,\n entityHref,\n entityAvatarSrc,\n generatedAtIso,\n stats,\n sections,\n onRegenerate,\n regenerateLabel,\n onClose,\n disclaimer,\n locale,\n className,\n 'aria-label': ariaLabel,\n ...rest\n },\n ref,\n ) {\n const { t } = useTranslation('ui');\n const headingId = useId();\n const heading =\n title ?? t('entitySummary.title', { defaultValue: 'AI summary' });\n\n /* ----- Agent handle (structural state + regenerate / close) ----- */\n const sectionsRef = useRef(sections);\n sectionsRef.current = sections;\n const generatedAtRef = useRef(generatedAtIso);\n generatedAtRef.current = generatedAtIso;\n const onRegenerateRef = useRef(onRegenerate);\n onRegenerateRef.current = onRegenerate;\n const onCloseRef = useRef(onClose);\n onCloseRef.current = onClose;\n\n const rootRef = useRef<HTMLElement>(null);\n useImperativeHandle(ref, () => rootRef.current as HTMLElement, []);\n\n const handle = useMemo<EntitySummaryHandle>(\n () => ({\n // Structural only — section headings are fixed category labels, never\n // the entity name or the bullet items (both PHI).\n getState: () => ({\n generatedAtIso: generatedAtRef.current,\n sections: sectionsRef.current.map((s) => ({\n id: s.id,\n heading: s.heading,\n tone: s.tone ?? 'default',\n itemCount: s.items.length,\n })),\n }),\n canRegenerate: () => !!onRegenerateRef.current,\n regenerate: () => onRegenerateRef.current?.(),\n canClose: () => !!onCloseRef.current,\n close: () => onCloseRef.current?.(),\n }),\n [],\n );\n useAgentRegistration(entitySummaryAgent, handle, id);\n\n // The generated-at line — the brief's \"subtitle\" under the entity name,\n // or a standalone line when there's no entity. A clock glyph leads it.\n const generatedLine = generatedAtIso ? (\n <span className=\"ds:inline-flex ds:items-center ds:gap-[var(--spacing-2xs)] type-meta ds:text-[color:var(--muted-foreground)]\">\n <Clock aria-hidden=\"true\" className=\"ds:size-3.5 ds:shrink-0\" />\n <span>\n {t('entitySummary.generatedAt', { defaultValue: 'Generated' })}\n </span>\n <Timestamp value={generatedAtIso} format=\"absolute\" locale={locale} />\n </span>\n ) : null;\n\n return (\n <section\n ref={rootRef}\n data-component=\"entity-summary\"\n data-component-id={id}\n aria-labelledby={ariaLabel ? undefined : headingId}\n aria-label={ariaLabel}\n className={['ds:flex ds:flex-col', className].filter(Boolean).join(' ')}\n {...rest}\n >\n {/* Header — the shared rail-panel pattern. Title + Regenerate;\n the close affordance is injected by the rail, not the panel. */}\n <PanelHeader\n title={heading}\n icon={<ContactRound aria-hidden=\"true\" />}\n headingId={ariaLabel ? undefined : headingId}\n sticky\n divider\n actions={\n onRegenerate || onClose ? (\n <>\n {onRegenerate ? (\n <Button\n type=\"button\"\n size=\"sm\"\n intent=\"ghost\"\n startIcon={<RefreshCw aria-hidden=\"true\" />}\n onClick={onRegenerate}\n >\n {regenerateLabel ??\n t('entitySummary.regenerate', {\n defaultValue: 'Regenerate',\n })}\n </Button>\n ) : null}\n {onClose ? (\n <IconButton\n icon={<X aria-hidden=\"true\" />}\n size=\"sm\"\n intent=\"ghost\"\n aria-label={t('common.close', { defaultValue: 'Close' })}\n onClick={onClose}\n />\n ) : null}\n </>\n ) : undefined\n }\n />\n\n {/* Body */}\n <div className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-md)] ds:p-[var(--spacing-md)]\">\n {entityName || generatedAtIso || (stats && stats.length > 0) ? (\n <div className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-md)]\">\n {/* Identity — the entity's avatar + name, generated-at as the\n subtitle beneath. Without a name, the generated line stands\n alone. */}\n {entityName ? (\n <div className=\"ds:flex ds:items-center ds:gap-[var(--spacing-sm)]\">\n <Avatar\n name={entityName}\n src={entityAvatarSrc}\n size=\"sm\"\n className=\"ds:shrink-0\"\n />\n <div className=\"ds:flex ds:min-w-0 ds:flex-col ds:gap-[var(--spacing-2xs)]\">\n {entityHref ? (\n <Link\n href={entityHref}\n className=\"type-body-sm ds:font-semibold\"\n >\n {entityName}\n </Link>\n ) : (\n <span className=\"type-body-sm ds:font-semibold ds:text-[color:var(--foreground)]\">\n {entityName}\n </span>\n )}\n {generatedLine}\n </div>\n </div>\n ) : (\n generatedLine\n )}\n\n {/* Corpus stats — a compact KPI card: value over label, with a\n hairline divider between cells. */}\n {stats && stats.length > 0 ? (\n <Card variant=\"elevated\">\n {/* eslint-disable-next-line jsx-a11y/no-redundant-roles -- role=\"list\" restores list semantics that ds:list-none strips in Safari/VoiceOver */}\n <ul\n role=\"list\"\n className=\"ds:m-0 ds:flex ds:list-none ds:items-stretch\"\n >\n {stats.map((stat, index) => (\n <li\n key={`${stat.label}-${index}`}\n className={[\n 'ds:flex ds:flex-1 ds:flex-col ds:items-center ds:gap-[var(--spacing-2xs)] ds:p-[var(--spacing-sm)] ds:text-center',\n index > 0\n ? 'ds:border-s ds:border-[color:var(--card-border)]'\n : '',\n ]\n .filter(Boolean)\n .join(' ')}\n >\n <span className=\"type-metric ds:[--type-metric-size:var(--font-size-lg)] ds:text-[color:var(--foreground)]\">\n {stat.value}\n </span>\n <span className=\"type-meta ds:text-[color:var(--muted-foreground)]\">\n {stat.label}\n </span>\n </li>\n ))}\n </ul>\n </Card>\n ) : null}\n </div>\n ) : null}\n\n {/* Sections */}\n {sections.map((section) => (\n <Section key={section.id} section={section} />\n ))}\n\n {/* Disclaimer */}\n <p className=\"ds:m-0 type-meta ds:text-[color:var(--muted-foreground)]\">\n {disclaimer ??\n t('entitySummary.disclaimer', {\n defaultValue:\n 'Does not replace clinical judgement · verify accuracy before clinical use · BETA',\n })}\n </p>\n </div>\n </section>\n );\n },\n);\n\nfunction Section({ section }: { section: EntitySummarySection }): ReactNode {\n const headingId = useId();\n\n // The risk-flag section composes the kit's warning `Alert` primitive rather\n // than re-painting the warning tokens by hand — same border, surface, alert\n // glyph, and `--warning-foreground` treatment as every other warning in the\n // app. `live=\"off\"`: the brief is static content, not a just-occurred event,\n // so the items read in normal flow instead of being announced assertively.\n // A per-section `icon` overrides Alert's default alert triangle.\n if (section.tone === 'attention') {\n // The shared `--shadow-card` lifts the warning callout to the same\n // elevation as the surrounding section cards, so the stack reads as one\n // set of raised panels rather than a flat warning band among cards.\n return (\n <Alert\n variant=\"warning\"\n live=\"off\"\n icon={section.icon}\n className=\"ds:shadow-[var(--shadow-card)]\"\n >\n <Alert.Title as=\"h3\">{section.heading}</Alert.Title>\n <ul className={ITEMS_CLASSES}>\n {section.items.map((item, index) => (\n <li key={index}>{item}</li>\n ))}\n </ul>\n </Alert>\n );\n }\n\n // Default sections are raised cards — the scannable \"panel per topic\" stack,\n // matching platform's Sintesi IA. The card owns its own padding (so we drive\n // it from a single content div rather than Card.Header/Body) and is named by\n // its heading for assistive tech.\n return (\n <Card variant=\"elevated\" aria-labelledby={headingId}>\n <div className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-sm)] ds:p-[var(--spacing-md)]\">\n <div className=\"ds:flex ds:items-center ds:gap-[var(--spacing-xs)]\">\n {section.icon ? (\n <span aria-hidden=\"true\" className={MEDALLION_CLASSES}>\n {section.icon}\n </span>\n ) : null}\n <h3\n id={headingId}\n className=\"ds:m-0 type-eyebrow ds:text-[color:var(--foreground)]\"\n >\n {section.heading}\n </h3>\n </div>\n <ul className={`${ITEMS_CLASSES} ds:text-[color:var(--foreground)]`}>\n {section.items.map((item, index) => (\n <li key={index}>{item}</li>\n ))}\n </ul>\n </div>\n </Card>\n );\n}\n"],"names":["__iconNode","ContactRound","createLucideIcon","entitySummaryAgent","handle","MEDALLION_CLASSES","ITEMS_CLASSES","EntitySummary","forwardRef","id","title","entityName","entityHref","entityAvatarSrc","generatedAtIso","stats","sections","onRegenerate","regenerateLabel","onClose","disclaimer","locale","className","ariaLabel","rest","ref","t","useTranslation","headingId","useId","heading","sectionsRef","useRef","generatedAtRef","onRegenerateRef","onCloseRef","rootRef","useImperativeHandle","useMemo","s","_a","useAgentRegistration","generatedLine","jsxs","jsx","Clock","Timestamp","PanelHeader","Fragment","Button","RefreshCw","IconButton","X","Avatar","Link","Card","stat","index","section","Section","Alert","item"],"mappings":"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","x_google_ignoreList":[0]}
|
|
1
|
+
{"version":3,"file":"entity-summary-Dzk54yom.js","sources":["../../node_modules/lucide-react/dist/esm/icons/contact-round.mjs","../../src/components/entity-summary/entity-summary.agent.ts","../../src/components/entity-summary/entity-summary.tsx"],"sourcesContent":["/**\n * @license lucide-react v1.22.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\"path\", { d: \"M16 2v2\", key: \"scm5qe\" }],\n [\"path\", { d: \"M17.915 22a6 6 0 0 0-12 0\", key: \"suqz9p\" }],\n [\"path\", { d: \"M8 2v2\", key: \"pbkmx\" }],\n [\"circle\", { cx: \"12\", cy: \"12\", r: \"4\", key: \"4exip2\" }],\n [\"rect\", { x: \"3\", y: \"4\", width: \"18\", height: \"18\", rx: \"2\", key: \"12vinp\" }]\n];\nconst ContactRound = createLucideIcon(\"contact-round\", __iconNode);\n\nexport { __iconNode, ContactRound as default };\n//# sourceMappingURL=contact-round.mjs.map\n","/* -------------------------------------------------------------------- */\n/* Agent adapter — EntitySummary. */\n/* */\n/* The AI narrative brief (\"Sintesi IA\") for an entity. The agent can */\n/* read the brief's STRUCTURE (generated-at + section ids / headings / */\n/* tone / item counts — fixed category labels, never the entity name or */\n/* the bullet items, both PHI) and drive the two affordances: regenerate */\n/* the brief and dismiss the panel. Generation itself is gated upstream */\n/* by AiConsentBanner; this adapter only re-requests an already-consented */\n/* brief. */\n/* -------------------------------------------------------------------- */\n\nimport type { AgentAdapter } from '../../agent/types';\nimport type { EntitySummaryHandle } from './entity-summary';\n\nexport const entitySummaryAgent: AgentAdapter<EntitySummaryHandle> = {\n id: 'entity-summary',\n // 'close' backs close; regenerate is a host-driven refresh with no\n // dedicated capability in the closed vocabulary.\n capabilities: ['close'],\n state: {\n sections: {\n type: 'Array<{ id: string; heading: string; tone: \"default\" | \"attention\"; itemCount: number }>',\n descriptionKey: 'ui.agent.entitySummary.state.sections',\n description:\n 'Structural section list — ids, fixed category headings, tone and item counts. Never the entity name or the bullet items (both PHI).',\n read: (handle) => handle.getState().sections,\n },\n generatedAtIso: {\n type: 'string | undefined',\n descriptionKey: 'ui.agent.entitySummary.state.generatedAtIso',\n description: 'ISO-8601 instant the brief was generated, when known.',\n read: (handle) => handle.getState().generatedAtIso,\n },\n },\n actions: {\n regenerate: {\n // Re-requests a fresh brief from the model — reaches an external system.\n safety: 'write',\n openWorld: true,\n descriptionKey: 'ui.agent.entitySummary.actions.regenerate',\n description:\n 'Request the host to regenerate the AI brief. No-op when the regenerate affordance is not available.',\n invoke: (handle) => {\n if (handle.canRegenerate()) handle.regenerate();\n },\n },\n close: {\n // Ephemeral panel-visibility change — read.\n safety: 'read',\n idempotent: true,\n descriptionKey: 'ui.agent.entitySummary.actions.close',\n description:\n 'Dismiss the summary panel. No-op when the close affordance is not available (e.g. docked in the rail).',\n invoke: (handle) => {\n if (handle.canClose()) handle.close();\n },\n },\n },\n domHooks: {\n root: {\n attr: 'data-component',\n value: 'entity-summary',\n description: 'Marks the EntitySummary panel region.',\n },\n instanceId: {\n attr: 'data-component-id',\n sourceProp: 'id',\n description:\n 'Sourced from the id prop. Required to address a specific summary panel from the agent.',\n },\n },\n};\n","import {\n forwardRef,\n useId,\n useImperativeHandle,\n useMemo,\n useRef,\n type HTMLAttributes,\n type ReactNode,\n} from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { ContactRound, Clock, RefreshCw, X } from 'lucide-react';\nimport { Alert } from '../alert';\nimport { Avatar } from '../avatar';\nimport { Button } from '../button';\nimport { Card } from '../card';\nimport { IconButton } from '../button/icon-button';\nimport { Link } from '../link';\nimport { PanelHeader } from '../panel-header';\nimport { Timestamp } from '../timestamp';\nimport { useAgentRegistration } from '../../agent/registry';\nimport { entitySummaryAgent } from './entity-summary.agent';\n\n/* ------------------------------------------------------------------ */\n/* EntitySummary — the AI narrative brief for an entity. */\n/* */\n/* The kit form of platform's \"Sintesi IA\": a generated, sectioned */\n/* brief of a patient / care plan — header (entity · generated-at · */\n/* regenerate · corpus stats), N labelled sections of bullet items */\n/* (with inline entity links), and a BETA disclaimer. The `attention` */\n/* section tone carries the clinically valuable risk flags. */\n/* */\n/* The kit owns the layout, i18n and theming; the consumer passes */\n/* structured `sections` (data-in) so the brief re-themes and */\n/* localises rather than rendering a model HTML blob. Gate generation */\n/* behind `AiConsentBanner` upstream. */\n/* ------------------------------------------------------------------ */\n\n/** A corpus stat shown in the header (e.g. `{ value: 5, label: 'care plans' }`). */\nexport interface EntitySummaryStat {\n value: string | number;\n label: string;\n}\n\n/** One narrative section — a heading over a list of bullet items. */\nexport interface EntitySummarySection {\n id: string;\n heading: string;\n /**\n * Leading glyph for the section. On default sections it's the scannability\n * anchor shown in a `--primary`-tinted medallion beside the heading (e.g. a\n * calendar for \"Scheduled\", a wallet for \"Financial\"); omit it to render no\n * medallion. On `attention` sections it overrides the warning Alert's icon\n * (which defaults to an alert triangle).\n */\n icon?: ReactNode;\n /**\n * `attention` renders the section as the kit's warning `Alert` — the\n * standard risk-flag treatment (border, warning surface, alert glyph,\n * `--warning-foreground` text) — for clinically important callouts.\n */\n tone?: 'default' | 'attention';\n /** Bullet items — `ReactNode` so consumers compose inline entity links. */\n items: ReactNode[];\n}\n\n/**\n * Curated agent handle for EntitySummary. Exposes structural state only —\n * never the entity name or the section items (both PHI). See\n * `entity-summary.agent.ts`.\n */\nexport interface EntitySummaryHandle {\n /** Structural snapshot — generated-at + section ids/headings/tone/count. No PHI. */\n getState: () => {\n generatedAtIso?: string;\n sections: Array<{\n id: string;\n heading: string;\n tone: 'default' | 'attention';\n itemCount: number;\n }>;\n };\n /** Whether the regenerate affordance is available. */\n canRegenerate: () => boolean;\n /** Request the host to regenerate the brief (mirrors onRegenerate). */\n regenerate: () => void;\n /** Whether the close affordance is available. */\n canClose: () => boolean;\n /** Dismiss the panel (mirrors onClose). */\n close: () => void;\n}\n\nexport interface EntitySummaryProps extends Omit<\n HTMLAttributes<HTMLElement>,\n 'title' | 'children'\n> {\n /**\n * Stable instance id. Surfaced on the root as `data-component-id` so an\n * agent / MCP UI bridge can address this specific summary panel.\n */\n id?: string;\n /** Panel title. Defaults to the localised \"AI summary\". */\n title?: string;\n /** Entity name shown beside its avatar in the header (links when `entityHref` is set). */\n entityName?: string;\n /** Entity href for the name link. */\n entityHref?: string;\n /** Avatar image URL for the entity. Falls back to initials derived from `entityName`. */\n entityAvatarSrc?: string;\n /** ISO-8601 instant the brief was generated. */\n generatedAtIso?: string;\n /** Corpus the brief was built from, shown as a compact KPI card. */\n stats?: EntitySummaryStat[];\n /** The narrative sections, in order. */\n sections: EntitySummarySection[];\n /** Regenerate the brief. Omit to hide the affordance. */\n onRegenerate?: () => void;\n /** Regenerate-button label. */\n regenerateLabel?: string;\n /**\n * Dismiss the panel. Renders a close button in the panel header for\n * STANDALONE use (outside the rail). When docked in `ControlRoomRail`, omit\n * this — the rail injects its own close via `PanelHeaderActionsProvider`\n * (passing it while docked would render a duplicate close control).\n */\n onClose?: () => void;\n /** Footer disclaimer. Defaults to the BETA clinical-judgement note. */\n disclaimer?: ReactNode;\n /** BCP-47 locale for the generated-at timestamp. */\n locale?: string;\n /** Accessible name for the panel region (defaults to `title`). */\n 'aria-label'?: string;\n}\n\n/* ------------------------------------------------------------------ */\n/* Section presentation. The `attention` tone renders a different */\n/* element tree (the kit's warning Alert) rather than a class variant, */\n/* so the branch lives in `Section`; these constants carry the shared */\n/* class sets for the default (prose) sections. */\n/* ------------------------------------------------------------------ */\n\n// The default section's leading icon chip — a --primary-tinted medallion\n// that anchors the heading. No tone variants: the attention tone is owned\n// by the Alert primitive, so this stays a plain class set.\nconst MEDALLION_CLASSES =\n 'ds:flex ds:size-7 ds:shrink-0 ds:items-center ds:justify-center ds:rounded-[var(--radius-md)] ds:[&_svg]:size-4 ds:bg-primary/10 ds:text-[color:var(--primary)]';\n\n// The bullet list shared by every section — indented disc items.\nconst ITEMS_CLASSES =\n 'ds:m-0 ds:flex ds:list-disc ds:flex-col ds:gap-[var(--spacing-2xs)] ds:ps-[var(--spacing-md)] type-body-sm';\n\nexport const EntitySummary = forwardRef<HTMLElement, EntitySummaryProps>(\n function EntitySummary(\n {\n id,\n title,\n entityName,\n entityHref,\n entityAvatarSrc,\n generatedAtIso,\n stats,\n sections,\n onRegenerate,\n regenerateLabel,\n onClose,\n disclaimer,\n locale,\n className,\n 'aria-label': ariaLabel,\n ...rest\n },\n ref,\n ) {\n const { t } = useTranslation('ui');\n const headingId = useId();\n const heading =\n title ?? t('entitySummary.title', { defaultValue: 'AI summary' });\n\n /* ----- Agent handle (structural state + regenerate / close) ----- */\n const sectionsRef = useRef(sections);\n sectionsRef.current = sections;\n const generatedAtRef = useRef(generatedAtIso);\n generatedAtRef.current = generatedAtIso;\n const onRegenerateRef = useRef(onRegenerate);\n onRegenerateRef.current = onRegenerate;\n const onCloseRef = useRef(onClose);\n onCloseRef.current = onClose;\n\n const rootRef = useRef<HTMLElement>(null);\n useImperativeHandle(ref, () => rootRef.current as HTMLElement, []);\n\n const handle = useMemo<EntitySummaryHandle>(\n () => ({\n // Structural only — section headings are fixed category labels, never\n // the entity name or the bullet items (both PHI).\n getState: () => ({\n generatedAtIso: generatedAtRef.current,\n sections: sectionsRef.current.map((s) => ({\n id: s.id,\n heading: s.heading,\n tone: s.tone ?? 'default',\n itemCount: s.items.length,\n })),\n }),\n canRegenerate: () => !!onRegenerateRef.current,\n regenerate: () => onRegenerateRef.current?.(),\n canClose: () => !!onCloseRef.current,\n close: () => onCloseRef.current?.(),\n }),\n [],\n );\n useAgentRegistration(entitySummaryAgent, handle, id);\n\n // The generated-at line — the brief's \"subtitle\" under the entity name,\n // or a standalone line when there's no entity. A clock glyph leads it.\n const generatedLine = generatedAtIso ? (\n <span className=\"ds:inline-flex ds:items-center ds:gap-[var(--spacing-2xs)] type-meta ds:text-[color:var(--muted-foreground)]\">\n <Clock aria-hidden=\"true\" className=\"ds:size-3.5 ds:shrink-0\" />\n <span>\n {t('entitySummary.generatedAt', { defaultValue: 'Generated' })}\n </span>\n <Timestamp value={generatedAtIso} format=\"absolute\" locale={locale} />\n </span>\n ) : null;\n\n return (\n <section\n ref={rootRef}\n data-component=\"entity-summary\"\n data-component-id={id}\n aria-labelledby={ariaLabel ? undefined : headingId}\n aria-label={ariaLabel}\n className={['ds:flex ds:flex-col', className].filter(Boolean).join(' ')}\n {...rest}\n >\n {/* Header — the shared rail-panel pattern. Title + Regenerate;\n the close affordance is injected by the rail, not the panel. */}\n <PanelHeader\n title={heading}\n icon={<ContactRound aria-hidden=\"true\" />}\n headingId={ariaLabel ? undefined : headingId}\n sticky\n divider\n actions={\n onRegenerate || onClose ? (\n <>\n {onRegenerate ? (\n <Button\n type=\"button\"\n size=\"sm\"\n intent=\"ghost\"\n startIcon={<RefreshCw aria-hidden=\"true\" />}\n onClick={onRegenerate}\n >\n {regenerateLabel ??\n t('entitySummary.regenerate', {\n defaultValue: 'Regenerate',\n })}\n </Button>\n ) : null}\n {onClose ? (\n <IconButton\n icon={<X aria-hidden=\"true\" />}\n size=\"sm\"\n intent=\"ghost\"\n aria-label={t('common.close', { defaultValue: 'Close' })}\n onClick={onClose}\n />\n ) : null}\n </>\n ) : undefined\n }\n />\n\n {/* Body */}\n <div className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-md)] ds:p-[var(--spacing-md)]\">\n {entityName || generatedAtIso || (stats && stats.length > 0) ? (\n <div className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-md)]\">\n {/* Identity — the entity's avatar + name, generated-at as the\n subtitle beneath. Without a name, the generated line stands\n alone. */}\n {entityName ? (\n <div className=\"ds:flex ds:items-center ds:gap-[var(--spacing-sm)]\">\n <Avatar\n name={entityName}\n src={entityAvatarSrc}\n size=\"sm\"\n className=\"ds:shrink-0\"\n />\n <div className=\"ds:flex ds:min-w-0 ds:flex-col ds:gap-[var(--spacing-2xs)]\">\n {entityHref ? (\n <Link\n href={entityHref}\n className=\"type-body-sm ds:font-semibold\"\n >\n {entityName}\n </Link>\n ) : (\n <span className=\"type-body-sm ds:font-semibold ds:text-[color:var(--foreground)]\">\n {entityName}\n </span>\n )}\n {generatedLine}\n </div>\n </div>\n ) : (\n generatedLine\n )}\n\n {/* Corpus stats — a compact KPI card: value over label, with a\n hairline divider between cells. */}\n {stats && stats.length > 0 ? (\n <Card variant=\"elevated\">\n {/* eslint-disable-next-line jsx-a11y/no-redundant-roles -- role=\"list\" restores list semantics that ds:list-none strips in Safari/VoiceOver */}\n <ul\n role=\"list\"\n className=\"ds:m-0 ds:flex ds:list-none ds:items-stretch\"\n >\n {stats.map((stat, index) => (\n <li\n key={`${stat.label}-${index}`}\n className={[\n 'ds:flex ds:flex-1 ds:flex-col ds:items-center ds:gap-[var(--spacing-2xs)] ds:p-[var(--spacing-sm)] ds:text-center',\n index > 0\n ? 'ds:border-s ds:border-[color:var(--card-border)]'\n : '',\n ]\n .filter(Boolean)\n .join(' ')}\n >\n <span className=\"type-metric ds:[--type-metric-size:var(--font-size-lg)] ds:text-[color:var(--foreground)]\">\n {stat.value}\n </span>\n <span className=\"type-meta ds:text-[color:var(--muted-foreground)]\">\n {stat.label}\n </span>\n </li>\n ))}\n </ul>\n </Card>\n ) : null}\n </div>\n ) : null}\n\n {/* Sections */}\n {sections.map((section) => (\n <Section key={section.id} section={section} />\n ))}\n\n {/* Disclaimer */}\n <p className=\"ds:m-0 type-meta ds:text-[color:var(--muted-foreground)]\">\n {disclaimer ??\n t('entitySummary.disclaimer', {\n defaultValue:\n 'Does not replace clinical judgement · verify accuracy before clinical use · BETA',\n })}\n </p>\n </div>\n </section>\n );\n },\n);\n\nfunction Section({ section }: { section: EntitySummarySection }): ReactNode {\n const headingId = useId();\n\n // The risk-flag section composes the kit's warning `Alert` primitive rather\n // than re-painting the warning tokens by hand — same border, surface, alert\n // glyph, and `--warning-foreground` treatment as every other warning in the\n // app. `live=\"off\"`: the brief is static content, not a just-occurred event,\n // so the items read in normal flow instead of being announced assertively.\n // A per-section `icon` overrides Alert's default alert triangle.\n if (section.tone === 'attention') {\n // The shared `--shadow-card` lifts the warning callout to the same\n // elevation as the surrounding section cards, so the stack reads as one\n // set of raised panels rather than a flat warning band among cards.\n return (\n <Alert\n variant=\"warning\"\n live=\"off\"\n icon={section.icon}\n className=\"ds:shadow-[var(--shadow-card)]\"\n >\n <Alert.Title as=\"h3\">{section.heading}</Alert.Title>\n <ul className={ITEMS_CLASSES}>\n {section.items.map((item, index) => (\n <li key={index}>{item}</li>\n ))}\n </ul>\n </Alert>\n );\n }\n\n // Default sections are raised cards — the scannable \"panel per topic\" stack,\n // matching platform's Sintesi IA. The card owns its own padding (so we drive\n // it from a single content div rather than Card.Header/Body) and is named by\n // its heading for assistive tech.\n return (\n <Card variant=\"elevated\" aria-labelledby={headingId}>\n <div className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-sm)] ds:p-[var(--spacing-md)]\">\n <div className=\"ds:flex ds:items-center ds:gap-[var(--spacing-xs)]\">\n {section.icon ? (\n <span aria-hidden=\"true\" className={MEDALLION_CLASSES}>\n {section.icon}\n </span>\n ) : null}\n <h3\n id={headingId}\n className=\"ds:m-0 type-eyebrow ds:text-[color:var(--foreground)]\"\n >\n {section.heading}\n </h3>\n </div>\n <ul className={`${ITEMS_CLASSES} ds:text-[color:var(--foreground)]`}>\n {section.items.map((item, index) => (\n <li key={index}>{item}</li>\n ))}\n </ul>\n </div>\n </Card>\n );\n}\n"],"names":["__iconNode","ContactRound","createLucideIcon","entitySummaryAgent","handle","MEDALLION_CLASSES","ITEMS_CLASSES","EntitySummary","forwardRef","id","title","entityName","entityHref","entityAvatarSrc","generatedAtIso","stats","sections","onRegenerate","regenerateLabel","onClose","disclaimer","locale","className","ariaLabel","rest","ref","t","useTranslation","headingId","useId","heading","sectionsRef","useRef","generatedAtRef","onRegenerateRef","onCloseRef","rootRef","useImperativeHandle","useMemo","s","_a","useAgentRegistration","generatedLine","jsxs","jsx","Clock","Timestamp","PanelHeader","Fragment","Button","RefreshCw","IconButton","X","Avatar","Link","Card","stat","index","section","Section","Alert","item"],"mappings":"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","x_google_ignoreList":[0]}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { c as a } from "./createLucideIcon-DhHxpK9K.js";
|
|
2
|
+
/**
|
|
3
|
+
* @license lucide-react v1.22.0 - ISC
|
|
4
|
+
*
|
|
5
|
+
* This source code is licensed under the ISC license.
|
|
6
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
7
|
+
*/
|
|
8
|
+
const e = [
|
|
9
|
+
[
|
|
10
|
+
"path",
|
|
11
|
+
{
|
|
12
|
+
d: "M14.364 13.634a2 2 0 0 0-.506.854l-.837 2.87a.5.5 0 0 0 .62.62l2.87-.837a2 2 0 0 0 .854-.506l4.013-4.009a1 1 0 0 0-3.004-3.004z",
|
|
13
|
+
key: "ukzhwg"
|
|
14
|
+
}
|
|
15
|
+
],
|
|
16
|
+
["path", { d: "M14.487 7.858A1 1 0 0 1 14 7V2", key: "1klhew" }],
|
|
17
|
+
[
|
|
18
|
+
"path",
|
|
19
|
+
{
|
|
20
|
+
d: "M20 19.645V20a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l2.516 2.516",
|
|
21
|
+
key: "rxaxab"
|
|
22
|
+
}
|
|
23
|
+
],
|
|
24
|
+
["path", { d: "M8 18h1", key: "13wk12" }]
|
|
25
|
+
], h = a("file-pen-line", e);
|
|
26
|
+
export {
|
|
27
|
+
h as F
|
|
28
|
+
};
|
|
29
|
+
//# sourceMappingURL=file-pen-line-k4uMBM3h.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-pen-line-k4uMBM3h.js","sources":["../../node_modules/lucide-react/dist/esm/icons/file-pen-line.mjs"],"sourcesContent":["/**\n * @license lucide-react v1.22.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\n \"path\",\n {\n d: \"M14.364 13.634a2 2 0 0 0-.506.854l-.837 2.87a.5.5 0 0 0 .62.62l2.87-.837a2 2 0 0 0 .854-.506l4.013-4.009a1 1 0 0 0-3.004-3.004z\",\n key: \"ukzhwg\"\n }\n ],\n [\"path\", { d: \"M14.487 7.858A1 1 0 0 1 14 7V2\", key: \"1klhew\" }],\n [\n \"path\",\n {\n d: \"M20 19.645V20a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l2.516 2.516\",\n key: \"rxaxab\"\n }\n ],\n [\"path\", { d: \"M8 18h1\", key: \"13wk12\" }]\n];\nconst FilePenLine = createLucideIcon(\"file-pen-line\", __iconNode);\n\nexport { __iconNode, FilePenLine as default };\n//# sourceMappingURL=file-pen-line.mjs.map\n"],"names":["__iconNode","FilePenLine","createLucideIcon"],"mappings":";AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AASA,MAAMA,IAAa;AAAA,EACjB;AAAA,IACE;AAAA,IACA;AAAA,MACE,GAAG;AAAA,MACH,KAAK;AAAA,IACX;AAAA,EACA;AAAA,EACE,CAAC,QAAQ,EAAE,GAAG,kCAAkC,KAAK,SAAQ,CAAE;AAAA,EAC/D;AAAA,IACE;AAAA,IACA;AAAA,MACE,GAAG;AAAA,MACH,KAAK;AAAA,IACX;AAAA,EACA;AAAA,EACE,CAAC,QAAQ,EAAE,GAAG,WAAW,KAAK,SAAQ,CAAE;AAC1C,GACMC,IAAcC,EAAiB,iBAAiBF,CAAU;","x_google_ignoreList":[0]}
|
|
@@ -3,7 +3,7 @@ import { forwardRef as E, useState as F, useRef as i, useEffect as M, useMemo as
|
|
|
3
3
|
import { c as _ } from "./index-D2ZczOXr.js";
|
|
4
4
|
import { useTranslation as H } from "react-i18next";
|
|
5
5
|
import { P as f } from "./popover-CN5IsOeS.js";
|
|
6
|
-
import { L as V } from "./link-
|
|
6
|
+
import { L as V } from "./link-CeV7FoI6.js";
|
|
7
7
|
import { S as q } from "./scroll-area-CY5SLYNw.js";
|
|
8
8
|
import { c as $ } from "./compose-refs-C0k0tdqF.js";
|
|
9
9
|
import { u as G } from "./registry-DvAUVLHh.js";
|
|
@@ -263,4 +263,4 @@ export {
|
|
|
263
263
|
Z as I,
|
|
264
264
|
Q as i
|
|
265
265
|
};
|
|
266
|
-
//# sourceMappingURL=info-tip-
|
|
266
|
+
//# sourceMappingURL=info-tip-B3cn3fY2.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"info-tip-C-MPkShR.js","sources":["../../src/components/info-tip/info-tip.agent.ts","../../src/components/info-tip/info-tip.tsx"],"sourcesContent":["import type { AgentAdapter } from '../../agent/types';\nimport type { InfoTipHandle } from './info-tip';\n\nexport const infoTipAgent: AgentAdapter<InfoTipHandle> = {\n id: 'info-tip',\n capabilities: ['open', 'close'],\n state: {\n isOpen: {\n type: 'boolean',\n descriptionKey: 'ui.agent.infoTip.state.isOpen',\n description: 'True when the info tip card is currently open.',\n read: (handle) => handle.getIsOpen(),\n },\n },\n actions: {\n open: {\n safety: 'read',\n idempotent: true,\n descriptionKey: 'ui.agent.infoTip.actions.open',\n description:\n 'Open the info tip card (including its formula and Learn more link, when set).',\n invoke: (handle) => {\n handle.open();\n },\n },\n close: {\n safety: 'read',\n idempotent: true,\n descriptionKey: 'ui.agent.infoTip.actions.close',\n description: 'Close the info tip card.',\n invoke: (handle) => {\n handle.close();\n },\n },\n },\n domHooks: {\n root: {\n attr: 'data-component',\n value: 'info-tip',\n description: 'Marks the InfoTip trigger button.',\n },\n instanceId: {\n attr: 'data-component-id',\n sourceProp: 'id',\n description: 'Sourced from the id prop on InfoTip.',\n },\n },\n};\n","import {\n forwardRef,\n useEffect,\n useMemo,\n useRef,\n useState,\n type MouseEvent as ReactMouseEvent,\n type ReactNode,\n} from 'react';\nimport { cva } from 'class-variance-authority';\nimport { useTranslation } from 'react-i18next';\nimport { Info } from 'lucide-react';\nimport { Popover } from '../popover';\nimport { Link } from '../link';\nimport { ScrollArea } from '../scroll-area';\nimport { composeRefs } from '../_shared/compose-refs';\nimport { useAgentRegistration } from '../../agent';\nimport { infoTipAgent } from './info-tip.agent';\n\n/* -------------------------------------------------------------------- */\n/* Trigger — a small circular, branded affordance: card surface inside */\n/* the circle, accent ring + accent \"i\" glyph, and a soft drop shadow. */\n/* The accent alias is safe here: `--accent` resolves to magenta-700 in */\n/* light mode (the AA-safe interactive step) and the dark accent on dark */\n/* surfaces — never reference a raw magenta ramp step. */\n/* -------------------------------------------------------------------- */\n\nconst infoTipTriggerVariants = cva(\n [\n 'ds:relative ds:inline-flex ds:shrink-0 ds:items-center ds:justify-center',\n 'ds:rounded-[var(--radius-full)]',\n 'ds:bg-[var(--card)]',\n 'ds:text-[var(--accent)]',\n // Single ring: the Lucide Info glyph draws its own accent circle, so the\n // trigger carries NO CSS border of its own (a border would read as a\n // second, concentric ring). The white circle comes from `bg-card` showing\n // through the glyph, lifted by the drop shadow.\n 'ds:shadow-[var(--shadow-sm)]',\n 'ds:cursor-pointer',\n 'ds:transition-[color,box-shadow] ds:motion-reduce:transition-none',\n 'ds:hover:text-[var(--accent-hover)] ds:hover:shadow-[var(--shadow-md)]',\n 'ds:data-[state=open]:text-[var(--accent-hover)] ds:data-[state=open]:shadow-[var(--shadow-md)]',\n 'ds:focus-visible:outline-[length:var(--focus-ring-width)] ds:focus-visible:outline-solid ds:focus-visible:outline-ring ds:focus-visible:outline-offset-[length:var(--focus-ring-offset)]',\n 'ds:forced-colors:focus-visible:outline-[CanvasText]',\n ].join(' '),\n {\n variants: {\n size: {\n // Both diameters sit below `--min-target-size` (44/48px), so each\n // re-uses IconButton's invisible `::before` hit-area expansion to a\n // full touch target on touch / small screens. From the `sm:`\n // breakpoint up the pointer is precise, so the expansion relaxes —\n // but the interactive target must never fall below WCAG 2.5.8's 24px:\n // • md (24px visual) already meets the 24px floor, so its `::before`\n // is hidden on desktop and the 24px circle IS the target.\n // • sm (20px visual) would fall to 20px if hidden — below the floor\n // — so instead of hiding, its `::before` shrinks to a persistent\n // `--spacing-lg` (24px) minimum that holds on desktop too.\n sm: 'ds:w-5 ds:h-5 ds:before:absolute ds:before:inset-x-[calc((var(--min-target-size)-100%)/-2)] ds:before:inset-y-[calc((var(--min-target-size)-100%)/-2)] ds:before:content-[\"\"] ds:sm:before:inset-x-[calc((var(--spacing-lg)-100%)/-2)] ds:sm:before:inset-y-[calc((var(--spacing-lg)-100%)/-2)]',\n md: 'ds:w-6 ds:h-6 ds:before:absolute ds:before:inset-x-[calc((var(--min-target-size)-100%)/-2)] ds:before:inset-y-[calc((var(--min-target-size)-100%)/-2)] ds:before:content-[\"\"] ds:sm:before:hidden',\n },\n },\n defaultVariants: {\n size: 'md',\n },\n },\n);\n\n// Curated agent-readiness handle — see info-tip.agent.ts.\nexport interface InfoTipHandle {\n getIsOpen: () => boolean;\n open: () => void;\n close: () => void;\n}\n\nexport interface InfoTipProps {\n /** Body of the tip — explanatory text shown in the floating card. */\n content: ReactNode;\n /** Optional heading rendered above the body. */\n heading?: ReactNode;\n /**\n * Trigger diameter. Also sets the floating card width unless `cardSize`\n * is given: `sm` → `--popover-size-sm`, `md` → `--popover-size-md`.\n */\n size?: 'sm' | 'md';\n /**\n * Width of the floating card, when it should differ from the trigger size:\n * `sm` → `--popover-size-sm`, `md` → `--popover-size-md`, `lg` →\n * `--popover-size-lg`. Defaults to the width that matches `size`, so a\n * small trigger can open a wider card for a longer explanation.\n */\n cardSize?: 'sm' | 'md' | 'lg';\n /** Logical side the card opens on. Default `'top'`. */\n side?: 'start' | 'top' | 'end' | 'bottom';\n /** Alignment along the side axis. Default `'center'`. */\n align?: 'start' | 'center' | 'end';\n /**\n * Accessible name for the trigger. Defaults to the translated\n * \"More information\" chrome string.\n */\n 'aria-label'?: string;\n /**\n * Opaque instance id — emitted as `data-component-id` on the trigger and\n * used to register the instance with the host agent registry.\n */\n id?: string;\n /** Extra classes merged onto the trigger button. */\n className?: string;\n /**\n * A formula written in words, shown below `content` in a quiet block, e.g.\n * \"Net revenue = invoices issued − credit notes\". It is part of the card's\n * description, so screen readers hear it.\n */\n formula?: ReactNode;\n /**\n * When set, the card gains a footer \"Learn more\" link to this URL and\n * becomes interactive: Tab from the open trigger moves to the link,\n * Shift+Tab returns, Escape closes and refocuses the trigger. Without it the\n * card is explanatory text and focus stays on the trigger, unless the text\n * is long enough to scroll: then Tab reaches the text so it can be scrolled.\n */\n learnMoreHref?: string;\n /**\n * Makes the card interactive: `content` may hold links or buttons (for\n * example a short list of links, use the kit `Link`). Tab from the open\n * trigger moves into the card, Shift+Tab from its first control returns,\n * Tab past its last closes the card and carries on after the trigger, and\n * Escape closes and refocuses the trigger. The card is named from\n * `heading` and its body is left out of `aria-describedby`, so links are\n * not read as flat text. Default `false`: the card stays explanatory.\n */\n interactive?: boolean;\n /** Link text. Defaults to the translated \"Learn more\" chrome string. */\n learnMoreLabel?: string;\n /**\n * Called when the link is activated. An SPA can call `event.preventDefault()`\n * and route client-side; the anchor keeps its real `href` either way.\n */\n onLearnMore?: (event: ReactMouseEvent<HTMLAnchorElement>) => void;\n}\n\nconst TABBABLE =\n 'a[href], button:not([disabled]), input:not([disabled]):not([type=\"hidden\"]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex=\"-1\"])';\n\nfunction firstTabbable(root: HTMLElement | null): HTMLElement | null {\n if (!root) return null;\n const all = root.querySelectorAll<HTMLElement>(TABBABLE);\n for (const el of all) {\n const style = getComputedStyle(el);\n if (!el.hidden && style.display !== 'none' && style.visibility !== 'hidden')\n return el;\n }\n return null;\n}\n\n// Interactive bodies stay out of the description: links read as flat text there.\nfunction BodyRegion({\n interactive,\n className,\n children,\n}: {\n interactive: boolean;\n className: string;\n children: ReactNode;\n}) {\n if (!interactive) {\n return (\n <Popover.Description className={className}>\n {children}\n </Popover.Description>\n );\n }\n return (\n <div\n className={`ds:text-[var(--muted-foreground)] type-body-sm ds:mt-[var(--spacing-xs)] ${className}`}\n >\n {children}\n </div>\n );\n}\n\n/**\n * InfoTip — a deliberate, branded \"more information\" affordance: a small\n * circular trigger that reveals an explanatory card on hover **and** click\n * (click also serves touch devices). Composes the kit Popover in\n * `openOn=\"hover-or-click\"` mode — hover intent, keyboard focus, Escape and\n * focus-return are all handled by the Popover/Radix layer.\n */\nexport const InfoTip = forwardRef<HTMLButtonElement, InfoTipProps>(\n (\n {\n content,\n heading,\n size = 'md',\n cardSize,\n side = 'top',\n align = 'center',\n 'aria-label': ariaLabelProp,\n id,\n className,\n formula,\n interactive = false,\n learnMoreHref,\n learnMoreLabel,\n onLearnMore,\n },\n ref,\n ) => {\n const { t } = useTranslation('ui');\n const [open, setOpen] = useState(false);\n\n // Agent handle.\n const openRef = useRef(open);\n useEffect(() => {\n openRef.current = open;\n }, [open]);\n\n const agentHandle = useMemo<InfoTipHandle>(\n () => ({\n getIsOpen: () => openRef.current,\n open: () => setOpen(true),\n close: () => setOpen(false),\n }),\n [],\n );\n useAgentRegistration(infoTipAgent, agentHandle, id);\n\n // Press bookkeeping. In hover-or-click mode the Popover opens as soon as\n // the trigger receives focus — which happens on pointerdown, BEFORE the\n // click event that Radix uses to toggle. Without intervention every\n // click/tap on a closed tip opens it (focus) and instantly toggles it\n // closed again (click). So each press (pointerdown, or Enter/Space)\n // snapshots the open state and the click handler consumes it: if the\n // press itself opened the card, swallow Radix's toggle so the card stays\n // open; if it was already open, let the toggle close it.\n //\n // `null` means \"no press recorded for this click\" — an orphan click\n // (programmatic .click(), or assistive tech dispatching click with no\n // pointer/key event). Those must fall through to Radix's default toggle\n // rather than read a stale snapshot, so the guard treats `null` as\n // \"don't suppress\" and every click clears the snapshot back to `null`.\n const pressStateRef = useRef<boolean | null>(null);\n const handlePressStart = () => {\n pressStateRef.current = openRef.current;\n };\n\n const hasLink = learnMoreHref != null;\n const triggerRef = useRef<HTMLButtonElement | null>(null);\n const composedTriggerRef = useMemo(\n () => composeRefs<HTMLButtonElement>(ref, triggerRef),\n [ref],\n );\n const linkRef = useRef<HTMLAnchorElement | null>(null);\n const contentRef = useRef<HTMLDivElement | null>(null);\n // A long tip is capped at the height the viewport leaves it and its text\n // scrolls in a ScrollArea, which is a tab stop only while it can scroll.\n const scrollRef = useRef<HTMLDivElement | null>(null);\n\n const ariaLabel =\n ariaLabelProp ?? t('infoTip.triggerLabel', 'More information');\n\n return (\n <Popover openOn=\"hover-or-click\" open={open} onOpenChange={setOpen}>\n <Popover.Trigger\n ref={composedTriggerRef}\n aria-label={ariaLabel}\n className={infoTipTriggerVariants({ size, className })}\n data-component=\"info-tip\"\n data-component-id={id}\n onPointerDown={handlePressStart}\n onKeyDown={(event) => {\n if (event.key === 'Enter' || event.key === ' ') {\n handlePressStart();\n }\n // The card is portalled, so native Tab order would skip it. Tab\n // from the open trigger goes to the scrolling text when it\n // overflows, otherwise straight to the link.\n const scroll = scrollRef.current;\n const scrollable = scroll?.tabIndex === 0;\n const next = scrollable\n ? scroll\n : interactive\n ? firstTabbable(contentRef.current)\n : linkRef.current;\n if (\n (hasLink || scrollable || interactive) &&\n event.key === 'Tab' &&\n !event.shiftKey &&\n openRef.current &&\n next\n ) {\n event.preventDefault();\n next.focus();\n }\n }}\n onClick={(event) => {\n // Consume this click's press snapshot. A genuine pointer/keyboard\n // press recorded `false`/`true` on press-start; an orphan click\n // with no preceding pointerdown/keydown finds `null` and is left\n // to Radix's default toggle.\n const wasOpenAtPressStart = pressStateRef.current;\n pressStateRef.current = null;\n if (wasOpenAtPressStart === false && openRef.current) {\n // This press opened the card via focus — keep it open and\n // skip Radix's click toggle.\n event.preventDefault();\n }\n }}\n >\n <Info\n aria-hidden=\"true\"\n // Fills the circle so the glyph's own ring IS the trigger's\n // visible edge and the drop shadow hugs it.\n className={size === 'sm' ? 'ds:size-5' : 'ds:size-6'}\n />\n </Popover.Trigger>\n <Popover.Content\n ref={contentRef}\n side={side}\n align={align}\n size={cardSize ?? (size === 'sm' ? 'sm' : 'md')}\n // Never taller than the space the viewport leaves; the text scrolls.\n // The card itself does not clip, so its arrow stays visible.\n className={[\n 'ds:flex ds:flex-col ds:max-h-[var(--radix-popover-content-available-height)]',\n // Links and buttons reach the touch target on small screens.\n interactive &&\n 'ds:max-sm:[&_a]:inline-flex ds:max-sm:[&_a]:items-center ds:max-sm:[&_a]:min-block-[var(--min-target-size)]',\n ]\n .filter(Boolean)\n .join(' ')}\n // The card is a Radix `role=\"dialog\"` surface, which axe requires\n // to have an accessible name (aria-dialog-name). With a heading,\n // Popover wires aria-labelledby; without one, fall back to the\n // trigger's label.\n aria-label={heading == null ? ariaLabel : undefined}\n // Toggletip focus contract: the card is explanatory text, never\n // interactive, so focus stays on the trigger for the whole\n // open/close cycle. Preventing the open move also keeps Escape\n // reliable — if Radix pulled focus into the card, closing would\n // refocus the trigger and re-fire the hover-mode focus handler,\n // reopening the card it just closed. Preventing the close move\n // keeps an unhover-close from stealing focus mid-task.\n //\n // With a learn-more link, or text long enough to scroll, the card\n // is interactive, but the same contract holds: focus is never\n // pulled in on open, only Tab moves it to the text or the link. Escape from inside the card is handled below so\n // focus returns to the trigger without re-firing its focus-open.\n onOpenAutoFocus={(event) => event.preventDefault()}\n onCloseAutoFocus={(event) => event.preventDefault()}\n onEscapeKeyDown={(event) => {\n // Focus anywhere inside the card (the link, or the card itself\n // after a click on its text) goes back to the trigger.\n const active = document.activeElement;\n if (active && contentRef.current?.contains(active)) {\n event.preventDefault();\n triggerRef.current?.focus();\n setOpen(false);\n }\n }}\n >\n {heading != null && <Popover.Heading>{heading}</Popover.Heading>}\n <BodyRegion\n interactive={interactive}\n className=\"ds:flex ds:min-h-0 ds:flex-col\"\n >\n <ScrollArea\n ref={scrollRef}\n type=\"native\"\n aria-label={typeof heading === 'string' ? heading : ariaLabel}\n // At high zoom the heading and link keep their height; the text\n // keeps at least three lines rather than collapsing to nothing.\n className=\"ds:min-h-[3lh]\"\n >\n {content}\n {formula != null && (\n <div\n data-slot=\"formula\"\n className=\"type-body-sm ds:mt-[var(--spacing-sm)] ds:rounded-[var(--radius-sm)] ds:bg-[var(--muted)] ds:px-[var(--spacing-sm)] ds:py-[var(--spacing-xs)] ds:text-[var(--foreground)] ds:tabular-nums\"\n >\n <span className=\"ds:sr-only\">\n {t('infoTip.formula', 'Formula')}:{' '}\n </span>\n {formula}\n </div>\n )}\n </ScrollArea>\n </BodyRegion>\n {hasLink && (\n <div\n data-slot=\"footer\"\n className=\"ds:mt-[var(--spacing-sm)] ds:flex ds:justify-end\"\n >\n <Link\n ref={linkRef}\n href={learnMoreHref}\n onClick={onLearnMore}\n weight=\"strong\"\n className=\"type-body-sm\"\n >\n {learnMoreLabel ?? t('infoTip.learnMore', 'Learn more')}\n </Link>\n </div>\n )}\n </Popover.Content>\n </Popover>\n );\n },\n);\n\nInfoTip.displayName = 'InfoTip';\n"],"names":["infoTipAgent","handle","infoTipTriggerVariants","cva","TABBABLE","firstTabbable","root","all","el","style","BodyRegion","interactive","className","children","jsx","Popover","InfoTip","forwardRef","content","heading","size","cardSize","side","align","ariaLabelProp","id","formula","learnMoreHref","learnMoreLabel","onLearnMore","ref","t","useTranslation","open","setOpen","useState","openRef","useRef","useEffect","agentHandle","useMemo","useAgentRegistration","pressStateRef","handlePressStart","hasLink","triggerRef","composedTriggerRef","composeRefs","linkRef","contentRef","scrollRef","ariaLabel","event","scroll","scrollable","next","wasOpenAtPressStart","Info","jsxs","active","_a","_b","ScrollArea","Link"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"info-tip-B3cn3fY2.js","sources":["../../src/components/info-tip/info-tip.agent.ts","../../src/components/info-tip/info-tip.tsx"],"sourcesContent":["import type { AgentAdapter } from '../../agent/types';\nimport type { InfoTipHandle } from './info-tip';\n\nexport const infoTipAgent: AgentAdapter<InfoTipHandle> = {\n id: 'info-tip',\n capabilities: ['open', 'close'],\n state: {\n isOpen: {\n type: 'boolean',\n descriptionKey: 'ui.agent.infoTip.state.isOpen',\n description: 'True when the info tip card is currently open.',\n read: (handle) => handle.getIsOpen(),\n },\n },\n actions: {\n open: {\n safety: 'read',\n idempotent: true,\n descriptionKey: 'ui.agent.infoTip.actions.open',\n description:\n 'Open the info tip card (including its formula and Learn more link, when set).',\n invoke: (handle) => {\n handle.open();\n },\n },\n close: {\n safety: 'read',\n idempotent: true,\n descriptionKey: 'ui.agent.infoTip.actions.close',\n description: 'Close the info tip card.',\n invoke: (handle) => {\n handle.close();\n },\n },\n },\n domHooks: {\n root: {\n attr: 'data-component',\n value: 'info-tip',\n description: 'Marks the InfoTip trigger button.',\n },\n instanceId: {\n attr: 'data-component-id',\n sourceProp: 'id',\n description: 'Sourced from the id prop on InfoTip.',\n },\n },\n};\n","import {\n forwardRef,\n useEffect,\n useMemo,\n useRef,\n useState,\n type MouseEvent as ReactMouseEvent,\n type ReactNode,\n} from 'react';\nimport { cva } from 'class-variance-authority';\nimport { useTranslation } from 'react-i18next';\nimport { Info } from 'lucide-react';\nimport { Popover } from '../popover';\nimport { Link } from '../link';\nimport { ScrollArea } from '../scroll-area';\nimport { composeRefs } from '../_shared/compose-refs';\nimport { useAgentRegistration } from '../../agent';\nimport { infoTipAgent } from './info-tip.agent';\n\n/* -------------------------------------------------------------------- */\n/* Trigger — a small circular, branded affordance: card surface inside */\n/* the circle, accent ring + accent \"i\" glyph, and a soft drop shadow. */\n/* The accent alias is safe here: `--accent` resolves to magenta-700 in */\n/* light mode (the AA-safe interactive step) and the dark accent on dark */\n/* surfaces — never reference a raw magenta ramp step. */\n/* -------------------------------------------------------------------- */\n\nconst infoTipTriggerVariants = cva(\n [\n 'ds:relative ds:inline-flex ds:shrink-0 ds:items-center ds:justify-center',\n 'ds:rounded-[var(--radius-full)]',\n 'ds:bg-[var(--card)]',\n 'ds:text-[var(--accent)]',\n // Single ring: the Lucide Info glyph draws its own accent circle, so the\n // trigger carries NO CSS border of its own (a border would read as a\n // second, concentric ring). The white circle comes from `bg-card` showing\n // through the glyph, lifted by the drop shadow.\n 'ds:shadow-[var(--shadow-sm)]',\n 'ds:cursor-pointer',\n 'ds:transition-[color,box-shadow] ds:motion-reduce:transition-none',\n 'ds:hover:text-[var(--accent-hover)] ds:hover:shadow-[var(--shadow-md)]',\n 'ds:data-[state=open]:text-[var(--accent-hover)] ds:data-[state=open]:shadow-[var(--shadow-md)]',\n 'ds:focus-visible:outline-[length:var(--focus-ring-width)] ds:focus-visible:outline-solid ds:focus-visible:outline-ring ds:focus-visible:outline-offset-[length:var(--focus-ring-offset)]',\n 'ds:forced-colors:focus-visible:outline-[CanvasText]',\n ].join(' '),\n {\n variants: {\n size: {\n // Both diameters sit below `--min-target-size` (44/48px), so each\n // re-uses IconButton's invisible `::before` hit-area expansion to a\n // full touch target on touch / small screens. From the `sm:`\n // breakpoint up the pointer is precise, so the expansion relaxes —\n // but the interactive target must never fall below WCAG 2.5.8's 24px:\n // • md (24px visual) already meets the 24px floor, so its `::before`\n // is hidden on desktop and the 24px circle IS the target.\n // • sm (20px visual) would fall to 20px if hidden — below the floor\n // — so instead of hiding, its `::before` shrinks to a persistent\n // `--spacing-lg` (24px) minimum that holds on desktop too.\n sm: 'ds:w-5 ds:h-5 ds:before:absolute ds:before:inset-x-[calc((var(--min-target-size)-100%)/-2)] ds:before:inset-y-[calc((var(--min-target-size)-100%)/-2)] ds:before:content-[\"\"] ds:sm:before:inset-x-[calc((var(--spacing-lg)-100%)/-2)] ds:sm:before:inset-y-[calc((var(--spacing-lg)-100%)/-2)]',\n md: 'ds:w-6 ds:h-6 ds:before:absolute ds:before:inset-x-[calc((var(--min-target-size)-100%)/-2)] ds:before:inset-y-[calc((var(--min-target-size)-100%)/-2)] ds:before:content-[\"\"] ds:sm:before:hidden',\n },\n },\n defaultVariants: {\n size: 'md',\n },\n },\n);\n\n// Curated agent-readiness handle — see info-tip.agent.ts.\nexport interface InfoTipHandle {\n getIsOpen: () => boolean;\n open: () => void;\n close: () => void;\n}\n\nexport interface InfoTipProps {\n /** Body of the tip — explanatory text shown in the floating card. */\n content: ReactNode;\n /** Optional heading rendered above the body. */\n heading?: ReactNode;\n /**\n * Trigger diameter. Also sets the floating card width unless `cardSize`\n * is given: `sm` → `--popover-size-sm`, `md` → `--popover-size-md`.\n */\n size?: 'sm' | 'md';\n /**\n * Width of the floating card, when it should differ from the trigger size:\n * `sm` → `--popover-size-sm`, `md` → `--popover-size-md`, `lg` →\n * `--popover-size-lg`. Defaults to the width that matches `size`, so a\n * small trigger can open a wider card for a longer explanation.\n */\n cardSize?: 'sm' | 'md' | 'lg';\n /** Logical side the card opens on. Default `'top'`. */\n side?: 'start' | 'top' | 'end' | 'bottom';\n /** Alignment along the side axis. Default `'center'`. */\n align?: 'start' | 'center' | 'end';\n /**\n * Accessible name for the trigger. Defaults to the translated\n * \"More information\" chrome string.\n */\n 'aria-label'?: string;\n /**\n * Opaque instance id — emitted as `data-component-id` on the trigger and\n * used to register the instance with the host agent registry.\n */\n id?: string;\n /** Extra classes merged onto the trigger button. */\n className?: string;\n /**\n * A formula written in words, shown below `content` in a quiet block, e.g.\n * \"Net revenue = invoices issued − credit notes\". It is part of the card's\n * description, so screen readers hear it.\n */\n formula?: ReactNode;\n /**\n * When set, the card gains a footer \"Learn more\" link to this URL and\n * becomes interactive: Tab from the open trigger moves to the link,\n * Shift+Tab returns, Escape closes and refocuses the trigger. Without it the\n * card is explanatory text and focus stays on the trigger, unless the text\n * is long enough to scroll: then Tab reaches the text so it can be scrolled.\n */\n learnMoreHref?: string;\n /**\n * Makes the card interactive: `content` may hold links or buttons (for\n * example a short list of links, use the kit `Link`). Tab from the open\n * trigger moves into the card, Shift+Tab from its first control returns,\n * Tab past its last closes the card and carries on after the trigger, and\n * Escape closes and refocuses the trigger. The card is named from\n * `heading` and its body is left out of `aria-describedby`, so links are\n * not read as flat text. Default `false`: the card stays explanatory.\n */\n interactive?: boolean;\n /** Link text. Defaults to the translated \"Learn more\" chrome string. */\n learnMoreLabel?: string;\n /**\n * Called when the link is activated. An SPA can call `event.preventDefault()`\n * and route client-side; the anchor keeps its real `href` either way.\n */\n onLearnMore?: (event: ReactMouseEvent<HTMLAnchorElement>) => void;\n}\n\nconst TABBABLE =\n 'a[href], button:not([disabled]), input:not([disabled]):not([type=\"hidden\"]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex=\"-1\"])';\n\nfunction firstTabbable(root: HTMLElement | null): HTMLElement | null {\n if (!root) return null;\n const all = root.querySelectorAll<HTMLElement>(TABBABLE);\n for (const el of all) {\n const style = getComputedStyle(el);\n if (!el.hidden && style.display !== 'none' && style.visibility !== 'hidden')\n return el;\n }\n return null;\n}\n\n// Interactive bodies stay out of the description: links read as flat text there.\nfunction BodyRegion({\n interactive,\n className,\n children,\n}: {\n interactive: boolean;\n className: string;\n children: ReactNode;\n}) {\n if (!interactive) {\n return (\n <Popover.Description className={className}>\n {children}\n </Popover.Description>\n );\n }\n return (\n <div\n className={`ds:text-[var(--muted-foreground)] type-body-sm ds:mt-[var(--spacing-xs)] ${className}`}\n >\n {children}\n </div>\n );\n}\n\n/**\n * InfoTip — a deliberate, branded \"more information\" affordance: a small\n * circular trigger that reveals an explanatory card on hover **and** click\n * (click also serves touch devices). Composes the kit Popover in\n * `openOn=\"hover-or-click\"` mode — hover intent, keyboard focus, Escape and\n * focus-return are all handled by the Popover/Radix layer.\n */\nexport const InfoTip = forwardRef<HTMLButtonElement, InfoTipProps>(\n (\n {\n content,\n heading,\n size = 'md',\n cardSize,\n side = 'top',\n align = 'center',\n 'aria-label': ariaLabelProp,\n id,\n className,\n formula,\n interactive = false,\n learnMoreHref,\n learnMoreLabel,\n onLearnMore,\n },\n ref,\n ) => {\n const { t } = useTranslation('ui');\n const [open, setOpen] = useState(false);\n\n // Agent handle.\n const openRef = useRef(open);\n useEffect(() => {\n openRef.current = open;\n }, [open]);\n\n const agentHandle = useMemo<InfoTipHandle>(\n () => ({\n getIsOpen: () => openRef.current,\n open: () => setOpen(true),\n close: () => setOpen(false),\n }),\n [],\n );\n useAgentRegistration(infoTipAgent, agentHandle, id);\n\n // Press bookkeeping. In hover-or-click mode the Popover opens as soon as\n // the trigger receives focus — which happens on pointerdown, BEFORE the\n // click event that Radix uses to toggle. Without intervention every\n // click/tap on a closed tip opens it (focus) and instantly toggles it\n // closed again (click). So each press (pointerdown, or Enter/Space)\n // snapshots the open state and the click handler consumes it: if the\n // press itself opened the card, swallow Radix's toggle so the card stays\n // open; if it was already open, let the toggle close it.\n //\n // `null` means \"no press recorded for this click\" — an orphan click\n // (programmatic .click(), or assistive tech dispatching click with no\n // pointer/key event). Those must fall through to Radix's default toggle\n // rather than read a stale snapshot, so the guard treats `null` as\n // \"don't suppress\" and every click clears the snapshot back to `null`.\n const pressStateRef = useRef<boolean | null>(null);\n const handlePressStart = () => {\n pressStateRef.current = openRef.current;\n };\n\n const hasLink = learnMoreHref != null;\n const triggerRef = useRef<HTMLButtonElement | null>(null);\n const composedTriggerRef = useMemo(\n () => composeRefs<HTMLButtonElement>(ref, triggerRef),\n [ref],\n );\n const linkRef = useRef<HTMLAnchorElement | null>(null);\n const contentRef = useRef<HTMLDivElement | null>(null);\n // A long tip is capped at the height the viewport leaves it and its text\n // scrolls in a ScrollArea, which is a tab stop only while it can scroll.\n const scrollRef = useRef<HTMLDivElement | null>(null);\n\n const ariaLabel =\n ariaLabelProp ?? t('infoTip.triggerLabel', 'More information');\n\n return (\n <Popover openOn=\"hover-or-click\" open={open} onOpenChange={setOpen}>\n <Popover.Trigger\n ref={composedTriggerRef}\n aria-label={ariaLabel}\n className={infoTipTriggerVariants({ size, className })}\n data-component=\"info-tip\"\n data-component-id={id}\n onPointerDown={handlePressStart}\n onKeyDown={(event) => {\n if (event.key === 'Enter' || event.key === ' ') {\n handlePressStart();\n }\n // The card is portalled, so native Tab order would skip it. Tab\n // from the open trigger goes to the scrolling text when it\n // overflows, otherwise straight to the link.\n const scroll = scrollRef.current;\n const scrollable = scroll?.tabIndex === 0;\n const next = scrollable\n ? scroll\n : interactive\n ? firstTabbable(contentRef.current)\n : linkRef.current;\n if (\n (hasLink || scrollable || interactive) &&\n event.key === 'Tab' &&\n !event.shiftKey &&\n openRef.current &&\n next\n ) {\n event.preventDefault();\n next.focus();\n }\n }}\n onClick={(event) => {\n // Consume this click's press snapshot. A genuine pointer/keyboard\n // press recorded `false`/`true` on press-start; an orphan click\n // with no preceding pointerdown/keydown finds `null` and is left\n // to Radix's default toggle.\n const wasOpenAtPressStart = pressStateRef.current;\n pressStateRef.current = null;\n if (wasOpenAtPressStart === false && openRef.current) {\n // This press opened the card via focus — keep it open and\n // skip Radix's click toggle.\n event.preventDefault();\n }\n }}\n >\n <Info\n aria-hidden=\"true\"\n // Fills the circle so the glyph's own ring IS the trigger's\n // visible edge and the drop shadow hugs it.\n className={size === 'sm' ? 'ds:size-5' : 'ds:size-6'}\n />\n </Popover.Trigger>\n <Popover.Content\n ref={contentRef}\n side={side}\n align={align}\n size={cardSize ?? (size === 'sm' ? 'sm' : 'md')}\n // Never taller than the space the viewport leaves; the text scrolls.\n // The card itself does not clip, so its arrow stays visible.\n className={[\n 'ds:flex ds:flex-col ds:max-h-[var(--radix-popover-content-available-height)]',\n // Links and buttons reach the touch target on small screens.\n interactive &&\n 'ds:max-sm:[&_a]:inline-flex ds:max-sm:[&_a]:items-center ds:max-sm:[&_a]:min-block-[var(--min-target-size)]',\n ]\n .filter(Boolean)\n .join(' ')}\n // The card is a Radix `role=\"dialog\"` surface, which axe requires\n // to have an accessible name (aria-dialog-name). With a heading,\n // Popover wires aria-labelledby; without one, fall back to the\n // trigger's label.\n aria-label={heading == null ? ariaLabel : undefined}\n // Toggletip focus contract: the card is explanatory text, never\n // interactive, so focus stays on the trigger for the whole\n // open/close cycle. Preventing the open move also keeps Escape\n // reliable — if Radix pulled focus into the card, closing would\n // refocus the trigger and re-fire the hover-mode focus handler,\n // reopening the card it just closed. Preventing the close move\n // keeps an unhover-close from stealing focus mid-task.\n //\n // With a learn-more link, or text long enough to scroll, the card\n // is interactive, but the same contract holds: focus is never\n // pulled in on open, only Tab moves it to the text or the link. Escape from inside the card is handled below so\n // focus returns to the trigger without re-firing its focus-open.\n onOpenAutoFocus={(event) => event.preventDefault()}\n onCloseAutoFocus={(event) => event.preventDefault()}\n onEscapeKeyDown={(event) => {\n // Focus anywhere inside the card (the link, or the card itself\n // after a click on its text) goes back to the trigger.\n const active = document.activeElement;\n if (active && contentRef.current?.contains(active)) {\n event.preventDefault();\n triggerRef.current?.focus();\n setOpen(false);\n }\n }}\n >\n {heading != null && <Popover.Heading>{heading}</Popover.Heading>}\n <BodyRegion\n interactive={interactive}\n className=\"ds:flex ds:min-h-0 ds:flex-col\"\n >\n <ScrollArea\n ref={scrollRef}\n type=\"native\"\n aria-label={typeof heading === 'string' ? heading : ariaLabel}\n // At high zoom the heading and link keep their height; the text\n // keeps at least three lines rather than collapsing to nothing.\n className=\"ds:min-h-[3lh]\"\n >\n {content}\n {formula != null && (\n <div\n data-slot=\"formula\"\n className=\"type-body-sm ds:mt-[var(--spacing-sm)] ds:rounded-[var(--radius-sm)] ds:bg-[var(--muted)] ds:px-[var(--spacing-sm)] ds:py-[var(--spacing-xs)] ds:text-[var(--foreground)] ds:tabular-nums\"\n >\n <span className=\"ds:sr-only\">\n {t('infoTip.formula', 'Formula')}:{' '}\n </span>\n {formula}\n </div>\n )}\n </ScrollArea>\n </BodyRegion>\n {hasLink && (\n <div\n data-slot=\"footer\"\n className=\"ds:mt-[var(--spacing-sm)] ds:flex ds:justify-end\"\n >\n <Link\n ref={linkRef}\n href={learnMoreHref}\n onClick={onLearnMore}\n weight=\"strong\"\n className=\"type-body-sm\"\n >\n {learnMoreLabel ?? t('infoTip.learnMore', 'Learn more')}\n </Link>\n </div>\n )}\n </Popover.Content>\n </Popover>\n );\n },\n);\n\nInfoTip.displayName = 'InfoTip';\n"],"names":["infoTipAgent","handle","infoTipTriggerVariants","cva","TABBABLE","firstTabbable","root","all","el","style","BodyRegion","interactive","className","children","jsx","Popover","InfoTip","forwardRef","content","heading","size","cardSize","side","align","ariaLabelProp","id","formula","learnMoreHref","learnMoreLabel","onLearnMore","ref","t","useTranslation","open","setOpen","useState","openRef","useRef","useEffect","agentHandle","useMemo","useAgentRegistration","pressStateRef","handlePressStart","hasLink","triggerRef","composedTriggerRef","composeRefs","linkRef","contentRef","scrollRef","ariaLabel","event","scroll","scrollable","next","wasOpenAtPressStart","Info","jsxs","active","_a","_b","ScrollArea","Link"],"mappings":"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"}
|
|
@@ -2,7 +2,7 @@ import { jsx as t, jsxs as j } from "react/jsx-runtime";
|
|
|
2
2
|
import { forwardRef as B } from "react";
|
|
3
3
|
import { c as u } from "./index-D2ZczOXr.js";
|
|
4
4
|
import { useTranslation as D } from "react-i18next";
|
|
5
|
-
import { a as G } from "./whatsapp-button-
|
|
5
|
+
import { a as G } from "./whatsapp-button-XbozeDl_.js";
|
|
6
6
|
import { G as O } from "./globe-sHBW1JN5.js";
|
|
7
7
|
import { E as P } from "./external-link-CY6zAXXU.js";
|
|
8
8
|
const o = {
|
|
@@ -329,4 +329,4 @@ export {
|
|
|
329
329
|
d1 as L,
|
|
330
330
|
n1 as S
|
|
331
331
|
};
|
|
332
|
-
//# sourceMappingURL=link-
|
|
332
|
+
//# sourceMappingURL=link-CeV7FoI6.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"link-DtCfnLnF.js","sources":["../../src/components/_shared/social-brand-icons.tsx","../../src/components/link/social-url.ts","../../src/components/link/link.tsx"],"sourcesContent":["/** Brand artwork shared by Link and PublicFooter. No network requests.\n * Existing Facebook, Instagram, LinkedIn and YouTube paths are preserved\n * from PublicFooter. Additional paths: Simple Icons 16.35.0 (CC0-1.0).\n * https://github.com/simple-icons/simple-icons/tree/16.35.0/icons\n * Brand names are invariant proper nouns, not translatable interface copy.\n */\nimport type { ComponentType, SVGProps } from 'react';\nimport { WhatsAppGlyph } from '../whatsapp-button/whatsapp-button';\n\ntype IconProps = SVGProps<SVGSVGElement>;\ntype SocialIcon = ComponentType<IconProps>;\n\nconst baseProps = {\n viewBox: '0 0 24 24',\n fill: 'currentColor',\n xmlns: 'http://www.w3.org/2000/svg',\n} as const;\n\nconst LinkedinIcon: SocialIcon = (props) => (\n <svg {...baseProps} {...props}>\n <path d=\"M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85 3.601 0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433a2.062 2.062 0 0 1-2.063-2.065 2.063 2.063 0 1 1 2.063 2.065zm1.782 13.019H3.555V9h3.564v11.452zM22.225 0H1.771C.792 0 0 .774 0 1.729v20.542C0 23.227.792 24 1.771 24h20.451C23.2 24 24 23.227 24 22.271V1.729C24 .774 23.2 0 22.222 0h.003z\" />\n </svg>\n);\n\nconst YoutubeIcon: SocialIcon = (props) => (\n <svg {...baseProps} {...props}>\n <path d=\"M23.498 6.186a3.016 3.016 0 0 0-2.122-2.136C19.505 3.545 12 3.545 12 3.545s-7.505 0-9.377.505A3.017 3.017 0 0 0 .502 6.186C0 8.07 0 12 0 12s0 3.93.502 5.814a3.016 3.016 0 0 0 2.122 2.136c1.871.505 9.376.505 9.376.505s7.505 0 9.377-.505a3.015 3.015 0 0 0 2.122-2.136C24 15.93 24 12 24 12s0-3.93-.502-5.814zM9.545 15.568V8.432L15.818 12l-6.273 3.568z\" />\n </svg>\n);\n\nconst InstagramIcon: SocialIcon = (props) => (\n <svg {...baseProps} {...props}>\n <path d=\"M12 2.163c3.204 0 3.584.012 4.85.07 3.252.148 4.771 1.691 4.919 4.919.058 1.265.069 1.645.069 4.849 0 3.205-.012 3.584-.069 4.849-.149 3.225-1.664 4.771-4.919 4.919-1.266.058-1.644.07-4.85.07-3.204 0-3.584-.012-4.849-.07-3.26-.149-4.771-1.699-4.919-4.92-.058-1.265-.07-1.644-.07-4.849 0-3.204.013-3.583.07-4.849.149-3.227 1.664-4.771 4.919-4.919 1.266-.057 1.645-.069 4.849-.069zM12 0C8.741 0 8.333.014 7.053.072 2.695.272.273 2.69.073 7.052.014 8.333 0 8.741 0 12c0 3.259.014 3.668.072 4.948.2 4.358 2.618 6.78 6.98 6.98C8.333 23.986 8.741 24 12 24c3.259 0 3.668-.014 4.948-.072 4.354-.2 6.782-2.618 6.979-6.98.059-1.28.073-1.689.073-4.948 0-3.259-.014-3.667-.072-4.947-.196-4.354-2.617-6.78-6.979-6.98C15.668.014 15.259 0 12 0zm0 5.838a6.162 6.162 0 1 0 0 12.324 6.162 6.162 0 0 0 0-12.324zM12 16a4 4 0 1 1 0-8 4 4 0 0 1 0 8zm6.406-11.845a1.44 1.44 0 1 0 0 2.881 1.44 1.44 0 0 0 0-2.881z\" />\n </svg>\n);\n\nconst FacebookIcon: SocialIcon = (props) => (\n <svg {...baseProps} {...props}>\n <path d=\"M24 12.073c0-6.627-5.373-12-12-12s-12 5.373-12 12c0 5.99 4.388 10.954 10.125 11.854v-8.385H7.078v-3.47h3.047V9.43c0-3.007 1.792-4.669 4.533-4.669 1.312 0 2.686.235 2.686.235v2.953H15.83c-1.491 0-1.956.925-1.956 1.874v2.25h3.328l-.532 3.47h-2.796v8.385C19.612 23.027 24 18.062 24 12.073z\" />\n </svg>\n);\n\nconst XIcon: SocialIcon = (props) => (\n <svg {...baseProps} {...props}>\n <path d=\"M14.234 10.162 22.977 0h-2.072l-7.591 8.824L7.251 0H.258l9.168 13.343L.258 24H2.33l8.016-9.318L16.749 24h6.993zm-2.837 3.299-.929-1.329L3.076 1.56h3.182l5.965 8.532.929 1.329 7.754 11.09h-3.182z\" />\n </svg>\n);\n\nconst TiktokIcon: SocialIcon = (props) => (\n <svg {...baseProps} {...props}>\n <path d=\"M12.525.02c1.31-.02 2.61-.01 3.91-.02.08 1.53.63 3.09 1.75 4.17 1.12 1.11 2.7 1.62 4.24 1.79v4.03c-1.44-.05-2.89-.35-4.2-.97-.57-.26-1.1-.59-1.62-.93-.01 2.92.01 5.84-.02 8.75-.08 1.4-.54 2.79-1.35 3.94-1.31 1.92-3.58 3.17-5.91 3.21-1.43.08-2.86-.31-4.08-1.03-2.02-1.19-3.44-3.37-3.65-5.71-.02-.5-.03-1-.01-1.49.18-1.9 1.12-3.72 2.58-4.96 1.66-1.44 3.98-2.13 6.15-1.72.02 1.48-.04 2.96-.04 4.44-.99-.32-2.15-.23-3.02.37-.63.41-1.11 1.04-1.36 1.75-.21.51-.15 1.07-.14 1.61.24 1.64 1.82 3.02 3.5 2.87 1.12-.01 2.19-.66 2.77-1.61.19-.33.4-.67.41-1.06.1-1.79.06-3.57.07-5.36.01-4.03-.01-8.05.02-12.07z\" />\n </svg>\n);\n\nconst ThreadsIcon: SocialIcon = (props) => (\n <svg {...baseProps} {...props}>\n <path d=\"M18.263 11.097c-.03-3.486-1.92-5.586-5.111-5.586-2.13 0-3.922.963-4.863 2.499l2.062 1.438c.535-.843 1.272-1.543 2.628-1.543 1.528 0 2.318.85 2.544 2.431a15 15 0 0 0-2.236-.173c-4.125 0-6.068 1.867-6.068 4.336s1.943 3.99 4.804 3.99c3.139 0 5.013-2.115 5.781-4.735.798.361 1.348 1.204 1.348 2.47 0 3.387-3.907 5.232-7.22 5.232-4.885 0-8.077-3.207-8.077-8.424 0-6.392 4.223-10.487 9.9-10.487 3.808 0 5.69 1.671 6.97 3.914l2.108-1.475C21.44 2.078 18.331 0 13.663 0 6.227 0 1.168 5.277 1.168 12.934c0 7 4.953 11.066 10.856 11.066 4.878 0 9.809-2.846 9.809-7.716 0-2.545-1.46-4.231-3.569-5.187m-6.33 4.855c-1.077 0-2.026-.512-2.026-1.453 0-1.483 1.822-1.934 3.606-1.934.678 0 1.34.045 1.927.173-.422 1.927-1.671 3.215-3.508 3.214Z\" />\n </svg>\n);\n\nconst BlueskyIcon: SocialIcon = (props) => (\n <svg {...baseProps} {...props}>\n <path d=\"M5.202 2.857C7.954 4.922 10.913 9.11 12 11.358c1.087-2.247 4.046-6.436 6.798-8.501C20.783 1.366 24 .213 24 3.883c0 .732-.42 6.156-.667 7.037-.856 3.061-3.978 3.842-6.755 3.37 4.854.826 6.089 3.562 3.422 6.299-5.065 5.196-7.28-1.304-7.847-2.97-.104-.305-.152-.448-.153-.327 0-.121-.05.022-.153.327-.568 1.666-2.782 8.166-7.847 2.97-2.667-2.737-1.432-5.473 3.422-6.3-2.777.473-5.899-.308-6.755-3.369C.42 10.04 0 4.615 0 3.883c0-3.67 3.217-2.517 5.202-1.026\" />\n </svg>\n);\n\nconst PinterestIcon: SocialIcon = (props) => (\n <svg {...baseProps} {...props}>\n <path d=\"M12.017 0C5.396 0 .029 5.367.029 11.987c0 5.079 3.158 9.417 7.618 11.162-.105-.949-.199-2.403.041-3.439.219-.937 1.406-5.957 1.406-5.957s-.359-.72-.359-1.781c0-1.663.967-2.911 2.168-2.911 1.024 0 1.518.769 1.518 1.688 0 1.029-.653 2.567-.992 3.992-.285 1.193.6 2.165 1.775 2.165 2.128 0 3.768-2.245 3.768-5.487 0-2.861-2.063-4.869-5.008-4.869-3.41 0-5.409 2.562-5.409 5.199 0 1.033.394 2.143.889 2.741.099.12.112.225.085.345-.09.375-.293 1.199-.334 1.363-.053.225-.172.271-.401.165-1.495-.69-2.433-2.878-2.433-4.646 0-3.776 2.748-7.252 7.92-7.252 4.158 0 7.392 2.967 7.392 6.923 0 4.135-2.607 7.462-6.233 7.462-1.214 0-2.354-.629-2.758-1.379l-.749 2.848c-.269 1.045-1.004 2.352-1.498 3.146 1.123.345 2.306.535 3.55.535 6.607 0 11.985-5.365 11.985-11.987C23.97 5.39 18.592.026 11.985.026L12.017 0z\" />\n </svg>\n);\n\nconst RedditIcon: SocialIcon = (props) => (\n <svg {...baseProps} {...props}>\n <path d=\"M12 0C5.373 0 0 5.373 0 12c0 3.314 1.343 6.314 3.515 8.485l-2.286 2.286C.775 23.225 1.097 24 1.738 24H12c6.627 0 12-5.373 12-12S18.627 0 12 0Zm4.388 3.199c1.104 0 1.999.895 1.999 1.999 0 1.105-.895 2-1.999 2-.946 0-1.739-.657-1.947-1.539v.002c-1.147.162-2.032 1.15-2.032 2.341v.007c1.776.067 3.4.567 4.686 1.363.473-.363 1.064-.58 1.707-.58 1.547 0 2.802 1.254 2.802 2.802 0 1.117-.655 2.081-1.601 2.531-.088 3.256-3.637 5.876-7.997 5.876-4.361 0-7.905-2.617-7.998-5.87-.954-.447-1.614-1.415-1.614-2.538 0-1.548 1.255-2.802 2.803-2.802.645 0 1.239.218 1.712.585 1.275-.79 2.881-1.291 4.64-1.365v-.01c0-1.663 1.263-3.034 2.88-3.207.188-.911.993-1.595 1.959-1.595Zm-8.085 8.376c-.784 0-1.459.78-1.506 1.797-.047 1.016.64 1.429 1.426 1.429.786 0 1.371-.369 1.418-1.385.047-1.017-.553-1.841-1.338-1.841Zm7.406 0c-.786 0-1.385.824-1.338 1.841.047 1.017.634 1.385 1.418 1.385.785 0 1.473-.413 1.426-1.429-.046-1.017-.721-1.797-1.506-1.797Zm-3.703 4.013c-.974 0-1.907.048-2.77.135-.147.015-.241.168-.183.305.483 1.154 1.622 1.964 2.953 1.964 1.33 0 2.47-.81 2.953-1.964.057-.137-.037-.29-.184-.305-.863-.087-1.795-.135-2.769-.135Z\" />\n </svg>\n);\n\nconst SnapchatIcon: SocialIcon = (props) => (\n <svg {...baseProps} {...props}>\n <path d=\"M12.206.793c.99 0 4.347.276 5.93 3.821.529 1.193.403 3.219.299 4.847l-.003.06c-.012.18-.022.345-.03.51.075.045.203.09.401.09.3-.016.659-.12 1.033-.301.165-.088.344-.104.464-.104.182 0 .359.029.509.09.45.149.734.479.734.838.015.449-.39.839-1.213 1.168-.089.029-.209.075-.344.119-.45.135-1.139.36-1.333.81-.09.224-.061.524.12.868l.015.015c.06.136 1.526 3.475 4.791 4.014.255.044.435.27.42.509 0 .075-.015.149-.045.225-.24.569-1.273.988-3.146 1.271-.059.091-.12.375-.164.57-.029.179-.074.36-.134.553-.076.271-.27.405-.555.405h-.03c-.135 0-.313-.031-.538-.074-.36-.075-.765-.135-1.273-.135-.3 0-.599.015-.913.074-.6.104-1.123.464-1.723.884-.853.599-1.826 1.288-3.294 1.288-.06 0-.119-.015-.18-.015h-.149c-1.468 0-2.427-.675-3.279-1.288-.599-.42-1.107-.779-1.707-.884-.314-.045-.629-.074-.928-.074-.54 0-.958.089-1.272.149-.211.043-.391.074-.54.074-.374 0-.523-.224-.583-.42-.061-.192-.09-.389-.135-.567-.046-.181-.105-.494-.166-.57-1.918-.222-2.95-.642-3.189-1.226-.031-.063-.052-.15-.055-.225-.015-.243.165-.465.42-.509 3.264-.54 4.73-3.879 4.791-4.02l.016-.029c.18-.345.224-.645.119-.869-.195-.434-.884-.658-1.332-.809-.121-.029-.24-.074-.346-.119-1.107-.435-1.257-.93-1.197-1.273.09-.479.674-.793 1.168-.793.146 0 .27.029.383.074.42.194.789.3 1.104.3.234 0 .384-.06.465-.105l-.046-.569c-.098-1.626-.225-3.651.307-4.837C7.392 1.077 10.739.807 11.727.807l.419-.015h.06z\" />\n </svg>\n);\n\nconst TelegramIcon: SocialIcon = (props) => (\n <svg {...baseProps} {...props}>\n <path d=\"M11.944 0A12 12 0 0 0 0 12a12 12 0 0 0 12 12 12 12 0 0 0 12-12A12 12 0 0 0 12 0a12 12 0 0 0-.056 0zm4.962 7.224c.1-.002.321.023.465.14a.506.506 0 0 1 .171.325c.016.093.036.306.02.472-.18 1.898-.962 6.502-1.36 8.627-.168.9-.499 1.201-.82 1.23-.696.065-1.225-.46-1.9-.902-1.056-.693-1.653-1.124-2.678-1.8-1.185-.78-.417-1.21.258-1.91.177-.184 3.247-2.977 3.307-3.23.007-.032.014-.15-.056-.212s-.174-.041-.249-.024c-.106.024-1.793 1.14-5.061 3.345-.48.33-.913.49-1.302.48-.428-.008-1.252-.241-1.865-.44-.752-.245-1.349-.374-1.297-.789.027-.216.325-.437.893-.663 3.498-1.524 5.83-2.529 6.998-3.014 3.332-1.386 4.025-1.627 4.476-1.635z\" />\n </svg>\n);\n\nconst DiscordIcon: SocialIcon = (props) => (\n <svg {...baseProps} {...props}>\n <path d=\"M20.317 4.3698a19.7913 19.7913 0 00-4.8851-1.5152.0741.0741 0 00-.0785.0371c-.211.3753-.4447.8648-.6083 1.2495-1.8447-.2762-3.68-.2762-5.4868 0-.1636-.3933-.4058-.8742-.6177-1.2495a.077.077 0 00-.0785-.037 19.7363 19.7363 0 00-4.8852 1.515.0699.0699 0 00-.0321.0277C.5334 9.0458-.319 13.5799.0992 18.0578a.0824.0824 0 00.0312.0561c2.0528 1.5076 4.0413 2.4228 5.9929 3.0294a.0777.0777 0 00.0842-.0276c.4616-.6304.8731-1.2952 1.226-1.9942a.076.076 0 00-.0416-.1057c-.6528-.2476-1.2743-.5495-1.8722-.8923a.077.077 0 01-.0076-.1277c.1258-.0943.2517-.1923.3718-.2914a.0743.0743 0 01.0776-.0105c3.9278 1.7933 8.18 1.7933 12.0614 0a.0739.0739 0 01.0785.0095c.1202.099.246.1981.3728.2924a.077.077 0 01-.0066.1276 12.2986 12.2986 0 01-1.873.8914.0766.0766 0 00-.0407.1067c.3604.698.7719 1.3628 1.225 1.9932a.076.076 0 00.0842.0286c1.961-.6067 3.9495-1.5219 6.0023-3.0294a.077.077 0 00.0313-.0552c.5004-5.177-.8382-9.6739-3.5485-13.6604a.061.061 0 00-.0312-.0286zM8.02 15.3312c-1.1825 0-2.1569-1.0857-2.1569-2.419 0-1.3332.9555-2.4189 2.157-2.4189 1.2108 0 2.1757 1.0952 2.1568 2.419 0 1.3332-.9555 2.4189-2.1569 2.4189zm7.9748 0c-1.1825 0-2.1569-1.0857-2.1569-2.419 0-1.3332.9554-2.4189 2.1569-2.4189 1.2108 0 2.1757 1.0952 2.1568 2.419 0 1.3332-.946 2.4189-2.1568 2.4189Z\" />\n </svg>\n);\n\nconst TwitchIcon: SocialIcon = (props) => (\n <svg {...baseProps} {...props}>\n <path d=\"M11.571 4.714h1.715v5.143H11.57zm4.715 0H18v5.143h-1.714zM6 0L1.714 4.286v15.428h5.143V24l4.286-4.286h3.428L22.286 12V0zm14.571 11.143l-3.428 3.428h-3.429l-3 3v-3H6.857V1.714h13.714Z\" />\n </svg>\n);\n\nconst GithubIcon: SocialIcon = (props) => (\n <svg {...baseProps} {...props}>\n <path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\" />\n </svg>\n);\n\nexport const SOCIAL_LINK_ICONS = {\n linkedin: LinkedinIcon,\n youtube: YoutubeIcon,\n instagram: InstagramIcon,\n facebook: FacebookIcon,\n x: XIcon,\n tiktok: TiktokIcon,\n threads: ThreadsIcon,\n bluesky: BlueskyIcon,\n pinterest: PinterestIcon,\n reddit: RedditIcon,\n snapchat: SnapchatIcon,\n telegram: TelegramIcon,\n discord: DiscordIcon,\n twitch: TwitchIcon,\n github: GithubIcon,\n whatsapp: WhatsAppGlyph,\n} as const;\n","/**\n * Exact hostname aliases only. Never inspect the path/query or accept\n * arbitrary subdomains: those may be controlled by another publisher.\n * Labels are invariant brand names, matching the shared brand artwork.\n */\nconst SOCIAL_PROVIDERS = [\n {\n id: 'facebook',\n label: 'Facebook',\n hosts: [\n 'facebook.com',\n 'www.facebook.com',\n 'm.facebook.com',\n 'web.facebook.com',\n 'fb.com',\n 'fb.me',\n ],\n },\n {\n id: 'instagram',\n label: 'Instagram',\n hosts: ['instagram.com', 'www.instagram.com', 'instagr.am'],\n },\n {\n id: 'x',\n label: 'X',\n hosts: [\n 'x.com',\n 'www.x.com',\n 'twitter.com',\n 'www.twitter.com',\n 'mobile.twitter.com',\n ],\n },\n {\n id: 'tiktok',\n label: 'TikTok',\n hosts: [\n 'tiktok.com',\n 'www.tiktok.com',\n 'm.tiktok.com',\n 'vm.tiktok.com',\n 'vt.tiktok.com',\n ],\n },\n {\n id: 'linkedin',\n label: 'LinkedIn',\n hosts: ['linkedin.com', 'www.linkedin.com', 'm.linkedin.com', 'lnkd.in'],\n },\n {\n id: 'youtube',\n label: 'YouTube',\n hosts: [\n 'youtube.com',\n 'www.youtube.com',\n 'm.youtube.com',\n 'music.youtube.com',\n 'youtu.be',\n ],\n },\n {\n id: 'threads',\n label: 'Threads',\n hosts: ['threads.com', 'www.threads.com', 'threads.net', 'www.threads.net'],\n },\n { id: 'bluesky', label: 'Bluesky', hosts: ['bsky.app', 'www.bsky.app'] },\n {\n id: 'pinterest',\n label: 'Pinterest',\n hosts: [\n 'pinterest.com',\n 'www.pinterest.com',\n 'pinterest.it',\n 'www.pinterest.it',\n 'pinterest.de',\n 'www.pinterest.de',\n 'pinterest.fr',\n 'www.pinterest.fr',\n 'pinterest.es',\n 'www.pinterest.es',\n 'pinterest.pt',\n 'www.pinterest.pt',\n 'pinterest.co.uk',\n 'www.pinterest.co.uk',\n 'pinterest.ca',\n 'www.pinterest.ca',\n 'pinterest.com.au',\n 'www.pinterest.com.au',\n 'pinterest.ch',\n 'www.pinterest.ch',\n 'pinterest.at',\n 'www.pinterest.at',\n 'pinterest.nl',\n 'www.pinterest.nl',\n 'pin.it',\n ],\n },\n {\n id: 'reddit',\n label: 'Reddit',\n hosts: ['reddit.com', 'www.reddit.com', 'old.reddit.com', 'redd.it'],\n },\n {\n id: 'snapchat',\n label: 'Snapchat',\n hosts: ['snapchat.com', 'www.snapchat.com'],\n },\n {\n id: 'telegram',\n label: 'Telegram',\n hosts: ['t.me', 'telegram.me', 'telegram.org', 'www.telegram.org'],\n },\n {\n id: 'whatsapp',\n label: 'WhatsApp',\n hosts: [\n 'wa.me',\n 'whatsapp.com',\n 'www.whatsapp.com',\n 'api.whatsapp.com',\n 'chat.whatsapp.com',\n ],\n },\n {\n id: 'discord',\n label: 'Discord',\n hosts: ['discord.com', 'www.discord.com', 'discord.gg', 'discordapp.com'],\n },\n {\n id: 'twitch',\n label: 'Twitch',\n hosts: ['twitch.tv', 'www.twitch.tv', 'm.twitch.tv'],\n },\n { id: 'github', label: 'GitHub', hosts: ['github.com', 'www.github.com'] },\n] as const;\n\n/** Resolve a web URL without fetching it, following redirects or using the DOM. */\nexport function resolveSocialUrl(href: string) {\n if (typeof href !== 'string') return null;\n const value = href.trim();\n // Reject control characters, embedded whitespace and browser backslash\n // normalisation rather than displaying a brand for an ambiguous input.\n if (!value || /[\\s\\\\\\p{Cc}]/u.test(value)) return null;\n\n let candidate: string;\n if (/^https?:\\/\\/[^/?#]/i.test(value)) {\n candidate = value;\n } else if (value.startsWith('//') && !value.startsWith('///')) {\n candidate = `https:${value}`;\n } else if (/^[^/:?#]+\\.[^/:?#]+(?:[/:?#]|$)/.test(value)) {\n candidate = `https://${value}`;\n } else {\n return null;\n }\n\n try {\n const url = new URL(candidate);\n if (\n !['http:', 'https:'].includes(url.protocol) ||\n !url.hostname ||\n url.username ||\n url.password\n ) {\n return null;\n }\n\n const provider = SOCIAL_PROVIDERS.find(({ hosts }) =>\n hosts.some((host) => host === url.hostname),\n );\n return {\n href: url.href,\n hostname: url.hostname,\n // A non-standard port can serve something other than the social site.\n provider: url.port ? undefined : provider,\n };\n } catch {\n return null;\n }\n}\n","import { forwardRef, type AnchorHTMLAttributes, type ReactNode } from 'react';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { useTranslation } from 'react-i18next';\nimport { ExternalLink, Globe } from 'lucide-react';\nimport { SOCIAL_LINK_ICONS } from '../_shared/social-brand-icons';\nimport { resolveSocialUrl } from './social-url';\n\n/* ------------------------------------------------------------------ */\n/* CVA */\n/* ------------------------------------------------------------------ */\n\n/**\n * Link is the semantic anchor primitive for inline navigation —\n * privacy / terms in form copy, external \"remote support\" links in\n * sidebars, in-paragraph references inside info-tip body copy.\n *\n * For action affordances that *look* like a link but trigger UI rather\n * than navigation, use `<Button intent=\"link\">` instead — the semantic\n * boundary matters for screen readers and keyboard users.\n */\nconst linkVariants = cva(\n [\n // Always inline text, icons included, so a long label wraps like any\n // other text and the trailing glyph follows its last word.\n 'ds:inline',\n 'ds:underline-offset-4',\n 'ds:rounded-[var(--radius-xs)]',\n 'ds:transition-colors ds:duration-[var(--animation-duration)] ds:motion-reduce:transition-none',\n 'ds:focus-visible:outline-[length:var(--focus-ring-width)] ds:focus-visible:outline-solid',\n 'ds:focus-visible:outline-ring ds:focus-visible:outline-offset-[length:var(--focus-ring-offset)]',\n 'ds:forced-colors:focus-visible:outline-[CanvasText]',\n 'ds:aria-disabled:cursor-not-allowed ds:aria-disabled:opacity-50 ds:aria-disabled:no-underline',\n ].join(' '),\n {\n variants: {\n variant: {\n default: '',\n social: '',\n },\n intent: {\n // `--primary` falls below 4.5:1 as text on the dark page and on the\n // light app shell, so the link re-points it (and its hover step) at\n // `--primary-readable`, which differs in light and dark but not in\n // the accessible themes. The colour classes stay as they were: a\n // host still on an older token sheet keeps today's look, and a\n // consumer `className` wins or loses exactly as before.\n default:\n 'ds:[--primary:var(--primary-readable)] ds:[--primary-hover:var(--primary-readable-hover)] ds:text-primary ds:underline ds:hover:text-primary-hover ds:active:opacity-80',\n subtle:\n 'ds:text-muted-foreground ds:no-underline ds:hover:text-foreground ds:hover:underline ds:active:opacity-80',\n inverted:\n 'ds:text-primary-foreground ds:underline ds:hover:opacity-90 ds:active:opacity-80',\n },\n weight: {\n normal: 'ds:font-normal',\n strong: 'ds:font-semibold',\n },\n },\n defaultVariants: {\n variant: 'default',\n intent: 'default',\n weight: 'normal',\n },\n },\n);\n\n/*\n * An icon slot is a no-wrap span holding a word joiner (U+2060, as CSS\n * content so it never reaches textContent) and the glyph box, so the\n * glyph cannot break away from the word beside it.\n */\nconst iconSlotVariants = cva('ds:whitespace-nowrap', {\n variants: {\n edge: {\n start: String.raw`ds:after:content-['\\2060']`,\n end: String.raw`ds:before:content-['\\2060']`,\n },\n },\n});\n\n/*\n * The glyph box. Its own word joiner is a line-tall text item that gives\n * the box the text's baseline, so the 1em glyph centres on the line just\n * as the old flex anchor did, with no font-metric guesswork.\n */\nconst iconBoxVariants = cva(\n [\n 'ds:inline-flex ds:items-center',\n String.raw`ds:before:content-['\\2060']`,\n 'ds:[&_svg]:size-[1em] ds:[&_svg]:shrink-0',\n ].join(' '),\n {\n variants: {\n edge: {\n start: 'ds:me-[var(--spacing-xs)]',\n end: 'ds:ms-[var(--spacing-xs)]',\n },\n },\n },\n);\n\n/* ------------------------------------------------------------------ */\n/* Public types */\n/* ------------------------------------------------------------------ */\n\nexport interface LinkProps\n extends\n Omit<AnchorHTMLAttributes<HTMLAnchorElement>, 'href'>,\n VariantProps<typeof linkVariants> {\n /** Anchor target. Required — the whole point of the component. */\n href: string;\n /**\n * `social` detects a supported web URL and supplies its brand logo and\n * name. Children and startIcon override the automatic content. Unknown\n * websites use a globe and hostname; invalid URLs are non-interactive.\n * Bare domains and protocol-relative URLs are normalised to HTTPS.\n */\n variant?: 'default' | 'social' | null;\n /**\n * Flag the link as opening in a new browsing context. Automatically\n * adds `target=\"_blank\"` + `rel=\"noopener noreferrer\"` and renders a\n * decorative trailing `ExternalLink` icon plus an i18n'd \"Opens in a\n * new tab\" label for assistive tech. Defaults to true for `social`\n * unless an explicit target requests the current/named browsing context.\n */\n external?: boolean;\n /**\n * Render the trailing external-link glyph. Default `true` — set to\n * `false` for surfaces (footer, social rows, dense nav) where the\n * indicator adds visual noise. The `target` / `rel` / \"opens in new\n * tab\" screen-reader text are still applied.\n */\n externalIcon?: boolean;\n /**\n * Render the link in a non-interactive disabled state. Strips `href`,\n * adds `aria-disabled` + `role=\"link\"`, suppresses the underline.\n * Prefer hiding the link entirely when possible — disabled links are\n * a usability anti-pattern outside of state-machine flows.\n */\n disabled?: boolean;\n /** Optional leading icon (inline-start). */\n startIcon?: ReactNode;\n /** Optional trailing icon (inline-end). Ignored when `external`. */\n endIcon?: ReactNode;\n /** @deprecated No effect: the icon layout follows the icon props. Kept so existing callers compile. */\n hasIcon?: 'yes' | 'no' | null;\n}\n\n/* ------------------------------------------------------------------ */\n/* Component */\n/* ------------------------------------------------------------------ */\n\nexport const Link = forwardRef<HTMLAnchorElement, LinkProps>(\n (\n {\n href,\n external,\n externalIcon = true,\n disabled = false,\n startIcon,\n endIcon,\n hasIcon: _hasIcon,\n intent,\n variant = 'default',\n weight,\n className,\n children,\n target,\n rel,\n onClick,\n ...rest\n },\n ref,\n ) => {\n const { t } = useTranslation('ui');\n\n const social = variant === 'social' ? resolveSocialUrl(href ?? '') : null;\n const isDisabled = disabled || (variant === 'social' && !social);\n // Only the social variant hides the external cues when disabled; ordinary\n // links keep them exactly as before.\n const hideExternalCues = variant === 'social' && isDisabled;\n const isExternal =\n external ?? (variant === 'social' && (!target || target === '_blank'));\n const effectiveTarget = isExternal ? '_blank' : target;\n const effectiveRel = isExternal\n ? [rel, 'noopener', 'noreferrer'].filter(Boolean).join(' ')\n : rel;\n const SocialIcon = social?.provider\n ? SOCIAL_LINK_ICONS[social.provider.id]\n : Globe;\n const resolvedStartIcon =\n startIcon === undefined && variant === 'social' ? (\n <SocialIcon aria-hidden=\"true\" focusable=\"false\" />\n ) : (\n startIcon\n );\n const label =\n children ??\n (variant === 'social'\n ? social?.provider?.label ||\n social?.hostname ||\n t('contactProfileCard.label.website')\n : undefined);\n\n const externalLabel = t('link.opensInNewTab', 'Opens in a new tab');\n\n const handleClick: AnchorHTMLAttributes<HTMLAnchorElement>['onClick'] = (\n event,\n ) => {\n if (isDisabled) {\n event.preventDefault();\n return;\n }\n onClick?.(event);\n };\n\n const showExternalIcon = isExternal && externalIcon && !hideExternalCues;\n\n return (\n <a\n ref={ref}\n // When disabled, drop href so the link is not actionable; pair\n // with aria-disabled + role=\"link\" so AT still announces the\n // role (the implicit role disappears once href is removed).\n href={isDisabled ? undefined : (social?.href ?? href)}\n role={isDisabled ? 'link' : undefined}\n aria-disabled={isDisabled || undefined}\n target={effectiveTarget}\n rel={effectiveRel || undefined}\n onClick={handleClick}\n data-component=\"link\"\n data-intent={intent ?? 'default'}\n data-variant={variant ?? 'default'}\n data-social-network={social?.provider?.id}\n className={linkVariants({ variant, intent, weight, className })}\n {...rest}\n >\n {resolvedStartIcon ? (\n <span\n aria-hidden=\"true\"\n className={iconSlotVariants({ edge: 'start' })}\n >\n <span className={iconBoxVariants({ edge: 'start' })}>\n {resolvedStartIcon}\n </span>\n </span>\n ) : null}\n {label}\n {showExternalIcon || (!isExternal && endIcon) ? (\n <span\n aria-hidden=\"true\"\n className={iconSlotVariants({ edge: 'end' })}\n >\n <span className={iconBoxVariants({ edge: 'end' })}>\n {showExternalIcon ? (\n <ExternalLink className=\"ds:size-[1em]\" />\n ) : (\n endIcon\n )}\n </span>\n </span>\n ) : null}\n {showExternalIcon ? (\n // Labelled, empty and out of flow: name algorithms add the label\n // after a space, and textContent stays the caller's text.\n <span aria-label={externalLabel} className=\"ds:sr-only\" />\n ) : isExternal && !hideExternalCues ? (\n // External wiring without the glyph — keep the SR-only\n // \"opens in new tab\" announcement so the affordance reads.\n <span className=\"ds:sr-only\">{externalLabel}</span>\n ) : null}\n </a>\n );\n },\n);\n\nLink.displayName = 'Link';\n"],"names":["baseProps","LinkedinIcon","props","jsx","YoutubeIcon","InstagramIcon","FacebookIcon","XIcon","TiktokIcon","ThreadsIcon","BlueskyIcon","PinterestIcon","RedditIcon","SnapchatIcon","TelegramIcon","DiscordIcon","TwitchIcon","GithubIcon","SOCIAL_LINK_ICONS","WhatsAppGlyph","SOCIAL_PROVIDERS","resolveSocialUrl","href","value","candidate","url","provider","hosts","host","linkVariants","cva","iconSlotVariants","iconBoxVariants","Link","forwardRef","external","externalIcon","disabled","startIcon","endIcon","_hasIcon","intent","variant","weight","className","children","target","rel","onClick","rest","ref","t","useTranslation","social","isDisabled","hideExternalCues","isExternal","effectiveTarget","effectiveRel","SocialIcon","Globe","resolvedStartIcon","label","_a","externalLabel","handleClick","event","showExternalIcon","jsxs","_b","ExternalLink"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"link-CeV7FoI6.js","sources":["../../src/components/_shared/social-brand-icons.tsx","../../src/components/link/social-url.ts","../../src/components/link/link.tsx"],"sourcesContent":["/** Brand artwork shared by Link and PublicFooter. No network requests.\n * Existing Facebook, Instagram, LinkedIn and YouTube paths are preserved\n * from PublicFooter. Additional paths: Simple Icons 16.35.0 (CC0-1.0).\n * https://github.com/simple-icons/simple-icons/tree/16.35.0/icons\n * Brand names are invariant proper nouns, not translatable interface copy.\n */\nimport type { ComponentType, SVGProps } from 'react';\nimport { WhatsAppGlyph } from '../whatsapp-button/whatsapp-button';\n\ntype IconProps = SVGProps<SVGSVGElement>;\ntype SocialIcon = ComponentType<IconProps>;\n\nconst baseProps = {\n viewBox: '0 0 24 24',\n fill: 'currentColor',\n xmlns: 'http://www.w3.org/2000/svg',\n} as const;\n\nconst LinkedinIcon: SocialIcon = (props) => (\n <svg {...baseProps} {...props}>\n <path d=\"M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85 3.601 0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433a2.062 2.062 0 0 1-2.063-2.065 2.063 2.063 0 1 1 2.063 2.065zm1.782 13.019H3.555V9h3.564v11.452zM22.225 0H1.771C.792 0 0 .774 0 1.729v20.542C0 23.227.792 24 1.771 24h20.451C23.2 24 24 23.227 24 22.271V1.729C24 .774 23.2 0 22.222 0h.003z\" />\n </svg>\n);\n\nconst YoutubeIcon: SocialIcon = (props) => (\n <svg {...baseProps} {...props}>\n <path d=\"M23.498 6.186a3.016 3.016 0 0 0-2.122-2.136C19.505 3.545 12 3.545 12 3.545s-7.505 0-9.377.505A3.017 3.017 0 0 0 .502 6.186C0 8.07 0 12 0 12s0 3.93.502 5.814a3.016 3.016 0 0 0 2.122 2.136c1.871.505 9.376.505 9.376.505s7.505 0 9.377-.505a3.015 3.015 0 0 0 2.122-2.136C24 15.93 24 12 24 12s0-3.93-.502-5.814zM9.545 15.568V8.432L15.818 12l-6.273 3.568z\" />\n </svg>\n);\n\nconst InstagramIcon: SocialIcon = (props) => (\n <svg {...baseProps} {...props}>\n <path d=\"M12 2.163c3.204 0 3.584.012 4.85.07 3.252.148 4.771 1.691 4.919 4.919.058 1.265.069 1.645.069 4.849 0 3.205-.012 3.584-.069 4.849-.149 3.225-1.664 4.771-4.919 4.919-1.266.058-1.644.07-4.85.07-3.204 0-3.584-.012-4.849-.07-3.26-.149-4.771-1.699-4.919-4.92-.058-1.265-.07-1.644-.07-4.849 0-3.204.013-3.583.07-4.849.149-3.227 1.664-4.771 4.919-4.919 1.266-.057 1.645-.069 4.849-.069zM12 0C8.741 0 8.333.014 7.053.072 2.695.272.273 2.69.073 7.052.014 8.333 0 8.741 0 12c0 3.259.014 3.668.072 4.948.2 4.358 2.618 6.78 6.98 6.98C8.333 23.986 8.741 24 12 24c3.259 0 3.668-.014 4.948-.072 4.354-.2 6.782-2.618 6.979-6.98.059-1.28.073-1.689.073-4.948 0-3.259-.014-3.667-.072-4.947-.196-4.354-2.617-6.78-6.979-6.98C15.668.014 15.259 0 12 0zm0 5.838a6.162 6.162 0 1 0 0 12.324 6.162 6.162 0 0 0 0-12.324zM12 16a4 4 0 1 1 0-8 4 4 0 0 1 0 8zm6.406-11.845a1.44 1.44 0 1 0 0 2.881 1.44 1.44 0 0 0 0-2.881z\" />\n </svg>\n);\n\nconst FacebookIcon: SocialIcon = (props) => (\n <svg {...baseProps} {...props}>\n <path d=\"M24 12.073c0-6.627-5.373-12-12-12s-12 5.373-12 12c0 5.99 4.388 10.954 10.125 11.854v-8.385H7.078v-3.47h3.047V9.43c0-3.007 1.792-4.669 4.533-4.669 1.312 0 2.686.235 2.686.235v2.953H15.83c-1.491 0-1.956.925-1.956 1.874v2.25h3.328l-.532 3.47h-2.796v8.385C19.612 23.027 24 18.062 24 12.073z\" />\n </svg>\n);\n\nconst XIcon: SocialIcon = (props) => (\n <svg {...baseProps} {...props}>\n <path d=\"M14.234 10.162 22.977 0h-2.072l-7.591 8.824L7.251 0H.258l9.168 13.343L.258 24H2.33l8.016-9.318L16.749 24h6.993zm-2.837 3.299-.929-1.329L3.076 1.56h3.182l5.965 8.532.929 1.329 7.754 11.09h-3.182z\" />\n </svg>\n);\n\nconst TiktokIcon: SocialIcon = (props) => (\n <svg {...baseProps} {...props}>\n <path d=\"M12.525.02c1.31-.02 2.61-.01 3.91-.02.08 1.53.63 3.09 1.75 4.17 1.12 1.11 2.7 1.62 4.24 1.79v4.03c-1.44-.05-2.89-.35-4.2-.97-.57-.26-1.1-.59-1.62-.93-.01 2.92.01 5.84-.02 8.75-.08 1.4-.54 2.79-1.35 3.94-1.31 1.92-3.58 3.17-5.91 3.21-1.43.08-2.86-.31-4.08-1.03-2.02-1.19-3.44-3.37-3.65-5.71-.02-.5-.03-1-.01-1.49.18-1.9 1.12-3.72 2.58-4.96 1.66-1.44 3.98-2.13 6.15-1.72.02 1.48-.04 2.96-.04 4.44-.99-.32-2.15-.23-3.02.37-.63.41-1.11 1.04-1.36 1.75-.21.51-.15 1.07-.14 1.61.24 1.64 1.82 3.02 3.5 2.87 1.12-.01 2.19-.66 2.77-1.61.19-.33.4-.67.41-1.06.1-1.79.06-3.57.07-5.36.01-4.03-.01-8.05.02-12.07z\" />\n </svg>\n);\n\nconst ThreadsIcon: SocialIcon = (props) => (\n <svg {...baseProps} {...props}>\n <path d=\"M18.263 11.097c-.03-3.486-1.92-5.586-5.111-5.586-2.13 0-3.922.963-4.863 2.499l2.062 1.438c.535-.843 1.272-1.543 2.628-1.543 1.528 0 2.318.85 2.544 2.431a15 15 0 0 0-2.236-.173c-4.125 0-6.068 1.867-6.068 4.336s1.943 3.99 4.804 3.99c3.139 0 5.013-2.115 5.781-4.735.798.361 1.348 1.204 1.348 2.47 0 3.387-3.907 5.232-7.22 5.232-4.885 0-8.077-3.207-8.077-8.424 0-6.392 4.223-10.487 9.9-10.487 3.808 0 5.69 1.671 6.97 3.914l2.108-1.475C21.44 2.078 18.331 0 13.663 0 6.227 0 1.168 5.277 1.168 12.934c0 7 4.953 11.066 10.856 11.066 4.878 0 9.809-2.846 9.809-7.716 0-2.545-1.46-4.231-3.569-5.187m-6.33 4.855c-1.077 0-2.026-.512-2.026-1.453 0-1.483 1.822-1.934 3.606-1.934.678 0 1.34.045 1.927.173-.422 1.927-1.671 3.215-3.508 3.214Z\" />\n </svg>\n);\n\nconst BlueskyIcon: SocialIcon = (props) => (\n <svg {...baseProps} {...props}>\n <path d=\"M5.202 2.857C7.954 4.922 10.913 9.11 12 11.358c1.087-2.247 4.046-6.436 6.798-8.501C20.783 1.366 24 .213 24 3.883c0 .732-.42 6.156-.667 7.037-.856 3.061-3.978 3.842-6.755 3.37 4.854.826 6.089 3.562 3.422 6.299-5.065 5.196-7.28-1.304-7.847-2.97-.104-.305-.152-.448-.153-.327 0-.121-.05.022-.153.327-.568 1.666-2.782 8.166-7.847 2.97-2.667-2.737-1.432-5.473 3.422-6.3-2.777.473-5.899-.308-6.755-3.369C.42 10.04 0 4.615 0 3.883c0-3.67 3.217-2.517 5.202-1.026\" />\n </svg>\n);\n\nconst PinterestIcon: SocialIcon = (props) => (\n <svg {...baseProps} {...props}>\n <path d=\"M12.017 0C5.396 0 .029 5.367.029 11.987c0 5.079 3.158 9.417 7.618 11.162-.105-.949-.199-2.403.041-3.439.219-.937 1.406-5.957 1.406-5.957s-.359-.72-.359-1.781c0-1.663.967-2.911 2.168-2.911 1.024 0 1.518.769 1.518 1.688 0 1.029-.653 2.567-.992 3.992-.285 1.193.6 2.165 1.775 2.165 2.128 0 3.768-2.245 3.768-5.487 0-2.861-2.063-4.869-5.008-4.869-3.41 0-5.409 2.562-5.409 5.199 0 1.033.394 2.143.889 2.741.099.12.112.225.085.345-.09.375-.293 1.199-.334 1.363-.053.225-.172.271-.401.165-1.495-.69-2.433-2.878-2.433-4.646 0-3.776 2.748-7.252 7.92-7.252 4.158 0 7.392 2.967 7.392 6.923 0 4.135-2.607 7.462-6.233 7.462-1.214 0-2.354-.629-2.758-1.379l-.749 2.848c-.269 1.045-1.004 2.352-1.498 3.146 1.123.345 2.306.535 3.55.535 6.607 0 11.985-5.365 11.985-11.987C23.97 5.39 18.592.026 11.985.026L12.017 0z\" />\n </svg>\n);\n\nconst RedditIcon: SocialIcon = (props) => (\n <svg {...baseProps} {...props}>\n <path d=\"M12 0C5.373 0 0 5.373 0 12c0 3.314 1.343 6.314 3.515 8.485l-2.286 2.286C.775 23.225 1.097 24 1.738 24H12c6.627 0 12-5.373 12-12S18.627 0 12 0Zm4.388 3.199c1.104 0 1.999.895 1.999 1.999 0 1.105-.895 2-1.999 2-.946 0-1.739-.657-1.947-1.539v.002c-1.147.162-2.032 1.15-2.032 2.341v.007c1.776.067 3.4.567 4.686 1.363.473-.363 1.064-.58 1.707-.58 1.547 0 2.802 1.254 2.802 2.802 0 1.117-.655 2.081-1.601 2.531-.088 3.256-3.637 5.876-7.997 5.876-4.361 0-7.905-2.617-7.998-5.87-.954-.447-1.614-1.415-1.614-2.538 0-1.548 1.255-2.802 2.803-2.802.645 0 1.239.218 1.712.585 1.275-.79 2.881-1.291 4.64-1.365v-.01c0-1.663 1.263-3.034 2.88-3.207.188-.911.993-1.595 1.959-1.595Zm-8.085 8.376c-.784 0-1.459.78-1.506 1.797-.047 1.016.64 1.429 1.426 1.429.786 0 1.371-.369 1.418-1.385.047-1.017-.553-1.841-1.338-1.841Zm7.406 0c-.786 0-1.385.824-1.338 1.841.047 1.017.634 1.385 1.418 1.385.785 0 1.473-.413 1.426-1.429-.046-1.017-.721-1.797-1.506-1.797Zm-3.703 4.013c-.974 0-1.907.048-2.77.135-.147.015-.241.168-.183.305.483 1.154 1.622 1.964 2.953 1.964 1.33 0 2.47-.81 2.953-1.964.057-.137-.037-.29-.184-.305-.863-.087-1.795-.135-2.769-.135Z\" />\n </svg>\n);\n\nconst SnapchatIcon: SocialIcon = (props) => (\n <svg {...baseProps} {...props}>\n <path d=\"M12.206.793c.99 0 4.347.276 5.93 3.821.529 1.193.403 3.219.299 4.847l-.003.06c-.012.18-.022.345-.03.51.075.045.203.09.401.09.3-.016.659-.12 1.033-.301.165-.088.344-.104.464-.104.182 0 .359.029.509.09.45.149.734.479.734.838.015.449-.39.839-1.213 1.168-.089.029-.209.075-.344.119-.45.135-1.139.36-1.333.81-.09.224-.061.524.12.868l.015.015c.06.136 1.526 3.475 4.791 4.014.255.044.435.27.42.509 0 .075-.015.149-.045.225-.24.569-1.273.988-3.146 1.271-.059.091-.12.375-.164.57-.029.179-.074.36-.134.553-.076.271-.27.405-.555.405h-.03c-.135 0-.313-.031-.538-.074-.36-.075-.765-.135-1.273-.135-.3 0-.599.015-.913.074-.6.104-1.123.464-1.723.884-.853.599-1.826 1.288-3.294 1.288-.06 0-.119-.015-.18-.015h-.149c-1.468 0-2.427-.675-3.279-1.288-.599-.42-1.107-.779-1.707-.884-.314-.045-.629-.074-.928-.074-.54 0-.958.089-1.272.149-.211.043-.391.074-.54.074-.374 0-.523-.224-.583-.42-.061-.192-.09-.389-.135-.567-.046-.181-.105-.494-.166-.57-1.918-.222-2.95-.642-3.189-1.226-.031-.063-.052-.15-.055-.225-.015-.243.165-.465.42-.509 3.264-.54 4.73-3.879 4.791-4.02l.016-.029c.18-.345.224-.645.119-.869-.195-.434-.884-.658-1.332-.809-.121-.029-.24-.074-.346-.119-1.107-.435-1.257-.93-1.197-1.273.09-.479.674-.793 1.168-.793.146 0 .27.029.383.074.42.194.789.3 1.104.3.234 0 .384-.06.465-.105l-.046-.569c-.098-1.626-.225-3.651.307-4.837C7.392 1.077 10.739.807 11.727.807l.419-.015h.06z\" />\n </svg>\n);\n\nconst TelegramIcon: SocialIcon = (props) => (\n <svg {...baseProps} {...props}>\n <path d=\"M11.944 0A12 12 0 0 0 0 12a12 12 0 0 0 12 12 12 12 0 0 0 12-12A12 12 0 0 0 12 0a12 12 0 0 0-.056 0zm4.962 7.224c.1-.002.321.023.465.14a.506.506 0 0 1 .171.325c.016.093.036.306.02.472-.18 1.898-.962 6.502-1.36 8.627-.168.9-.499 1.201-.82 1.23-.696.065-1.225-.46-1.9-.902-1.056-.693-1.653-1.124-2.678-1.8-1.185-.78-.417-1.21.258-1.91.177-.184 3.247-2.977 3.307-3.23.007-.032.014-.15-.056-.212s-.174-.041-.249-.024c-.106.024-1.793 1.14-5.061 3.345-.48.33-.913.49-1.302.48-.428-.008-1.252-.241-1.865-.44-.752-.245-1.349-.374-1.297-.789.027-.216.325-.437.893-.663 3.498-1.524 5.83-2.529 6.998-3.014 3.332-1.386 4.025-1.627 4.476-1.635z\" />\n </svg>\n);\n\nconst DiscordIcon: SocialIcon = (props) => (\n <svg {...baseProps} {...props}>\n <path d=\"M20.317 4.3698a19.7913 19.7913 0 00-4.8851-1.5152.0741.0741 0 00-.0785.0371c-.211.3753-.4447.8648-.6083 1.2495-1.8447-.2762-3.68-.2762-5.4868 0-.1636-.3933-.4058-.8742-.6177-1.2495a.077.077 0 00-.0785-.037 19.7363 19.7363 0 00-4.8852 1.515.0699.0699 0 00-.0321.0277C.5334 9.0458-.319 13.5799.0992 18.0578a.0824.0824 0 00.0312.0561c2.0528 1.5076 4.0413 2.4228 5.9929 3.0294a.0777.0777 0 00.0842-.0276c.4616-.6304.8731-1.2952 1.226-1.9942a.076.076 0 00-.0416-.1057c-.6528-.2476-1.2743-.5495-1.8722-.8923a.077.077 0 01-.0076-.1277c.1258-.0943.2517-.1923.3718-.2914a.0743.0743 0 01.0776-.0105c3.9278 1.7933 8.18 1.7933 12.0614 0a.0739.0739 0 01.0785.0095c.1202.099.246.1981.3728.2924a.077.077 0 01-.0066.1276 12.2986 12.2986 0 01-1.873.8914.0766.0766 0 00-.0407.1067c.3604.698.7719 1.3628 1.225 1.9932a.076.076 0 00.0842.0286c1.961-.6067 3.9495-1.5219 6.0023-3.0294a.077.077 0 00.0313-.0552c.5004-5.177-.8382-9.6739-3.5485-13.6604a.061.061 0 00-.0312-.0286zM8.02 15.3312c-1.1825 0-2.1569-1.0857-2.1569-2.419 0-1.3332.9555-2.4189 2.157-2.4189 1.2108 0 2.1757 1.0952 2.1568 2.419 0 1.3332-.9555 2.4189-2.1569 2.4189zm7.9748 0c-1.1825 0-2.1569-1.0857-2.1569-2.419 0-1.3332.9554-2.4189 2.1569-2.4189 1.2108 0 2.1757 1.0952 2.1568 2.419 0 1.3332-.946 2.4189-2.1568 2.4189Z\" />\n </svg>\n);\n\nconst TwitchIcon: SocialIcon = (props) => (\n <svg {...baseProps} {...props}>\n <path d=\"M11.571 4.714h1.715v5.143H11.57zm4.715 0H18v5.143h-1.714zM6 0L1.714 4.286v15.428h5.143V24l4.286-4.286h3.428L22.286 12V0zm14.571 11.143l-3.428 3.428h-3.429l-3 3v-3H6.857V1.714h13.714Z\" />\n </svg>\n);\n\nconst GithubIcon: SocialIcon = (props) => (\n <svg {...baseProps} {...props}>\n <path d=\"M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\" />\n </svg>\n);\n\nexport const SOCIAL_LINK_ICONS = {\n linkedin: LinkedinIcon,\n youtube: YoutubeIcon,\n instagram: InstagramIcon,\n facebook: FacebookIcon,\n x: XIcon,\n tiktok: TiktokIcon,\n threads: ThreadsIcon,\n bluesky: BlueskyIcon,\n pinterest: PinterestIcon,\n reddit: RedditIcon,\n snapchat: SnapchatIcon,\n telegram: TelegramIcon,\n discord: DiscordIcon,\n twitch: TwitchIcon,\n github: GithubIcon,\n whatsapp: WhatsAppGlyph,\n} as const;\n","/**\n * Exact hostname aliases only. Never inspect the path/query or accept\n * arbitrary subdomains: those may be controlled by another publisher.\n * Labels are invariant brand names, matching the shared brand artwork.\n */\nconst SOCIAL_PROVIDERS = [\n {\n id: 'facebook',\n label: 'Facebook',\n hosts: [\n 'facebook.com',\n 'www.facebook.com',\n 'm.facebook.com',\n 'web.facebook.com',\n 'fb.com',\n 'fb.me',\n ],\n },\n {\n id: 'instagram',\n label: 'Instagram',\n hosts: ['instagram.com', 'www.instagram.com', 'instagr.am'],\n },\n {\n id: 'x',\n label: 'X',\n hosts: [\n 'x.com',\n 'www.x.com',\n 'twitter.com',\n 'www.twitter.com',\n 'mobile.twitter.com',\n ],\n },\n {\n id: 'tiktok',\n label: 'TikTok',\n hosts: [\n 'tiktok.com',\n 'www.tiktok.com',\n 'm.tiktok.com',\n 'vm.tiktok.com',\n 'vt.tiktok.com',\n ],\n },\n {\n id: 'linkedin',\n label: 'LinkedIn',\n hosts: ['linkedin.com', 'www.linkedin.com', 'm.linkedin.com', 'lnkd.in'],\n },\n {\n id: 'youtube',\n label: 'YouTube',\n hosts: [\n 'youtube.com',\n 'www.youtube.com',\n 'm.youtube.com',\n 'music.youtube.com',\n 'youtu.be',\n ],\n },\n {\n id: 'threads',\n label: 'Threads',\n hosts: ['threads.com', 'www.threads.com', 'threads.net', 'www.threads.net'],\n },\n { id: 'bluesky', label: 'Bluesky', hosts: ['bsky.app', 'www.bsky.app'] },\n {\n id: 'pinterest',\n label: 'Pinterest',\n hosts: [\n 'pinterest.com',\n 'www.pinterest.com',\n 'pinterest.it',\n 'www.pinterest.it',\n 'pinterest.de',\n 'www.pinterest.de',\n 'pinterest.fr',\n 'www.pinterest.fr',\n 'pinterest.es',\n 'www.pinterest.es',\n 'pinterest.pt',\n 'www.pinterest.pt',\n 'pinterest.co.uk',\n 'www.pinterest.co.uk',\n 'pinterest.ca',\n 'www.pinterest.ca',\n 'pinterest.com.au',\n 'www.pinterest.com.au',\n 'pinterest.ch',\n 'www.pinterest.ch',\n 'pinterest.at',\n 'www.pinterest.at',\n 'pinterest.nl',\n 'www.pinterest.nl',\n 'pin.it',\n ],\n },\n {\n id: 'reddit',\n label: 'Reddit',\n hosts: ['reddit.com', 'www.reddit.com', 'old.reddit.com', 'redd.it'],\n },\n {\n id: 'snapchat',\n label: 'Snapchat',\n hosts: ['snapchat.com', 'www.snapchat.com'],\n },\n {\n id: 'telegram',\n label: 'Telegram',\n hosts: ['t.me', 'telegram.me', 'telegram.org', 'www.telegram.org'],\n },\n {\n id: 'whatsapp',\n label: 'WhatsApp',\n hosts: [\n 'wa.me',\n 'whatsapp.com',\n 'www.whatsapp.com',\n 'api.whatsapp.com',\n 'chat.whatsapp.com',\n ],\n },\n {\n id: 'discord',\n label: 'Discord',\n hosts: ['discord.com', 'www.discord.com', 'discord.gg', 'discordapp.com'],\n },\n {\n id: 'twitch',\n label: 'Twitch',\n hosts: ['twitch.tv', 'www.twitch.tv', 'm.twitch.tv'],\n },\n { id: 'github', label: 'GitHub', hosts: ['github.com', 'www.github.com'] },\n] as const;\n\n/** Resolve a web URL without fetching it, following redirects or using the DOM. */\nexport function resolveSocialUrl(href: string) {\n if (typeof href !== 'string') return null;\n const value = href.trim();\n // Reject control characters, embedded whitespace and browser backslash\n // normalisation rather than displaying a brand for an ambiguous input.\n if (!value || /[\\s\\\\\\p{Cc}]/u.test(value)) return null;\n\n let candidate: string;\n if (/^https?:\\/\\/[^/?#]/i.test(value)) {\n candidate = value;\n } else if (value.startsWith('//') && !value.startsWith('///')) {\n candidate = `https:${value}`;\n } else if (/^[^/:?#]+\\.[^/:?#]+(?:[/:?#]|$)/.test(value)) {\n candidate = `https://${value}`;\n } else {\n return null;\n }\n\n try {\n const url = new URL(candidate);\n if (\n !['http:', 'https:'].includes(url.protocol) ||\n !url.hostname ||\n url.username ||\n url.password\n ) {\n return null;\n }\n\n const provider = SOCIAL_PROVIDERS.find(({ hosts }) =>\n hosts.some((host) => host === url.hostname),\n );\n return {\n href: url.href,\n hostname: url.hostname,\n // A non-standard port can serve something other than the social site.\n provider: url.port ? undefined : provider,\n };\n } catch {\n return null;\n }\n}\n","import { forwardRef, type AnchorHTMLAttributes, type ReactNode } from 'react';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { useTranslation } from 'react-i18next';\nimport { ExternalLink, Globe } from 'lucide-react';\nimport { SOCIAL_LINK_ICONS } from '../_shared/social-brand-icons';\nimport { resolveSocialUrl } from './social-url';\n\n/* ------------------------------------------------------------------ */\n/* CVA */\n/* ------------------------------------------------------------------ */\n\n/**\n * Link is the semantic anchor primitive for inline navigation —\n * privacy / terms in form copy, external \"remote support\" links in\n * sidebars, in-paragraph references inside info-tip body copy.\n *\n * For action affordances that *look* like a link but trigger UI rather\n * than navigation, use `<Button intent=\"link\">` instead — the semantic\n * boundary matters for screen readers and keyboard users.\n */\nconst linkVariants = cva(\n [\n // Always inline text, icons included, so a long label wraps like any\n // other text and the trailing glyph follows its last word.\n 'ds:inline',\n 'ds:underline-offset-4',\n 'ds:rounded-[var(--radius-xs)]',\n 'ds:transition-colors ds:duration-[var(--animation-duration)] ds:motion-reduce:transition-none',\n 'ds:focus-visible:outline-[length:var(--focus-ring-width)] ds:focus-visible:outline-solid',\n 'ds:focus-visible:outline-ring ds:focus-visible:outline-offset-[length:var(--focus-ring-offset)]',\n 'ds:forced-colors:focus-visible:outline-[CanvasText]',\n 'ds:aria-disabled:cursor-not-allowed ds:aria-disabled:opacity-50 ds:aria-disabled:no-underline',\n ].join(' '),\n {\n variants: {\n variant: {\n default: '',\n social: '',\n },\n intent: {\n // `--primary` falls below 4.5:1 as text on the dark page and on the\n // light app shell, so the link re-points it (and its hover step) at\n // `--primary-readable`, which differs in light and dark but not in\n // the accessible themes. The colour classes stay as they were: a\n // host still on an older token sheet keeps today's look, and a\n // consumer `className` wins or loses exactly as before.\n default:\n 'ds:[--primary:var(--primary-readable)] ds:[--primary-hover:var(--primary-readable-hover)] ds:text-primary ds:underline ds:hover:text-primary-hover ds:active:opacity-80',\n subtle:\n 'ds:text-muted-foreground ds:no-underline ds:hover:text-foreground ds:hover:underline ds:active:opacity-80',\n inverted:\n 'ds:text-primary-foreground ds:underline ds:hover:opacity-90 ds:active:opacity-80',\n },\n weight: {\n normal: 'ds:font-normal',\n strong: 'ds:font-semibold',\n },\n },\n defaultVariants: {\n variant: 'default',\n intent: 'default',\n weight: 'normal',\n },\n },\n);\n\n/*\n * An icon slot is a no-wrap span holding a word joiner (U+2060, as CSS\n * content so it never reaches textContent) and the glyph box, so the\n * glyph cannot break away from the word beside it.\n */\nconst iconSlotVariants = cva('ds:whitespace-nowrap', {\n variants: {\n edge: {\n start: String.raw`ds:after:content-['\\2060']`,\n end: String.raw`ds:before:content-['\\2060']`,\n },\n },\n});\n\n/*\n * The glyph box. Its own word joiner is a line-tall text item that gives\n * the box the text's baseline, so the 1em glyph centres on the line just\n * as the old flex anchor did, with no font-metric guesswork.\n */\nconst iconBoxVariants = cva(\n [\n 'ds:inline-flex ds:items-center',\n String.raw`ds:before:content-['\\2060']`,\n 'ds:[&_svg]:size-[1em] ds:[&_svg]:shrink-0',\n ].join(' '),\n {\n variants: {\n edge: {\n start: 'ds:me-[var(--spacing-xs)]',\n end: 'ds:ms-[var(--spacing-xs)]',\n },\n },\n },\n);\n\n/* ------------------------------------------------------------------ */\n/* Public types */\n/* ------------------------------------------------------------------ */\n\nexport interface LinkProps\n extends\n Omit<AnchorHTMLAttributes<HTMLAnchorElement>, 'href'>,\n VariantProps<typeof linkVariants> {\n /** Anchor target. Required — the whole point of the component. */\n href: string;\n /**\n * `social` detects a supported web URL and supplies its brand logo and\n * name. Children and startIcon override the automatic content. Unknown\n * websites use a globe and hostname; invalid URLs are non-interactive.\n * Bare domains and protocol-relative URLs are normalised to HTTPS.\n */\n variant?: 'default' | 'social' | null;\n /**\n * Flag the link as opening in a new browsing context. Automatically\n * adds `target=\"_blank\"` + `rel=\"noopener noreferrer\"` and renders a\n * decorative trailing `ExternalLink` icon plus an i18n'd \"Opens in a\n * new tab\" label for assistive tech. Defaults to true for `social`\n * unless an explicit target requests the current/named browsing context.\n */\n external?: boolean;\n /**\n * Render the trailing external-link glyph. Default `true` — set to\n * `false` for surfaces (footer, social rows, dense nav) where the\n * indicator adds visual noise. The `target` / `rel` / \"opens in new\n * tab\" screen-reader text are still applied.\n */\n externalIcon?: boolean;\n /**\n * Render the link in a non-interactive disabled state. Strips `href`,\n * adds `aria-disabled` + `role=\"link\"`, suppresses the underline.\n * Prefer hiding the link entirely when possible — disabled links are\n * a usability anti-pattern outside of state-machine flows.\n */\n disabled?: boolean;\n /** Optional leading icon (inline-start). */\n startIcon?: ReactNode;\n /** Optional trailing icon (inline-end). Ignored when `external`. */\n endIcon?: ReactNode;\n /** @deprecated No effect: the icon layout follows the icon props. Kept so existing callers compile. */\n hasIcon?: 'yes' | 'no' | null;\n}\n\n/* ------------------------------------------------------------------ */\n/* Component */\n/* ------------------------------------------------------------------ */\n\nexport const Link = forwardRef<HTMLAnchorElement, LinkProps>(\n (\n {\n href,\n external,\n externalIcon = true,\n disabled = false,\n startIcon,\n endIcon,\n hasIcon: _hasIcon,\n intent,\n variant = 'default',\n weight,\n className,\n children,\n target,\n rel,\n onClick,\n ...rest\n },\n ref,\n ) => {\n const { t } = useTranslation('ui');\n\n const social = variant === 'social' ? resolveSocialUrl(href ?? '') : null;\n const isDisabled = disabled || (variant === 'social' && !social);\n // Only the social variant hides the external cues when disabled; ordinary\n // links keep them exactly as before.\n const hideExternalCues = variant === 'social' && isDisabled;\n const isExternal =\n external ?? (variant === 'social' && (!target || target === '_blank'));\n const effectiveTarget = isExternal ? '_blank' : target;\n const effectiveRel = isExternal\n ? [rel, 'noopener', 'noreferrer'].filter(Boolean).join(' ')\n : rel;\n const SocialIcon = social?.provider\n ? SOCIAL_LINK_ICONS[social.provider.id]\n : Globe;\n const resolvedStartIcon =\n startIcon === undefined && variant === 'social' ? (\n <SocialIcon aria-hidden=\"true\" focusable=\"false\" />\n ) : (\n startIcon\n );\n const label =\n children ??\n (variant === 'social'\n ? social?.provider?.label ||\n social?.hostname ||\n t('contactProfileCard.label.website')\n : undefined);\n\n const externalLabel = t('link.opensInNewTab', 'Opens in a new tab');\n\n const handleClick: AnchorHTMLAttributes<HTMLAnchorElement>['onClick'] = (\n event,\n ) => {\n if (isDisabled) {\n event.preventDefault();\n return;\n }\n onClick?.(event);\n };\n\n const showExternalIcon = isExternal && externalIcon && !hideExternalCues;\n\n return (\n <a\n ref={ref}\n // When disabled, drop href so the link is not actionable; pair\n // with aria-disabled + role=\"link\" so AT still announces the\n // role (the implicit role disappears once href is removed).\n href={isDisabled ? undefined : (social?.href ?? href)}\n role={isDisabled ? 'link' : undefined}\n aria-disabled={isDisabled || undefined}\n target={effectiveTarget}\n rel={effectiveRel || undefined}\n onClick={handleClick}\n data-component=\"link\"\n data-intent={intent ?? 'default'}\n data-variant={variant ?? 'default'}\n data-social-network={social?.provider?.id}\n className={linkVariants({ variant, intent, weight, className })}\n {...rest}\n >\n {resolvedStartIcon ? (\n <span\n aria-hidden=\"true\"\n className={iconSlotVariants({ edge: 'start' })}\n >\n <span className={iconBoxVariants({ edge: 'start' })}>\n {resolvedStartIcon}\n </span>\n </span>\n ) : null}\n {label}\n {showExternalIcon || (!isExternal && endIcon) ? (\n <span\n aria-hidden=\"true\"\n className={iconSlotVariants({ edge: 'end' })}\n >\n <span className={iconBoxVariants({ edge: 'end' })}>\n {showExternalIcon ? (\n <ExternalLink className=\"ds:size-[1em]\" />\n ) : (\n endIcon\n )}\n </span>\n </span>\n ) : null}\n {showExternalIcon ? (\n // Labelled, empty and out of flow: name algorithms add the label\n // after a space, and textContent stays the caller's text.\n <span aria-label={externalLabel} className=\"ds:sr-only\" />\n ) : isExternal && !hideExternalCues ? (\n // External wiring without the glyph — keep the SR-only\n // \"opens in new tab\" announcement so the affordance reads.\n <span className=\"ds:sr-only\">{externalLabel}</span>\n ) : null}\n </a>\n );\n },\n);\n\nLink.displayName = 'Link';\n"],"names":["baseProps","LinkedinIcon","props","jsx","YoutubeIcon","InstagramIcon","FacebookIcon","XIcon","TiktokIcon","ThreadsIcon","BlueskyIcon","PinterestIcon","RedditIcon","SnapchatIcon","TelegramIcon","DiscordIcon","TwitchIcon","GithubIcon","SOCIAL_LINK_ICONS","WhatsAppGlyph","SOCIAL_PROVIDERS","resolveSocialUrl","href","value","candidate","url","provider","hosts","host","linkVariants","cva","iconSlotVariants","iconBoxVariants","Link","forwardRef","external","externalIcon","disabled","startIcon","endIcon","_hasIcon","intent","variant","weight","className","children","target","rel","onClick","rest","ref","t","useTranslation","social","isDisabled","hideExternalCues","isExternal","effectiveTarget","effectiveRel","SocialIcon","Globe","resolvedStartIcon","label","_a","externalLabel","handleClick","event","showExternalIcon","jsxs","_b","ExternalLink"],"mappings":"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"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx as s, jsxs as w, Fragment as x } from "react/jsx-runtime";
|
|
2
2
|
import { forwardRef as N, useMemo as l } from "react";
|
|
3
3
|
import { c as p } from "./index-D2ZczOXr.js";
|
|
4
|
-
import { L as C } from "./link-
|
|
4
|
+
import { L as C } from "./link-CeV7FoI6.js";
|
|
5
5
|
import { u as G } from "./registry-DvAUVLHh.js";
|
|
6
6
|
const I = {
|
|
7
7
|
id: "nav-grid",
|
|
@@ -165,4 +165,4 @@ export {
|
|
|
165
165
|
I as n,
|
|
166
166
|
c as t
|
|
167
167
|
};
|
|
168
|
-
//# sourceMappingURL=nav-grid-
|
|
168
|
+
//# sourceMappingURL=nav-grid-dEgDAri3.js.map
|