@alfadocs/ui-kit-debug 0.41.2 → 0.42.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/address-autocomplete-CSjMrBvu.js +358 -0
- package/dist/_chunks/address-autocomplete-CSjMrBvu.js.map +1 -0
- package/dist/_chunks/{alia-sidebar-DXsYPinm.js → alia-sidebar-BpX4z_af.js} +2 -2
- package/dist/_chunks/{alia-sidebar-DXsYPinm.js.map → alia-sidebar-BpX4z_af.js.map} +1 -1
- package/dist/_chunks/{bmi-calculator-DnEr513I.js → bmi-calculator-D4juUcyF.js} +57 -51
- package/dist/_chunks/bmi-calculator-D4juUcyF.js.map +1 -0
- package/dist/_chunks/{breadcrumb-CLlhx7qo.js → breadcrumb-OTbaY70e.js} +4 -4
- package/dist/_chunks/{breadcrumb-CLlhx7qo.js.map → breadcrumb-OTbaY70e.js.map} +1 -1
- package/dist/_chunks/cycle-calculator-DsZbyzX6.js +191 -0
- package/dist/_chunks/cycle-calculator-DsZbyzX6.js.map +1 -0
- package/dist/_chunks/{document-scanner-CqS_klIr.js → document-scanner-BqLsGs4Y.js} +7 -7
- package/dist/_chunks/{document-scanner-CqS_klIr.js.map → document-scanner-BqLsGs4Y.js.map} +1 -1
- package/dist/_chunks/{dropdown-menu-BC5ZdOMo.js → dropdown-menu-CUEXqKis.js} +2 -2
- package/dist/_chunks/{dropdown-menu-BC5ZdOMo.js.map → dropdown-menu-CUEXqKis.js.map} +1 -1
- package/dist/_chunks/{due-date-calculator-CUspKSTw.js → due-date-calculator-s_CBgaFs.js} +53 -40
- package/dist/_chunks/due-date-calculator-s_CBgaFs.js.map +1 -0
- package/dist/_chunks/{editable-currency-cell-renderer-DgkCIIcO.js → editable-currency-cell-renderer-BhUkRiPZ.js} +2 -2
- package/dist/_chunks/{editable-currency-cell-renderer-DgkCIIcO.js.map → editable-currency-cell-renderer-BhUkRiPZ.js.map} +1 -1
- package/dist/_chunks/{freemium-paywall-BAk3a6er.js → freemium-paywall-BLXESpH4.js} +2 -2
- package/dist/_chunks/{freemium-paywall-BAk3a6er.js.map → freemium-paywall-BLXESpH4.js.map} +1 -1
- package/dist/_chunks/{gestational-age-calculator-CsQ05qDy.js → gestational-age-calculator-CWOG3bkI.js} +56 -43
- package/dist/_chunks/gestational-age-calculator-CWOG3bkI.js.map +1 -0
- package/dist/_chunks/{header-settings-CBLwUK6t.js → header-settings-Bx0Biimh.js} +2 -2
- package/dist/_chunks/{header-settings-CBLwUK6t.js.map → header-settings-Bx0Biimh.js.map} +1 -1
- package/dist/_chunks/index.modern-D2LGACWg.js +1529 -0
- package/dist/_chunks/index.modern-D2LGACWg.js.map +1 -0
- package/dist/_chunks/insert-result-DtQQeSSf.js +227 -0
- package/dist/_chunks/insert-result-DtQQeSSf.js.map +1 -0
- package/dist/_chunks/{kbd-Cglkd7CY.js → kbd-D855ZXIW.js} +2 -2
- package/dist/_chunks/{kbd-Cglkd7CY.js.map → kbd-D855ZXIW.js.map} +1 -1
- package/dist/_chunks/map-view-Tb5VfK9Y.js +333 -0
- package/dist/_chunks/map-view-Tb5VfK9Y.js.map +1 -0
- package/dist/_chunks/marketplace-app-shell-kVAVycz_.js +391 -0
- package/dist/_chunks/marketplace-app-shell-kVAVycz_.js.map +1 -0
- package/dist/_chunks/{patient-search-CBq62kmL.js → patient-search-DPe2ZYEL.js} +2 -2
- package/dist/_chunks/{patient-search-CBq62kmL.js.map → patient-search-DPe2ZYEL.js.map} +1 -1
- package/dist/_chunks/{patient-shell-DF81lALv.js → patient-shell-lDX3wwu6.js} +2 -2
- package/dist/_chunks/{patient-shell-DF81lALv.js.map → patient-shell-lDX3wwu6.js.map} +1 -1
- package/dist/_chunks/{payment-form-Dy3WIIsC.js → payment-form-BzVsG6Ks.js} +5 -5
- package/dist/_chunks/{payment-form-Dy3WIIsC.js.map → payment-form-BzVsG6Ks.js.map} +1 -1
- package/dist/_chunks/{pdf-viewer-Cy6Ul3hZ.js → pdf-viewer-B6MC6VTx.js} +139 -126
- package/dist/_chunks/pdf-viewer-B6MC6VTx.js.map +1 -0
- package/dist/_chunks/{practice-results-C0d4IL5E.js → practice-results-CrLpEiiW.js} +4 -4
- package/dist/_chunks/{practice-results-C0d4IL5E.js.map → practice-results-CrLpEiiW.js.map} +1 -1
- package/dist/_chunks/pregnancy-weight-gain-B7kBK-ZR.js +223 -0
- package/dist/_chunks/pregnancy-weight-gain-B7kBK-ZR.js.map +1 -0
- package/dist/_chunks/{public-header.agent-B2dDg2_d.js → public-header.agent-BY6FH71R.js} +2 -2
- package/dist/_chunks/{public-header.agent-B2dDg2_d.js.map → public-header.agent-BY6FH71R.js.map} +1 -1
- package/dist/_chunks/radio-group-CLjK-SlK.js +167 -0
- package/dist/_chunks/radio-group-CLjK-SlK.js.map +1 -0
- package/dist/_chunks/{rich-text-editor-DLbg2852.js → rich-text-editor-DhGIBd4a.js} +10 -10
- package/dist/_chunks/{rich-text-editor-DLbg2852.js.map → rich-text-editor-DhGIBd4a.js.map} +1 -1
- package/dist/_chunks/{sheet-BV-yuLE2.js → sheet-xbzu4YiY.js} +7 -7
- package/dist/_chunks/{sheet-BV-yuLE2.js.map → sheet-xbzu4YiY.js.map} +1 -1
- package/dist/_chunks/{sign-document-CpLDZ6Db.js → sign-document-QHfcNKFj.js} +5 -5
- package/dist/_chunks/{sign-document-CpLDZ6Db.js.map → sign-document-QHfcNKFj.js.map} +1 -1
- package/dist/_chunks/{signature-capture-DoiBd6i3.js → signature-capture-CpMBhqQ9.js} +6 -6
- package/dist/_chunks/{signature-capture-DoiBd6i3.js.map → signature-capture-CpMBhqQ9.js.map} +1 -1
- package/dist/_chunks/tab-bar-C4II-7ej.js +86 -0
- package/dist/_chunks/tab-bar-C4II-7ej.js.map +1 -0
- package/dist/_chunks/{theme-toggle-DpC28kt5.js → theme-toggle-ClATnY4Q.js} +2 -2
- package/dist/_chunks/{theme-toggle-DpC28kt5.js.map → theme-toggle-ClATnY4Q.js.map} +1 -1
- package/dist/_chunks/{toast.agent-WHHfw5VX.js → toast.agent-B0MCsvdZ.js} +2 -2
- package/dist/_chunks/{toast.agent-WHHfw5VX.js.map → toast.agent-B0MCsvdZ.js.map} +1 -1
- package/dist/_chunks/{unit-converter-EUwO6QYq.js → unit-converter-D1UrEUxa.js} +46 -40
- package/dist/_chunks/unit-converter-D1UrEUxa.js.map +1 -0
- package/dist/_chunks/{workflow-map-C3gB0FvB.js → workflow-map-BFNpzTiw.js} +2 -2
- package/dist/_chunks/{workflow-map-C3gB0FvB.js.map → workflow-map-BFNpzTiw.js.map} +1 -1
- package/dist/agent-catalog.json +1 -1
- package/dist/brand/product-lockup/product-lockup.d.ts +16 -0
- package/dist/brand/product-lockup/product-lockup.d.ts.map +1 -1
- package/dist/components/_shared/insert-result.d.ts +21 -4
- package/dist/components/_shared/insert-result.d.ts.map +1 -1
- package/dist/components/address-autocomplete/address-autocomplete.d.ts +77 -0
- package/dist/components/address-autocomplete/address-autocomplete.d.ts.map +1 -0
- package/dist/components/address-autocomplete/index.d.ts +4 -0
- package/dist/components/address-autocomplete/index.d.ts.map +1 -0
- package/dist/components/address-autocomplete/index.js +6 -0
- package/dist/components/address-autocomplete/index.js.map +1 -0
- package/dist/components/address-autocomplete/parse-address.d.ts +52 -0
- package/dist/components/address-autocomplete/parse-address.d.ts.map +1 -0
- package/dist/components/bmi-calculator/bmi-calculator.d.ts +11 -1
- package/dist/components/bmi-calculator/bmi-calculator.d.ts.map +1 -1
- package/dist/components/bmi-calculator/index.js +1 -1
- package/dist/components/breadcrumb/index.js +1 -1
- package/dist/components/cycle-calculator/cycle-calculator.d.ts +12 -2
- package/dist/components/cycle-calculator/cycle-calculator.d.ts.map +1 -1
- package/dist/components/cycle-calculator/index.js +1 -1
- package/dist/components/data-table/index.js +1 -1
- package/dist/components/document-scanner/index.js +1 -1
- package/dist/components/dropdown-menu/index.js +1 -1
- package/dist/components/due-date-calculator/due-date-calculator.d.ts +11 -1
- package/dist/components/due-date-calculator/due-date-calculator.d.ts.map +1 -1
- package/dist/components/due-date-calculator/index.js +1 -1
- package/dist/components/freemium-paywall/index.js +1 -1
- package/dist/components/gestational-age-calculator/gestational-age-calculator.d.ts +12 -2
- package/dist/components/gestational-age-calculator/gestational-age-calculator.d.ts.map +1 -1
- package/dist/components/gestational-age-calculator/index.js +1 -1
- package/dist/components/header-settings/index.js +1 -1
- package/dist/components/index.d.ts +3 -1
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/kbd/index.js +1 -1
- package/dist/components/map-view/index.js +1 -1
- package/dist/components/matrix-rain/matrix-rain.d.ts +1 -1
- package/dist/components/patient-search/index.js +1 -1
- package/dist/components/payment-form/index.js +1 -1
- package/dist/components/pdf-viewer/index.js +1 -1
- package/dist/components/pdf-viewer/pdf-viewer.d.ts.map +1 -1
- package/dist/components/practice-results/index.js +1 -1
- package/dist/components/pregnancy-weight-gain/index.js +1 -1
- package/dist/components/pregnancy-weight-gain/pregnancy-weight-gain.d.ts +12 -2
- package/dist/components/pregnancy-weight-gain/pregnancy-weight-gain.d.ts.map +1 -1
- package/dist/components/public-header/index.js +1 -1
- package/dist/components/radio-group/index.js +1 -1
- package/dist/components/radio-group/radio-group.d.ts.map +1 -1
- package/dist/components/rich-text-editor/index.js +1 -1
- package/dist/components/sheet/index.js +1 -1
- package/dist/components/sheet/sheet.d.ts.map +1 -1
- package/dist/components/sign-document/index.js +1 -1
- package/dist/components/signature-capture/index.js +1 -1
- package/dist/components/tab-bar/index.d.ts +3 -0
- package/dist/components/tab-bar/index.d.ts.map +1 -0
- package/dist/components/tab-bar/index.js +5 -0
- package/dist/components/tab-bar/index.js.map +1 -0
- package/dist/components/tab-bar/tab-bar.d.ts +61 -0
- package/dist/components/tab-bar/tab-bar.d.ts.map +1 -0
- package/dist/components/theme-toggle/index.js +1 -1
- package/dist/components/toast/index.js +1 -1
- package/dist/components/unit-converter/index.js +1 -1
- package/dist/components/unit-converter/unit-converter.d.ts +11 -1
- package/dist/components/unit-converter/unit-converter.d.ts.map +1 -1
- package/dist/components/workflow/index.js +1 -1
- package/dist/i18n/locales/ar.d.ts +17 -0
- package/dist/i18n/locales/ar.d.ts.map +1 -1
- package/dist/i18n/locales/ar.js +18 -1
- package/dist/i18n/locales/ar.js.map +1 -1
- package/dist/i18n/locales/de.d.ts +17 -0
- package/dist/i18n/locales/de.d.ts.map +1 -1
- package/dist/i18n/locales/de.js +18 -1
- package/dist/i18n/locales/de.js.map +1 -1
- package/dist/i18n/locales/el.d.ts +17 -0
- package/dist/i18n/locales/el.d.ts.map +1 -1
- package/dist/i18n/locales/el.js +18 -1
- package/dist/i18n/locales/el.js.map +1 -1
- package/dist/i18n/locales/en.d.ts +17 -0
- package/dist/i18n/locales/en.d.ts.map +1 -1
- package/dist/i18n/locales/en.js +18 -1
- package/dist/i18n/locales/en.js.map +1 -1
- package/dist/i18n/locales/es.d.ts +17 -0
- package/dist/i18n/locales/es.d.ts.map +1 -1
- package/dist/i18n/locales/es.js +18 -1
- package/dist/i18n/locales/es.js.map +1 -1
- package/dist/i18n/locales/fr.d.ts +17 -0
- package/dist/i18n/locales/fr.d.ts.map +1 -1
- package/dist/i18n/locales/fr.js +18 -1
- package/dist/i18n/locales/fr.js.map +1 -1
- package/dist/i18n/locales/hi.d.ts +17 -0
- package/dist/i18n/locales/hi.d.ts.map +1 -1
- package/dist/i18n/locales/hi.js +18 -1
- package/dist/i18n/locales/hi.js.map +1 -1
- package/dist/i18n/locales/it.d.ts +17 -0
- package/dist/i18n/locales/it.d.ts.map +1 -1
- package/dist/i18n/locales/it.js +18 -1
- package/dist/i18n/locales/it.js.map +1 -1
- package/dist/i18n/locales/ja.d.ts +17 -0
- package/dist/i18n/locales/ja.d.ts.map +1 -1
- package/dist/i18n/locales/ja.js +18 -1
- package/dist/i18n/locales/ja.js.map +1 -1
- package/dist/i18n/locales/nl.d.ts +17 -0
- package/dist/i18n/locales/nl.d.ts.map +1 -1
- package/dist/i18n/locales/nl.js +18 -1
- package/dist/i18n/locales/nl.js.map +1 -1
- package/dist/i18n/locales/pl.d.ts +17 -0
- package/dist/i18n/locales/pl.d.ts.map +1 -1
- package/dist/i18n/locales/pl.js +18 -1
- package/dist/i18n/locales/pl.js.map +1 -1
- package/dist/i18n/locales/pt.d.ts +17 -0
- package/dist/i18n/locales/pt.d.ts.map +1 -1
- package/dist/i18n/locales/pt.js +18 -1
- package/dist/i18n/locales/pt.js.map +1 -1
- package/dist/i18n/locales/ro.d.ts +17 -0
- package/dist/i18n/locales/ro.d.ts.map +1 -1
- package/dist/i18n/locales/ro.js +18 -1
- package/dist/i18n/locales/ro.js.map +1 -1
- package/dist/i18n/locales/ru.d.ts +17 -0
- package/dist/i18n/locales/ru.d.ts.map +1 -1
- package/dist/i18n/locales/ru.js +18 -1
- package/dist/i18n/locales/ru.js.map +1 -1
- package/dist/i18n/locales/sq.d.ts +17 -0
- package/dist/i18n/locales/sq.d.ts.map +1 -1
- package/dist/i18n/locales/sq.js +18 -1
- package/dist/i18n/locales/sq.js.map +1 -1
- package/dist/i18n/locales/sv.d.ts +17 -0
- package/dist/i18n/locales/sv.d.ts.map +1 -1
- package/dist/i18n/locales/sv.js +18 -1
- package/dist/i18n/locales/sv.js.map +1 -1
- package/dist/i18n/locales/tr.d.ts +17 -0
- package/dist/i18n/locales/tr.d.ts.map +1 -1
- package/dist/i18n/locales/tr.js +18 -1
- package/dist/i18n/locales/tr.js.map +1 -1
- package/dist/i18n/locales/zh.d.ts +17 -0
- package/dist/i18n/locales/zh.d.ts.map +1 -1
- package/dist/i18n/locales/zh.js +18 -1
- package/dist/i18n/locales/zh.js.map +1 -1
- package/dist/index.js +604 -599
- package/dist/index.js.map +1 -1
- package/dist/locales/ar.json +18 -1
- package/dist/locales/de.json +18 -1
- package/dist/locales/el.json +18 -1
- package/dist/locales/en.json +18 -1
- package/dist/locales/es.json +18 -1
- package/dist/locales/fr.json +18 -1
- package/dist/locales/hi.json +18 -1
- package/dist/locales/it.json +18 -1
- package/dist/locales/ja.json +18 -1
- package/dist/locales/nl.json +18 -1
- package/dist/locales/pl.json +18 -1
- package/dist/locales/pt.json +18 -1
- package/dist/locales/ro.json +18 -1
- package/dist/locales/ru.json +18 -1
- package/dist/locales/sq.json +18 -1
- package/dist/locales/sv.json +18 -1
- package/dist/locales/tr.json +18 -1
- package/dist/locales/zh.json +18 -1
- package/dist/patterns/alia-assistant/index.js +1 -1
- package/dist/patterns/marketplace-app-shell/index.js +1 -1
- package/dist/patterns/marketplace-app-shell/marketplace-app-shell.d.ts +30 -3
- package/dist/patterns/marketplace-app-shell/marketplace-app-shell.d.ts.map +1 -1
- package/dist/patterns/patient-shell/index.js +1 -1
- package/dist/tokens.css +1 -1
- package/package.json +16 -1
- package/dist/_chunks/bmi-calculator-DnEr513I.js.map +0 -1
- package/dist/_chunks/cycle-calculator-B5Uj9QeT.js +0 -185
- package/dist/_chunks/cycle-calculator-B5Uj9QeT.js.map +0 -1
- package/dist/_chunks/due-date-calculator-CUspKSTw.js.map +0 -1
- package/dist/_chunks/gestational-age-calculator-CsQ05qDy.js.map +0 -1
- package/dist/_chunks/insert-result-yJ0QavoN.js +0 -133
- package/dist/_chunks/insert-result-yJ0QavoN.js.map +0 -1
- package/dist/_chunks/map-view-qJLybrmN.js +0 -1850
- package/dist/_chunks/map-view-qJLybrmN.js.map +0 -1
- package/dist/_chunks/marketplace-app-shell-BlxVizU4.js +0 -296
- package/dist/_chunks/marketplace-app-shell-BlxVizU4.js.map +0 -1
- package/dist/_chunks/pdf-viewer-Cy6Ul3hZ.js.map +0 -1
- package/dist/_chunks/pregnancy-weight-gain-BCdi-JSv.js +0 -209
- package/dist/_chunks/pregnancy-weight-gain-BCdi-JSv.js.map +0 -1
- package/dist/_chunks/radio-group-BcF92GEF.js +0 -152
- package/dist/_chunks/radio-group-BcF92GEF.js.map +0 -1
- package/dist/_chunks/unit-converter-EUwO6QYq.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"breadcrumb-CLlhx7qo.js","sources":["../../src/components/breadcrumb/breadcrumb.agent.ts","../../src/components/breadcrumb/breadcrumb.tsx"],"sourcesContent":["/* -------------------------------------------------------------------- */\n/* Agent adapter — Breadcrumb. */\n/* */\n/* Breadcrumb is a navigation trail. Items expose their stable route id */\n/* + href ONLY — labels can contain patient names or other PHI and MUST */\n/* NOT be exposed on `data-*` or in adapter state (see PRS §26 §6.1). */\n/* */\n/* See `src/docs/26-agent-readiness.mdx` for the full contract. */\n/* -------------------------------------------------------------------- */\n\nimport type { AgentAdapter } from '../../agent/types';\nimport type { BreadcrumbHandle } from './breadcrumb';\n\nexport interface BreadcrumbAgentItem {\n id: string;\n href?: string;\n}\n\nexport const breadcrumbAgent: AgentAdapter<BreadcrumbHandle> = {\n id: 'breadcrumb',\n capabilities: ['navigate'],\n state: {\n items: {\n type: 'Array<{ id: string, href?: string }>',\n descriptionKey: 'ui.agent.breadcrumb.state.items',\n description:\n 'Ordered list of crumb ids + hrefs in display order. Labels are intentionally excluded — they may contain PHI.',\n read: (handle) => handle.getItems(),\n },\n },\n actions: {\n navigate_to: {\n safety: 'read',\n argsType: '{ id: string }',\n descriptionKey: 'ui.agent.breadcrumb.actions.navigateTo',\n description:\n 'Activate the crumb with the given id — equivalent to clicking the link.',\n invoke: (handle, args: { id: string }) => {\n handle.navigateTo(args.id);\n },\n },\n },\n domHooks: {\n root: {\n attr: 'data-component',\n value: 'breadcrumb',\n description: 'Marks the Breadcrumb root `<nav>`.',\n },\n instanceId: {\n attr: 'data-component-id',\n sourceProp: 'id',\n description: 'Sourced from the id prop.',\n },\n item: {\n attr: 'data-crumb-id',\n description:\n 'Stable opaque id of a crumb. Labels are NEVER carried in data-* — they may contain PHI.',\n },\n },\n};\n","import {\n Children,\n cloneElement,\n createContext,\n forwardRef,\n isValidElement,\n useContext,\n useImperativeHandle,\n useMemo,\n useRef,\n type AnchorHTMLAttributes,\n type ComponentPropsWithoutRef,\n type ReactElement,\n type ReactNode,\n} from 'react';\nimport * as DropdownMenu from '@radix-ui/react-dropdown-menu';\nimport { Slot } from '@radix-ui/react-slot';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { useTranslation } from 'react-i18next';\nimport { ChevronRight, MoreHorizontal } from 'lucide-react';\nimport { useAgentRegistration } from '../../agent/registry';\nimport { breadcrumbAgent } from './breadcrumb.agent';\n\n/* -------------------------------------------------------------------- */\n/* Context — shares separator variant between siblings */\n/* -------------------------------------------------------------------- */\n\ntype SeparatorVariant = 'chevron' | 'slash';\n\ninterface BreadcrumbContextValue {\n separator: SeparatorVariant;\n}\n\nconst BreadcrumbContext = createContext<BreadcrumbContextValue>({\n separator: 'chevron',\n});\n\n/* -------------------------------------------------------------------- */\n/* Root — <nav aria-label> wrapper + truncation engine */\n/* -------------------------------------------------------------------- */\n\nexport interface BreadcrumbProps extends Omit<\n ComponentPropsWithoutRef<'nav'>,\n 'id'\n> {\n /** Override the default `aria-label` (falls back to translated `ui.navigation.breadcrumb.label`). */\n 'aria-label'?: string;\n /** Separator glyph between items. @default 'chevron' */\n separator?: SeparatorVariant;\n /** Maximum number of visible crumbs before collapsing. @default 4 */\n maxItems?: number;\n /** Items kept visible at the start. @default 1 */\n itemsBeforeCollapse?: number;\n /** Items kept visible at the end. @default 1 */\n itemsAfterCollapse?: number;\n /** If true, disables collapse behaviour. */\n disableCollapse?: boolean;\n /**\n * Consumer-supplied instance id, surfaced as `data-component-id` so an\n * agent / UI bridge can address this instance.\n */\n id?: string;\n}\n\n/**\n * Imperative handle for agent-readiness.\n *\n * Items expose their stable id (`BreadcrumbItem` `id` prop, falling back\n * to the `BreadcrumbLink` href) and href — never their visible label,\n * which may contain PHI (see PRS §26 §6.1).\n */\nexport interface BreadcrumbHandle {\n getItems: () => Array<{ id: string; href?: string }>;\n navigateTo: (id: string) => void;\n}\n\nconst Breadcrumb = forwardRef<HTMLElement, BreadcrumbProps>(\n (\n {\n children,\n className,\n 'aria-label': ariaLabel,\n separator = 'chevron',\n maxItems = 4,\n itemsBeforeCollapse = 1,\n itemsAfterCollapse = 1,\n disableCollapse = false,\n id,\n ...rest\n },\n ref,\n ) => {\n const { t } = useTranslation();\n\n const items = useMemo(() => extractAgentItems(children), [children]);\n\n const handle = useMemo<BreadcrumbHandle>(\n () => ({\n getItems: () => items,\n navigateTo: (targetId: string) => {\n const hit = items.find((i) => i.id === targetId);\n if (!hit?.href) return;\n if (typeof window === 'undefined') return;\n // Same allow-list as the BreadcrumbLink renderer — never honour\n // `javascript:` / `data:` URLs.\n const trimmed = hit.href.trim();\n if (/^\\s*javascript:/i.test(trimmed)) return;\n window.location.assign(trimmed);\n },\n }),\n [items],\n );\n const innerRef = useRef<HTMLElement>(null);\n useImperativeHandle(ref, () => innerRef.current as HTMLElement, []);\n useAgentRegistration(breadcrumbAgent, handle, id);\n\n return (\n <BreadcrumbContext.Provider value={{ separator }}>\n <nav\n ref={innerRef}\n id={id}\n aria-label={ariaLabel ?? t('navigation.breadcrumb.label')}\n data-component=\"breadcrumb\"\n data-component-id={id}\n className={className}\n {...rest}\n >\n <BreadcrumbList\n maxItems={maxItems}\n itemsBeforeCollapse={itemsBeforeCollapse}\n itemsAfterCollapse={itemsAfterCollapse}\n disableCollapse={disableCollapse}\n >\n {children}\n </BreadcrumbList>\n </nav>\n </BreadcrumbContext.Provider>\n );\n },\n);\nBreadcrumb.displayName = 'Breadcrumb';\n\n/**\n * Walks the Breadcrumb children to collect `{ id, href }` for the agent\n * handle. The id is taken from the BreadcrumbItem's `id` prop, falling\n * back to the inner BreadcrumbLink's href (or an index string as a last\n * resort). Labels are never read — they may contain PHI.\n */\nfunction extractAgentItems(\n children: ReactNode,\n): Array<{ id: string; href?: string }> {\n const out: Array<{ id: string; href?: string }> = [];\n let index = 0;\n Children.forEach(children, (child) => {\n if (!isValidElement(child)) return;\n // Only collect Items. Anything else (separators, custom wrappers) is\n // skipped — the agent contract addresses crumbs, not chrome.\n if (child.type !== BreadcrumbItem) return;\n const itemProps = child.props as BreadcrumbItemProps & {\n id?: string;\n children?: ReactNode;\n };\n let href: string | undefined;\n Children.forEach(itemProps.children, (grandchild) => {\n if (href) return;\n if (!isValidElement(grandchild)) return;\n if (grandchild.type !== BreadcrumbLink) return;\n const linkProps = grandchild.props as BreadcrumbLinkProps;\n if (typeof linkProps.href === 'string') href = linkProps.href;\n });\n const id = itemProps.id ?? href ?? String(index);\n out.push({ id, href });\n index += 1;\n });\n return out;\n}\n\n/* -------------------------------------------------------------------- */\n/* List — walks its children, injects separators & ellipsis */\n/* -------------------------------------------------------------------- */\n\nconst listClasses = [\n 'ds:flex ds:flex-wrap ds:items-center',\n 'ds:gap-[var(--spacing-xs)]',\n 'ds:text-[var(--font-size-sm)] ds:text-[var(--muted-foreground)]',\n 'ds:ps-0 ds:m-0',\n 'ds:list-none',\n].join(' ');\n\nexport interface BreadcrumbListProps extends ComponentPropsWithoutRef<'ol'> {\n maxItems?: number;\n itemsBeforeCollapse?: number;\n itemsAfterCollapse?: number;\n disableCollapse?: boolean;\n}\n\nconst BreadcrumbList = forwardRef<HTMLOListElement, BreadcrumbListProps>(\n (\n {\n children,\n className,\n maxItems = 4,\n itemsBeforeCollapse = 1,\n itemsAfterCollapse = 1,\n disableCollapse = false,\n ...rest\n },\n ref,\n ) => {\n const arr = Children.toArray(children).filter((c) =>\n isValidElement(c),\n ) as ReactElement[];\n const total = arr.length;\n\n const shouldCollapse =\n !disableCollapse &&\n total > maxItems &&\n itemsBeforeCollapse + itemsAfterCollapse < total;\n\n const renderItem = (child: ReactElement, isLast: boolean, key: string) =>\n cloneElement(child, {\n isCurrent: (child.props as BreadcrumbItemProps).isCurrent ?? isLast,\n key,\n } as Partial<BreadcrumbItemProps>);\n\n const renderSeparatorIf = (condition: boolean, key: string) =>\n condition ? <BreadcrumbSeparator key={key} /> : null;\n\n const nodes: ReactNode[] = [];\n if (!shouldCollapse) {\n arr.forEach((child, i) => {\n const isLast = i === total - 1;\n nodes.push(renderItem(child, isLast, `item-${i}`));\n nodes.push(renderSeparatorIf(!isLast, `sep-${i}`));\n });\n } else {\n const before = arr.slice(0, itemsBeforeCollapse);\n const after = arr.slice(total - itemsAfterCollapse);\n const hidden = arr.slice(itemsBeforeCollapse, total - itemsAfterCollapse);\n\n before.forEach((child, i) => {\n nodes.push(renderItem(child, false, `b-${i}`));\n nodes.push(renderSeparatorIf(true, `b-sep-${i}`));\n });\n\n nodes.push(\n <BreadcrumbItem key=\"ellipsis\">\n <BreadcrumbEllipsis hiddenItems={hidden} />\n </BreadcrumbItem>,\n );\n nodes.push(renderSeparatorIf(true, 'ellipsis-sep'));\n\n after.forEach((child, i) => {\n const isLast = i === after.length - 1;\n nodes.push(renderItem(child, isLast, `a-${i}`));\n nodes.push(renderSeparatorIf(!isLast, `a-sep-${i}`));\n });\n }\n\n return (\n <ol\n ref={ref}\n className={[listClasses, className].filter(Boolean).join(' ')}\n {...rest}\n >\n {nodes}\n </ol>\n );\n },\n);\nBreadcrumbList.displayName = 'BreadcrumbList';\n\n/* -------------------------------------------------------------------- */\n/* Item — <li> marks current when `isCurrent` */\n/* -------------------------------------------------------------------- */\n\nconst itemClasses = [\n 'ds:inline-flex ds:items-center',\n 'ds:max-inline-size-[16rem]',\n 'ds:min-h-[var(--min-target-size)]',\n 'ds:py-[var(--spacing-xs)]',\n].join(' ');\n\nexport interface BreadcrumbItemProps extends ComponentPropsWithoutRef<'li'> {\n /** Set automatically by `BreadcrumbList` on the final item. */\n isCurrent?: boolean;\n}\n\nconst BreadcrumbItem = forwardRef<HTMLLIElement, BreadcrumbItemProps>(\n ({ children, className, isCurrent = false, id, ...rest }, ref) => {\n // Derive an agent crumb id: explicit `id` prop, else the inner link's\n // href. Labels are never used — they may contain PHI (PRS §26 §6.1).\n let derived: string | undefined = id;\n if (!derived) {\n Children.forEach(children, (child) => {\n if (derived) return;\n if (!isValidElement(child)) return;\n if (child.type !== BreadcrumbLink) return;\n const linkProps = child.props as BreadcrumbLinkProps;\n if (typeof linkProps.href === 'string') derived = linkProps.href;\n });\n }\n return (\n <li\n ref={ref}\n id={id}\n data-crumb-id={derived}\n className={[itemClasses, className].filter(Boolean).join(' ')}\n {...rest}\n >\n {Children.map(children, (child) =>\n isValidElement(child) &&\n (child.type === BreadcrumbLink ||\n (child.props as { _link?: boolean })?._link)\n ? cloneElement(child as ReactElement<BreadcrumbLinkProps>, {\n isCurrent,\n })\n : child,\n )}\n </li>\n );\n },\n);\nBreadcrumbItem.displayName = 'BreadcrumbItem';\n\n/* -------------------------------------------------------------------- */\n/* Link — renders <a>, or plain text when current */\n/* -------------------------------------------------------------------- */\n\nconst linkClasses = [\n 'ds:inline-flex ds:items-center',\n 'ds:max-inline-size-[16rem]',\n 'ds:overflow-hidden ds:text-ellipsis ds:whitespace-nowrap',\n 'ds:break-normal',\n 'ds:text-[var(--muted-foreground)] ds:no-underline',\n 'ds:hover:text-[var(--foreground)] ds:hover:underline',\n 'ds:focus-visible:outline-[length:var(--focus-ring-width)] ds:focus-visible:outline-solid',\n 'ds:focus-visible:outline-[var(--ring)] ds:focus-visible:outline-offset-[length:var(--focus-ring-offset)]',\n 'ds:rounded-[var(--radius-sm)]',\n 'ds:transition-colors ds:duration-[var(--animation-duration)] ds:motion-reduce:transition-none',\n 'ds:min-h-[var(--min-target-size)] ds:ps-[var(--spacing-xs)] ds:pe-[var(--spacing-xs)]',\n].join(' ');\n\nconst currentClasses = [\n 'ds:inline-flex ds:items-center',\n 'ds:max-inline-size-[16rem]',\n 'ds:overflow-hidden ds:text-ellipsis ds:whitespace-nowrap',\n 'ds:break-normal',\n 'ds:text-[var(--foreground)] ds:font-[var(--font-weight-semibold)]',\n 'ds:min-h-[var(--min-target-size)] ds:ps-[var(--spacing-xs)] ds:pe-[var(--spacing-xs)]',\n].join(' ');\n\nexport interface BreadcrumbLinkProps extends AnchorHTMLAttributes<HTMLAnchorElement> {\n /** Use Radix `Slot` so consumers can pass a router link. */\n asChild?: boolean;\n /** Set by the parent Item when this is the current page. */\n isCurrent?: boolean;\n}\n\nconst BreadcrumbLink = forwardRef<HTMLAnchorElement, BreadcrumbLinkProps>(\n (\n { asChild = false, isCurrent = false, className, children, ...rest },\n ref,\n ) => {\n const { t } = useTranslation();\n\n if (isCurrent) {\n return (\n <span\n aria-current=\"page\"\n aria-label={\n (rest['aria-label'] as string | undefined) ??\n t('navigation.breadcrumb.current')\n }\n className={[currentClasses, className].filter(Boolean).join(' ')}\n >\n {children}\n </span>\n );\n }\n\n if (asChild) {\n return (\n <Slot\n ref={ref}\n className={[linkClasses, className].filter(Boolean).join(' ')}\n {...rest}\n >\n {children}\n </Slot>\n );\n }\n\n return (\n <a\n ref={ref}\n className={[linkClasses, className].filter(Boolean).join(' ')}\n {...rest}\n >\n {children}\n </a>\n );\n },\n);\nBreadcrumbLink.displayName = 'BreadcrumbLink';\n\n/* -------------------------------------------------------------------- */\n/* Separator */\n/* -------------------------------------------------------------------- */\n\nconst separatorVariants = cva(\n [\n 'ds:inline-flex ds:items-center ds:justify-center',\n 'ds:text-[var(--muted-foreground)]',\n 'ds:ms-[var(--spacing-xs)] ds:me-[var(--spacing-xs)]',\n 'ds:select-none',\n ].join(' '),\n {\n variants: {\n variant: {\n chevron: '',\n slash: '',\n },\n },\n defaultVariants: { variant: 'chevron' },\n },\n);\n\nexport interface BreadcrumbSeparatorProps\n extends\n Omit<ComponentPropsWithoutRef<'li'>, 'children'>,\n VariantProps<typeof separatorVariants> {\n children?: ReactNode;\n}\n\nconst BreadcrumbSeparator = forwardRef<HTMLLIElement, BreadcrumbSeparatorProps>(\n ({ className, variant, children, ...rest }, ref) => {\n const ctx = useContext(BreadcrumbContext);\n const resolved = variant ?? ctx.separator;\n const defaultGlyph =\n resolved === 'slash' ? (\n <span aria-hidden=\"true\">/</span>\n ) : (\n <ChevronRight\n aria-hidden=\"true\"\n className=\"ds:size-4 ds:rtl:-scale-x-100\"\n />\n );\n return (\n <li\n ref={ref}\n aria-hidden=\"true\"\n role=\"presentation\"\n className={separatorVariants({ variant: resolved, className })}\n {...rest}\n >\n {children ?? defaultGlyph}\n </li>\n );\n },\n);\nBreadcrumbSeparator.displayName = 'BreadcrumbSeparator';\n\n/* -------------------------------------------------------------------- */\n/* Ellipsis — opens a Radix DropdownMenu with hidden crumbs */\n/* -------------------------------------------------------------------- */\n\nconst ellipsisTriggerClasses = [\n 'ds:inline-flex ds:items-center ds:justify-center',\n 'ds:min-w-[var(--min-target-size)] ds:min-h-[var(--min-target-size)]',\n 'ds:rounded-[var(--radius-sm)]',\n 'ds:text-[var(--muted-foreground)]',\n 'ds:hover:text-[var(--foreground)]',\n 'ds:focus-visible:outline-[length:var(--focus-ring-width)] ds:focus-visible:outline-solid',\n 'ds:focus-visible:outline-[var(--ring)] ds:focus-visible:outline-offset-[length:var(--focus-ring-offset)]',\n 'ds:transition-colors ds:duration-[var(--animation-duration)] ds:motion-reduce:transition-none',\n].join(' ');\n\nconst ellipsisContentClasses = [\n 'ds:z-[var(--z-dropdown)] ds:min-w-[12rem] ds:overflow-hidden',\n 'ds:rounded-[var(--radius-md)] ds:border ds:border-[var(--border)]',\n 'ds:bg-[var(--background)] ds:text-[var(--foreground)]',\n 'ds:shadow-[var(--shadow-lg)]',\n 'ds:p-[var(--spacing-xs)]',\n 'ds:animate-in ds:fade-in ds:zoom-in-95 ds:motion-reduce:animate-none',\n].join(' ');\n\nconst ellipsisItemClasses = [\n 'ds:flex ds:items-center',\n 'ds:min-h-[var(--min-target-size)]',\n 'ds:ps-[var(--spacing-sm)] ds:pe-[var(--spacing-sm)]',\n 'ds:rounded-[var(--radius-sm)]',\n 'ds:text-[var(--foreground)] ds:cursor-pointer ds:select-none',\n 'ds:data-[highlighted]:bg-[var(--muted)] ds:data-[highlighted]:text-[var(--foreground)]',\n 'ds:outline-none',\n].join(' ');\n\nexport interface BreadcrumbEllipsisProps extends ComponentPropsWithoutRef<'button'> {\n /** Hidden crumb elements rendered inside the dropdown menu. */\n hiddenItems?: ReactElement[];\n}\n\nconst BreadcrumbEllipsis = forwardRef<\n HTMLButtonElement,\n BreadcrumbEllipsisProps\n>(({ className, hiddenItems = [], ...rest }, ref) => {\n const { t } = useTranslation();\n const showPath = t('navigation.breadcrumb.showPath');\n return (\n <DropdownMenu.Root>\n <DropdownMenu.Trigger asChild>\n <button\n ref={ref}\n type=\"button\"\n aria-label={showPath}\n className={[ellipsisTriggerClasses, className]\n .filter(Boolean)\n .join(' ')}\n {...rest}\n >\n <MoreHorizontal aria-hidden=\"true\" className=\"ds:size-4\" />\n <span className=\"ds:sr-only\">{showPath}</span>\n </button>\n </DropdownMenu.Trigger>\n <DropdownMenu.Portal>\n <DropdownMenu.Content\n className={ellipsisContentClasses}\n align=\"start\"\n sideOffset={6}\n >\n {hiddenItems.map((item, i) => {\n // Extract the anchor inside the hidden BreadcrumbItem (if any)\n const linkChild = extractLink(item);\n return (\n <DropdownMenu.Item\n key={`hidden-${i}`}\n asChild\n className={ellipsisItemClasses}\n >\n {linkChild ?? <span>{item}</span>}\n </DropdownMenu.Item>\n );\n })}\n </DropdownMenu.Content>\n </DropdownMenu.Portal>\n </DropdownMenu.Root>\n );\n});\nBreadcrumbEllipsis.displayName = 'BreadcrumbEllipsis';\n\n/**\n * Walks a `BreadcrumbItem` to find the first child whose type is\n * `BreadcrumbLink` and returns the link rendered as a plain `<a>` so the\n * dropdown item can adopt its navigational behaviour.\n */\nfunction extractLink(item: ReactElement): ReactElement | null {\n let found: ReactElement | null = null;\n const itemChildren = (item.props as { children?: ReactNode }).children;\n Children.forEach(itemChildren, (child) => {\n if (found) return;\n if (!isValidElement(child)) return;\n if (child.type === BreadcrumbLink) {\n const linkProps = child.props as BreadcrumbLinkProps & {\n children?: ReactNode;\n };\n const href =\n typeof linkProps.href === 'string' ? linkProps.href : undefined;\n const safeHref = href && /^\\s*javascript:/i.test(href) ? undefined : href;\n found = (\n <a\n href={safeHref}\n onClick={\n linkProps.onClick as AnchorHTMLAttributes<HTMLAnchorElement>['onClick']\n }\n >\n {linkProps.children}\n </a>\n );\n }\n });\n return found;\n}\n\nexport {\n Breadcrumb,\n BreadcrumbList,\n BreadcrumbItem,\n BreadcrumbLink,\n BreadcrumbSeparator,\n BreadcrumbEllipsis,\n};\n"],"names":["breadcrumbAgent","handle","args","BreadcrumbContext","createContext","Breadcrumb","forwardRef","children","className","ariaLabel","separator","maxItems","itemsBeforeCollapse","itemsAfterCollapse","disableCollapse","id","rest","ref","t","useTranslation","items","useMemo","extractAgentItems","targetId","hit","i","trimmed","innerRef","useRef","useImperativeHandle","useAgentRegistration","jsx","BreadcrumbList","out","index","Children","child","isValidElement","BreadcrumbItem","itemProps","href","grandchild","BreadcrumbLink","linkProps","listClasses","arr","total","shouldCollapse","renderItem","isLast","key","cloneElement","renderSeparatorIf","condition","BreadcrumbSeparator","nodes","before","after","hidden","BreadcrumbEllipsis","itemClasses","isCurrent","derived","_a","linkClasses","currentClasses","asChild","Slot","separatorVariants","cva","variant","ctx","useContext","resolved","defaultGlyph","ChevronRight","ellipsisTriggerClasses","ellipsisContentClasses","ellipsisItemClasses","hiddenItems","showPath","jsxs","DropdownMenu","MoreHorizontal","item","linkChild","extractLink","found","itemChildren","safeHref"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"breadcrumb-OTbaY70e.js","sources":["../../src/components/breadcrumb/breadcrumb.agent.ts","../../src/components/breadcrumb/breadcrumb.tsx"],"sourcesContent":["/* -------------------------------------------------------------------- */\n/* Agent adapter — Breadcrumb. */\n/* */\n/* Breadcrumb is a navigation trail. Items expose their stable route id */\n/* + href ONLY — labels can contain patient names or other PHI and MUST */\n/* NOT be exposed on `data-*` or in adapter state (see PRS §26 §6.1). */\n/* */\n/* See `src/docs/26-agent-readiness.mdx` for the full contract. */\n/* -------------------------------------------------------------------- */\n\nimport type { AgentAdapter } from '../../agent/types';\nimport type { BreadcrumbHandle } from './breadcrumb';\n\nexport interface BreadcrumbAgentItem {\n id: string;\n href?: string;\n}\n\nexport const breadcrumbAgent: AgentAdapter<BreadcrumbHandle> = {\n id: 'breadcrumb',\n capabilities: ['navigate'],\n state: {\n items: {\n type: 'Array<{ id: string, href?: string }>',\n descriptionKey: 'ui.agent.breadcrumb.state.items',\n description:\n 'Ordered list of crumb ids + hrefs in display order. Labels are intentionally excluded — they may contain PHI.',\n read: (handle) => handle.getItems(),\n },\n },\n actions: {\n navigate_to: {\n safety: 'read',\n argsType: '{ id: string }',\n descriptionKey: 'ui.agent.breadcrumb.actions.navigateTo',\n description:\n 'Activate the crumb with the given id — equivalent to clicking the link.',\n invoke: (handle, args: { id: string }) => {\n handle.navigateTo(args.id);\n },\n },\n },\n domHooks: {\n root: {\n attr: 'data-component',\n value: 'breadcrumb',\n description: 'Marks the Breadcrumb root `<nav>`.',\n },\n instanceId: {\n attr: 'data-component-id',\n sourceProp: 'id',\n description: 'Sourced from the id prop.',\n },\n item: {\n attr: 'data-crumb-id',\n description:\n 'Stable opaque id of a crumb. Labels are NEVER carried in data-* — they may contain PHI.',\n },\n },\n};\n","import {\n Children,\n cloneElement,\n createContext,\n forwardRef,\n isValidElement,\n useContext,\n useImperativeHandle,\n useMemo,\n useRef,\n type AnchorHTMLAttributes,\n type ComponentPropsWithoutRef,\n type ReactElement,\n type ReactNode,\n} from 'react';\nimport * as DropdownMenu from '@radix-ui/react-dropdown-menu';\nimport { Slot } from '@radix-ui/react-slot';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { useTranslation } from 'react-i18next';\nimport { ChevronRight, MoreHorizontal } from 'lucide-react';\nimport { useAgentRegistration } from '../../agent/registry';\nimport { breadcrumbAgent } from './breadcrumb.agent';\n\n/* -------------------------------------------------------------------- */\n/* Context — shares separator variant between siblings */\n/* -------------------------------------------------------------------- */\n\ntype SeparatorVariant = 'chevron' | 'slash';\n\ninterface BreadcrumbContextValue {\n separator: SeparatorVariant;\n}\n\nconst BreadcrumbContext = createContext<BreadcrumbContextValue>({\n separator: 'chevron',\n});\n\n/* -------------------------------------------------------------------- */\n/* Root — <nav aria-label> wrapper + truncation engine */\n/* -------------------------------------------------------------------- */\n\nexport interface BreadcrumbProps extends Omit<\n ComponentPropsWithoutRef<'nav'>,\n 'id'\n> {\n /** Override the default `aria-label` (falls back to translated `ui.navigation.breadcrumb.label`). */\n 'aria-label'?: string;\n /** Separator glyph between items. @default 'chevron' */\n separator?: SeparatorVariant;\n /** Maximum number of visible crumbs before collapsing. @default 4 */\n maxItems?: number;\n /** Items kept visible at the start. @default 1 */\n itemsBeforeCollapse?: number;\n /** Items kept visible at the end. @default 1 */\n itemsAfterCollapse?: number;\n /** If true, disables collapse behaviour. */\n disableCollapse?: boolean;\n /**\n * Consumer-supplied instance id, surfaced as `data-component-id` so an\n * agent / UI bridge can address this instance.\n */\n id?: string;\n}\n\n/**\n * Imperative handle for agent-readiness.\n *\n * Items expose their stable id (`BreadcrumbItem` `id` prop, falling back\n * to the `BreadcrumbLink` href) and href — never their visible label,\n * which may contain PHI (see PRS §26 §6.1).\n */\nexport interface BreadcrumbHandle {\n getItems: () => Array<{ id: string; href?: string }>;\n navigateTo: (id: string) => void;\n}\n\nconst Breadcrumb = forwardRef<HTMLElement, BreadcrumbProps>(\n (\n {\n children,\n className,\n 'aria-label': ariaLabel,\n separator = 'chevron',\n maxItems = 4,\n itemsBeforeCollapse = 1,\n itemsAfterCollapse = 1,\n disableCollapse = false,\n id,\n ...rest\n },\n ref,\n ) => {\n const { t } = useTranslation();\n\n const items = useMemo(() => extractAgentItems(children), [children]);\n\n const handle = useMemo<BreadcrumbHandle>(\n () => ({\n getItems: () => items,\n navigateTo: (targetId: string) => {\n const hit = items.find((i) => i.id === targetId);\n if (!hit?.href) return;\n if (typeof window === 'undefined') return;\n // Same allow-list as the BreadcrumbLink renderer — never honour\n // `javascript:` / `data:` URLs.\n const trimmed = hit.href.trim();\n if (/^\\s*javascript:/i.test(trimmed)) return;\n window.location.assign(trimmed);\n },\n }),\n [items],\n );\n const innerRef = useRef<HTMLElement>(null);\n useImperativeHandle(ref, () => innerRef.current as HTMLElement, []);\n useAgentRegistration(breadcrumbAgent, handle, id);\n\n return (\n <BreadcrumbContext.Provider value={{ separator }}>\n <nav\n ref={innerRef}\n id={id}\n aria-label={ariaLabel ?? t('navigation.breadcrumb.label')}\n data-component=\"breadcrumb\"\n data-component-id={id}\n className={className}\n {...rest}\n >\n <BreadcrumbList\n maxItems={maxItems}\n itemsBeforeCollapse={itemsBeforeCollapse}\n itemsAfterCollapse={itemsAfterCollapse}\n disableCollapse={disableCollapse}\n >\n {children}\n </BreadcrumbList>\n </nav>\n </BreadcrumbContext.Provider>\n );\n },\n);\nBreadcrumb.displayName = 'Breadcrumb';\n\n/**\n * Walks the Breadcrumb children to collect `{ id, href }` for the agent\n * handle. The id is taken from the BreadcrumbItem's `id` prop, falling\n * back to the inner BreadcrumbLink's href (or an index string as a last\n * resort). Labels are never read — they may contain PHI.\n */\nfunction extractAgentItems(\n children: ReactNode,\n): Array<{ id: string; href?: string }> {\n const out: Array<{ id: string; href?: string }> = [];\n let index = 0;\n Children.forEach(children, (child) => {\n if (!isValidElement(child)) return;\n // Only collect Items. Anything else (separators, custom wrappers) is\n // skipped — the agent contract addresses crumbs, not chrome.\n if (child.type !== BreadcrumbItem) return;\n const itemProps = child.props as BreadcrumbItemProps & {\n id?: string;\n children?: ReactNode;\n };\n let href: string | undefined;\n Children.forEach(itemProps.children, (grandchild) => {\n if (href) return;\n if (!isValidElement(grandchild)) return;\n if (grandchild.type !== BreadcrumbLink) return;\n const linkProps = grandchild.props as BreadcrumbLinkProps;\n if (typeof linkProps.href === 'string') href = linkProps.href;\n });\n const id = itemProps.id ?? href ?? String(index);\n out.push({ id, href });\n index += 1;\n });\n return out;\n}\n\n/* -------------------------------------------------------------------- */\n/* List — walks its children, injects separators & ellipsis */\n/* -------------------------------------------------------------------- */\n\nconst listClasses = [\n 'ds:flex ds:flex-wrap ds:items-center',\n 'ds:gap-[var(--spacing-xs)]',\n 'ds:text-[var(--font-size-sm)] ds:text-[var(--muted-foreground)]',\n 'ds:ps-0 ds:m-0',\n 'ds:list-none',\n].join(' ');\n\nexport interface BreadcrumbListProps extends ComponentPropsWithoutRef<'ol'> {\n maxItems?: number;\n itemsBeforeCollapse?: number;\n itemsAfterCollapse?: number;\n disableCollapse?: boolean;\n}\n\nconst BreadcrumbList = forwardRef<HTMLOListElement, BreadcrumbListProps>(\n (\n {\n children,\n className,\n maxItems = 4,\n itemsBeforeCollapse = 1,\n itemsAfterCollapse = 1,\n disableCollapse = false,\n ...rest\n },\n ref,\n ) => {\n const arr = Children.toArray(children).filter((c) =>\n isValidElement(c),\n ) as ReactElement[];\n const total = arr.length;\n\n const shouldCollapse =\n !disableCollapse &&\n total > maxItems &&\n itemsBeforeCollapse + itemsAfterCollapse < total;\n\n const renderItem = (child: ReactElement, isLast: boolean, key: string) =>\n cloneElement(child, {\n isCurrent: (child.props as BreadcrumbItemProps).isCurrent ?? isLast,\n key,\n } as Partial<BreadcrumbItemProps>);\n\n const renderSeparatorIf = (condition: boolean, key: string) =>\n condition ? <BreadcrumbSeparator key={key} /> : null;\n\n const nodes: ReactNode[] = [];\n if (!shouldCollapse) {\n arr.forEach((child, i) => {\n const isLast = i === total - 1;\n nodes.push(renderItem(child, isLast, `item-${i}`));\n nodes.push(renderSeparatorIf(!isLast, `sep-${i}`));\n });\n } else {\n const before = arr.slice(0, itemsBeforeCollapse);\n const after = arr.slice(total - itemsAfterCollapse);\n const hidden = arr.slice(itemsBeforeCollapse, total - itemsAfterCollapse);\n\n before.forEach((child, i) => {\n nodes.push(renderItem(child, false, `b-${i}`));\n nodes.push(renderSeparatorIf(true, `b-sep-${i}`));\n });\n\n nodes.push(\n <BreadcrumbItem key=\"ellipsis\">\n <BreadcrumbEllipsis hiddenItems={hidden} />\n </BreadcrumbItem>,\n );\n nodes.push(renderSeparatorIf(true, 'ellipsis-sep'));\n\n after.forEach((child, i) => {\n const isLast = i === after.length - 1;\n nodes.push(renderItem(child, isLast, `a-${i}`));\n nodes.push(renderSeparatorIf(!isLast, `a-sep-${i}`));\n });\n }\n\n return (\n <ol\n ref={ref}\n className={[listClasses, className].filter(Boolean).join(' ')}\n {...rest}\n >\n {nodes}\n </ol>\n );\n },\n);\nBreadcrumbList.displayName = 'BreadcrumbList';\n\n/* -------------------------------------------------------------------- */\n/* Item — <li> marks current when `isCurrent` */\n/* -------------------------------------------------------------------- */\n\nconst itemClasses = [\n 'ds:inline-flex ds:items-center',\n 'ds:[max-inline-size:16rem]',\n 'ds:min-h-[var(--min-target-size)]',\n 'ds:py-[var(--spacing-xs)]',\n].join(' ');\n\nexport interface BreadcrumbItemProps extends ComponentPropsWithoutRef<'li'> {\n /** Set automatically by `BreadcrumbList` on the final item. */\n isCurrent?: boolean;\n}\n\nconst BreadcrumbItem = forwardRef<HTMLLIElement, BreadcrumbItemProps>(\n ({ children, className, isCurrent = false, id, ...rest }, ref) => {\n // Derive an agent crumb id: explicit `id` prop, else the inner link's\n // href. Labels are never used — they may contain PHI (PRS §26 §6.1).\n let derived: string | undefined = id;\n if (!derived) {\n Children.forEach(children, (child) => {\n if (derived) return;\n if (!isValidElement(child)) return;\n if (child.type !== BreadcrumbLink) return;\n const linkProps = child.props as BreadcrumbLinkProps;\n if (typeof linkProps.href === 'string') derived = linkProps.href;\n });\n }\n return (\n <li\n ref={ref}\n id={id}\n data-crumb-id={derived}\n className={[itemClasses, className].filter(Boolean).join(' ')}\n {...rest}\n >\n {Children.map(children, (child) =>\n isValidElement(child) &&\n (child.type === BreadcrumbLink ||\n (child.props as { _link?: boolean })?._link)\n ? cloneElement(child as ReactElement<BreadcrumbLinkProps>, {\n isCurrent,\n })\n : child,\n )}\n </li>\n );\n },\n);\nBreadcrumbItem.displayName = 'BreadcrumbItem';\n\n/* -------------------------------------------------------------------- */\n/* Link — renders <a>, or plain text when current */\n/* -------------------------------------------------------------------- */\n\nconst linkClasses = [\n 'ds:inline-flex ds:items-center',\n 'ds:[max-inline-size:16rem]',\n 'ds:overflow-hidden ds:text-ellipsis ds:whitespace-nowrap',\n 'ds:break-normal',\n 'ds:text-[var(--muted-foreground)] ds:no-underline',\n 'ds:hover:text-[var(--foreground)] ds:hover:underline',\n 'ds:focus-visible:outline-[length:var(--focus-ring-width)] ds:focus-visible:outline-solid',\n 'ds:focus-visible:outline-[var(--ring)] ds:focus-visible:outline-offset-[length:var(--focus-ring-offset)]',\n 'ds:rounded-[var(--radius-sm)]',\n 'ds:transition-colors ds:duration-[var(--animation-duration)] ds:motion-reduce:transition-none',\n 'ds:min-h-[var(--min-target-size)] ds:ps-[var(--spacing-xs)] ds:pe-[var(--spacing-xs)]',\n].join(' ');\n\nconst currentClasses = [\n 'ds:inline-flex ds:items-center',\n 'ds:[max-inline-size:16rem]',\n 'ds:overflow-hidden ds:text-ellipsis ds:whitespace-nowrap',\n 'ds:break-normal',\n 'ds:text-[var(--foreground)] ds:font-[var(--font-weight-semibold)]',\n 'ds:min-h-[var(--min-target-size)] ds:ps-[var(--spacing-xs)] ds:pe-[var(--spacing-xs)]',\n].join(' ');\n\nexport interface BreadcrumbLinkProps extends AnchorHTMLAttributes<HTMLAnchorElement> {\n /** Use Radix `Slot` so consumers can pass a router link. */\n asChild?: boolean;\n /** Set by the parent Item when this is the current page. */\n isCurrent?: boolean;\n}\n\nconst BreadcrumbLink = forwardRef<HTMLAnchorElement, BreadcrumbLinkProps>(\n (\n { asChild = false, isCurrent = false, className, children, ...rest },\n ref,\n ) => {\n const { t } = useTranslation();\n\n if (isCurrent) {\n return (\n <span\n aria-current=\"page\"\n aria-label={\n (rest['aria-label'] as string | undefined) ??\n t('navigation.breadcrumb.current')\n }\n className={[currentClasses, className].filter(Boolean).join(' ')}\n >\n {children}\n </span>\n );\n }\n\n if (asChild) {\n return (\n <Slot\n ref={ref}\n className={[linkClasses, className].filter(Boolean).join(' ')}\n {...rest}\n >\n {children}\n </Slot>\n );\n }\n\n return (\n <a\n ref={ref}\n className={[linkClasses, className].filter(Boolean).join(' ')}\n {...rest}\n >\n {children}\n </a>\n );\n },\n);\nBreadcrumbLink.displayName = 'BreadcrumbLink';\n\n/* -------------------------------------------------------------------- */\n/* Separator */\n/* -------------------------------------------------------------------- */\n\nconst separatorVariants = cva(\n [\n 'ds:inline-flex ds:items-center ds:justify-center',\n 'ds:text-[var(--muted-foreground)]',\n 'ds:ms-[var(--spacing-xs)] ds:me-[var(--spacing-xs)]',\n 'ds:select-none',\n ].join(' '),\n {\n variants: {\n variant: {\n chevron: '',\n slash: '',\n },\n },\n defaultVariants: { variant: 'chevron' },\n },\n);\n\nexport interface BreadcrumbSeparatorProps\n extends\n Omit<ComponentPropsWithoutRef<'li'>, 'children'>,\n VariantProps<typeof separatorVariants> {\n children?: ReactNode;\n}\n\nconst BreadcrumbSeparator = forwardRef<HTMLLIElement, BreadcrumbSeparatorProps>(\n ({ className, variant, children, ...rest }, ref) => {\n const ctx = useContext(BreadcrumbContext);\n const resolved = variant ?? ctx.separator;\n const defaultGlyph =\n resolved === 'slash' ? (\n <span aria-hidden=\"true\">/</span>\n ) : (\n <ChevronRight\n aria-hidden=\"true\"\n className=\"ds:size-4 ds:rtl:-scale-x-100\"\n />\n );\n return (\n <li\n ref={ref}\n aria-hidden=\"true\"\n role=\"presentation\"\n className={separatorVariants({ variant: resolved, className })}\n {...rest}\n >\n {children ?? defaultGlyph}\n </li>\n );\n },\n);\nBreadcrumbSeparator.displayName = 'BreadcrumbSeparator';\n\n/* -------------------------------------------------------------------- */\n/* Ellipsis — opens a Radix DropdownMenu with hidden crumbs */\n/* -------------------------------------------------------------------- */\n\nconst ellipsisTriggerClasses = [\n 'ds:inline-flex ds:items-center ds:justify-center',\n 'ds:min-w-[var(--min-target-size)] ds:min-h-[var(--min-target-size)]',\n 'ds:rounded-[var(--radius-sm)]',\n 'ds:text-[var(--muted-foreground)]',\n 'ds:hover:text-[var(--foreground)]',\n 'ds:focus-visible:outline-[length:var(--focus-ring-width)] ds:focus-visible:outline-solid',\n 'ds:focus-visible:outline-[var(--ring)] ds:focus-visible:outline-offset-[length:var(--focus-ring-offset)]',\n 'ds:transition-colors ds:duration-[var(--animation-duration)] ds:motion-reduce:transition-none',\n].join(' ');\n\nconst ellipsisContentClasses = [\n 'ds:z-[var(--z-dropdown)] ds:min-w-[12rem] ds:overflow-hidden',\n 'ds:rounded-[var(--radius-md)] ds:border ds:border-[var(--border)]',\n 'ds:bg-[var(--background)] ds:text-[var(--foreground)]',\n 'ds:shadow-[var(--shadow-lg)]',\n 'ds:p-[var(--spacing-xs)]',\n 'ds:animate-in ds:fade-in ds:zoom-in-95 ds:motion-reduce:animate-none',\n].join(' ');\n\nconst ellipsisItemClasses = [\n 'ds:flex ds:items-center',\n 'ds:min-h-[var(--min-target-size)]',\n 'ds:ps-[var(--spacing-sm)] ds:pe-[var(--spacing-sm)]',\n 'ds:rounded-[var(--radius-sm)]',\n 'ds:text-[var(--foreground)] ds:cursor-pointer ds:select-none',\n 'ds:data-[highlighted]:bg-[var(--muted)] ds:data-[highlighted]:text-[var(--foreground)]',\n 'ds:outline-none',\n].join(' ');\n\nexport interface BreadcrumbEllipsisProps extends ComponentPropsWithoutRef<'button'> {\n /** Hidden crumb elements rendered inside the dropdown menu. */\n hiddenItems?: ReactElement[];\n}\n\nconst BreadcrumbEllipsis = forwardRef<\n HTMLButtonElement,\n BreadcrumbEllipsisProps\n>(({ className, hiddenItems = [], ...rest }, ref) => {\n const { t } = useTranslation();\n const showPath = t('navigation.breadcrumb.showPath');\n return (\n <DropdownMenu.Root>\n <DropdownMenu.Trigger asChild>\n <button\n ref={ref}\n type=\"button\"\n aria-label={showPath}\n className={[ellipsisTriggerClasses, className]\n .filter(Boolean)\n .join(' ')}\n {...rest}\n >\n <MoreHorizontal aria-hidden=\"true\" className=\"ds:size-4\" />\n <span className=\"ds:sr-only\">{showPath}</span>\n </button>\n </DropdownMenu.Trigger>\n <DropdownMenu.Portal>\n <DropdownMenu.Content\n className={ellipsisContentClasses}\n align=\"start\"\n sideOffset={6}\n >\n {hiddenItems.map((item, i) => {\n // Extract the anchor inside the hidden BreadcrumbItem (if any)\n const linkChild = extractLink(item);\n return (\n <DropdownMenu.Item\n key={`hidden-${i}`}\n asChild\n className={ellipsisItemClasses}\n >\n {linkChild ?? <span>{item}</span>}\n </DropdownMenu.Item>\n );\n })}\n </DropdownMenu.Content>\n </DropdownMenu.Portal>\n </DropdownMenu.Root>\n );\n});\nBreadcrumbEllipsis.displayName = 'BreadcrumbEllipsis';\n\n/**\n * Walks a `BreadcrumbItem` to find the first child whose type is\n * `BreadcrumbLink` and returns the link rendered as a plain `<a>` so the\n * dropdown item can adopt its navigational behaviour.\n */\nfunction extractLink(item: ReactElement): ReactElement | null {\n let found: ReactElement | null = null;\n const itemChildren = (item.props as { children?: ReactNode }).children;\n Children.forEach(itemChildren, (child) => {\n if (found) return;\n if (!isValidElement(child)) return;\n if (child.type === BreadcrumbLink) {\n const linkProps = child.props as BreadcrumbLinkProps & {\n children?: ReactNode;\n };\n const href =\n typeof linkProps.href === 'string' ? linkProps.href : undefined;\n const safeHref = href && /^\\s*javascript:/i.test(href) ? undefined : href;\n found = (\n <a\n href={safeHref}\n onClick={\n linkProps.onClick as AnchorHTMLAttributes<HTMLAnchorElement>['onClick']\n }\n >\n {linkProps.children}\n </a>\n );\n }\n });\n return found;\n}\n\nexport {\n Breadcrumb,\n BreadcrumbList,\n BreadcrumbItem,\n BreadcrumbLink,\n BreadcrumbSeparator,\n BreadcrumbEllipsis,\n};\n"],"names":["breadcrumbAgent","handle","args","BreadcrumbContext","createContext","Breadcrumb","forwardRef","children","className","ariaLabel","separator","maxItems","itemsBeforeCollapse","itemsAfterCollapse","disableCollapse","id","rest","ref","t","useTranslation","items","useMemo","extractAgentItems","targetId","hit","i","trimmed","innerRef","useRef","useImperativeHandle","useAgentRegistration","jsx","BreadcrumbList","out","index","Children","child","isValidElement","BreadcrumbItem","itemProps","href","grandchild","BreadcrumbLink","linkProps","listClasses","arr","total","shouldCollapse","renderItem","isLast","key","cloneElement","renderSeparatorIf","condition","BreadcrumbSeparator","nodes","before","after","hidden","BreadcrumbEllipsis","itemClasses","isCurrent","derived","_a","linkClasses","currentClasses","asChild","Slot","separatorVariants","cva","variant","ctx","useContext","resolved","defaultGlyph","ChevronRight","ellipsisTriggerClasses","ellipsisContentClasses","ellipsisItemClasses","hiddenItems","showPath","jsxs","DropdownMenu","MoreHorizontal","item","linkChild","extractLink","found","itemChildren","safeHref"],"mappings":"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"}
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
import { jsxs as r, jsx as e } from "react/jsx-runtime";
|
|
2
|
+
import { forwardRef as F, useState as L, useMemo as x, useEffect as A } from "react";
|
|
3
|
+
import { c as S } from "./index-D2ZczOXr.js";
|
|
4
|
+
import { useTranslation as T } from "react-i18next";
|
|
5
|
+
import { F as P } from "./form-field-BOm9hK35.js";
|
|
6
|
+
import { D as W } from "./date-picker-CvQfs6Xh.js";
|
|
7
|
+
import { N as $ } from "./number-input-Dj5L3pXK.js";
|
|
8
|
+
import { B as v } from "./badge-zsf5i5bH.js";
|
|
9
|
+
import { I as H } from "./insert-result-DtQQeSSf.js";
|
|
10
|
+
import { a as i } from "./react-day-picker-CdtIiKjx.js";
|
|
11
|
+
import { C as I } from "./check-DPdL_Sm7.js";
|
|
12
|
+
import { H as z } from "./heart-C0faivFf.js";
|
|
13
|
+
import { c as k } from "./createLucideIcon-CrFbzy84.js";
|
|
14
|
+
/**
|
|
15
|
+
* @license lucide-react v1.8.0 - ISC
|
|
16
|
+
*
|
|
17
|
+
* This source code is licensed under the ISC license.
|
|
18
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
19
|
+
*/
|
|
20
|
+
const B = [
|
|
21
|
+
[
|
|
22
|
+
"path",
|
|
23
|
+
{
|
|
24
|
+
d: "M12 22a7 7 0 0 0 7-7c0-2-1-3.9-3-5.5s-3.5-4-4-6.5c-.5 2.5-2 4.9-4 6.5C6 11.1 5 13 5 15a7 7 0 0 0 7 7z",
|
|
25
|
+
key: "c7niix"
|
|
26
|
+
}
|
|
27
|
+
]
|
|
28
|
+
], Y = k("droplet", B), h = 28, j = 14, M = 1;
|
|
29
|
+
function U(n, c = 3) {
|
|
30
|
+
const d = n.cycleLength ?? h, { lastPeriodStart: s } = n, o = i(s, d - j), u = {
|
|
31
|
+
start: i(o, -5),
|
|
32
|
+
end: i(o, M)
|
|
33
|
+
}, f = i(s, d), p = Array.from(
|
|
34
|
+
{ length: c },
|
|
35
|
+
(C, g) => i(s, d * (g + 1))
|
|
36
|
+
);
|
|
37
|
+
return { nextPeriod: f, ovulation: o, fertileWindow: u, upcomingPeriods: p };
|
|
38
|
+
}
|
|
39
|
+
const G = S("ds:flex ds:flex-col ds:gap-[var(--spacing-lg)]", {
|
|
40
|
+
variants: {
|
|
41
|
+
width: { full: "ds:w-full", auto: "ds:inline-flex" }
|
|
42
|
+
},
|
|
43
|
+
defaultVariants: { width: "full" }
|
|
44
|
+
}), V = F(
|
|
45
|
+
({
|
|
46
|
+
defaultCycleLength: n = h,
|
|
47
|
+
onResultChange: c,
|
|
48
|
+
onInsert: d,
|
|
49
|
+
insertVariant: s = "insert",
|
|
50
|
+
onCopy: o,
|
|
51
|
+
onError: u,
|
|
52
|
+
id: f,
|
|
53
|
+
width: p,
|
|
54
|
+
className: C
|
|
55
|
+
}, g) => {
|
|
56
|
+
const { t: a, i18n: N } = T(), [m, w] = L(void 0), [y, b] = L(
|
|
57
|
+
n
|
|
58
|
+
), t = x(() => m ? U({
|
|
59
|
+
lastPeriodStart: m,
|
|
60
|
+
cycleLength: y ?? h
|
|
61
|
+
}) : null, [m, y]), D = x(
|
|
62
|
+
() => new Intl.DateTimeFormat(N.language, { dateStyle: "medium" }),
|
|
63
|
+
[N.language]
|
|
64
|
+
);
|
|
65
|
+
A(() => {
|
|
66
|
+
c == null || c(t);
|
|
67
|
+
}, [t, c]);
|
|
68
|
+
const E = x(() => /* @__PURE__ */ new Date(), []), l = (_) => D.format(_);
|
|
69
|
+
return /* @__PURE__ */ r(
|
|
70
|
+
"div",
|
|
71
|
+
{
|
|
72
|
+
ref: g,
|
|
73
|
+
"data-component": "cycle-calculator",
|
|
74
|
+
"data-component-id": f,
|
|
75
|
+
className: G({ width: p, className: C }),
|
|
76
|
+
children: [
|
|
77
|
+
/* @__PURE__ */ r("div", { className: "ds:grid ds:grid-cols-1 ds:gap-[var(--spacing-md)] ds:sm:grid-cols-2", children: [
|
|
78
|
+
/* @__PURE__ */ e(P, { label: a("cycleCalculator.lastPeriod"), children: /* @__PURE__ */ e(
|
|
79
|
+
W,
|
|
80
|
+
{
|
|
81
|
+
value: m,
|
|
82
|
+
onChange: w,
|
|
83
|
+
maxDate: E
|
|
84
|
+
}
|
|
85
|
+
) }),
|
|
86
|
+
/* @__PURE__ */ e(
|
|
87
|
+
P,
|
|
88
|
+
{
|
|
89
|
+
label: a("cycleCalculator.cycleLength"),
|
|
90
|
+
description: a("cycleCalculator.cycleLengthHint"),
|
|
91
|
+
children: /* @__PURE__ */ e(
|
|
92
|
+
$,
|
|
93
|
+
{
|
|
94
|
+
mode: "integer",
|
|
95
|
+
min: 20,
|
|
96
|
+
max: 45,
|
|
97
|
+
value: y,
|
|
98
|
+
onChange: b
|
|
99
|
+
}
|
|
100
|
+
)
|
|
101
|
+
}
|
|
102
|
+
)
|
|
103
|
+
] }),
|
|
104
|
+
/* @__PURE__ */ e("p", { className: "ds:sr-only", role: "status", "aria-live": "polite", children: t ? `${a("cycleCalculator.ovulation")}: ${l(t.ovulation)}. ${a(
|
|
105
|
+
"cycleCalculator.nextPeriod"
|
|
106
|
+
)}: ${l(t.nextPeriod)}.` : "" }),
|
|
107
|
+
t ? /* @__PURE__ */ r("div", { className: "ds:flex ds:flex-col ds:gap-[var(--spacing-md)]", children: [
|
|
108
|
+
/* @__PURE__ */ r("dl", { className: "ds:grid ds:grid-cols-1 ds:gap-[var(--spacing-md)] ds:sm:grid-cols-3", children: [
|
|
109
|
+
/* @__PURE__ */ r("div", { className: "ds:flex ds:flex-col ds:items-center ds:gap-[var(--spacing-xs)] ds:text-center", children: [
|
|
110
|
+
/* @__PURE__ */ e("dt", { className: "type-label ds:text-muted-foreground", children: a("cycleCalculator.ovulation") }),
|
|
111
|
+
/* @__PURE__ */ e("dd", { children: /* @__PURE__ */ e(
|
|
112
|
+
v,
|
|
113
|
+
{
|
|
114
|
+
variant: "success",
|
|
115
|
+
size: "lg",
|
|
116
|
+
leading: /* @__PURE__ */ e(I, { "aria-hidden": !0 }),
|
|
117
|
+
children: l(t.ovulation)
|
|
118
|
+
}
|
|
119
|
+
) })
|
|
120
|
+
] }),
|
|
121
|
+
/* @__PURE__ */ r("div", { className: "ds:flex ds:flex-col ds:items-center ds:gap-[var(--spacing-xs)] ds:text-center", children: [
|
|
122
|
+
/* @__PURE__ */ e("dt", { className: "type-label ds:text-muted-foreground", children: a("cycleCalculator.fertileWindow") }),
|
|
123
|
+
/* @__PURE__ */ e("dd", { children: /* @__PURE__ */ r(
|
|
124
|
+
v,
|
|
125
|
+
{
|
|
126
|
+
variant: "accent",
|
|
127
|
+
size: "lg",
|
|
128
|
+
leading: /* @__PURE__ */ e(z, { "aria-hidden": !0 }),
|
|
129
|
+
children: [
|
|
130
|
+
l(t.fertileWindow.start),
|
|
131
|
+
" –",
|
|
132
|
+
" ",
|
|
133
|
+
l(t.fertileWindow.end)
|
|
134
|
+
]
|
|
135
|
+
}
|
|
136
|
+
) })
|
|
137
|
+
] }),
|
|
138
|
+
/* @__PURE__ */ r("div", { className: "ds:flex ds:flex-col ds:items-center ds:gap-[var(--spacing-xs)] ds:text-center", children: [
|
|
139
|
+
/* @__PURE__ */ e("dt", { className: "type-label ds:text-muted-foreground", children: a("cycleCalculator.nextPeriod") }),
|
|
140
|
+
/* @__PURE__ */ e("dd", { children: /* @__PURE__ */ e(
|
|
141
|
+
v,
|
|
142
|
+
{
|
|
143
|
+
variant: "error",
|
|
144
|
+
size: "lg",
|
|
145
|
+
leading: /* @__PURE__ */ e(Y, { "aria-hidden": !0 }),
|
|
146
|
+
children: l(t.nextPeriod)
|
|
147
|
+
}
|
|
148
|
+
) })
|
|
149
|
+
] })
|
|
150
|
+
] }),
|
|
151
|
+
s === "copy" || d ? /* @__PURE__ */ e(
|
|
152
|
+
H,
|
|
153
|
+
{
|
|
154
|
+
onInsert: d,
|
|
155
|
+
variant: s,
|
|
156
|
+
onCopy: o,
|
|
157
|
+
onError: u,
|
|
158
|
+
card: {
|
|
159
|
+
title: a("insert.title.cycle"),
|
|
160
|
+
fields: [
|
|
161
|
+
{
|
|
162
|
+
label: a("cycleCalculator.ovulation"),
|
|
163
|
+
value: l(t.ovulation)
|
|
164
|
+
},
|
|
165
|
+
{
|
|
166
|
+
label: a("cycleCalculator.fertileWindow"),
|
|
167
|
+
value: `${l(t.fertileWindow.start)} – ${l(
|
|
168
|
+
t.fertileWindow.end
|
|
169
|
+
)}`
|
|
170
|
+
},
|
|
171
|
+
{
|
|
172
|
+
label: a("cycleCalculator.nextPeriod"),
|
|
173
|
+
value: l(t.nextPeriod)
|
|
174
|
+
}
|
|
175
|
+
]
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
) : null
|
|
179
|
+
] }) : /* @__PURE__ */ e("p", { className: "type-body ds:text-muted-foreground", children: a("cycleCalculator.empty") })
|
|
180
|
+
]
|
|
181
|
+
}
|
|
182
|
+
);
|
|
183
|
+
}
|
|
184
|
+
);
|
|
185
|
+
V.displayName = "CycleCalculator";
|
|
186
|
+
export {
|
|
187
|
+
V as C,
|
|
188
|
+
j as L,
|
|
189
|
+
U as p
|
|
190
|
+
};
|
|
191
|
+
//# sourceMappingURL=cycle-calculator-DsZbyzX6.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cycle-calculator-DsZbyzX6.js","sources":["../../node_modules/lucide-react/dist/esm/icons/droplet.js","../../src/components/cycle-calculator/cycle.ts","../../src/components/cycle-calculator/cycle-calculator.tsx"],"sourcesContent":["/**\n * @license lucide-react v1.8.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.js';\n\nconst __iconNode = [\n [\n \"path\",\n {\n d: \"M12 22a7 7 0 0 0 7-7c0-2-1-3.9-3-5.5s-3.5-4-4-6.5c-.5 2.5-2 4.9-4 6.5C6 11.1 5 13 5 15a7 7 0 0 0 7 7z\",\n key: \"c7niix\"\n }\n ]\n];\nconst Droplet = createLucideIcon(\"droplet\", __iconNode);\n\nexport { __iconNode, Droplet as default };\n//# sourceMappingURL=droplet.js.map\n","/* ------------------------------------------------------------------ */\n/* Menstrual-cycle prediction — pure, framework-free, unit-testable. */\n/* */\n/* Uses the standard fixed-luteal-phase model: ovulation falls ~14 days */\n/* before the next period, so on a cycle of length L ovulation is day */\n/* (L − 14). The fertile window spans the 5 days before ovulation */\n/* (sperm survival) through 1 day after (oocyte viability). */\n/* ------------------------------------------------------------------ */\n\nimport { addDays } from 'date-fns';\n\n/** Standard menstrual-cycle length. */\nexport const DEFAULT_CYCLE_LENGTH = 28;\n/** Luteal phase is biologically near-constant at ~14 days. */\nexport const LUTEAL_PHASE_DAYS = 14;\n/** Sperm survive up to ~5 days before ovulation. */\nexport const FERTILE_DAYS_BEFORE = 5;\n/** The oocyte is viable ~1 day after ovulation. */\nexport const FERTILE_DAYS_AFTER = 1;\n\nexport interface CycleInput {\n /** First day of the most recent period. */\n lastPeriodStart: Date;\n /** Average cycle length in days. Defaults to 28. */\n cycleLength?: number;\n /** Period (bleed) length in days. Optional — used for the period range. */\n periodLength?: number;\n}\n\nexport interface DateRange {\n start: Date;\n end: Date;\n}\n\nexport interface CyclePrediction {\n /** Start date of the next period. */\n nextPeriod: Date;\n /** Estimated ovulation date. */\n ovulation: Date;\n /** Fertile window (5 days before ovulation → 1 day after). */\n fertileWindow: DateRange;\n /** Start dates of the next few periods (length = `occurrences`). */\n upcomingPeriods: Date[];\n}\n\n/**\n * Predict ovulation, the fertile window and upcoming periods from the last\n * period's start date. `occurrences` controls how many future periods to\n * list (default 3).\n */\nexport function predictCycle(\n input: CycleInput,\n occurrences = 3,\n): CyclePrediction {\n const cycle = input.cycleLength ?? DEFAULT_CYCLE_LENGTH;\n const { lastPeriodStart } = input;\n\n const ovulation = addDays(lastPeriodStart, cycle - LUTEAL_PHASE_DAYS);\n const fertileWindow: DateRange = {\n start: addDays(ovulation, -FERTILE_DAYS_BEFORE),\n end: addDays(ovulation, FERTILE_DAYS_AFTER),\n };\n const nextPeriod = addDays(lastPeriodStart, cycle);\n const upcomingPeriods = Array.from({ length: occurrences }, (_, i) =>\n addDays(lastPeriodStart, cycle * (i + 1)),\n );\n\n return { nextPeriod, ovulation, fertileWindow, upcomingPeriods };\n}\n","/* ------------------------------------------------------------------ */\n/* CycleCalculator — predict ovulation, fertile window and upcoming */\n/* periods from the last period's start date. */\n/* */\n/* Maths lives in `./cycle` (pure, separately tested). */\n/* ------------------------------------------------------------------ */\n\nimport { forwardRef, useEffect, useMemo, useState } from 'react';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { useTranslation } from 'react-i18next';\nimport { Heart, Check, Droplet } from 'lucide-react';\nimport { FormField } from '../form-field';\nimport { DatePicker } from '../date-picker';\nimport { NumberInput } from '../number-input';\nimport { Badge } from '../badge';\nimport {\n InsertButton,\n type InsertPayload,\n type InsertVariant,\n type InsertMode,\n} from '../_shared/insert-result';\nimport {\n type CyclePrediction,\n predictCycle,\n DEFAULT_CYCLE_LENGTH,\n} from './cycle';\n\nconst rootVariants = cva('ds:flex ds:flex-col ds:gap-[var(--spacing-lg)]', {\n variants: {\n width: { full: 'ds:w-full', auto: 'ds:inline-flex' },\n },\n defaultVariants: { width: 'full' },\n});\n\nexport interface CycleCalculatorProps extends VariantProps<\n typeof rootVariants\n> {\n /** Initial cycle length in days. Defaults to 28. */\n defaultCycleLength?: number;\n /** Fires whenever a prediction can be computed (and `null` when it can't). */\n onResultChange?: (result: CyclePrediction | null) => void;\n /** When provided, shows the result-action buttons that emit / copy the result. */\n onInsert?: (payload: InsertPayload) => void;\n /**\n * Which verb the result button performs. Defaults to `'insert'`.\n * Use `'copy'` in an app-shell surface (no editor to insert into) — the\n * button writes the result to the clipboard as a multi-format `ClipboardItem`.\n */\n insertVariant?: InsertVariant;\n /** `copy` variant only — fired after a successful clipboard write. */\n onCopy?: (mode: InsertMode) => void;\n /** `copy` variant only — fired if the clipboard write can't proceed. */\n onError?: (error: unknown) => void;\n /** Opaque instance id, emitted as `data-component-id`. */\n id?: string;\n /** Extra class names on the wrapper. */\n className?: string;\n}\n\nexport const CycleCalculator = forwardRef<HTMLDivElement, CycleCalculatorProps>(\n (\n {\n defaultCycleLength = DEFAULT_CYCLE_LENGTH,\n onResultChange,\n onInsert,\n insertVariant = 'insert',\n onCopy,\n onError,\n id,\n width,\n className,\n },\n ref,\n ) => {\n const { t, i18n } = useTranslation();\n\n const [lastPeriod, setLastPeriod] = useState<Date | undefined>(undefined);\n const [cycleLength, setCycleLength] = useState<number | null>(\n defaultCycleLength,\n );\n\n const result = useMemo<CyclePrediction | null>(() => {\n if (!lastPeriod) return null;\n return predictCycle({\n lastPeriodStart: lastPeriod,\n cycleLength: cycleLength ?? DEFAULT_CYCLE_LENGTH,\n });\n }, [lastPeriod, cycleLength]);\n\n const dateFormatter = useMemo(\n () => new Intl.DateTimeFormat(i18n.language, { dateStyle: 'medium' }),\n [i18n.language],\n );\n\n useEffect(() => {\n onResultChange?.(result);\n }, [result, onResultChange]);\n\n const today = useMemo(() => new Date(), []);\n\n const fmt = (d: Date): string => dateFormatter.format(d);\n\n return (\n <div\n ref={ref}\n data-component=\"cycle-calculator\"\n data-component-id={id}\n className={rootVariants({ width, className })}\n >\n <div className=\"ds:grid ds:grid-cols-1 ds:gap-[var(--spacing-md)] ds:sm:grid-cols-2\">\n <FormField label={t('cycleCalculator.lastPeriod')}>\n <DatePicker\n value={lastPeriod}\n onChange={setLastPeriod}\n maxDate={today}\n />\n </FormField>\n <FormField\n label={t('cycleCalculator.cycleLength')}\n description={t('cycleCalculator.cycleLengthHint')}\n >\n <NumberInput\n mode=\"integer\"\n min={20}\n max={45}\n value={cycleLength}\n onChange={setCycleLength}\n />\n </FormField>\n </div>\n\n <p className=\"ds:sr-only\" role=\"status\" aria-live=\"polite\">\n {result\n ? `${t('cycleCalculator.ovulation')}: ${fmt(result.ovulation)}. ${t(\n 'cycleCalculator.nextPeriod',\n )}: ${fmt(result.nextPeriod)}.`\n : ''}\n </p>\n\n {result ? (\n <div className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-md)]\">\n <dl className=\"ds:grid ds:grid-cols-1 ds:gap-[var(--spacing-md)] ds:sm:grid-cols-3\">\n <div className=\"ds:flex ds:flex-col ds:items-center ds:gap-[var(--spacing-xs)] ds:text-center\">\n <dt className=\"type-label ds:text-muted-foreground\">\n {t('cycleCalculator.ovulation')}\n </dt>\n <dd>\n <Badge\n variant=\"success\"\n size=\"lg\"\n leading={<Check aria-hidden />}\n >\n {fmt(result.ovulation)}\n </Badge>\n </dd>\n </div>\n <div className=\"ds:flex ds:flex-col ds:items-center ds:gap-[var(--spacing-xs)] ds:text-center\">\n <dt className=\"type-label ds:text-muted-foreground\">\n {t('cycleCalculator.fertileWindow')}\n </dt>\n <dd>\n <Badge\n variant=\"accent\"\n size=\"lg\"\n leading={<Heart aria-hidden />}\n >\n {fmt(result.fertileWindow.start)} –{' '}\n {fmt(result.fertileWindow.end)}\n </Badge>\n </dd>\n </div>\n <div className=\"ds:flex ds:flex-col ds:items-center ds:gap-[var(--spacing-xs)] ds:text-center\">\n <dt className=\"type-label ds:text-muted-foreground\">\n {t('cycleCalculator.nextPeriod')}\n </dt>\n <dd>\n <Badge\n variant=\"error\"\n size=\"lg\"\n leading={<Droplet aria-hidden />}\n >\n {fmt(result.nextPeriod)}\n </Badge>\n </dd>\n </div>\n </dl>\n {insertVariant === 'copy' || onInsert ? (\n <InsertButton\n onInsert={onInsert}\n variant={insertVariant}\n onCopy={onCopy}\n onError={onError}\n card={{\n title: t('insert.title.cycle'),\n fields: [\n {\n label: t('cycleCalculator.ovulation'),\n value: fmt(result.ovulation),\n },\n {\n label: t('cycleCalculator.fertileWindow'),\n value: `${fmt(result.fertileWindow.start)} – ${fmt(\n result.fertileWindow.end,\n )}`,\n },\n {\n label: t('cycleCalculator.nextPeriod'),\n value: fmt(result.nextPeriod),\n },\n ],\n }}\n />\n ) : null}\n </div>\n ) : (\n <p className=\"type-body ds:text-muted-foreground\">\n {t('cycleCalculator.empty')}\n </p>\n )}\n </div>\n );\n },\n);\n\nCycleCalculator.displayName = 'CycleCalculator';\n"],"names":["__iconNode","Droplet","createLucideIcon","DEFAULT_CYCLE_LENGTH","LUTEAL_PHASE_DAYS","FERTILE_DAYS_AFTER","predictCycle","input","occurrences","cycle","lastPeriodStart","ovulation","addDays","fertileWindow","nextPeriod","upcomingPeriods","_","i","rootVariants","cva","CycleCalculator","forwardRef","defaultCycleLength","onResultChange","onInsert","insertVariant","onCopy","onError","id","width","className","ref","t","i18n","useTranslation","lastPeriod","setLastPeriod","useState","cycleLength","setCycleLength","result","useMemo","dateFormatter","useEffect","today","fmt","d","jsxs","jsx","FormField","DatePicker","NumberInput","Badge","Check","Heart","InsertButton"],"mappings":"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","x_google_ignoreList":[0]}
|
|
@@ -114,9 +114,9 @@ const rr = [
|
|
|
114
114
|
{
|
|
115
115
|
variants: {
|
|
116
116
|
size: {
|
|
117
|
-
sm: "ds:max-inline-size
|
|
118
|
-
md: "ds:max-inline-size
|
|
119
|
-
lg: "ds:max-inline-size
|
|
117
|
+
sm: "ds:[max-inline-size:20rem]",
|
|
118
|
+
md: "ds:[max-inline-size:28rem]",
|
|
119
|
+
lg: "ds:[max-inline-size:36rem]"
|
|
120
120
|
}
|
|
121
121
|
},
|
|
122
122
|
defaultVariants: { size: "md" }
|
|
@@ -520,7 +520,7 @@ const lr = {
|
|
|
520
520
|
{
|
|
521
521
|
intent: "secondary",
|
|
522
522
|
size: "md",
|
|
523
|
-
className: "ds:min-block-size
|
|
523
|
+
className: "ds:[min-block-size:var(--min-target-size)] ds:[min-inline-size:var(--min-target-size)]",
|
|
524
524
|
startIcon: /* @__PURE__ */ n(Je, { "aria-hidden": "true" }),
|
|
525
525
|
onClick: te,
|
|
526
526
|
disabled: g,
|
|
@@ -533,7 +533,7 @@ const lr = {
|
|
|
533
533
|
ref: me,
|
|
534
534
|
intent: "primary",
|
|
535
535
|
size: "md",
|
|
536
|
-
className: "ds:min-block-size
|
|
536
|
+
className: "ds:[min-block-size:var(--min-target-size)] ds:[min-inline-size:var(--min-target-size)]",
|
|
537
537
|
startIcon: /* @__PURE__ */ n(Qe, { "aria-hidden": "true" }),
|
|
538
538
|
onClick: ee,
|
|
539
539
|
disabled: g || b == null,
|
|
@@ -664,7 +664,7 @@ const lr = {
|
|
|
664
664
|
ref: pe,
|
|
665
665
|
intent: "primary",
|
|
666
666
|
size: "md",
|
|
667
|
-
className: "ds:min-block-size
|
|
667
|
+
className: "ds:[min-block-size:var(--min-target-size)] ds:[min-inline-size:var(--min-target-size)]",
|
|
668
668
|
loading: t === "requesting",
|
|
669
669
|
startIcon: /* @__PURE__ */ n(ye, { "aria-hidden": "true" }),
|
|
670
670
|
onClick: () => {
|
|
@@ -700,4 +700,4 @@ export {
|
|
|
700
700
|
ur as D,
|
|
701
701
|
nr as d
|
|
702
702
|
};
|
|
703
|
-
//# sourceMappingURL=document-scanner-
|
|
703
|
+
//# sourceMappingURL=document-scanner-BqLsGs4Y.js.map
|