@alfadocs/ui-kit-debug 1.90.2 → 1.91.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/{agenda-card-BDuvreCe.js → agenda-card-BhY342MA.js} +2 -2
- package/dist/_chunks/{agenda-card-BDuvreCe.js.map → agenda-card-BhY342MA.js.map} +1 -1
- package/dist/_chunks/{agenda-tray-D-jvptdo.js → agenda-tray-BmxBGEci.js} +2 -2
- package/dist/_chunks/{agenda-tray-D-jvptdo.js.map → agenda-tray-BmxBGEci.js.map} +1 -1
- package/dist/_chunks/{alia-sidebar-CsTRAxC8.js → alia-sidebar-ovRX_oti.js} +3 -3
- package/dist/_chunks/{alia-sidebar-CsTRAxC8.js.map → alia-sidebar-ovRX_oti.js.map} +1 -1
- package/dist/_chunks/{appointment-card-5JMWi9_f.js → appointment-card-Bstc1p7a.js} +2 -2
- package/dist/_chunks/{appointment-card-5JMWi9_f.js.map → appointment-card-Bstc1p7a.js.map} +1 -1
- package/dist/_chunks/{appointment-peek-39BwVMUf.js → appointment-peek-C0kKqnFk.js} +2 -2
- package/dist/_chunks/{appointment-peek-39BwVMUf.js.map → appointment-peek-C0kKqnFk.js.map} +1 -1
- package/dist/_chunks/{appointment-timeline-1-Za2miy.js → appointment-timeline-rbt9AwHO.js} +2 -2
- package/dist/_chunks/{appointment-timeline-1-Za2miy.js.map → appointment-timeline-rbt9AwHO.js.map} +1 -1
- package/dist/_chunks/{appointment-tray-Dwc8MSIQ.js → appointment-tray-6zd8RLIL.js} +2 -2
- package/dist/_chunks/{appointment-tray-Dwc8MSIQ.js.map → appointment-tray-6zd8RLIL.js.map} +1 -1
- package/dist/_chunks/{avatar-BPiPL7ND.js → avatar-a6042Ox2.js} +52 -52
- package/dist/_chunks/avatar-a6042Ox2.js.map +1 -0
- package/dist/_chunks/{balance-badge-cell-D9VhFp0L.js → balance-badge-cell-BtJvre1-.js} +2 -2
- package/dist/_chunks/{balance-badge-cell-D9VhFp0L.js.map → balance-badge-cell-BtJvre1-.js.map} +1 -1
- package/dist/_chunks/booking-opt_h7Uc.js +4590 -0
- package/dist/_chunks/booking-opt_h7Uc.js.map +1 -0
- package/dist/_chunks/{calendar-ClB-jWH1.js → calendar-CmiMS4FJ.js} +2 -2
- package/dist/_chunks/{calendar-ClB-jWH1.js.map → calendar-CmiMS4FJ.js.map} +1 -1
- package/dist/_chunks/{calendar-appointment-editor-dialog-CiAGAX2t.js → calendar-appointment-editor-dialog-sJKLoVJ2.js} +7 -7
- package/dist/_chunks/{calendar-appointment-editor-dialog-CiAGAX2t.js.map → calendar-appointment-editor-dialog-sJKLoVJ2.js.map} +1 -1
- package/dist/_chunks/{care-plan-card-BYCPNDvA.js → care-plan-card-DD9rEWYN.js} +2 -2
- package/dist/_chunks/{care-plan-card-BYCPNDvA.js.map → care-plan-card-DD9rEWYN.js.map} +1 -1
- package/dist/_chunks/{care-plan-header-BzsAg6oY.js → care-plan-header-CXUJQt8Q.js} +2 -2
- package/dist/_chunks/{care-plan-header-BzsAg6oY.js.map → care-plan-header-CXUJQt8Q.js.map} +1 -1
- package/dist/_chunks/{chat-message-CmFJdEre.js → chat-message-LRO_6Ee3.js} +2 -2
- package/dist/_chunks/{chat-message-CmFJdEre.js.map → chat-message-LRO_6Ee3.js.map} +1 -1
- package/dist/_chunks/{clinical-note-card-Caidqcwa.js → clinical-note-card-Cut2lNmu.js} +3 -3
- package/dist/_chunks/{clinical-note-card-Caidqcwa.js.map → clinical-note-card-Cut2lNmu.js.map} +1 -1
- package/dist/_chunks/{contact-card-Czu60UvU.js → contact-card-ClvEDM9e.js} +2 -2
- package/dist/_chunks/{contact-card-Czu60UvU.js.map → contact-card-ClvEDM9e.js.map} +1 -1
- package/dist/_chunks/{contact-profile-card-Da1vmJQI.js → contact-profile-card-CX45mZA3.js} +106 -95
- package/dist/_chunks/contact-profile-card-CX45mZA3.js.map +1 -0
- package/dist/_chunks/{dependent-selector-C4kOgO8b.js → dependent-selector-CyNi7M_f.js} +2 -2
- package/dist/_chunks/{dependent-selector-C4kOgO8b.js.map → dependent-selector-CyNi7M_f.js.map} +1 -1
- package/dist/_chunks/{entity-summary-BLxzSSXK.js → entity-summary-B_bOloqP.js} +3 -3
- package/dist/_chunks/{entity-summary-BLxzSSXK.js.map → entity-summary-B_bOloqP.js.map} +1 -1
- package/dist/_chunks/error-page-B0fGNTRB.js +419 -0
- package/dist/_chunks/error-page-B0fGNTRB.js.map +1 -0
- package/dist/_chunks/{languages-CZqBaPwI.js → languages-CGLX6Qpe.js} +3 -15
- package/dist/_chunks/languages-CGLX6Qpe.js.map +1 -0
- package/dist/_chunks/link-DtCfnLnF.js +332 -0
- package/dist/_chunks/link-DtCfnLnF.js.map +1 -0
- package/dist/_chunks/{link-cell-renderer-CnCgudvq.js → link-cell-renderer-BS3V4LA6.js} +2 -2
- package/dist/_chunks/{link-cell-renderer-CnCgudvq.js.map → link-cell-renderer-BS3V4LA6.js.map} +1 -1
- package/dist/_chunks/{marketplace-app-shell-CmZx0Oam.js → marketplace-app-shell-CJQtx3sv.js} +2 -2
- package/dist/_chunks/{marketplace-app-shell-CmZx0Oam.js.map → marketplace-app-shell-CJQtx3sv.js.map} +1 -1
- package/dist/_chunks/{message-card-CvCnCssc.js → message-card-B6SduXJv.js} +2 -2
- package/dist/_chunks/{message-card-CvCnCssc.js.map → message-card-B6SduXJv.js.map} +1 -1
- package/dist/_chunks/{message-tray-IJYvy6Cf.js → message-tray-Cllf-v0G.js} +2 -2
- package/dist/_chunks/{message-tray-IJYvy6Cf.js.map → message-tray-Cllf-v0G.js.map} +1 -1
- package/dist/_chunks/{nav-grid-Oc4aCPrg.js → nav-grid-D2xVcHTO.js} +2 -2
- package/dist/_chunks/{nav-grid-Oc4aCPrg.js.map → nav-grid-D2xVcHTO.js.map} +1 -1
- package/dist/_chunks/{note-attachment-DIlIQ7JF.js → note-attachment-cnj2JRrg.js} +2 -2
- package/dist/_chunks/{note-attachment-DIlIQ7JF.js.map → note-attachment-cnj2JRrg.js.map} +1 -1
- package/dist/_chunks/{note-timeline-KzL52MmB.js → note-timeline-BrjHBQfx.js} +2 -2
- package/dist/_chunks/{note-timeline-KzL52MmB.js.map → note-timeline-BrjHBQfx.js.map} +1 -1
- package/dist/_chunks/{notes-panel-Dywo6R55.js → notes-panel-ib7I3aNf.js} +2 -2
- package/dist/_chunks/{notes-panel-Dywo6R55.js.map → notes-panel-ib7I3aNf.js.map} +1 -1
- package/dist/_chunks/{operator-hero-6aAIQaFZ.js → operator-hero-C_5B-8Qp.js} +43 -41
- package/dist/_chunks/operator-hero-C_5B-8Qp.js.map +1 -0
- package/dist/_chunks/{patient-details-BUr7Oemx.js → patient-details-BjcUpD9S.js} +3 -3
- package/dist/_chunks/{patient-details-BUr7Oemx.js.map → patient-details-BjcUpD9S.js.map} +1 -1
- package/dist/_chunks/{patient-field-row-bJk8Q_qr.js → patient-field-row-B0tdiaWi.js} +2 -2
- package/dist/_chunks/{patient-field-row-bJk8Q_qr.js.map → patient-field-row-B0tdiaWi.js.map} +1 -1
- package/dist/_chunks/{patient-summary-card-CCQZ8X37.js → patient-summary-card-Cvv6_Ugk.js} +4 -4
- package/dist/_chunks/{patient-summary-card-CCQZ8X37.js.map → patient-summary-card-Cvv6_Ugk.js.map} +1 -1
- package/dist/_chunks/{payment-request-card-MndSlVoK.js → payment-request-card-BfGauFY0.js} +2 -2
- package/dist/_chunks/{payment-request-card-MndSlVoK.js.map → payment-request-card-BfGauFY0.js.map} +1 -1
- package/dist/_chunks/{practice-profile-hero-qfrsFQI_.js → practice-profile-hero-ClzE-4CB.js} +76 -73
- package/dist/_chunks/practice-profile-hero-ClzE-4CB.js.map +1 -0
- package/dist/_chunks/{practice-results-DQuOfqej.js → practice-results-CQ_KvEXK.js} +517 -514
- package/dist/_chunks/practice-results-CQ_KvEXK.js.map +1 -0
- package/dist/_chunks/{product-hub-panel-Blag8t8f.js → product-hub-panel-bHi7lkVD.js} +2 -2
- package/dist/_chunks/{product-hub-panel-Blag8t8f.js.map → product-hub-panel-bHi7lkVD.js.map} +1 -1
- package/dist/_chunks/public-footer-IoRWoAMz.js +596 -0
- package/dist/_chunks/public-footer-IoRWoAMz.js.map +1 -0
- package/dist/_chunks/{signature-request-DjY-X62H.js → signature-request-DvhyrRpn.js} +3 -3
- package/dist/_chunks/{signature-request-DjY-X62H.js.map → signature-request-DvhyrRpn.js.map} +1 -1
- package/dist/_chunks/{signed-out-frame-G-3ATOdu.js → signed-out-frame-CgRXOUzi.js} +2 -2
- package/dist/_chunks/{signed-out-frame-G-3ATOdu.js.map → signed-out-frame-CgRXOUzi.js.map} +1 -1
- package/dist/_chunks/{slot-grid-DrwynKeN.js → slot-grid-B-IAFX3C.js} +180 -169
- package/dist/_chunks/slot-grid-B-IAFX3C.js.map +1 -0
- package/dist/_chunks/{timeline-wUuTDFY_.js → timeline-BcYHdP56.js} +2 -2
- package/dist/_chunks/{timeline-wUuTDFY_.js.map → timeline-BcYHdP56.js.map} +1 -1
- package/dist/_chunks/{use-appointment-details-read-BytPq3Ux.js → use-appointment-details-read-D8vDg0sg.js} +5 -5
- package/dist/_chunks/{use-appointment-details-read-BytPq3Ux.js.map → use-appointment-details-read-D8vDg0sg.js.map} +1 -1
- package/dist/agent-catalog.json +2 -2
- package/dist/components/_shared/social-brand-icons.d.ts +29 -0
- package/dist/components/_shared/social-brand-icons.d.ts.map +1 -0
- package/dist/components/agenda-card/index.js +1 -1
- package/dist/components/agenda-tray/index.js +1 -1
- package/dist/components/appointment-card/index.js +2 -2
- package/dist/components/appointment-details-panel/index.js +1 -1
- package/dist/components/appointment-peek/index.js +1 -1
- package/dist/components/appointment-timeline/index.js +1 -1
- package/dist/components/avatar/avatar.d.ts +14 -0
- package/dist/components/avatar/avatar.d.ts.map +1 -1
- package/dist/components/avatar/index.js +1 -1
- package/dist/components/booking/booking-types.d.ts +26 -0
- package/dist/components/booking/booking-types.d.ts.map +1 -1
- package/dist/components/booking/booking.d.ts.map +1 -1
- package/dist/components/booking/details-form.d.ts.map +1 -1
- package/dist/components/booking/index.js +1 -1
- package/dist/components/booking/slot-load-state.d.ts +11 -0
- package/dist/components/booking/slot-load-state.d.ts.map +1 -0
- package/dist/components/calendar/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/chat-message/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/data-table/index.js +1 -1
- package/dist/components/dependent-selector/index.js +1 -1
- package/dist/components/entity-summary/index.js +1 -1
- package/dist/components/link/index.js +1 -1
- package/dist/components/link/link.d.ts +10 -1
- package/dist/components/link/link.d.ts.map +1 -1
- package/dist/components/link/social-url.d.ts +71 -0
- package/dist/components/link/social-url.d.ts.map +1 -0
- package/dist/components/message-card/index.js +1 -1
- package/dist/components/message-tray/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/operator-hero/index.js +1 -1
- package/dist/components/operator-hero/operator-hero.d.ts +6 -0
- package/dist/components/operator-hero/operator-hero.d.ts.map +1 -1
- package/dist/components/patient-details/index.js +1 -1
- package/dist/components/patient-summary-card/index.js +1 -1
- package/dist/components/patient-table/index.js +1 -1
- package/dist/components/payment-card/index.js +1 -1
- package/dist/components/practice-profile-hero/index.js +1 -1
- package/dist/components/practice-profile-hero/practice-profile-hero.d.ts +6 -0
- package/dist/components/practice-profile-hero/practice-profile-hero.d.ts.map +1 -1
- package/dist/components/practice-results/index.js +1 -1
- package/dist/components/practice-results/practice-results.d.ts +8 -2
- package/dist/components/practice-results/practice-results.d.ts.map +1 -1
- package/dist/components/product-hub-tray/index.js +1 -1
- package/dist/components/public-footer/index.js +1 -1
- package/dist/components/public-footer/public-footer.d.ts +13 -1
- package/dist/components/public-footer/public-footer.d.ts.map +1 -1
- package/dist/components/public-footer/socials.d.ts +6 -5
- package/dist/components/public-footer/socials.d.ts.map +1 -1
- package/dist/components/slot-grid/index.js +1 -1
- package/dist/components/slot-grid/slot-grid.d.ts +2 -0
- package/dist/components/slot-grid/slot-grid.d.ts.map +1 -1
- package/dist/components/timeline/index.js +1 -1
- package/dist/i18n/config.d.ts.map +1 -1
- package/dist/i18n/config.js +224 -96
- package/dist/i18n/config.js.map +1 -1
- package/dist/i18n/locales/ar.d.ts +3 -0
- package/dist/i18n/locales/ar.d.ts.map +1 -1
- package/dist/i18n/locales/ar.js +4 -1
- package/dist/i18n/locales/ar.js.map +1 -1
- package/dist/i18n/locales/de.d.ts +3 -0
- package/dist/i18n/locales/de.d.ts.map +1 -1
- package/dist/i18n/locales/de.js +4 -1
- package/dist/i18n/locales/de.js.map +1 -1
- package/dist/i18n/locales/el.d.ts +3 -0
- package/dist/i18n/locales/el.d.ts.map +1 -1
- package/dist/i18n/locales/el.js +4 -1
- package/dist/i18n/locales/el.js.map +1 -1
- package/dist/i18n/locales/en.d.ts +3 -0
- package/dist/i18n/locales/en.d.ts.map +1 -1
- package/dist/i18n/locales/en.js +3 -0
- package/dist/i18n/locales/en.js.map +1 -1
- package/dist/i18n/locales/es.d.ts +3 -0
- package/dist/i18n/locales/es.d.ts.map +1 -1
- package/dist/i18n/locales/es.js +4 -1
- package/dist/i18n/locales/es.js.map +1 -1
- package/dist/i18n/locales/fr.d.ts +3 -0
- package/dist/i18n/locales/fr.d.ts.map +1 -1
- package/dist/i18n/locales/fr.js +4 -1
- package/dist/i18n/locales/fr.js.map +1 -1
- package/dist/i18n/locales/hi.d.ts +3 -0
- package/dist/i18n/locales/hi.d.ts.map +1 -1
- package/dist/i18n/locales/hi.js +4 -1
- package/dist/i18n/locales/hi.js.map +1 -1
- package/dist/i18n/locales/it.d.ts +3 -0
- package/dist/i18n/locales/it.d.ts.map +1 -1
- package/dist/i18n/locales/it.js +4 -1
- package/dist/i18n/locales/it.js.map +1 -1
- package/dist/i18n/locales/ja.d.ts +3 -0
- package/dist/i18n/locales/ja.d.ts.map +1 -1
- package/dist/i18n/locales/ja.js +4 -1
- package/dist/i18n/locales/ja.js.map +1 -1
- package/dist/i18n/locales/nl.d.ts +3 -0
- package/dist/i18n/locales/nl.d.ts.map +1 -1
- package/dist/i18n/locales/nl.js +4 -1
- package/dist/i18n/locales/nl.js.map +1 -1
- package/dist/i18n/locales/pl.d.ts +3 -0
- package/dist/i18n/locales/pl.d.ts.map +1 -1
- package/dist/i18n/locales/pl.js +4 -1
- package/dist/i18n/locales/pl.js.map +1 -1
- package/dist/i18n/locales/pt.d.ts +3 -0
- package/dist/i18n/locales/pt.d.ts.map +1 -1
- package/dist/i18n/locales/pt.js +4 -1
- package/dist/i18n/locales/pt.js.map +1 -1
- package/dist/i18n/locales/ro.d.ts +3 -0
- package/dist/i18n/locales/ro.d.ts.map +1 -1
- package/dist/i18n/locales/ro.js +4 -1
- package/dist/i18n/locales/ro.js.map +1 -1
- package/dist/i18n/locales/ru.d.ts +3 -0
- package/dist/i18n/locales/ru.d.ts.map +1 -1
- package/dist/i18n/locales/ru.js +4 -1
- package/dist/i18n/locales/ru.js.map +1 -1
- package/dist/i18n/locales/sq.d.ts +3 -0
- package/dist/i18n/locales/sq.d.ts.map +1 -1
- package/dist/i18n/locales/sq.js +4 -1
- package/dist/i18n/locales/sq.js.map +1 -1
- package/dist/i18n/locales/sv.d.ts +3 -0
- package/dist/i18n/locales/sv.d.ts.map +1 -1
- package/dist/i18n/locales/sv.js +4 -1
- package/dist/i18n/locales/sv.js.map +1 -1
- package/dist/i18n/locales/tr.d.ts +3 -0
- package/dist/i18n/locales/tr.d.ts.map +1 -1
- package/dist/i18n/locales/tr.js +4 -1
- package/dist/i18n/locales/tr.js.map +1 -1
- package/dist/i18n/locales/zh.d.ts +3 -0
- package/dist/i18n/locales/zh.d.ts.map +1 -1
- package/dist/i18n/locales/zh.js +4 -1
- package/dist/i18n/locales/zh.js.map +1 -1
- package/dist/index.js +42 -42
- package/dist/locales/ar.json +4 -1
- package/dist/locales/de.json +4 -1
- package/dist/locales/el.json +4 -1
- package/dist/locales/en.json +3 -0
- package/dist/locales/es.json +4 -1
- package/dist/locales/fr.json +4 -1
- package/dist/locales/hi.json +4 -1
- package/dist/locales/it.json +4 -1
- package/dist/locales/ja.json +4 -1
- package/dist/locales/nl.json +4 -1
- package/dist/locales/pl.json +4 -1
- package/dist/locales/pt.json +4 -1
- package/dist/locales/ro.json +4 -1
- package/dist/locales/ru.json +4 -1
- package/dist/locales/sq.json +4 -1
- package/dist/locales/sv.json +4 -1
- package/dist/locales/tr.json +4 -1
- package/dist/locales/zh.json +4 -1
- package/dist/patterns/alia-assistant/index.js +1 -1
- package/dist/patterns/calendar/index.js +1 -1
- package/dist/patterns/error-page/error-page-english.d.ts +71 -0
- package/dist/patterns/error-page/error-page-english.d.ts.map +1 -0
- package/dist/patterns/error-page/error-page.d.ts.map +1 -1
- package/dist/patterns/error-page/index.js +1 -1
- package/dist/patterns/marketplace-app-shell/index.js +1 -1
- package/dist/patterns/signature-request/index.js +1 -1
- package/dist/patterns/signed-out-frame/index.js +1 -1
- package/dist/tokens.css +1 -1
- package/package.json +1 -1
- package/dist/_chunks/avatar-BPiPL7ND.js.map +0 -1
- package/dist/_chunks/booking-CcE_oviI.js +0 -4373
- package/dist/_chunks/booking-CcE_oviI.js.map +0 -1
- package/dist/_chunks/contact-profile-card-Da1vmJQI.js.map +0 -1
- package/dist/_chunks/error-page-Bhai-spN.js +0 -344
- package/dist/_chunks/error-page-Bhai-spN.js.map +0 -1
- package/dist/_chunks/languages-CZqBaPwI.js.map +0 -1
- package/dist/_chunks/link-N5_YpLtm.js +0 -138
- package/dist/_chunks/link-N5_YpLtm.js.map +0 -1
- package/dist/_chunks/operator-hero-6aAIQaFZ.js.map +0 -1
- package/dist/_chunks/practice-profile-hero-qfrsFQI_.js.map +0 -1
- package/dist/_chunks/practice-results-DQuOfqej.js.map +0 -1
- package/dist/_chunks/public-footer-CXOrdAaS.js +0 -568
- package/dist/_chunks/public-footer-CXOrdAaS.js.map +0 -1
- package/dist/_chunks/slot-grid-DrwynKeN.js.map +0 -1
|
@@ -1,138 +0,0 @@
|
|
|
1
|
-
import { jsxs as S, jsx as e } from "react/jsx-runtime";
|
|
2
|
-
import { forwardRef as T } from "react";
|
|
3
|
-
import { c as i } from "./index-D2ZczOXr.js";
|
|
4
|
-
import { useTranslation as V } from "react-i18next";
|
|
5
|
-
import { E as _ } from "./external-link-CY6zAXXU.js";
|
|
6
|
-
const E = i(
|
|
7
|
-
[
|
|
8
|
-
// Always inline text, icons included, so a long label wraps like any
|
|
9
|
-
// other text and the trailing glyph follows its last word.
|
|
10
|
-
"ds:inline",
|
|
11
|
-
"ds:underline-offset-4",
|
|
12
|
-
"ds:rounded-[var(--radius-xs)]",
|
|
13
|
-
"ds:transition-colors ds:duration-[var(--animation-duration)] ds:motion-reduce:transition-none",
|
|
14
|
-
"ds:focus-visible:outline-[length:var(--focus-ring-width)] ds:focus-visible:outline-solid",
|
|
15
|
-
"ds:focus-visible:outline-ring ds:focus-visible:outline-offset-[length:var(--focus-ring-offset)]",
|
|
16
|
-
"ds:forced-colors:focus-visible:outline-[CanvasText]",
|
|
17
|
-
"ds:aria-disabled:cursor-not-allowed ds:aria-disabled:opacity-50 ds:aria-disabled:no-underline"
|
|
18
|
-
].join(" "),
|
|
19
|
-
{
|
|
20
|
-
variants: {
|
|
21
|
-
intent: {
|
|
22
|
-
// `--primary` falls below 4.5:1 as text on the dark page and on the
|
|
23
|
-
// light app shell, so the link re-points it (and its hover step) at
|
|
24
|
-
// `--primary-readable`, which differs in light and dark but not in
|
|
25
|
-
// the accessible themes. The colour classes stay as they were: a
|
|
26
|
-
// host still on an older token sheet keeps today's look, and a
|
|
27
|
-
// consumer `className` wins or loses exactly as before.
|
|
28
|
-
default: "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",
|
|
29
|
-
subtle: "ds:text-muted-foreground ds:no-underline ds:hover:text-foreground ds:hover:underline ds:active:opacity-80",
|
|
30
|
-
inverted: "ds:text-primary-foreground ds:underline ds:hover:opacity-90 ds:active:opacity-80"
|
|
31
|
-
},
|
|
32
|
-
weight: {
|
|
33
|
-
normal: "ds:font-normal",
|
|
34
|
-
strong: "ds:font-semibold"
|
|
35
|
-
}
|
|
36
|
-
},
|
|
37
|
-
defaultVariants: {
|
|
38
|
-
intent: "default",
|
|
39
|
-
weight: "normal"
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
), u = i("ds:whitespace-nowrap", {
|
|
43
|
-
variants: {
|
|
44
|
-
edge: {
|
|
45
|
-
start: String.raw`ds:after:content-['\2060']`,
|
|
46
|
-
end: String.raw`ds:before:content-['\2060']`
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
}), m = i(
|
|
50
|
-
[
|
|
51
|
-
"ds:inline-flex ds:items-center",
|
|
52
|
-
String.raw`ds:before:content-['\2060']`,
|
|
53
|
-
"ds:[&_svg]:size-[1em] ds:[&_svg]:shrink-0"
|
|
54
|
-
].join(" "),
|
|
55
|
-
{
|
|
56
|
-
variants: {
|
|
57
|
-
edge: {
|
|
58
|
-
start: "ds:me-[var(--spacing-xs)]",
|
|
59
|
-
end: "ds:ms-[var(--spacing-xs)]"
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
), z = T(
|
|
64
|
-
({
|
|
65
|
-
href: v,
|
|
66
|
-
external: s = !1,
|
|
67
|
-
externalIcon: p = !0,
|
|
68
|
-
disabled: n = !1,
|
|
69
|
-
startIcon: t,
|
|
70
|
-
endIcon: o,
|
|
71
|
-
hasIcon: B,
|
|
72
|
-
intent: d,
|
|
73
|
-
weight: h,
|
|
74
|
-
className: g,
|
|
75
|
-
children: b,
|
|
76
|
-
target: y,
|
|
77
|
-
rel: l,
|
|
78
|
-
onClick: a,
|
|
79
|
-
...w
|
|
80
|
-
}, x) => {
|
|
81
|
-
const { t: N } = V("ui"), k = s ? "_blank" : y, j = s ? [l, "noopener", "noreferrer"].filter(Boolean).join(" ") : l, c = N("link.opensInNewTab", "Opens in a new tab"), L = (f) => {
|
|
82
|
-
if (n) {
|
|
83
|
-
f.preventDefault();
|
|
84
|
-
return;
|
|
85
|
-
}
|
|
86
|
-
a == null || a(f);
|
|
87
|
-
}, r = s && p;
|
|
88
|
-
return /* @__PURE__ */ S(
|
|
89
|
-
"a",
|
|
90
|
-
{
|
|
91
|
-
ref: x,
|
|
92
|
-
href: n ? void 0 : v,
|
|
93
|
-
role: n ? "link" : void 0,
|
|
94
|
-
"aria-disabled": n || void 0,
|
|
95
|
-
target: k,
|
|
96
|
-
rel: j || void 0,
|
|
97
|
-
onClick: L,
|
|
98
|
-
"data-component": "link",
|
|
99
|
-
"data-intent": d ?? "default",
|
|
100
|
-
className: E({ intent: d, weight: h, className: g }),
|
|
101
|
-
...w,
|
|
102
|
-
children: [
|
|
103
|
-
t ? /* @__PURE__ */ e(
|
|
104
|
-
"span",
|
|
105
|
-
{
|
|
106
|
-
"aria-hidden": "true",
|
|
107
|
-
className: u({ edge: "start" }),
|
|
108
|
-
children: /* @__PURE__ */ e("span", { className: m({ edge: "start" }), children: t })
|
|
109
|
-
}
|
|
110
|
-
) : null,
|
|
111
|
-
b,
|
|
112
|
-
r || !s && o ? /* @__PURE__ */ e(
|
|
113
|
-
"span",
|
|
114
|
-
{
|
|
115
|
-
"aria-hidden": "true",
|
|
116
|
-
className: u({ edge: "end" }),
|
|
117
|
-
children: /* @__PURE__ */ e("span", { className: m({ edge: "end" }), children: r ? /* @__PURE__ */ e(_, { className: "ds:size-[1em]" }) : o })
|
|
118
|
-
}
|
|
119
|
-
) : null,
|
|
120
|
-
r ? (
|
|
121
|
-
// Labelled, empty and out of flow: name algorithms add the label
|
|
122
|
-
// after a space, and textContent stays the caller's text.
|
|
123
|
-
/* @__PURE__ */ e("span", { "aria-label": c, className: "ds:sr-only" })
|
|
124
|
-
) : s ? (
|
|
125
|
-
// External wiring without the glyph — keep the SR-only
|
|
126
|
-
// "opens in new tab" announcement so the affordance reads.
|
|
127
|
-
/* @__PURE__ */ e("span", { className: "ds:sr-only", children: c })
|
|
128
|
-
) : null
|
|
129
|
-
]
|
|
130
|
-
}
|
|
131
|
-
);
|
|
132
|
-
}
|
|
133
|
-
);
|
|
134
|
-
z.displayName = "Link";
|
|
135
|
-
export {
|
|
136
|
-
z as L
|
|
137
|
-
};
|
|
138
|
-
//# sourceMappingURL=link-N5_YpLtm.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"link-N5_YpLtm.js","sources":["../../src/components/link/link.tsx"],"sourcesContent":["import { forwardRef, type AnchorHTMLAttributes, type ReactNode } from 'react';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { useTranslation } from 'react-i18next';\nimport { ExternalLink } from 'lucide-react';\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 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 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 * 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.\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 = false,\n externalIcon = true,\n disabled = false,\n startIcon,\n endIcon,\n hasIcon: _hasIcon,\n intent,\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 effectiveTarget = external ? '_blank' : target;\n const effectiveRel = external\n ? [rel, 'noopener', 'noreferrer'].filter(Boolean).join(' ')\n : rel;\n\n const externalLabel = t('link.opensInNewTab', 'Opens in a new tab');\n\n const handleClick: AnchorHTMLAttributes<HTMLAnchorElement>['onClick'] = (\n event,\n ) => {\n if (disabled) {\n event.preventDefault();\n return;\n }\n onClick?.(event);\n };\n\n const showExternalIcon = external && externalIcon;\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={disabled ? undefined : href}\n role={disabled ? 'link' : undefined}\n aria-disabled={disabled || undefined}\n target={effectiveTarget}\n rel={effectiveRel || undefined}\n onClick={handleClick}\n data-component=\"link\"\n data-intent={intent ?? 'default'}\n className={linkVariants({ intent, weight, className })}\n {...rest}\n >\n {startIcon ? (\n <span\n aria-hidden=\"true\"\n className={iconSlotVariants({ edge: 'start' })}\n >\n <span className={iconBoxVariants({ edge: 'start' })}>\n {startIcon}\n </span>\n </span>\n ) : null}\n {children}\n {showExternalIcon || (!external && 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 ) : external ? (\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":["linkVariants","cva","iconSlotVariants","iconBoxVariants","Link","forwardRef","href","external","externalIcon","disabled","startIcon","endIcon","_hasIcon","intent","weight","className","children","target","rel","onClick","rest","ref","t","useTranslation","effectiveTarget","effectiveRel","externalLabel","handleClick","event","showExternalIcon","jsxs","jsx","ExternalLink"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"operator-hero-6aAIQaFZ.js","sources":["../../src/components/operator-hero/operator-hero.agent.ts","../../src/components/operator-hero/operator-hero.tsx"],"sourcesContent":["import type { AgentAdapter } from '../../agent/types';\nimport type { OperatorHeroHandle } from './operator-hero';\n\nexport const operatorHeroAgent: AgentAdapter<OperatorHeroHandle> = {\n id: 'operator-hero',\n // Purely observable hero region — no interactive affordances and no\n // imperative actions on the handle (getName / getHasColor are read-only\n // projections). The previous `view_change` capability had no backing\n // action and is removed.\n capabilities: [],\n state: {\n name: {\n type: 'string',\n descriptionKey: 'ui.agent.operatorHero.state.name',\n description: 'Operator display name currently rendered.',\n read: (handle) => handle.getName(),\n },\n hasColor: {\n type: 'boolean',\n descriptionKey: 'ui.agent.operatorHero.state.hasColor',\n description:\n 'Whether a calendar-colour identity dot is rendered. Structural flag only — never the colour id or any PHI.',\n read: (handle) => handle.getHasColor(),\n },\n },\n actions: {},\n domHooks: {\n root: {\n attr: 'data-component',\n value: 'operator-hero',\n description: 'Marks the OperatorHero root region.',\n },\n instanceId: {\n attr: 'data-component-id',\n sourceProp: 'id',\n description: 'Sourced from the id prop.',\n },\n },\n};\n","import {\n forwardRef,\n useId,\n useRef,\n type ComponentPropsWithoutRef,\n type ReactNode,\n} from 'react';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { useTranslation } from 'react-i18next';\nimport { Avatar } from '../avatar/avatar';\nimport { Badge } from '../badge/badge';\nimport { Card } from '../card/card';\nimport { Rating } from '../rating/rating';\nimport { formatRating } from '../_shared/format-number';\nimport { colorIdToToken } from '../_shared/entity-card';\nimport { useIsomorphicLayoutEffect } from '../../hooks/use-isomorphic-layout-effect';\nimport { useAgentRegistration } from '../../agent/registry';\nimport { operatorHeroAgent } from './operator-hero.agent';\n\n/* -------------------------------------------------------------------- */\n/* OperatorHero */\n/* */\n/* The operator-page counterpart to the consumer-side `<PracticeHero>` */\n/* / `<PracticeProfileHero>` pattern. Differences from the practice */\n/* hero (per the spec): */\n/* */\n/* - Avatar instead of a full hero image background */\n/* - Ratings + reviews summary rendered inline */\n/* - Slightly shorter vertically — no cover strip, denser padding */\n/* */\n/* Use case: individual operator profile page (`/dentista/<slug>/ */\n/* operatori/<name>`), pair with `<ContactProfileCard>` below to fill */\n/* in the operator's contact + profession info. */\n/* -------------------------------------------------------------------- */\n\n/* -------------------------------------------------------------------- */\n/* CVA */\n/* -------------------------------------------------------------------- */\n\nconst rootVariants = cva('ds:w-full ds:text-[color:var(--foreground)]', {\n variants: {\n // Density toggle. Default `comfortable` matches the practice hero's\n // visual weight minus the cover strip. `compact` is for embedded\n // surfaces (booking aside, ROI Dashboard practice panel) where the\n // hero needs to fit in <12rem vertical.\n density: {\n comfortable: '',\n compact: '',\n },\n // Matches the kit's other `surface` props (Booking, ReviewsPanel,\n // ContactProfileCard). `'elevated'` wraps in `<Card>`.\n surface: {\n flat: '',\n elevated: '',\n },\n },\n defaultVariants: {\n density: 'comfortable',\n surface: 'elevated',\n },\n});\n\n/* -------------------------------------------------------------------- */\n/* Public types */\n/* -------------------------------------------------------------------- */\n\nexport interface OperatorHeroBadge {\n /** Display key — i18n is up to the consumer. */\n key: string;\n /** Display label. */\n label: string;\n /** Badge variant — falls back to `neutral`. */\n variant?: 'neutral' | 'info' | 'success' | 'warning' | 'error';\n}\n\nexport interface OperatorHeroRating {\n /** Mean rating, 0–5. */\n value: number;\n /** Total number of reviews. */\n count: number;\n}\n\nexport interface OperatorHeroHandle {\n getName: () => string;\n /** Structural flag — whether a calendar-colour dot is rendered. No PHI. */\n getHasColor: () => boolean;\n}\n\nexport interface OperatorHeroProps extends Omit<\n ComponentPropsWithoutRef<'div'>,\n 'aria-label' | 'children'\n> {\n /** Operator's display name. Rendered as the H1 heading. */\n name: string;\n /**\n * Optional calendar-colour identity for the operator. AlfaDocs assigns each\n * operator a numeric colour id; when present, a small colour dot is rendered\n * next to the name, tinted via `colorIdToToken(colorId)` (a `var(--…)` palette\n * token — never a literal). The id itself is a structural identifier, not PHI.\n */\n colorId?: string;\n /** Specialty / tagline subtitle (e.g. \"Dermatologa · 12 anni di esperienza\"). */\n tagline?: string;\n /**\n * Optional photo / avatar URL. The kit always renders an `<Avatar>` —\n * when `imageUrl` is missing the avatar falls back to initials.\n */\n imageUrl?: string;\n /** Rating summary — when present, renders a Rating + numeric breakdown line. */\n rating?: OperatorHeroRating;\n /**\n * Optional badge row beneath the rating. Use sparingly — 1–3 chips\n * suit the hero's density; longer lists belong in `<ContactProfileCard>`.\n */\n badges?: OperatorHeroBadge[];\n\n /* ----- Slots ----- */\n\n /**\n * Rendered at the inline-end of the heading row (right side on LTR).\n * Use for a \"Book with this operator\" `<Button>` or a \"Back to\n * practice\" link.\n */\n actionSlot?: ReactNode;\n\n /* ----- Styling ----- */\n\n /**\n * `comfortable` (default) — matches the practice hero's visual\n * weight minus the cover strip. `compact` halves the vertical\n * padding for embedded surfaces.\n */\n density?: 'comfortable' | 'compact';\n /**\n * `elevated` (default) wraps in `<Card variant=\"elevated\">`. `flat`\n * drops the Card — use inside another card / sheet.\n */\n surface?: 'flat' | 'elevated';\n\n /* ----- a11y ----- */\n\n 'aria-label'?: string;\n id?: string;\n}\n\n/* -------------------------------------------------------------------- */\n/* Component */\n/* -------------------------------------------------------------------- */\n\nexport const OperatorHero = forwardRef<HTMLDivElement, OperatorHeroProps>(\n (\n {\n name,\n colorId,\n tagline,\n imageUrl,\n rating,\n badges,\n actionSlot,\n density = 'comfortable',\n surface = 'elevated',\n 'aria-label': ariaLabel,\n id,\n className,\n ...rest\n },\n ref,\n ) => {\n const { t, i18n } = useTranslation('ui');\n const headingId = useId();\n const resolvedAriaLabel = ariaLabel ?? t('operatorHero.regionLabel');\n\n // Calendar-colour dot. Tint via a component-scoped CSS custom property set\n // imperatively on a ref — mirrors the Avatar `--avatar-color-override`\n // idiom so no `style={{…}}` attribute lands on the JSX (constraint §4).\n const hasColor = colorId !== undefined && colorId !== null;\n const dotRef = useRef<HTMLSpanElement>(null);\n\n useAgentRegistration(\n operatorHeroAgent,\n { getName: () => name, getHasColor: () => hasColor },\n id,\n );\n useIsomorphicLayoutEffect(() => {\n const el = dotRef.current;\n if (!el) return;\n if (hasColor) {\n el.style.setProperty('--operator-hero-color', colorIdToToken(colorId));\n } else {\n el.style.removeProperty('--operator-hero-color');\n }\n }, [hasColor, colorId]);\n\n // Same figure as the practice hero's Rating (\"4,9\" in Italian, \"5\"\n // for a whole score), so the visible line, this label and the\n // inner Rating's label all agree.\n const ratingValue = rating\n ? formatRating(rating.value, i18n.language)\n : undefined;\n const ratingLabel = rating\n ? t('operatorHero.ratingLabel', {\n value: ratingValue,\n count: rating.count,\n })\n : undefined;\n\n // Padding scales with density. Comfortable matches the practice\n // hero's `pt-xl pb-md` minus the cover strip; compact halves it.\n const bodyPaddingClass =\n density === 'comfortable'\n ? 'ds:pt-[var(--spacing-md)] ds:pb-[var(--spacing-md)]'\n : 'ds:pt-[var(--spacing-sm)] ds:pb-[var(--spacing-sm)]';\n\n // Avatar size keys off density: its height. Comfortable = 2xl\n // (128px) to read as the page hero, compact = xl (64px) for embedded\n // use. The 3:4 photo is three quarters as wide.\n const avatarSize = density === 'comfortable' ? '2xl' : 'xl';\n\n // Heading scale tracks density too. Comfortable uses the kit's\n // page-title token; compact drops to title-card so the operator\n // name doesn't dominate an embedded surface.\n const headingClass =\n density === 'comfortable' ? 'type-title-page' : 'type-title-card';\n\n const inner = (\n <div\n className={[\n 'ds:flex ds:items-start ds:gap-[var(--spacing-lg)]',\n bodyPaddingClass,\n 'ds:ps-[var(--spacing-md)] ds:pe-[var(--spacing-md)]',\n ].join(' ')}\n >\n {/* HTP-6712: the professional's photo is a 3:4 rounded rectangle,\n cropped towards the top so the face stays in. Same height as\n the old circle (128px, compact 64px). */}\n <Avatar\n size={avatarSize}\n shape=\"rounded\"\n ratio=\"3:4\"\n name={name}\n src={imageUrl}\n className=\"ds:shrink-0\"\n />\n <div className=\"ds:flex ds:min-w-0 ds:flex-1 ds:flex-col ds:gap-[var(--spacing-xs)]\">\n <div className=\"ds:flex ds:items-start ds:gap-[var(--spacing-md)] ds:flex-wrap\">\n <h1\n id={headingId}\n className={`${headingClass} ds:m-0 ds:flex ds:items-center ds:gap-[var(--spacing-xs)] ds:text-[color:var(--foreground)]`}\n >\n {hasColor ? (\n <span\n ref={dotRef}\n role=\"img\"\n aria-label={t('operatorHero.colorLabel', 'Calendar colour')}\n className=\"ds:inline-block ds:size-[var(--spacing-sm)] ds:shrink-0 ds:rounded-[var(--radius-full)] ds:bg-[var(--operator-hero-color)]\"\n />\n ) : null}\n {/* Practice-written name and tagline keep the direction they\n were typed in. The name gets its own span: `dir` on the\n flex h1 would move the colour dot too. */}\n <span dir=\"auto\">{name}</span>\n </h1>\n {actionSlot ? (\n <div className=\"ds:ms-auto ds:flex ds:shrink-0 ds:items-center ds:gap-[var(--spacing-xs)]\">\n {actionSlot}\n </div>\n ) : null}\n </div>\n {tagline ? (\n <p\n dir=\"auto\"\n className=\"type-body ds:m-0 ds:text-[color:var(--foreground)]\"\n >\n {tagline}\n </p>\n ) : null}\n {rating ? (\n // One image with one name (\"4,9 out of 5 stars. Reviews: 7.\"):\n // a name on a div without a role is ignored by screen readers,\n // which then read the stars and \"4,9 · 7\" with no \"reviews\".\n <div\n role=\"img\"\n className=\"ds:flex ds:items-center ds:gap-[var(--spacing-xs)]\"\n aria-label={ratingLabel}\n >\n {/* Decorative: the group above carries the one name. */}\n <Rating\n value={rating.value}\n max={5}\n size={density === 'comfortable' ? 'md' : 'sm'}\n decorative\n />\n <span className=\"type-body-sm ds:text-[color:var(--muted-foreground)]\">\n {ratingValue} · {rating.count}\n </span>\n </div>\n ) : null}\n {badges && badges.length > 0 ? (\n <div\n role=\"list\"\n className=\"ds:flex ds:flex-wrap ds:items-center ds:gap-[var(--spacing-2xs)] ds:mt-[var(--spacing-2xs)]\"\n >\n {badges.map((badge) => (\n <Badge\n key={badge.key}\n variant={badge.variant ?? 'neutral'}\n role=\"listitem\"\n >\n {badge.label}\n </Badge>\n ))}\n </div>\n ) : null}\n </div>\n </div>\n );\n\n return (\n <div\n ref={ref}\n role=\"region\"\n aria-label={resolvedAriaLabel}\n aria-labelledby={headingId}\n data-component=\"operator-hero\"\n data-component-id={id}\n data-density={density}\n id={id}\n className={rootVariants({ surface, density, className })}\n {...rest}\n >\n {surface === 'elevated' ? (\n <Card variant=\"elevated\">{inner}</Card>\n ) : (\n inner\n )}\n </div>\n );\n },\n);\n\nOperatorHero.displayName = 'OperatorHero';\n\nexport type OperatorHeroDensity = NonNullable<\n VariantProps<typeof rootVariants>['density']\n>;\n"],"names":["operatorHeroAgent","handle","rootVariants","cva","OperatorHero","forwardRef","name","colorId","tagline","imageUrl","rating","badges","actionSlot","density","surface","ariaLabel","id","className","rest","ref","t","i18n","useTranslation","headingId","useId","resolvedAriaLabel","hasColor","dotRef","useRef","useAgentRegistration","useIsomorphicLayoutEffect","el","colorIdToToken","ratingValue","formatRating","ratingLabel","bodyPaddingClass","avatarSize","headingClass","inner","jsxs","jsx","Avatar","Rating","badge","Badge","Card"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"practice-profile-hero-qfrsFQI_.js","sources":["../../src/components/practice-profile-hero/practice-profile-hero.agent.ts","../../src/components/practice-profile-hero/practice-profile-hero.tsx"],"sourcesContent":["import type { AgentAdapter } from '../../agent/types';\nimport type { PracticeProfileHeroHandle } from './practice-profile-hero';\n\nexport const practiceProfileHeroAgent: AgentAdapter<PracticeProfileHeroHandle> =\n {\n id: 'practice-profile-hero',\n // Purely observable hero region — no interactive affordances and no\n // imperative actions on the handle (getName / getHasCover are read-only\n // projections).\n capabilities: [],\n state: {\n name: {\n type: 'string',\n descriptionKey: 'ui.agent.practiceProfileHero.state.name',\n description: 'Practice display name currently rendered.',\n read: (handle) => handle.getName(),\n },\n hasCover: {\n type: 'boolean',\n descriptionKey: 'ui.agent.practiceProfileHero.state.hasCover',\n description:\n 'Whether a cover-image strip is rendered. Structural flag only — never the image URL or any PHI.',\n read: (handle) => handle.getHasCover(),\n },\n },\n actions: {},\n domHooks: {\n root: {\n attr: 'data-component',\n value: 'practice-profile-hero',\n description: 'Marks the PracticeProfileHero root region.',\n },\n instanceId: {\n attr: 'data-component-id',\n sourceProp: 'id',\n description: 'Sourced from the id prop.',\n },\n },\n };\n","import {\n forwardRef,\n useEffect,\n useId,\n useMemo,\n useRef,\n useState,\n type ComponentPropsWithoutRef,\n type ReactNode,\n} from 'react';\nimport { cva } from 'class-variance-authority';\nimport { Avatar } from '../avatar/avatar';\nimport { Badge } from '../badge/badge';\nimport { Card } from '../card/card';\nimport { Rating } from '../rating/rating';\nimport { useIsomorphicLayoutEffect } from '../../hooks/use-isomorphic-layout-effect';\nimport { useAgentRegistration } from '../../agent/registry';\nimport { practiceProfileHeroAgent } from './practice-profile-hero.agent';\n\n/* -------------------------------------------------------------------- */\n/* PracticeProfileHero */\n/* */\n/* The practice-page counterpart to `<OperatorHero>` — the top-of-page */\n/* hero for a practice profile (booking site `/p/<seoUrl>`, marketplace */\n/* practice views). Differences from the operator hero: */\n/* */\n/* - Optional cover strip: renders ONLY when `coverImageUrl` is set. */\n/* A practice without a configured cover image gets no strip at all */\n/* — never an empty brand-gradient band eating page space. */\n/* - Larger avatar at desktop widths (3xl), stepped down to xl and */\n/* stacked above the text on small viewports so the practice name, */\n/* tagline and rating keep the full line width on phones. */\n/* -------------------------------------------------------------------- */\n\n/* -------------------------------------------------------------------- */\n/* CVA */\n/* -------------------------------------------------------------------- */\n\nconst rootVariants = cva('ds:w-full ds:text-[color:var(--foreground)]', {\n variants: {\n // Matches the kit's other `surface` props (Booking, ReviewsPanel,\n // OperatorHero). `'elevated'` wraps in `<Card>`.\n surface: {\n flat: '',\n elevated: '',\n },\n },\n defaultVariants: {\n surface: 'elevated',\n },\n});\n\n/* -------------------------------------------------------------------- */\n/* Public types */\n/* -------------------------------------------------------------------- */\n\nexport interface PracticeProfileHeroBadge {\n /** Display key — i18n is up to the consumer. */\n key: string;\n /** Display label. */\n label: string;\n /** Badge variant — falls back to `neutral`. */\n variant?: 'neutral' | 'info' | 'success' | 'warning' | 'error';\n}\n\nexport interface PracticeProfileHeroRating {\n /** Mean rating, 0–5. */\n value: number;\n /** Total number of reviews. */\n count: number;\n}\n\nexport interface PracticeProfileHeroHandle {\n getName: () => string;\n /** Structural flag — whether a cover strip is rendered. No PHI. */\n getHasCover: () => boolean;\n}\n\nexport interface PracticeProfileHeroProps extends Omit<\n ComponentPropsWithoutRef<'div'>,\n 'aria-label' | 'children'\n> {\n /** Practice display name. Rendered as the H1 heading. */\n name: string;\n /** Slogan / tagline subtitle (e.g. \"15 anni di esperienza nel cuore di Brera\"). */\n tagline?: string;\n /**\n * Optional practice photo / logo URL. The kit always renders an\n * `<Avatar>` — when `imageUrl` is missing the avatar falls back to\n * initials.\n */\n imageUrl?: string;\n /**\n * Optional cover image painted as a full-width strip above the body.\n * The strip renders ONLY when this is set — a practice without a cover\n * image gets no strip (and no empty gradient band). While the image\n * loads, the brand gradient shows in the strip. If it fails to load\n * (404, 401, not an image), the strip goes, as if no cover had been\n * passed, and `data-has-cover` reads `\"false\"`. A different URL tries\n * again.\n */\n coverImageUrl?: string;\n /** Rating summary — when present, renders a Rating + numeric breakdown line. */\n rating?: PracticeProfileHeroRating;\n /**\n * Optional badge row beneath the rating. Use sparingly — 1–3 chips\n * suit the hero's density; longer lists belong in `<ContactProfileCard>`.\n */\n badges?: PracticeProfileHeroBadge[];\n\n /* ----- Slots ----- */\n\n /**\n * Rendered at the inline-end of the heading row (right side on LTR)\n * from `sm` up. The heading row wraps, so on a phone the action drops\n * onto its own line, starts flush with the practice name, and is free\n * to shrink into the column rather than overflow it.\n *\n * Use for a \"Book an appointment\" `<Button>` or a share action.\n */\n actionSlot?: ReactNode;\n\n /* ----- Styling ----- */\n\n /**\n * `elevated` (default) wraps in `<Card variant=\"elevated\">`. `flat`\n * drops the Card — use inside another card / sheet.\n */\n surface?: 'flat' | 'elevated';\n\n /* ----- a11y ----- */\n\n 'aria-label'?: string;\n id?: string;\n}\n\n/* -------------------------------------------------------------------- */\n/* Component */\n/* -------------------------------------------------------------------- */\n\nexport const PracticeProfileHero = forwardRef<\n HTMLDivElement,\n PracticeProfileHeroProps\n>(\n (\n {\n name,\n tagline,\n imageUrl,\n coverImageUrl,\n rating,\n badges,\n actionSlot,\n surface = 'elevated',\n 'aria-label': ariaLabel,\n id,\n className,\n ...rest\n },\n ref,\n ) => {\n const headingId = useId();\n\n // HTP-6708. A CSS background cannot report a failed load, so the URL\n // is probed with an Image (the browser serves both from one request).\n // The strip reserves its height while the image loads, with the brand\n // gradient showing: a cover that loads causes no layout shift, and one\n // that fails removes the strip in a single step. The outcome is kept\n // per URL, so a new URL starts loading again and is retried.\n const [coverOutcome, setCoverOutcome] = useState<{\n url: string;\n status: 'loaded' | 'error';\n } | null>(null);\n const coverStatus =\n coverImageUrl && coverOutcome?.url === coverImageUrl\n ? coverOutcome.status\n : 'loading';\n useEffect(() => {\n if (!coverImageUrl || typeof Image === 'undefined') return undefined;\n let current = true;\n const probe = new Image();\n probe.onload = () => {\n if (current) setCoverOutcome({ url: coverImageUrl, status: 'loaded' });\n };\n probe.onerror = () => {\n if (current) setCoverOutcome({ url: coverImageUrl, status: 'error' });\n };\n probe.src = coverImageUrl;\n return () => {\n current = false;\n probe.onload = null;\n probe.onerror = null;\n };\n }, [coverImageUrl]);\n const hasCover = Boolean(coverImageUrl) && coverStatus !== 'error';\n\n // Memoised so the registry doesn't see a fresh handle identity (and\n // fire unregister+register) on every render — mirrors Booking.\n const agentHandle = useMemo(\n () => ({ getName: () => name, getHasCover: () => hasCover }),\n [name, hasCover],\n );\n useAgentRegistration(practiceProfileHeroAgent, agentHandle, id);\n\n // Cover image URL lands as a component-scoped CSS custom property set\n // imperatively on a ref — mirrors the Avatar `--avatar-color-override`\n // idiom so no `style={{…}}` attribute lands on the JSX (constraint §4).\n const coverRef = useRef<HTMLDivElement>(null);\n useIsomorphicLayoutEffect(() => {\n const el = coverRef.current;\n if (!el) return;\n if (coverImageUrl) {\n el.style.setProperty(\n '--practice-profile-hero-cover',\n `url(\"${coverImageUrl.replace(/\\\\/g, '\\\\\\\\').replace(/\"/g, '\\\\\"')}\")`,\n );\n } else {\n el.style.removeProperty('--practice-profile-hero-cover');\n }\n // `hasCover`: the strip can come back (a new URL after a failure),\n // and the new element needs the property too.\n }, [coverImageUrl, hasCover]);\n\n const cover = hasCover ? (\n <div\n ref={coverRef}\n aria-hidden=\"true\"\n data-slot=\"cover\"\n data-state={coverStatus}\n className={[\n 'ds:h-32 ds:sm:h-40 ds:w-full',\n // Cover image layered over the brand gradient — the gradient is\n // the visible underlay while the image streams in. A failed image\n // removes the strip (see above). The `none` fallback keeps the\n // declaration valid before the layout effect sets the custom\n // property (SSR / first paint).\n 'ds:bg-[image:var(--practice-profile-hero-cover,none),var(--gradient-hero-brand)]',\n 'ds:bg-cover ds:bg-center',\n ].join(' ')}\n />\n ) : null;\n\n const body = (\n <div\n className={[\n // Phones: stacked column, smaller avatar — the practice name,\n // tagline and rating keep the full line width instead of being\n // squeezed beside a 3xl avatar. sm+: classic row layout.\n 'ds:flex ds:flex-col ds:items-start ds:gap-[var(--spacing-md)]',\n 'ds:sm:flex-row ds:sm:gap-[var(--spacing-lg)]',\n ].join(' ')}\n >\n {/* Responsive avatar — `ds:hidden` removes the inactive size from\n both the layout and the accessibility tree. Both renders are\n aria-hidden: the H1 right beside them already carries the\n practice name, so the avatar is decorative here. */}\n {/* HTP-6712: the practice photo is a 4:3 rounded rectangle, filled\n and cropped from the centre. It keeps the old circle's height\n (64px on phones, 192px from sm), so the hero does not grow. */}\n <div className=\"ds:shrink-0 ds:sm:hidden\">\n <Avatar\n size=\"xl\"\n shape=\"rounded\"\n ratio=\"4:3\"\n name={name}\n src={imageUrl}\n aria-hidden=\"true\"\n />\n </div>\n <div className=\"ds:hidden ds:shrink-0 ds:sm:block\">\n <Avatar\n size=\"3xl\"\n shape=\"rounded\"\n ratio=\"4:3\"\n name={name}\n src={imageUrl}\n aria-hidden=\"true\"\n />\n </div>\n <div className=\"ds:flex ds:w-full ds:min-w-0 ds:flex-1 ds:flex-col ds:gap-[var(--spacing-xs)]\">\n <div className=\"ds:flex ds:flex-wrap ds:items-start ds:gap-[var(--spacing-md)]\">\n {/* The practice's own words (name, tagline) keep the direction\n they were typed in, not the page's: `dir=\"auto\"`. */}\n <h1\n id={headingId}\n dir=\"auto\"\n className=\"type-title-page ds:m-0 ds:text-[color:var(--foreground)]\"\n >\n {name}\n </h1>\n {actionSlot ? (\n // `ms-auto` + `shrink-0` are the desktop contract, and both are\n // wrong once the row wraps on a phone: they stranded the action\n // at the inline-end of a start-aligned stack and stopped a wide\n // control fitting the column. Hence `sm:` and up only.\n <div className=\"ds:flex ds:min-w-0 ds:items-center ds:gap-[var(--spacing-xs)] ds:sm:ms-auto ds:sm:shrink-0\">\n {actionSlot}\n </div>\n ) : null}\n </div>\n {tagline ? (\n <p\n dir=\"auto\"\n className=\"type-body ds:m-0 ds:text-[color:var(--foreground)]\"\n >\n {tagline}\n </p>\n ) : null}\n {rating ? (\n // Rating owns the whole line: locale-formatted value, plural-\n // aware review count, and a single role=\"img\" announcement.\n <Rating\n value={rating.value}\n max={5}\n size=\"md\"\n reviews={{ count: rating.count }}\n />\n ) : null}\n {badges && badges.length > 0 ? (\n <div\n role=\"list\"\n className=\"ds:mt-[var(--spacing-2xs)] ds:flex ds:flex-wrap ds:items-center ds:gap-[var(--spacing-2xs)]\"\n >\n {badges.map((badge) => (\n <Badge\n key={badge.key}\n variant={badge.variant ?? 'neutral'}\n role=\"listitem\"\n >\n {badge.label}\n </Badge>\n ))}\n </div>\n ) : null}\n </div>\n </div>\n );\n\n return (\n <div\n ref={ref}\n role=\"region\"\n // A consumer-supplied aria-label wins; otherwise the region is\n // named by the practice-name H1 via aria-labelledby.\n aria-label={ariaLabel}\n aria-labelledby={ariaLabel ? undefined : headingId}\n data-component=\"practice-profile-hero\"\n data-component-id={id}\n data-has-cover={hasCover ? 'true' : 'false'}\n id={id}\n className={rootVariants({ surface, className })}\n {...rest}\n >\n {surface === 'elevated' ? (\n <Card variant=\"elevated\">\n {cover}\n <Card.Body>{body}</Card.Body>\n </Card>\n ) : (\n <>\n {cover}\n <div className=\"ds:pt-[var(--spacing-md)] ds:pb-[var(--spacing-md)]\">\n {body}\n </div>\n </>\n )}\n </div>\n );\n },\n);\n\nPracticeProfileHero.displayName = 'PracticeProfileHero';\n"],"names":["practiceProfileHeroAgent","handle","rootVariants","cva","PracticeProfileHero","forwardRef","name","tagline","imageUrl","coverImageUrl","rating","badges","actionSlot","surface","ariaLabel","id","className","rest","ref","headingId","useId","coverOutcome","setCoverOutcome","useState","coverStatus","useEffect","current","probe","hasCover","agentHandle","useMemo","useAgentRegistration","coverRef","useRef","useIsomorphicLayoutEffect","el","cover","jsx","body","jsxs","Avatar","Rating","badge","Badge","Card","Fragment"],"mappings":"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"}
|