@alfadocs/ui-kit-debug 0.31.4 → 0.31.6
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-UJA6Arbs.js → agenda-card-DtGlQde1.js} +2 -2
- package/dist/_chunks/{agenda-card-UJA6Arbs.js.map → agenda-card-DtGlQde1.js.map} +1 -1
- package/dist/_chunks/{agenda-tray-1fAxNOMz.js → agenda-tray-CXmlwt2K.js} +2 -2
- package/dist/_chunks/{agenda-tray-1fAxNOMz.js.map → agenda-tray-CXmlwt2K.js.map} +1 -1
- package/dist/_chunks/{badge-CptERaHx.js → badge-B9Cr6iEB.js} +30 -21
- package/dist/_chunks/badge-B9Cr6iEB.js.map +1 -0
- package/dist/_chunks/{benefit-card-CLPNpiQE.js → benefit-card-B86DH-PE.js} +14 -10
- package/dist/_chunks/benefit-card-B86DH-PE.js.map +1 -0
- package/dist/_chunks/{card-DKTMLVrw.js → card-CNri9ssR.js} +43 -37
- package/dist/_chunks/card-CNri9ssR.js.map +1 -0
- package/dist/_chunks/{contact-card-DYbp--s-.js → contact-card-Dos7Tley.js} +2 -2
- package/dist/_chunks/{contact-card-DYbp--s-.js.map → contact-card-Dos7Tley.js.map} +1 -1
- package/dist/_chunks/{editable-currency-cell-renderer-BpicmolK.js → editable-currency-cell-renderer-YvTwkFrD.js} +2 -2
- package/dist/_chunks/{editable-currency-cell-renderer-BpicmolK.js.map → editable-currency-cell-renderer-YvTwkFrD.js.map} +1 -1
- package/dist/_chunks/key-value-pair-CYE7NSpM.js +134 -0
- package/dist/_chunks/key-value-pair-CYE7NSpM.js.map +1 -0
- package/dist/_chunks/message-circle-C23eicgb.js +20 -0
- package/dist/_chunks/message-circle-C23eicgb.js.map +1 -0
- package/dist/_chunks/operator-hero-BsjE-kJF.js +171 -0
- package/dist/_chunks/operator-hero-BsjE-kJF.js.map +1 -0
- package/dist/_chunks/{patient-search-hFiYbqcl.js → patient-search-CSDru7QW.js} +2 -2
- package/dist/_chunks/{patient-search-hFiYbqcl.js.map → patient-search-CSDru7QW.js.map} +1 -1
- package/dist/_chunks/practice-profile-card-C2_2ZH_G.js +297 -0
- package/dist/_chunks/practice-profile-card-C2_2ZH_G.js.map +1 -0
- package/dist/_chunks/{practice-results-dOlljaAK.js → practice-results-VqbCUO1b.js} +225 -269
- package/dist/_chunks/practice-results-VqbCUO1b.js.map +1 -0
- package/dist/_chunks/{reviews-panel-yanuBZs-.js → reviews-panel-Cjys8G8K.js} +2 -2
- package/dist/_chunks/{reviews-panel-yanuBZs-.js.map → reviews-panel-Cjys8G8K.js.map} +1 -1
- package/dist/_chunks/shield-check-BhHyReu8.js +52 -0
- package/dist/_chunks/shield-check-BhHyReu8.js.map +1 -0
- package/dist/_chunks/{timeline-D0Wo7v_o.js → timeline-BZC7qGdy.js} +2 -2
- package/dist/_chunks/{timeline-D0Wo7v_o.js.map → timeline-BZC7qGdy.js.map} +1 -1
- package/dist/_chunks/{workflow-map-BSvQS3be.js → workflow-map-DfpjDZHK.js} +93 -107
- package/dist/_chunks/workflow-map-DfpjDZHK.js.map +1 -0
- package/dist/agent-catalog.json +55 -1
- package/dist/components/agenda-card/index.js +1 -1
- package/dist/components/agenda-tray/index.js +1 -1
- package/dist/components/badge/badge.d.ts +1 -1
- package/dist/components/badge/badge.d.ts.map +1 -1
- package/dist/components/badge/index.js +1 -1
- package/dist/components/benefit-card/benefit-card.d.ts.map +1 -1
- package/dist/components/benefit-card/index.js +1 -1
- package/dist/components/card/card.d.ts.map +1 -1
- package/dist/components/card/index.js +1 -1
- package/dist/components/contact-card/index.js +1 -1
- package/dist/components/data-table/index.js +1 -1
- package/dist/components/index.d.ts +2 -0
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/key-value-pair/index.d.ts +2 -2
- package/dist/components/key-value-pair/index.d.ts.map +1 -1
- package/dist/components/key-value-pair/index.js +3 -2
- package/dist/components/key-value-pair/key-value-pair.d.ts +10 -0
- package/dist/components/key-value-pair/key-value-pair.d.ts.map +1 -1
- package/dist/components/operator-hero/index.d.ts +4 -0
- package/dist/components/operator-hero/index.d.ts.map +1 -0
- package/dist/components/operator-hero/index.js +6 -0
- package/dist/components/operator-hero/index.js.map +1 -0
- package/dist/components/operator-hero/operator-hero.agent.d.ts +4 -0
- package/dist/components/operator-hero/operator-hero.agent.d.ts.map +1 -0
- package/dist/components/operator-hero/operator-hero.d.ts +64 -0
- package/dist/components/operator-hero/operator-hero.d.ts.map +1 -0
- package/dist/components/patient-search/index.js +1 -1
- package/dist/components/practice-profile-card/index.d.ts +4 -0
- package/dist/components/practice-profile-card/index.d.ts.map +1 -0
- package/dist/components/practice-profile-card/index.js +8 -0
- package/dist/components/practice-profile-card/index.js.map +1 -0
- package/dist/components/practice-profile-card/practice-profile-card.agent.d.ts +4 -0
- package/dist/components/practice-profile-card/practice-profile-card.agent.d.ts.map +1 -0
- package/dist/components/practice-profile-card/practice-profile-card.d.ts +115 -0
- package/dist/components/practice-profile-card/practice-profile-card.d.ts.map +1 -0
- package/dist/components/practice-results/index.js +1 -1
- package/dist/components/reviews-panel/index.js +1 -1
- package/dist/components/timeline/index.js +1 -1
- package/dist/components/workflow/index.js +1 -1
- package/dist/i18n/locales/ar.d.ts +23 -0
- package/dist/i18n/locales/ar.d.ts.map +1 -1
- package/dist/i18n/locales/ar.js +23 -0
- package/dist/i18n/locales/ar.js.map +1 -1
- package/dist/i18n/locales/de.d.ts +23 -0
- package/dist/i18n/locales/de.d.ts.map +1 -1
- package/dist/i18n/locales/de.js +23 -0
- package/dist/i18n/locales/de.js.map +1 -1
- package/dist/i18n/locales/el.d.ts +23 -0
- package/dist/i18n/locales/el.d.ts.map +1 -1
- package/dist/i18n/locales/el.js +23 -0
- package/dist/i18n/locales/el.js.map +1 -1
- package/dist/i18n/locales/en.d.ts +23 -0
- package/dist/i18n/locales/en.d.ts.map +1 -1
- package/dist/i18n/locales/en.js +23 -0
- package/dist/i18n/locales/en.js.map +1 -1
- package/dist/i18n/locales/es.d.ts +23 -0
- package/dist/i18n/locales/es.d.ts.map +1 -1
- package/dist/i18n/locales/es.js +23 -0
- package/dist/i18n/locales/es.js.map +1 -1
- package/dist/i18n/locales/fr.d.ts +23 -0
- package/dist/i18n/locales/fr.d.ts.map +1 -1
- package/dist/i18n/locales/fr.js +23 -0
- package/dist/i18n/locales/fr.js.map +1 -1
- package/dist/i18n/locales/hi.d.ts +23 -0
- package/dist/i18n/locales/hi.d.ts.map +1 -1
- package/dist/i18n/locales/hi.js +23 -0
- package/dist/i18n/locales/hi.js.map +1 -1
- package/dist/i18n/locales/it.d.ts +23 -0
- package/dist/i18n/locales/it.d.ts.map +1 -1
- package/dist/i18n/locales/it.js +23 -0
- package/dist/i18n/locales/it.js.map +1 -1
- package/dist/i18n/locales/ja.d.ts +23 -0
- package/dist/i18n/locales/ja.d.ts.map +1 -1
- package/dist/i18n/locales/ja.js +23 -0
- package/dist/i18n/locales/ja.js.map +1 -1
- package/dist/i18n/locales/nl.d.ts +23 -0
- package/dist/i18n/locales/nl.d.ts.map +1 -1
- package/dist/i18n/locales/nl.js +23 -0
- package/dist/i18n/locales/nl.js.map +1 -1
- package/dist/i18n/locales/pl.d.ts +23 -0
- package/dist/i18n/locales/pl.d.ts.map +1 -1
- package/dist/i18n/locales/pl.js +23 -0
- package/dist/i18n/locales/pl.js.map +1 -1
- package/dist/i18n/locales/pt.d.ts +23 -0
- package/dist/i18n/locales/pt.d.ts.map +1 -1
- package/dist/i18n/locales/pt.js +23 -0
- package/dist/i18n/locales/pt.js.map +1 -1
- package/dist/i18n/locales/ro.d.ts +23 -0
- package/dist/i18n/locales/ro.d.ts.map +1 -1
- package/dist/i18n/locales/ro.js +23 -0
- package/dist/i18n/locales/ro.js.map +1 -1
- package/dist/i18n/locales/ru.d.ts +23 -0
- package/dist/i18n/locales/ru.d.ts.map +1 -1
- package/dist/i18n/locales/ru.js +23 -0
- package/dist/i18n/locales/ru.js.map +1 -1
- package/dist/i18n/locales/sq.d.ts +23 -0
- package/dist/i18n/locales/sq.d.ts.map +1 -1
- package/dist/i18n/locales/sq.js +23 -0
- package/dist/i18n/locales/sq.js.map +1 -1
- package/dist/i18n/locales/sv.d.ts +23 -0
- package/dist/i18n/locales/sv.d.ts.map +1 -1
- package/dist/i18n/locales/sv.js +23 -0
- package/dist/i18n/locales/sv.js.map +1 -1
- package/dist/i18n/locales/tr.d.ts +23 -0
- package/dist/i18n/locales/tr.d.ts.map +1 -1
- package/dist/i18n/locales/tr.js +23 -0
- package/dist/i18n/locales/tr.js.map +1 -1
- package/dist/i18n/locales/zh.d.ts +23 -0
- package/dist/i18n/locales/zh.d.ts.map +1 -1
- package/dist/i18n/locales/zh.js +23 -0
- package/dist/i18n/locales/zh.js.map +1 -1
- package/dist/index.js +400 -391
- package/dist/index.js.map +1 -1
- package/dist/locales/ar.json +23 -0
- package/dist/locales/de.json +23 -0
- package/dist/locales/el.json +23 -0
- package/dist/locales/en.json +23 -0
- package/dist/locales/es.json +23 -0
- package/dist/locales/fr.json +23 -0
- package/dist/locales/hi.json +23 -0
- package/dist/locales/it.json +23 -0
- package/dist/locales/ja.json +23 -0
- package/dist/locales/nl.json +23 -0
- package/dist/locales/pl.json +23 -0
- package/dist/locales/pt.json +23 -0
- package/dist/locales/ro.json +23 -0
- package/dist/locales/ru.json +23 -0
- package/dist/locales/sq.json +23 -0
- package/dist/locales/sv.json +23 -0
- package/dist/locales/tr.json +23 -0
- package/dist/locales/zh.json +23 -0
- package/dist/tokens.css +1 -1
- package/package.json +9 -1
- package/dist/_chunks/badge-CptERaHx.js.map +0 -1
- package/dist/_chunks/benefit-card-CLPNpiQE.js.map +0 -1
- package/dist/_chunks/card-DKTMLVrw.js.map +0 -1
- package/dist/_chunks/key-value-pair-C8DaR3Xs.js +0 -98
- package/dist/_chunks/key-value-pair-C8DaR3Xs.js.map +0 -1
- package/dist/_chunks/practice-results-dOlljaAK.js.map +0 -1
- package/dist/_chunks/workflow-map-BSvQS3be.js.map +0 -1
|
@@ -3,7 +3,7 @@ import { forwardRef as v } from "react";
|
|
|
3
3
|
import { c as h } from "./index-D2ZczOXr.js";
|
|
4
4
|
import { useTranslation as b } from "react-i18next";
|
|
5
5
|
import { A as x } from "./avatar-BNQNhoyL.js";
|
|
6
|
-
import { B as y } from "./badge-
|
|
6
|
+
import { B as y } from "./badge-B9Cr6iEB.js";
|
|
7
7
|
import { C as N } from "./chevron-right-BrpYejk0.js";
|
|
8
8
|
const C = h(
|
|
9
9
|
[
|
|
@@ -138,4 +138,4 @@ export {
|
|
|
138
138
|
T as A,
|
|
139
139
|
w as i
|
|
140
140
|
};
|
|
141
|
-
//# sourceMappingURL=agenda-card-
|
|
141
|
+
//# sourceMappingURL=agenda-card-DtGlQde1.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agenda-card-UJA6Arbs.js","sources":["../../src/components/agenda-card/agenda-card.tsx"],"sourcesContent":["import { forwardRef, type HTMLAttributes, type ReactNode } from 'react';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { useTranslation } from 'react-i18next';\nimport { ChevronRight } from 'lucide-react';\nimport { Avatar } from '../avatar/avatar';\nimport { Badge } from '../badge/badge';\n\n/* ------------------------------------------------------------------ */\n/* Types */\n/* ------------------------------------------------------------------ */\n\nexport type AppointmentStatus = 'confirmed' | 'pending' | 'cancelled';\n\nexport interface AgendaItem {\n /** Unique identifier for the appointment. */\n id: string;\n /** Display time string (e.g. \"09:00\"). Localised by the consumer. */\n time: string;\n /** Patient identity — drives the avatar's initials + accessible name. */\n patient: { name: string; avatarUrl?: string };\n /** Treatment / appointment type — short localised label. */\n treatment?: string;\n /** Lifecycle state — drives a trailing status chip. */\n status?: AppointmentStatus;\n /** Optional deep link — when present the row is an anchor. */\n url?: string;\n}\n\nexport interface AgendaCardProps\n extends\n Omit<HTMLAttributes<HTMLDivElement>, 'onClick' | 'role' | 'title'>,\n VariantProps<typeof agendaCardVariants> {\n /** The appointment to render. */\n item: AgendaItem;\n /** Visual density. */\n size?: 'sm' | 'md';\n /** Fires when the row is activated. */\n onActivate?: (item: AgendaItem) => void;\n}\n\n/* ------------------------------------------------------------------ */\n/* CVA */\n/* ------------------------------------------------------------------ */\n\nconst agendaCardVariants = cva(\n [\n 'ds:relative ds:flex ds:items-center ds:gap-[var(--spacing-sm)]',\n 'ds:rounded-[var(--radius-sm)]',\n 'ds:transition-colors',\n 'ds:motion-reduce:transition-none',\n 'ds:text-start ds:group',\n 'ds:forced-colors:border ds:forced-colors:border-[CanvasText]',\n ].join(' '),\n {\n variants: {\n size: {\n sm: 'ds:p-[var(--spacing-sm)]',\n md: 'ds:p-[var(--spacing-md)]',\n },\n interactive: {\n true: 'ds:hover:bg-[color:var(--muted)]/40 ds:cursor-pointer',\n false: '',\n },\n },\n defaultVariants: {\n size: 'sm',\n interactive: false,\n },\n },\n);\n\nconst stretchedLinkClass = [\n 'ds:focus-visible:outline-none',\n \"ds:after:content-[''] ds:after:absolute ds:after:inset-0 ds:after:rounded-[var(--radius-sm)]\",\n 'ds:after:pointer-events-auto',\n 'ds:focus-visible:after:outline-[length:var(--focus-ring-width)]',\n 'ds:focus-visible:after:outline-solid',\n 'ds:focus-visible:after:outline-[color:var(--ring)]',\n 'ds:focus-visible:after:outline-offset-[length:var(--focus-ring-offset)]',\n 'ds:forced-colors:focus-visible:after:outline-[CanvasText]',\n].join(' ');\n\nexport function isSafeAgendaUrl(url: string): boolean {\n return /^(https?:\\/\\/(?!\\/)|\\/(?!\\/)|#)/.test(url);\n}\n\nconst STATUS_TONE: Record<AppointmentStatus, 'success' | 'warning' | 'error'> =\n {\n confirmed: 'success',\n pending: 'warning',\n cancelled: 'error',\n };\n\n/* ------------------------------------------------------------------ */\n/* Component */\n/* ------------------------------------------------------------------ */\n\nexport const AgendaCard = forwardRef<HTMLDivElement, AgendaCardProps>(\n ({ item, size = 'sm', onActivate, className, ...rest }, ref) => {\n const { t } = useTranslation();\n const interactive = !!onActivate;\n const hasSafeUrl = !!item.url && isSafeAgendaUrl(item.url);\n const ariaLabel = t('agendaCard.itemLabel', {\n time: item.time,\n patient: item.patient.name,\n treatment: item.treatment ?? '',\n defaultValue: '{{time}} · {{patient}}{{treatment, prepend, \" · \"}}',\n });\n\n const titleNode = (\n <span className=\"ds:flex-1 ds:min-w-0 ds:truncate type-body-sm ds:text-[color:var(--foreground)]\">\n {item.patient.name}\n </span>\n );\n\n let activator: ReactNode;\n if (interactive && hasSafeUrl) {\n activator = (\n <a\n href={item.url}\n aria-label={ariaLabel}\n className={stretchedLinkClass + ' ds:contents'}\n onClick={(e) => {\n if (e.defaultPrevented || e.metaKey || e.ctrlKey || e.shiftKey)\n return;\n onActivate?.(item);\n }}\n >\n {titleNode}\n </a>\n );\n } else if (interactive) {\n activator = (\n <button\n type=\"button\"\n aria-label={ariaLabel}\n className={\n stretchedLinkClass +\n ' ds:contents ds:bg-transparent ds:border-0 ds:p-0 ds:text-start'\n }\n onClick={() => onActivate?.(item)}\n >\n {titleNode}\n </button>\n );\n } else {\n activator = titleNode;\n }\n\n return (\n <div\n ref={ref}\n role=\"listitem\"\n data-component=\"agenda-card\"\n data-component-id={item.id}\n data-status={item.status ?? 'confirmed'}\n className={agendaCardVariants({ size, interactive, className })}\n {...rest}\n >\n <span\n aria-hidden=\"true\"\n className=\"ds:inline-flex ds:w-12 ds:shrink-0 type-body-sm ds:font-medium ds:text-[color:var(--foreground)] ds:tabular-nums\"\n >\n {item.time}\n </span>\n\n <Avatar\n name={item.patient.name}\n src={item.patient.avatarUrl}\n size={size === 'md' ? 'md' : 'sm'}\n className=\"ds:shrink-0\"\n aria-hidden=\"true\"\n role=\"presentation\"\n aria-label={undefined}\n />\n\n <div className=\"ds:flex-1 ds:min-w-0 ds:flex ds:flex-col ds:gap-[var(--spacing-2xs)]\">\n {activator}\n {item.treatment ? (\n <span className=\"type-eyebrow ds:text-[color:var(--muted-foreground)] ds:truncate\">\n {item.treatment}\n </span>\n ) : null}\n </div>\n\n {item.status && item.status !== 'confirmed' ? (\n <Badge\n variant={STATUS_TONE[item.status]}\n size=\"sm\"\n withDot\n className=\"ds:shrink-0\"\n >\n {t(`agendaCard.status.${item.status}`, item.status)}\n </Badge>\n ) : null}\n\n {interactive ? (\n <ChevronRight\n aria-hidden=\"true\"\n className=\"ds:size-4 ds:shrink-0 ds:text-[color:var(--muted-foreground)] ds:opacity-0 ds:transition-opacity ds:motion-reduce:transition-none ds:group-hover:opacity-100 ds:group-focus-within:opacity-100 ds:rtl:rotate-180\"\n />\n ) : null}\n </div>\n );\n },\n);\n\nAgendaCard.displayName = 'AgendaCard';\n"],"names":["agendaCardVariants","cva","stretchedLinkClass","isSafeAgendaUrl","url","STATUS_TONE","AgendaCard","forwardRef","item","size","onActivate","className","rest","ref","t","useTranslation","interactive","hasSafeUrl","ariaLabel","titleNode","jsx","activator","e","jsxs","Avatar","Badge","ChevronRight"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"agenda-card-DtGlQde1.js","sources":["../../src/components/agenda-card/agenda-card.tsx"],"sourcesContent":["import { forwardRef, type HTMLAttributes, type ReactNode } from 'react';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { useTranslation } from 'react-i18next';\nimport { ChevronRight } from 'lucide-react';\nimport { Avatar } from '../avatar/avatar';\nimport { Badge } from '../badge/badge';\n\n/* ------------------------------------------------------------------ */\n/* Types */\n/* ------------------------------------------------------------------ */\n\nexport type AppointmentStatus = 'confirmed' | 'pending' | 'cancelled';\n\nexport interface AgendaItem {\n /** Unique identifier for the appointment. */\n id: string;\n /** Display time string (e.g. \"09:00\"). Localised by the consumer. */\n time: string;\n /** Patient identity — drives the avatar's initials + accessible name. */\n patient: { name: string; avatarUrl?: string };\n /** Treatment / appointment type — short localised label. */\n treatment?: string;\n /** Lifecycle state — drives a trailing status chip. */\n status?: AppointmentStatus;\n /** Optional deep link — when present the row is an anchor. */\n url?: string;\n}\n\nexport interface AgendaCardProps\n extends\n Omit<HTMLAttributes<HTMLDivElement>, 'onClick' | 'role' | 'title'>,\n VariantProps<typeof agendaCardVariants> {\n /** The appointment to render. */\n item: AgendaItem;\n /** Visual density. */\n size?: 'sm' | 'md';\n /** Fires when the row is activated. */\n onActivate?: (item: AgendaItem) => void;\n}\n\n/* ------------------------------------------------------------------ */\n/* CVA */\n/* ------------------------------------------------------------------ */\n\nconst agendaCardVariants = cva(\n [\n 'ds:relative ds:flex ds:items-center ds:gap-[var(--spacing-sm)]',\n 'ds:rounded-[var(--radius-sm)]',\n 'ds:transition-colors',\n 'ds:motion-reduce:transition-none',\n 'ds:text-start ds:group',\n 'ds:forced-colors:border ds:forced-colors:border-[CanvasText]',\n ].join(' '),\n {\n variants: {\n size: {\n sm: 'ds:p-[var(--spacing-sm)]',\n md: 'ds:p-[var(--spacing-md)]',\n },\n interactive: {\n true: 'ds:hover:bg-[color:var(--muted)]/40 ds:cursor-pointer',\n false: '',\n },\n },\n defaultVariants: {\n size: 'sm',\n interactive: false,\n },\n },\n);\n\nconst stretchedLinkClass = [\n 'ds:focus-visible:outline-none',\n \"ds:after:content-[''] ds:after:absolute ds:after:inset-0 ds:after:rounded-[var(--radius-sm)]\",\n 'ds:after:pointer-events-auto',\n 'ds:focus-visible:after:outline-[length:var(--focus-ring-width)]',\n 'ds:focus-visible:after:outline-solid',\n 'ds:focus-visible:after:outline-[color:var(--ring)]',\n 'ds:focus-visible:after:outline-offset-[length:var(--focus-ring-offset)]',\n 'ds:forced-colors:focus-visible:after:outline-[CanvasText]',\n].join(' ');\n\nexport function isSafeAgendaUrl(url: string): boolean {\n return /^(https?:\\/\\/(?!\\/)|\\/(?!\\/)|#)/.test(url);\n}\n\nconst STATUS_TONE: Record<AppointmentStatus, 'success' | 'warning' | 'error'> =\n {\n confirmed: 'success',\n pending: 'warning',\n cancelled: 'error',\n };\n\n/* ------------------------------------------------------------------ */\n/* Component */\n/* ------------------------------------------------------------------ */\n\nexport const AgendaCard = forwardRef<HTMLDivElement, AgendaCardProps>(\n ({ item, size = 'sm', onActivate, className, ...rest }, ref) => {\n const { t } = useTranslation();\n const interactive = !!onActivate;\n const hasSafeUrl = !!item.url && isSafeAgendaUrl(item.url);\n const ariaLabel = t('agendaCard.itemLabel', {\n time: item.time,\n patient: item.patient.name,\n treatment: item.treatment ?? '',\n defaultValue: '{{time}} · {{patient}}{{treatment, prepend, \" · \"}}',\n });\n\n const titleNode = (\n <span className=\"ds:flex-1 ds:min-w-0 ds:truncate type-body-sm ds:text-[color:var(--foreground)]\">\n {item.patient.name}\n </span>\n );\n\n let activator: ReactNode;\n if (interactive && hasSafeUrl) {\n activator = (\n <a\n href={item.url}\n aria-label={ariaLabel}\n className={stretchedLinkClass + ' ds:contents'}\n onClick={(e) => {\n if (e.defaultPrevented || e.metaKey || e.ctrlKey || e.shiftKey)\n return;\n onActivate?.(item);\n }}\n >\n {titleNode}\n </a>\n );\n } else if (interactive) {\n activator = (\n <button\n type=\"button\"\n aria-label={ariaLabel}\n className={\n stretchedLinkClass +\n ' ds:contents ds:bg-transparent ds:border-0 ds:p-0 ds:text-start'\n }\n onClick={() => onActivate?.(item)}\n >\n {titleNode}\n </button>\n );\n } else {\n activator = titleNode;\n }\n\n return (\n <div\n ref={ref}\n role=\"listitem\"\n data-component=\"agenda-card\"\n data-component-id={item.id}\n data-status={item.status ?? 'confirmed'}\n className={agendaCardVariants({ size, interactive, className })}\n {...rest}\n >\n <span\n aria-hidden=\"true\"\n className=\"ds:inline-flex ds:w-12 ds:shrink-0 type-body-sm ds:font-medium ds:text-[color:var(--foreground)] ds:tabular-nums\"\n >\n {item.time}\n </span>\n\n <Avatar\n name={item.patient.name}\n src={item.patient.avatarUrl}\n size={size === 'md' ? 'md' : 'sm'}\n className=\"ds:shrink-0\"\n aria-hidden=\"true\"\n role=\"presentation\"\n aria-label={undefined}\n />\n\n <div className=\"ds:flex-1 ds:min-w-0 ds:flex ds:flex-col ds:gap-[var(--spacing-2xs)]\">\n {activator}\n {item.treatment ? (\n <span className=\"type-eyebrow ds:text-[color:var(--muted-foreground)] ds:truncate\">\n {item.treatment}\n </span>\n ) : null}\n </div>\n\n {item.status && item.status !== 'confirmed' ? (\n <Badge\n variant={STATUS_TONE[item.status]}\n size=\"sm\"\n withDot\n className=\"ds:shrink-0\"\n >\n {t(`agendaCard.status.${item.status}`, item.status)}\n </Badge>\n ) : null}\n\n {interactive ? (\n <ChevronRight\n aria-hidden=\"true\"\n className=\"ds:size-4 ds:shrink-0 ds:text-[color:var(--muted-foreground)] ds:opacity-0 ds:transition-opacity ds:motion-reduce:transition-none ds:group-hover:opacity-100 ds:group-focus-within:opacity-100 ds:rtl:rotate-180\"\n />\n ) : null}\n </div>\n );\n },\n);\n\nAgendaCard.displayName = 'AgendaCard';\n"],"names":["agendaCardVariants","cva","stretchedLinkClass","isSafeAgendaUrl","url","STATUS_TONE","AgendaCard","forwardRef","item","size","onActivate","className","rest","ref","t","useTranslation","interactive","hasSafeUrl","ariaLabel","titleNode","jsx","activator","e","jsxs","Avatar","Badge","ChevronRight"],"mappings":"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"}
|
|
@@ -5,7 +5,7 @@ import { useTranslation as j } from "react-i18next";
|
|
|
5
5
|
import { I as _ } from "./icon-button-CKEOrN37.js";
|
|
6
6
|
import { S as E } from "./skeleton-CZbwyJAA.js";
|
|
7
7
|
import { E as P } from "./empty-state-BLy7tigq.js";
|
|
8
|
-
import { A as H } from "./agenda-card-
|
|
8
|
+
import { A as H } from "./agenda-card-DtGlQde1.js";
|
|
9
9
|
import { u as K } from "./registry-nPAVE19X.js";
|
|
10
10
|
import { c as L } from "./createLucideIcon-CrFbzy84.js";
|
|
11
11
|
import { P as V } from "./plus-CYKNmfuA.js";
|
|
@@ -178,4 +178,4 @@ export {
|
|
|
178
178
|
G as A,
|
|
179
179
|
D as a
|
|
180
180
|
};
|
|
181
|
-
//# sourceMappingURL=agenda-tray-
|
|
181
|
+
//# sourceMappingURL=agenda-tray-CXmlwt2K.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agenda-tray-1fAxNOMz.js","sources":["../../node_modules/lucide-react/dist/esm/icons/calendar-days.js","../../src/components/agenda-tray/agenda-tray.agent.ts","../../src/components/agenda-tray/agenda-tray.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 [\"path\", { d: \"M8 2v4\", key: \"1cmpym\" }],\n [\"path\", { d: \"M16 2v4\", key: \"4m81vk\" }],\n [\"rect\", { width: \"18\", height: \"18\", x: \"3\", y: \"4\", rx: \"2\", key: \"1hopcy\" }],\n [\"path\", { d: \"M3 10h18\", key: \"8toen8\" }],\n [\"path\", { d: \"M8 14h.01\", key: \"6423bh\" }],\n [\"path\", { d: \"M12 14h.01\", key: \"1etili\" }],\n [\"path\", { d: \"M16 14h.01\", key: \"1gbofw\" }],\n [\"path\", { d: \"M8 18h.01\", key: \"lrp35t\" }],\n [\"path\", { d: \"M12 18h.01\", key: \"mhygvu\" }],\n [\"path\", { d: \"M16 18h.01\", key: \"kzsmim\" }]\n];\nconst CalendarDays = createLucideIcon(\"calendar-days\", __iconNode);\n\nexport { __iconNode, CalendarDays as default };\n//# sourceMappingURL=calendar-days.js.map\n","/* -------------------------------------------------------------------- */\n/* Agent adapter — AgendaTray. */\n/* */\n/* Tray-level surface: read appointment ids + lifecycle status (never */\n/* patient names / treatments), and route an activation through the */\n/* curated handle. AgendaTray is in-page (no open/close). */\n/* -------------------------------------------------------------------- */\n\nimport type { AgentAdapter } from '../../agent/types';\nimport type { AgendaTrayHandle } from './agenda-tray';\n\nexport const agendaTrayAgent: AgentAdapter<AgendaTrayHandle> = {\n id: 'agenda-tray',\n capabilities: ['select_single'],\n state: {\n items: {\n type: 'Array<{ id: string; status: string }>',\n descriptionKey: 'ui.agent.agendaTray.state.items',\n description:\n 'Currently-displayed appointments. Ids + status only — never patient identity.',\n read: (handle) => handle.getItems(),\n },\n },\n actions: {\n select_item: {\n safety: 'read',\n argsType: '{ id: string }',\n descriptionKey: 'ui.agent.agendaTray.actions.selectItem',\n description: 'Activate the appointment with the given id.',\n invoke: (handle, args: { id: string }) => {\n handle.selectItem(args.id);\n },\n },\n },\n domHooks: {\n root: {\n attr: 'data-component',\n value: 'agenda-tray',\n description: 'Marks the AgendaTray wrapper.',\n },\n instanceId: {\n attr: 'data-component-id',\n sourceProp: 'id',\n description:\n 'Sourced from the id prop. Required to address a specific tray from the agent.',\n },\n item: {\n attr: 'data-appointment-id',\n description:\n 'Stable appointment id emitted on each rendered AgendaCard inside the tray.',\n },\n },\n};\n","import {\n forwardRef,\n useImperativeHandle,\n useMemo,\n useRef,\n type HTMLAttributes,\n type ReactNode,\n} from 'react';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { useTranslation } from 'react-i18next';\nimport { CalendarDays, Plus } from 'lucide-react';\nimport { IconButton } from '../button/icon-button';\nimport { Skeleton } from '../skeleton/skeleton';\nimport { EmptyState } from '../empty-state/empty-state';\nimport { AgendaCard, type AgendaItem } from '../agenda-card';\nimport { useAgentRegistration } from '../../agent/registry';\nimport { agendaTrayAgent } from './agenda-tray.agent';\n\n/* ------------------------------------------------------------------ */\n/* CVA */\n/* ------------------------------------------------------------------ */\n\nconst agendaTrayVariants = cva(\n [\n 'ds:flex ds:flex-col',\n 'ds:rounded-[var(--radius-md)] ds:shadow-[var(--shadow-card)]',\n 'ds:bg-[color:var(--card)] ds:text-[color:var(--card-foreground)]',\n 'ds:overflow-hidden',\n ].join(' '),\n {\n variants: {\n size: {\n sm: '',\n md: '',\n },\n },\n defaultVariants: {\n size: 'sm',\n },\n },\n);\n\n/* ------------------------------------------------------------------ */\n/* Types */\n/* ------------------------------------------------------------------ */\n\n/**\n * Curated imperative handle for AgendaTray. Exposed as the forwardRef\n * target so a future agent / MCP UI bridge can drive the tray without\n * touching the DOM. See `agenda-tray.agent.ts`.\n */\nexport interface AgendaTrayHandle {\n getItems: () => Array<{ id: string; status: string }>;\n selectItem: (id: string) => void;\n}\n\nexport interface AgendaTrayProps\n extends\n Omit<HTMLAttributes<HTMLElement>, 'onClick' | 'id'>,\n VariantProps<typeof agendaTrayVariants> {\n /**\n * Stable instance id. Surfaced on the root as `data-component-id` so\n * an agent / MCP UI bridge can address this specific tray.\n */\n id?: string;\n items: AgendaItem[];\n /** Section title — rendered in the header. Localised by the consumer. */\n title?: string;\n /** Optional small caption (e.g. localised date) shown next to the title. */\n caption?: string;\n size?: 'sm' | 'md';\n onOpenAppointment?: (item: AgendaItem) => void;\n onAddAppointment?: () => void;\n /** Localised label for the \"Add\" affordance. */\n addLabel?: string;\n loading?: boolean;\n emptyTitle?: string;\n emptyDescription?: string;\n}\n\n/* ------------------------------------------------------------------ */\n/* Component */\n/* ------------------------------------------------------------------ */\n\nexport const AgendaTray = forwardRef<HTMLElement, AgendaTrayProps>(\n (\n {\n id,\n items,\n title,\n caption,\n size = 'sm',\n onOpenAppointment,\n onAddAppointment,\n addLabel,\n loading = false,\n emptyTitle,\n emptyDescription,\n className,\n ...rest\n },\n ref,\n ) => {\n const { t } = useTranslation();\n const heading = title ?? t('agendaTray.title', \"Today's appointments\");\n const resolvedAddLabel = addLabel ?? t('agendaTray.add', 'Add appointment');\n const isEmpty = !loading && items.length === 0;\n\n let body: ReactNode;\n if (loading) {\n body = (\n <div className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-sm)] ds:p-[var(--spacing-sm)]\">\n {[0, 1, 2].map((i) => (\n <Skeleton key={i} variant=\"rectangular\" height=\"2.5rem\" />\n ))}\n </div>\n );\n } else if (isEmpty) {\n body = (\n <div className=\"ds:p-[var(--spacing-md)]\">\n <EmptyState\n variant=\"first-use\"\n size=\"sm\"\n title={emptyTitle ?? t('agendaTray.empty.title', 'No appointments')}\n description={\n emptyDescription ??\n t(\n 'agendaTray.empty.description',\n 'New appointments will appear here.',\n )\n }\n />\n </div>\n );\n } else {\n body = (\n <ul className=\"ds:flex ds:list-none ds:flex-col\">\n {items.map((item) => (\n <AgendaCard\n key={item.id}\n item={item}\n size={size}\n onActivate={onOpenAppointment}\n data-appointment-id={item.id}\n />\n ))}\n </ul>\n );\n }\n\n /* Curated imperative handle for agent integration. See\n * agenda-tray.agent.ts. */\n const itemsRef = useRef<AgendaItem[]>(items);\n itemsRef.current = items;\n\n const innerRef = useRef<HTMLElement>(null);\n useImperativeHandle(ref, () => innerRef.current as HTMLElement, []);\n\n const handle = useMemo<AgendaTrayHandle>(\n () => ({\n getItems: () =>\n itemsRef.current.map((i) => ({\n id: i.id,\n status: i.status ?? 'confirmed',\n })),\n selectItem: (targetId: string) => {\n const found = itemsRef.current.find((i) => i.id === targetId);\n if (found) onOpenAppointment?.(found);\n },\n }),\n [onOpenAppointment],\n );\n\n useAgentRegistration(agendaTrayAgent, handle, id);\n\n return (\n <section\n ref={innerRef}\n aria-label={heading}\n data-component=\"agenda-tray\"\n data-component-id={id}\n className={agendaTrayVariants({ size, className })}\n {...rest}\n >\n <header className=\"ds:flex ds:items-center ds:justify-between ds:gap-[var(--spacing-sm)] ds:p-[var(--spacing-sm)]\">\n <div className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-2xs)] ds:min-w-0\">\n <h3 className=\"ds:m-0 ds:inline-flex ds:items-center ds:gap-[var(--spacing-xs)] type-title-card\">\n <CalendarDays aria-hidden=\"true\" className=\"ds:size-4\" />\n {heading}\n </h3>\n {caption ? (\n <span className=\"type-eyebrow ds:text-[color:var(--muted-foreground)]\">\n {caption}\n </span>\n ) : null}\n </div>\n {onAddAppointment ? (\n <IconButton\n icon={<Plus />}\n intent=\"outline\"\n size=\"sm\"\n aria-label={resolvedAddLabel}\n onClick={onAddAppointment}\n />\n ) : null}\n </header>\n {body}\n </section>\n );\n },\n);\n\nAgendaTray.displayName = 'AgendaTray';\n"],"names":["__iconNode","CalendarDays","createLucideIcon","agendaTrayAgent","handle","args","agendaTrayVariants","cva","AgendaTray","forwardRef","id","items","title","caption","size","onOpenAppointment","onAddAppointment","addLabel","loading","emptyTitle","emptyDescription","className","rest","ref","t","useTranslation","heading","resolvedAddLabel","isEmpty","body","jsx","i","Skeleton","EmptyState","item","AgendaCard","itemsRef","useRef","innerRef","useImperativeHandle","useMemo","targetId","found","useAgentRegistration","jsxs","IconButton","Plus"],"mappings":"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","x_google_ignoreList":[0]}
|
|
1
|
+
{"version":3,"file":"agenda-tray-CXmlwt2K.js","sources":["../../node_modules/lucide-react/dist/esm/icons/calendar-days.js","../../src/components/agenda-tray/agenda-tray.agent.ts","../../src/components/agenda-tray/agenda-tray.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 [\"path\", { d: \"M8 2v4\", key: \"1cmpym\" }],\n [\"path\", { d: \"M16 2v4\", key: \"4m81vk\" }],\n [\"rect\", { width: \"18\", height: \"18\", x: \"3\", y: \"4\", rx: \"2\", key: \"1hopcy\" }],\n [\"path\", { d: \"M3 10h18\", key: \"8toen8\" }],\n [\"path\", { d: \"M8 14h.01\", key: \"6423bh\" }],\n [\"path\", { d: \"M12 14h.01\", key: \"1etili\" }],\n [\"path\", { d: \"M16 14h.01\", key: \"1gbofw\" }],\n [\"path\", { d: \"M8 18h.01\", key: \"lrp35t\" }],\n [\"path\", { d: \"M12 18h.01\", key: \"mhygvu\" }],\n [\"path\", { d: \"M16 18h.01\", key: \"kzsmim\" }]\n];\nconst CalendarDays = createLucideIcon(\"calendar-days\", __iconNode);\n\nexport { __iconNode, CalendarDays as default };\n//# sourceMappingURL=calendar-days.js.map\n","/* -------------------------------------------------------------------- */\n/* Agent adapter — AgendaTray. */\n/* */\n/* Tray-level surface: read appointment ids + lifecycle status (never */\n/* patient names / treatments), and route an activation through the */\n/* curated handle. AgendaTray is in-page (no open/close). */\n/* -------------------------------------------------------------------- */\n\nimport type { AgentAdapter } from '../../agent/types';\nimport type { AgendaTrayHandle } from './agenda-tray';\n\nexport const agendaTrayAgent: AgentAdapter<AgendaTrayHandle> = {\n id: 'agenda-tray',\n capabilities: ['select_single'],\n state: {\n items: {\n type: 'Array<{ id: string; status: string }>',\n descriptionKey: 'ui.agent.agendaTray.state.items',\n description:\n 'Currently-displayed appointments. Ids + status only — never patient identity.',\n read: (handle) => handle.getItems(),\n },\n },\n actions: {\n select_item: {\n safety: 'read',\n argsType: '{ id: string }',\n descriptionKey: 'ui.agent.agendaTray.actions.selectItem',\n description: 'Activate the appointment with the given id.',\n invoke: (handle, args: { id: string }) => {\n handle.selectItem(args.id);\n },\n },\n },\n domHooks: {\n root: {\n attr: 'data-component',\n value: 'agenda-tray',\n description: 'Marks the AgendaTray wrapper.',\n },\n instanceId: {\n attr: 'data-component-id',\n sourceProp: 'id',\n description:\n 'Sourced from the id prop. Required to address a specific tray from the agent.',\n },\n item: {\n attr: 'data-appointment-id',\n description:\n 'Stable appointment id emitted on each rendered AgendaCard inside the tray.',\n },\n },\n};\n","import {\n forwardRef,\n useImperativeHandle,\n useMemo,\n useRef,\n type HTMLAttributes,\n type ReactNode,\n} from 'react';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { useTranslation } from 'react-i18next';\nimport { CalendarDays, Plus } from 'lucide-react';\nimport { IconButton } from '../button/icon-button';\nimport { Skeleton } from '../skeleton/skeleton';\nimport { EmptyState } from '../empty-state/empty-state';\nimport { AgendaCard, type AgendaItem } from '../agenda-card';\nimport { useAgentRegistration } from '../../agent/registry';\nimport { agendaTrayAgent } from './agenda-tray.agent';\n\n/* ------------------------------------------------------------------ */\n/* CVA */\n/* ------------------------------------------------------------------ */\n\nconst agendaTrayVariants = cva(\n [\n 'ds:flex ds:flex-col',\n 'ds:rounded-[var(--radius-md)] ds:shadow-[var(--shadow-card)]',\n 'ds:bg-[color:var(--card)] ds:text-[color:var(--card-foreground)]',\n 'ds:overflow-hidden',\n ].join(' '),\n {\n variants: {\n size: {\n sm: '',\n md: '',\n },\n },\n defaultVariants: {\n size: 'sm',\n },\n },\n);\n\n/* ------------------------------------------------------------------ */\n/* Types */\n/* ------------------------------------------------------------------ */\n\n/**\n * Curated imperative handle for AgendaTray. Exposed as the forwardRef\n * target so a future agent / MCP UI bridge can drive the tray without\n * touching the DOM. See `agenda-tray.agent.ts`.\n */\nexport interface AgendaTrayHandle {\n getItems: () => Array<{ id: string; status: string }>;\n selectItem: (id: string) => void;\n}\n\nexport interface AgendaTrayProps\n extends\n Omit<HTMLAttributes<HTMLElement>, 'onClick' | 'id'>,\n VariantProps<typeof agendaTrayVariants> {\n /**\n * Stable instance id. Surfaced on the root as `data-component-id` so\n * an agent / MCP UI bridge can address this specific tray.\n */\n id?: string;\n items: AgendaItem[];\n /** Section title — rendered in the header. Localised by the consumer. */\n title?: string;\n /** Optional small caption (e.g. localised date) shown next to the title. */\n caption?: string;\n size?: 'sm' | 'md';\n onOpenAppointment?: (item: AgendaItem) => void;\n onAddAppointment?: () => void;\n /** Localised label for the \"Add\" affordance. */\n addLabel?: string;\n loading?: boolean;\n emptyTitle?: string;\n emptyDescription?: string;\n}\n\n/* ------------------------------------------------------------------ */\n/* Component */\n/* ------------------------------------------------------------------ */\n\nexport const AgendaTray = forwardRef<HTMLElement, AgendaTrayProps>(\n (\n {\n id,\n items,\n title,\n caption,\n size = 'sm',\n onOpenAppointment,\n onAddAppointment,\n addLabel,\n loading = false,\n emptyTitle,\n emptyDescription,\n className,\n ...rest\n },\n ref,\n ) => {\n const { t } = useTranslation();\n const heading = title ?? t('agendaTray.title', \"Today's appointments\");\n const resolvedAddLabel = addLabel ?? t('agendaTray.add', 'Add appointment');\n const isEmpty = !loading && items.length === 0;\n\n let body: ReactNode;\n if (loading) {\n body = (\n <div className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-sm)] ds:p-[var(--spacing-sm)]\">\n {[0, 1, 2].map((i) => (\n <Skeleton key={i} variant=\"rectangular\" height=\"2.5rem\" />\n ))}\n </div>\n );\n } else if (isEmpty) {\n body = (\n <div className=\"ds:p-[var(--spacing-md)]\">\n <EmptyState\n variant=\"first-use\"\n size=\"sm\"\n title={emptyTitle ?? t('agendaTray.empty.title', 'No appointments')}\n description={\n emptyDescription ??\n t(\n 'agendaTray.empty.description',\n 'New appointments will appear here.',\n )\n }\n />\n </div>\n );\n } else {\n body = (\n <ul className=\"ds:flex ds:list-none ds:flex-col\">\n {items.map((item) => (\n <AgendaCard\n key={item.id}\n item={item}\n size={size}\n onActivate={onOpenAppointment}\n data-appointment-id={item.id}\n />\n ))}\n </ul>\n );\n }\n\n /* Curated imperative handle for agent integration. See\n * agenda-tray.agent.ts. */\n const itemsRef = useRef<AgendaItem[]>(items);\n itemsRef.current = items;\n\n const innerRef = useRef<HTMLElement>(null);\n useImperativeHandle(ref, () => innerRef.current as HTMLElement, []);\n\n const handle = useMemo<AgendaTrayHandle>(\n () => ({\n getItems: () =>\n itemsRef.current.map((i) => ({\n id: i.id,\n status: i.status ?? 'confirmed',\n })),\n selectItem: (targetId: string) => {\n const found = itemsRef.current.find((i) => i.id === targetId);\n if (found) onOpenAppointment?.(found);\n },\n }),\n [onOpenAppointment],\n );\n\n useAgentRegistration(agendaTrayAgent, handle, id);\n\n return (\n <section\n ref={innerRef}\n aria-label={heading}\n data-component=\"agenda-tray\"\n data-component-id={id}\n className={agendaTrayVariants({ size, className })}\n {...rest}\n >\n <header className=\"ds:flex ds:items-center ds:justify-between ds:gap-[var(--spacing-sm)] ds:p-[var(--spacing-sm)]\">\n <div className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-2xs)] ds:min-w-0\">\n <h3 className=\"ds:m-0 ds:inline-flex ds:items-center ds:gap-[var(--spacing-xs)] type-title-card\">\n <CalendarDays aria-hidden=\"true\" className=\"ds:size-4\" />\n {heading}\n </h3>\n {caption ? (\n <span className=\"type-eyebrow ds:text-[color:var(--muted-foreground)]\">\n {caption}\n </span>\n ) : null}\n </div>\n {onAddAppointment ? (\n <IconButton\n icon={<Plus />}\n intent=\"outline\"\n size=\"sm\"\n aria-label={resolvedAddLabel}\n onClick={onAddAppointment}\n />\n ) : null}\n </header>\n {body}\n </section>\n );\n },\n);\n\nAgendaTray.displayName = 'AgendaTray';\n"],"names":["__iconNode","CalendarDays","createLucideIcon","agendaTrayAgent","handle","args","agendaTrayVariants","cva","AgendaTray","forwardRef","id","items","title","caption","size","onOpenAppointment","onAddAppointment","addLabel","loading","emptyTitle","emptyDescription","className","rest","ref","t","useTranslation","heading","resolvedAddLabel","isEmpty","body","jsx","i","Skeleton","EmptyState","item","AgendaCard","itemsRef","useRef","innerRef","useImperativeHandle","useMemo","targetId","found","useAgentRegistration","jsxs","IconButton","Plus"],"mappings":"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","x_google_ignoreList":[0]}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { jsxs as
|
|
1
|
+
import { jsxs as l, jsx as e, Fragment as x } from "react/jsx-runtime";
|
|
2
2
|
import { forwardRef as w } from "react";
|
|
3
|
-
import { c as
|
|
3
|
+
import { c as a } from "./index-D2ZczOXr.js";
|
|
4
4
|
import { useTranslation as h } from "react-i18next";
|
|
5
5
|
import { T as y } from "./tooltip-DvmfrNvB.js";
|
|
6
|
-
const z =
|
|
6
|
+
const z = a(
|
|
7
7
|
[
|
|
8
8
|
"ds:inline-flex ds:items-center ds:gap-1",
|
|
9
9
|
// Typography comes from the eyebrow role: Medium 500 + uppercase + expanded tracking.
|
|
@@ -23,7 +23,12 @@ const z = r(
|
|
|
23
23
|
info: "ds:bg-info/15 ds:text-[var(--info-foreground)]",
|
|
24
24
|
success: "ds:bg-success/15 ds:text-[var(--success-foreground)]",
|
|
25
25
|
warning: "ds:bg-warning/15 ds:text-[var(--warning-foreground)]",
|
|
26
|
-
error: "ds:bg-destructive/15 ds:text-[var(--error-foreground)]"
|
|
26
|
+
error: "ds:bg-destructive/15 ds:text-[var(--error-foreground)]",
|
|
27
|
+
// Solid-fill brand variants — no border, foreground paired with the
|
|
28
|
+
// semantic token. Use for trust-signal chips in hero contexts where
|
|
29
|
+
// a tonal `info` / `neutral` would blend into the brand backdrop.
|
|
30
|
+
brand: "ds:bg-[var(--primary)] ds:text-[var(--primary-foreground)]",
|
|
31
|
+
accent: "ds:bg-[var(--accent)] ds:text-[var(--accent-foreground)]"
|
|
27
32
|
},
|
|
28
33
|
size: {
|
|
29
34
|
sm: "ds:h-4 ds:ps-1 ds:pe-1 ds:[--type-eyebrow-size:var(--font-size-2xs)]",
|
|
@@ -41,7 +46,7 @@ const z = r(
|
|
|
41
46
|
shape: "pill"
|
|
42
47
|
}
|
|
43
48
|
}
|
|
44
|
-
), N =
|
|
49
|
+
), N = a(
|
|
45
50
|
"ds:text-[length:var(--font-size-dot)] ds:leading-none ds:shrink-0",
|
|
46
51
|
{
|
|
47
52
|
variants: {
|
|
@@ -50,12 +55,16 @@ const z = r(
|
|
|
50
55
|
info: "ds:text-info",
|
|
51
56
|
success: "ds:text-success",
|
|
52
57
|
warning: "ds:text-warning",
|
|
53
|
-
error: "ds:text-destructive"
|
|
58
|
+
error: "ds:text-destructive",
|
|
59
|
+
// Solid-fill variants: dot draws in the paired foreground tone so
|
|
60
|
+
// it stays visible against the saturated primary/accent fill.
|
|
61
|
+
brand: "ds:text-[var(--primary-foreground)]",
|
|
62
|
+
accent: "ds:text-[var(--accent-foreground)]"
|
|
54
63
|
}
|
|
55
64
|
},
|
|
56
65
|
defaultVariants: { variant: "neutral" }
|
|
57
66
|
}
|
|
58
|
-
), V =
|
|
67
|
+
), V = a("ds:shrink-0 ds:[&>svg]:block", {
|
|
59
68
|
variants: {
|
|
60
69
|
size: {
|
|
61
70
|
// Icons shrink with the compact Badge scale: sm badge is 16 px tall, so
|
|
@@ -70,39 +79,39 @@ const z = r(
|
|
|
70
79
|
({
|
|
71
80
|
variant: t = "neutral",
|
|
72
81
|
size: n = "md",
|
|
73
|
-
shape:
|
|
82
|
+
shape: u = "pill",
|
|
74
83
|
leading: d,
|
|
75
|
-
withDot:
|
|
84
|
+
withDot: g = !1,
|
|
76
85
|
truncate: i = !1,
|
|
77
|
-
className:
|
|
86
|
+
className: f,
|
|
78
87
|
children: s,
|
|
79
88
|
"aria-label": o,
|
|
80
89
|
...p
|
|
81
|
-
},
|
|
82
|
-
const { t:
|
|
90
|
+
}, v) => {
|
|
91
|
+
const { t: m } = h(), r = !s && !!o, b = typeof s == "number", c = /* @__PURE__ */ l(
|
|
83
92
|
"span",
|
|
84
93
|
{
|
|
85
|
-
ref:
|
|
86
|
-
className: z({ variant: t, size: n, shape:
|
|
94
|
+
ref: v,
|
|
95
|
+
className: z({ variant: t, size: n, shape: u, className: f }),
|
|
87
96
|
"data-component": "badge",
|
|
88
|
-
role:
|
|
89
|
-
"aria-label":
|
|
97
|
+
role: r ? "img" : void 0,
|
|
98
|
+
"aria-label": r ? o : void 0,
|
|
90
99
|
...p,
|
|
91
100
|
children: [
|
|
92
|
-
|
|
101
|
+
g && /* @__PURE__ */ e("span", { "aria-hidden": "true", className: N({ variant: t }), children: "●" }),
|
|
93
102
|
d && /* @__PURE__ */ e("span", { "aria-hidden": "true", className: V({ size: n }), children: d }),
|
|
94
|
-
!
|
|
103
|
+
!r && (b ? /* @__PURE__ */ l(x, { children: [
|
|
95
104
|
/* @__PURE__ */ e("span", { "aria-hidden": "true", children: s }),
|
|
96
|
-
/* @__PURE__ */ e("span", { className: "ds:sr-only", children:
|
|
105
|
+
/* @__PURE__ */ e("span", { className: "ds:sr-only", children: m("badge.notifications", { count: s }) })
|
|
97
106
|
] }) : i ? /* @__PURE__ */ e("span", { className: "ds:max-w-[var(--badge-truncate-max-width)] ds:overflow-hidden ds:text-ellipsis ds:whitespace-nowrap", children: s }) : s)
|
|
98
107
|
]
|
|
99
108
|
}
|
|
100
109
|
);
|
|
101
|
-
return i && typeof s == "string" ? /* @__PURE__ */ e(y, { label: s, children:
|
|
110
|
+
return i && typeof s == "string" ? /* @__PURE__ */ e(y, { label: s, children: c }) : c;
|
|
102
111
|
}
|
|
103
112
|
);
|
|
104
113
|
j.displayName = "Badge";
|
|
105
114
|
export {
|
|
106
115
|
j as B
|
|
107
116
|
};
|
|
108
|
-
//# sourceMappingURL=badge-
|
|
117
|
+
//# sourceMappingURL=badge-B9Cr6iEB.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"badge-B9Cr6iEB.js","sources":["../../src/components/badge/badge.tsx"],"sourcesContent":["import { forwardRef, type ReactNode } from 'react';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { useTranslation } from 'react-i18next';\nimport { Tooltip } from '../tooltip';\n\n/* ------------------------------------------------------------------ */\n/* CVA — badge root */\n/* ------------------------------------------------------------------ */\n\nconst badgeVariants = cva(\n [\n 'ds:inline-flex ds:items-center ds:gap-1',\n // Typography comes from the eyebrow role: Medium 500 + uppercase + expanded tracking.\n // CVA size variants below override just `--type-eyebrow-size` so weight/transform/\n // tracking/line-height stay role-owned — same chip-family pattern as Tag.\n 'type-eyebrow',\n 'ds:whitespace-nowrap',\n 'ds:focus-visible:outline-none',\n 'ds:focus-visible:ring-[length:var(--focus-ring-width)]',\n 'ds:focus-visible:ring-[color:var(--ring)]',\n 'ds:focus-visible:ring-offset-[length:var(--focus-ring-offset)]',\n ].join(' '),\n {\n variants: {\n variant: {\n neutral: 'ds:bg-muted/20 ds:text-muted-foreground',\n info: 'ds:bg-info/15 ds:text-[var(--info-foreground)]',\n success: 'ds:bg-success/15 ds:text-[var(--success-foreground)]',\n warning: 'ds:bg-warning/15 ds:text-[var(--warning-foreground)]',\n error: 'ds:bg-destructive/15 ds:text-[var(--error-foreground)]',\n // Solid-fill brand variants — no border, foreground paired with the\n // semantic token. Use for trust-signal chips in hero contexts where\n // a tonal `info` / `neutral` would blend into the brand backdrop.\n brand: 'ds:bg-[var(--primary)] ds:text-[var(--primary-foreground)]',\n accent: 'ds:bg-[var(--accent)] ds:text-[var(--accent-foreground)]',\n },\n size: {\n sm: 'ds:h-4 ds:ps-1 ds:pe-1 ds:[--type-eyebrow-size:var(--font-size-2xs)]',\n md: 'ds:h-5 ds:ps-1.5 ds:pe-1.5 ds:[--type-eyebrow-size:var(--font-size-2xs)]',\n lg: 'ds:h-6 ds:ps-2 ds:pe-2 ds:[--type-eyebrow-size:var(--font-size-xs)]',\n },\n shape: {\n pill: 'ds:rounded-[var(--radius-full)]',\n rectangular: 'ds:rounded-[var(--radius-sm)]',\n },\n },\n defaultVariants: {\n variant: 'neutral',\n size: 'md',\n shape: 'pill',\n },\n },\n);\n\n/* ------------------------------------------------------------------ */\n/* CVA — leading dot */\n/* ------------------------------------------------------------------ */\n\nconst dotVariants = cva(\n 'ds:text-[length:var(--font-size-dot)] ds:leading-none ds:shrink-0',\n {\n variants: {\n variant: {\n neutral: 'ds:text-muted-foreground',\n info: 'ds:text-info',\n success: 'ds:text-success',\n warning: 'ds:text-warning',\n error: 'ds:text-destructive',\n // Solid-fill variants: dot draws in the paired foreground tone so\n // it stays visible against the saturated primary/accent fill.\n brand: 'ds:text-[var(--primary-foreground)]',\n accent: 'ds:text-[var(--accent-foreground)]',\n },\n },\n defaultVariants: { variant: 'neutral' },\n },\n);\n\n/* ------------------------------------------------------------------ */\n/* CVA — leading icon wrapper */\n/* ------------------------------------------------------------------ */\n\nconst iconWrapperVariants = cva('ds:shrink-0 ds:[&>svg]:block', {\n variants: {\n size: {\n // Icons shrink with the compact Badge scale: sm badge is 16 px tall, so\n // a 10 px glyph leaves room for the 1 px internal padding.\n sm: 'ds:[&>svg]:size-2.5',\n md: 'ds:[&>svg]:size-3',\n lg: 'ds:[&>svg]:size-3.5',\n },\n },\n defaultVariants: { size: 'md' },\n});\n\n/* ------------------------------------------------------------------ */\n/* BadgeProps */\n/* ------------------------------------------------------------------ */\n\nexport interface BadgeProps\n extends\n React.HTMLAttributes<HTMLSpanElement>,\n VariantProps<typeof badgeVariants> {\n /** Leading icon — renders before the label */\n leading?: ReactNode;\n /** Show a leading dot indicator (● shape) for colour-blind accessibility */\n withDot?: boolean;\n /** Truncate long text with ellipsis + tooltip showing full text */\n truncate?: boolean;\n /** For icon-only badges — provides the accessible name */\n 'aria-label'?: string;\n}\n\n/* ------------------------------------------------------------------ */\n/* Badge */\n/* ------------------------------------------------------------------ */\n\nexport const Badge = forwardRef<HTMLSpanElement, BadgeProps>(\n (\n {\n variant = 'neutral',\n size = 'md',\n shape = 'pill',\n leading,\n withDot = false,\n truncate = false,\n className,\n children,\n 'aria-label': ariaLabel,\n ...props\n },\n ref,\n ) => {\n const { t } = useTranslation();\n\n const isIconOnly = !children && !!ariaLabel;\n const isCount = typeof children === 'number';\n\n const badge = (\n <span\n ref={ref}\n className={badgeVariants({ variant, size, shape, className })}\n data-component=\"badge\"\n role={isIconOnly ? 'img' : undefined}\n aria-label={isIconOnly ? ariaLabel : undefined}\n {...props}\n >\n {withDot && (\n <span aria-hidden=\"true\" className={dotVariants({ variant })}>\n ●\n </span>\n )}\n {leading && (\n <span aria-hidden=\"true\" className={iconWrapperVariants({ size })}>\n {leading}\n </span>\n )}\n {!isIconOnly &&\n (isCount ? (\n <>\n <span aria-hidden=\"true\">{children}</span>\n <span className=\"ds:sr-only\">\n {t('badge.notifications', { count: children })}\n </span>\n </>\n ) : truncate ? (\n <span className=\"ds:max-w-[var(--badge-truncate-max-width)] ds:overflow-hidden ds:text-ellipsis ds:whitespace-nowrap\">\n {children}\n </span>\n ) : (\n children\n ))}\n </span>\n );\n\n if (truncate && typeof children === 'string') {\n return <Tooltip label={children}>{badge}</Tooltip>;\n }\n\n return badge;\n },\n);\n\nBadge.displayName = 'Badge';\n"],"names":["badgeVariants","cva","dotVariants","iconWrapperVariants","Badge","forwardRef","variant","size","shape","leading","withDot","truncate","className","children","ariaLabel","props","ref","t","useTranslation","isIconOnly","isCount","badge","jsxs","jsx","Fragment","Tooltip"],"mappings":"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"}
|
|
@@ -39,8 +39,12 @@ const _ = [
|
|
|
39
39
|
// emit a `--card-border` outline; light/dark themes use the
|
|
40
40
|
// soft 14% / 32% values (subtle but present) while accessible
|
|
41
41
|
// bumps to 50% black / 50% white for the strict-AA edge weight.
|
|
42
|
-
|
|
43
|
-
|
|
42
|
+
//
|
|
43
|
+
// 0.31.5: accessible theme also bumps border-width 1px → 2px —
|
|
44
|
+
// matches Card.elevated and PublicFooter compact. The thicker
|
|
45
|
+
// line reads as a deliberate boundary rather than a hairline.
|
|
46
|
+
elevated: "ds:shadow-[var(--shadow-card)] ds:border ds:border-[color:var(--card-border)] ds:[.theme-accessible_&]:border-2",
|
|
47
|
+
outlined: "ds:border ds:border-[color:var(--card-border)] ds:[.theme-accessible_&]:border-2"
|
|
44
48
|
}
|
|
45
49
|
},
|
|
46
50
|
defaultVariants: { variant: "elevated" }
|
|
@@ -142,7 +146,7 @@ function S(a, o) {
|
|
|
142
146
|
return a !== "auto" ? a : o ? _[o.index % _.length] : "primary";
|
|
143
147
|
}
|
|
144
148
|
const p = b(
|
|
145
|
-
({ columns: a = 3, children: o, className: c, ...
|
|
149
|
+
({ columns: a = 3, children: o, className: c, ...d }, l) => {
|
|
146
150
|
const i = w.toArray(o);
|
|
147
151
|
return /* @__PURE__ */ r(
|
|
148
152
|
"div",
|
|
@@ -150,8 +154,8 @@ const p = b(
|
|
|
150
154
|
ref: l,
|
|
151
155
|
"data-component": "benefit-card-row",
|
|
152
156
|
className: C({ columns: a, className: c }),
|
|
153
|
-
...
|
|
154
|
-
children: i.map((
|
|
157
|
+
...d,
|
|
158
|
+
children: i.map((n, t) => /* @__PURE__ */ r(m.Provider, { value: { index: t }, children: n }, t))
|
|
155
159
|
}
|
|
156
160
|
);
|
|
157
161
|
}
|
|
@@ -162,10 +166,10 @@ const x = b(
|
|
|
162
166
|
step: a,
|
|
163
167
|
icon: o,
|
|
164
168
|
title: c,
|
|
165
|
-
cta:
|
|
169
|
+
cta: d,
|
|
166
170
|
variant: l = "elevated",
|
|
167
171
|
accent: i = "auto",
|
|
168
|
-
children:
|
|
172
|
+
children: n,
|
|
169
173
|
className: t,
|
|
170
174
|
...u
|
|
171
175
|
}, f) => {
|
|
@@ -212,8 +216,8 @@ const x = b(
|
|
|
212
216
|
) : null
|
|
213
217
|
] }),
|
|
214
218
|
/* @__PURE__ */ r("h3", { className: "type-title-card ds:text-[var(--foreground)]", children: c }),
|
|
215
|
-
|
|
216
|
-
|
|
219
|
+
n ? /* @__PURE__ */ r("div", { className: "type-body ds:text-[var(--muted-foreground)] ds:flex-1", children: n }) : null,
|
|
220
|
+
d ? /* @__PURE__ */ r("div", { className: "ds:mt-[var(--spacing-xs)]", children: d }) : null
|
|
217
221
|
] })
|
|
218
222
|
]
|
|
219
223
|
}
|
|
@@ -227,4 +231,4 @@ const H = Object.assign(x, {
|
|
|
227
231
|
export {
|
|
228
232
|
H as B
|
|
229
233
|
};
|
|
230
|
-
//# sourceMappingURL=benefit-card-
|
|
234
|
+
//# sourceMappingURL=benefit-card-B86DH-PE.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"benefit-card-B86DH-PE.js","sources":["../../src/components/benefit-card/benefit-card.tsx"],"sourcesContent":["/* ------------------------------------------------------------------ */\n/* BenefitCard — marketing-surface card for \"benefit row\" / \"how it */\n/* works\" / \"why choose us\" sections. */\n/* */\n/* Visually distinguished from <Card> by: */\n/* 1. A 4px accent strip across the top (logical block-start). */\n/* 2. A tinted icon chip inside the body using `color-mix(in srgb, */\n/* var(--accent-token) 12%, var(--background))`. */\n/* 3. An optional zero-padded step chip (\"01\", \"02\", ...) in the */\n/* top-end corner. */\n/* 4. A hover lift (translateY -2px + --shadow-hover), gated through */\n/* `--animation-duration` so the accessible theme freezes it. */\n/* */\n/* Compound API: */\n/* <BenefitCard.Row columns={3}> */\n/* <BenefitCard step={1} icon={…} title=\"…\">…</BenefitCard> */\n/* ... */\n/* </BenefitCard.Row> */\n/* */\n/* `accent=\"auto\"` rotates through the brand palette by row index */\n/* (violet → purple → magenta → blue → green → red, then wraps). */\n/* Outside a Row, `auto` falls back to `primary`. */\n/* ------------------------------------------------------------------ */\n\nimport {\n Children,\n createContext,\n forwardRef,\n useContext,\n type HTMLAttributes,\n type ReactNode,\n} from 'react';\nimport { cva } from 'class-variance-authority';\n\n/* ------------------------------------------------------------------ */\n/* Accent wheel — used by `accent=\"auto\"` inside a Row. */\n/* ------------------------------------------------------------------ */\n\nconst ACCENT_WHEEL = [\n 'violet',\n 'purple',\n 'magenta',\n 'blue',\n 'green',\n 'red',\n] as const;\n\ntype WheelAccent = (typeof ACCENT_WHEEL)[number];\ntype SemanticAccent = 'primary' | 'accent' | 'info' | 'success' | 'warning';\ntype ResolvedAccent = SemanticAccent | WheelAccent;\ntype AccentProp = SemanticAccent | WheelAccent | 'auto';\n\n/* ------------------------------------------------------------------ */\n/* Row context */\n/* ------------------------------------------------------------------ */\n\ninterface RowContextValue {\n index: number;\n}\n\nconst RowContext = createContext<RowContextValue | null>(null);\n\n/* ------------------------------------------------------------------ */\n/* CVA — Row grid */\n/* ------------------------------------------------------------------ */\n\nconst rowVariants = cva('ds:grid ds:grid-cols-1 ds:gap-[var(--spacing-lg)]', {\n variants: {\n columns: {\n 1: 'ds:md:grid-cols-1',\n 2: 'ds:md:grid-cols-2',\n 3: 'ds:md:grid-cols-3',\n 4: 'ds:md:grid-cols-4',\n },\n },\n defaultVariants: { columns: 3 },\n});\n\n/* ------------------------------------------------------------------ */\n/* CVA — BenefitCard root */\n/* */\n/* The top 4px accent strip uses `border-block-start` (logical) so it */\n/* sits at the inline-start-block-start corner regardless of writing */\n/* direction. Border colour is set per-accent in the `accent` variant. */\n/* ------------------------------------------------------------------ */\n\n// Card chrome — no per-accent variant; the gradient top strip is rendered\n// as a separate sibling element so it can use a linear-gradient. The\n// hover shadow's tint comes from `hoverShadowVariants` on the same root.\nconst cardVariants = cva(\n [\n 'ds:relative ds:rounded-[var(--radius-lg)] ds:overflow-hidden',\n 'ds:flex ds:flex-col ds:h-full',\n 'ds:bg-[var(--card)] ds:text-[var(--card-foreground)]',\n // Hover lift — the transform is gated through `motion-safe:` so users\n // with `prefers-reduced-motion: reduce` see only the shadow change.\n // `--animation-duration` is pinned to 0ms in the accessible theme,\n // which collapses the transition without dropping the rule entirely.\n 'ds:transition-[transform,box-shadow] ds:duration-[var(--animation-duration)]',\n 'ds:motion-reduce:transition-none',\n 'ds:motion-safe:hover:-translate-y-1',\n ].join(' '),\n {\n variants: {\n variant: {\n // The accessible theme demands a visible boundary at ≥3:1 — shadow\n // alone doesn't clear that against the light page wash. Always\n // emit a `--card-border` outline; light/dark themes use the\n // soft 14% / 32% values (subtle but present) while accessible\n // bumps to 50% black / 50% white for the strict-AA edge weight.\n //\n // 0.31.5: accessible theme also bumps border-width 1px → 2px —\n // matches Card.elevated and PublicFooter compact. The thicker\n // line reads as a deliberate boundary rather than a hairline.\n elevated:\n 'ds:shadow-[var(--shadow-card)] ds:border ds:border-[color:var(--card-border)] ds:[.theme-accessible_&]:border-2',\n outlined:\n 'ds:border ds:border-[color:var(--card-border)] ds:[.theme-accessible_&]:border-2',\n },\n },\n defaultVariants: { variant: 'elevated' },\n },\n);\n\n/* ------------------------------------------------------------------ */\n/* Gradient top strip — Treatment B (Vivid). */\n/* */\n/* The strip is an absolutely-positioned `<span>` so its background can */\n/* be a `linear-gradient`. For brand-wheel accents (violet → purple → */\n/* magenta → blue → green → red) the gradient pairs with the next */\n/* wheel token. For semantic accents the gradient is a solid pair */\n/* (start=end) — same visual weight, less colour drama. */\n/* ------------------------------------------------------------------ */\n\nconst topStripVariants = cva(\n 'ds:absolute ds:inset-inline-0 ds:top-0 ds:h-[4px] ds:pointer-events-none',\n {\n variants: {\n accent: {\n primary:\n 'ds:bg-linear-to-r ds:from-[var(--primary)] ds:to-[var(--accent)]',\n accent:\n 'ds:bg-linear-to-r ds:from-[var(--accent)] ds:to-[var(--primary)]',\n info: 'ds:bg-linear-to-r ds:from-[var(--info)] ds:to-[var(--info)]',\n success:\n 'ds:bg-linear-to-r ds:from-[var(--success)] ds:to-[var(--success)]',\n warning:\n 'ds:bg-linear-to-r ds:from-[var(--warning)] ds:to-[var(--warning)]',\n violet:\n 'ds:bg-linear-to-r ds:from-[var(--color-violet-500)] ds:to-[var(--color-purple-500)]',\n purple:\n 'ds:bg-linear-to-r ds:from-[var(--color-purple-500)] ds:to-[var(--color-magenta-500)]',\n magenta:\n 'ds:bg-linear-to-r ds:from-[var(--color-magenta-500)] ds:to-[var(--color-violet-500)]',\n blue: 'ds:bg-linear-to-r ds:from-[var(--color-blue-500)] ds:to-[var(--color-green-500)]',\n green:\n 'ds:bg-linear-to-r ds:from-[var(--color-green-500)] ds:to-[var(--color-red-500)]',\n red: 'ds:bg-linear-to-r ds:from-[var(--color-red-500)] ds:to-[var(--color-blue-500)]',\n },\n },\n defaultVariants: { accent: 'primary' },\n },\n);\n\n/* ------------------------------------------------------------------ */\n/* Hover shadow — coloured halo on hover, tinted by accent. */\n/* ------------------------------------------------------------------ */\n\nconst hoverShadowVariants = cva('', {\n variants: {\n accent: {\n primary:\n 'ds:hover:shadow-[0_20px_40px_color-mix(in_srgb,var(--primary)_18%,transparent)]',\n accent:\n 'ds:hover:shadow-[0_20px_40px_color-mix(in_srgb,var(--accent)_18%,transparent)]',\n info: 'ds:hover:shadow-[0_20px_40px_color-mix(in_srgb,var(--info)_18%,transparent)]',\n success:\n 'ds:hover:shadow-[0_20px_40px_color-mix(in_srgb,var(--success)_18%,transparent)]',\n warning:\n 'ds:hover:shadow-[0_20px_40px_color-mix(in_srgb,var(--warning)_18%,transparent)]',\n violet:\n 'ds:hover:shadow-[0_20px_40px_color-mix(in_srgb,var(--color-violet-500)_18%,transparent)]',\n purple:\n 'ds:hover:shadow-[0_20px_40px_color-mix(in_srgb,var(--color-purple-500)_18%,transparent)]',\n magenta:\n 'ds:hover:shadow-[0_20px_40px_color-mix(in_srgb,var(--color-magenta-500)_18%,transparent)]',\n blue: 'ds:hover:shadow-[0_20px_40px_color-mix(in_srgb,var(--color-blue-500)_18%,transparent)]',\n green:\n 'ds:hover:shadow-[0_20px_40px_color-mix(in_srgb,var(--color-green-500)_18%,transparent)]',\n red: 'ds:hover:shadow-[0_20px_40px_color-mix(in_srgb,var(--color-red-500)_18%,transparent)]',\n },\n },\n defaultVariants: { accent: 'primary' },\n});\n\n/* ------------------------------------------------------------------ */\n/* CVA — icon chip */\n/* */\n/* The chip background uses `color-mix(in srgb, <token> 12%, */\n/* var(--background))` so it stays legible across themes. The Tailwind */\n/* JIT requires underscores in arbitrary-value classes wherever */\n/* whitespace would otherwise terminate the class. */\n/* ------------------------------------------------------------------ */\n\n// Icon chip — gradient tint (Treatment B). The chip pairs the resolved\n// accent with the \"next\" wheel/semantic token so the bg reads as a soft\n// diagonal blend instead of a flat tint, picking up the energy of the\n// gradient top strip. An inset highlight (`inset 0 1px 0` half-white)\n// adds a subtle glass edge.\nconst iconChipVariants = cva(\n [\n 'ds:inline-flex ds:items-center ds:justify-center',\n 'ds:size-14 ds:rounded-[var(--radius-md)] ds:shrink-0',\n 'ds:[&>svg]:size-7',\n 'ds:shadow-[inset_0_1px_0_color-mix(in_srgb,var(--foreground)_40%,transparent)]',\n ].join(' '),\n {\n variants: {\n accent: {\n primary:\n 'ds:text-[color:var(--primary)] ds:bg-linear-to-br ds:from-[color-mix(in_srgb,var(--primary)_22%,var(--background))] ds:to-[color-mix(in_srgb,var(--accent)_8%,var(--background))]',\n accent:\n 'ds:text-[color:var(--accent)] ds:bg-linear-to-br ds:from-[color-mix(in_srgb,var(--accent)_22%,var(--background))] ds:to-[color-mix(in_srgb,var(--primary)_8%,var(--background))]',\n info: 'ds:text-[color:var(--info)] ds:bg-linear-to-br ds:from-[color-mix(in_srgb,var(--info)_22%,var(--background))] ds:to-[color-mix(in_srgb,var(--info)_8%,var(--background))]',\n success:\n 'ds:text-[color:var(--success)] ds:bg-linear-to-br ds:from-[color-mix(in_srgb,var(--success)_22%,var(--background))] ds:to-[color-mix(in_srgb,var(--success)_8%,var(--background))]',\n warning:\n 'ds:text-[color:var(--warning)] ds:bg-linear-to-br ds:from-[color-mix(in_srgb,var(--warning)_22%,var(--background))] ds:to-[color-mix(in_srgb,var(--warning)_8%,var(--background))]',\n violet:\n 'ds:text-[color:var(--color-violet-500)] ds:bg-linear-to-br ds:from-[color-mix(in_srgb,var(--color-violet-500)_22%,var(--background))] ds:to-[color-mix(in_srgb,var(--color-purple-500)_8%,var(--background))]',\n purple:\n 'ds:text-[color:var(--color-purple-500)] ds:bg-linear-to-br ds:from-[color-mix(in_srgb,var(--color-purple-500)_22%,var(--background))] ds:to-[color-mix(in_srgb,var(--color-magenta-500)_8%,var(--background))]',\n magenta:\n 'ds:text-[color:var(--color-magenta-500)] ds:bg-linear-to-br ds:from-[color-mix(in_srgb,var(--color-magenta-500)_22%,var(--background))] ds:to-[color-mix(in_srgb,var(--color-violet-500)_8%,var(--background))]',\n blue: 'ds:text-[color:var(--color-blue-500)] ds:bg-linear-to-br ds:from-[color-mix(in_srgb,var(--color-blue-500)_22%,var(--background))] ds:to-[color-mix(in_srgb,var(--color-green-500)_8%,var(--background))]',\n green:\n 'ds:text-[color:var(--color-green-500)] ds:bg-linear-to-br ds:from-[color-mix(in_srgb,var(--color-green-500)_22%,var(--background))] ds:to-[color-mix(in_srgb,var(--color-red-500)_8%,var(--background))]',\n red: 'ds:text-[color:var(--color-red-500)] ds:bg-linear-to-br ds:from-[color-mix(in_srgb,var(--color-red-500)_22%,var(--background))] ds:to-[color-mix(in_srgb,var(--color-blue-500)_8%,var(--background))]',\n },\n },\n defaultVariants: { accent: 'primary' },\n },\n);\n\n/* ------------------------------------------------------------------ */\n/* Step chip — brand-tinted with a thin matching border. */\n/* ------------------------------------------------------------------ */\n\n// Text colour uses the -700 ramp step rather than -500 so the chip's\n// small `01` label clears WCAG AA (≥4.5:1) against its 12 %-tinted bg.\n// The brand -500 fails on the tinted surface (~4.07:1). For the\n// semantic accents we pin to the same brand-700 the kit resolves them\n// to (primary→violet-700, accent→magenta-700, etc.) so each variant\n// reads AA in light theme. In dark theme the tint surface darkens so\n// the ramp-700 text turns dark-on-dark and fails AA — we branch via\n// `[.theme-dark_&]:` to swap to the -200 ramp step (light text on the\n// dark tint), restoring comfortable contrast across both modes.\nconst stepChipVariants = cva(\n [\n 'type-eyebrow',\n 'ds:rounded-[var(--radius-full)]',\n 'ds:ps-[var(--spacing-sm)] ds:pe-[var(--spacing-sm)] ds:py-[var(--spacing-xs)]',\n // Accessible theme: the per-variant `30% primary` border is too\n // washed out for the ≥3:1 non-text contrast bar. Swap to\n // currentColor (which resolves to the brand-700 / -200 text colour\n // of the variant — same hue, fully opaque). Descendant selector\n // outweighs the per-variant declaration via specificity.\n 'ds:[.theme-accessible_&]:[border-color:currentColor]',\n ].join(' '),\n {\n variants: {\n accent: {\n primary:\n 'ds:text-[color:var(--color-violet-700)] ds:[.theme-dark_&]:text-[color:var(--color-violet-200)] ds:bg-[color-mix(in_srgb,var(--primary)_12%,var(--background))] ds:[border:1px_solid_color-mix(in_srgb,var(--primary)_30%,transparent)]',\n accent:\n 'ds:text-[color:var(--color-magenta-700)] ds:[.theme-dark_&]:text-[color:var(--color-magenta-200)] ds:bg-[color-mix(in_srgb,var(--accent)_12%,var(--background))] ds:[border:1px_solid_color-mix(in_srgb,var(--accent)_30%,transparent)]',\n info: 'ds:text-[color:var(--color-blue-700)] ds:[.theme-dark_&]:text-[color:var(--color-blue-200)] ds:bg-[color-mix(in_srgb,var(--info)_12%,var(--background))] ds:[border:1px_solid_color-mix(in_srgb,var(--info)_30%,transparent)]',\n success:\n 'ds:text-[color:var(--color-green-700)] ds:[.theme-dark_&]:text-[color:var(--color-green-200)] ds:bg-[color-mix(in_srgb,var(--success)_12%,var(--background))] ds:[border:1px_solid_color-mix(in_srgb,var(--success)_30%,transparent)]',\n warning:\n 'ds:text-[color:var(--color-red-700)] ds:[.theme-dark_&]:text-[color:var(--color-red-200)] ds:bg-[color-mix(in_srgb,var(--warning)_12%,var(--background))] ds:[border:1px_solid_color-mix(in_srgb,var(--warning)_30%,transparent)]',\n violet:\n 'ds:text-[color:var(--color-violet-700)] ds:[.theme-dark_&]:text-[color:var(--color-violet-200)] ds:bg-[color-mix(in_srgb,var(--color-violet-500)_12%,var(--background))] ds:[border:1px_solid_color-mix(in_srgb,var(--color-violet-500)_30%,transparent)]',\n purple:\n 'ds:text-[color:var(--color-purple-700)] ds:[.theme-dark_&]:text-[color:var(--color-purple-200)] ds:bg-[color-mix(in_srgb,var(--color-purple-500)_12%,var(--background))] ds:[border:1px_solid_color-mix(in_srgb,var(--color-purple-500)_30%,transparent)]',\n magenta:\n 'ds:text-[color:var(--color-magenta-700)] ds:[.theme-dark_&]:text-[color:var(--color-magenta-200)] ds:bg-[color-mix(in_srgb,var(--color-magenta-500)_12%,var(--background))] ds:[border:1px_solid_color-mix(in_srgb,var(--color-magenta-500)_30%,transparent)]',\n blue: 'ds:text-[color:var(--color-blue-700)] ds:[.theme-dark_&]:text-[color:var(--color-blue-200)] ds:bg-[color-mix(in_srgb,var(--color-blue-500)_12%,var(--background))] ds:[border:1px_solid_color-mix(in_srgb,var(--color-blue-500)_30%,transparent)]',\n green:\n 'ds:text-[color:var(--color-green-700)] ds:[.theme-dark_&]:text-[color:var(--color-green-200)] ds:bg-[color-mix(in_srgb,var(--color-green-500)_12%,var(--background))] ds:[border:1px_solid_color-mix(in_srgb,var(--color-green-500)_30%,transparent)]',\n red: 'ds:text-[color:var(--color-red-700)] ds:[.theme-dark_&]:text-[color:var(--color-red-200)] ds:bg-[color-mix(in_srgb,var(--color-red-500)_12%,var(--background))] ds:[border:1px_solid_color-mix(in_srgb,var(--color-red-500)_30%,transparent)]',\n },\n },\n defaultVariants: { accent: 'primary' },\n },\n);\n\n/* ------------------------------------------------------------------ */\n/* Types */\n/* ------------------------------------------------------------------ */\n\nexport interface BenefitCardProps extends Omit<\n HTMLAttributes<HTMLElement>,\n 'title'\n> {\n /** Step number; rendered as a zero-padded chip (\"01\", \"02\", …). Omit to hide. */\n step?: number;\n /** Icon node — usually an `<svg>` 24-32px. Rendered inside a tinted square chip. */\n icon?: ReactNode;\n /** Card heading. Always rendered inside an `<h3>` — pass only inline / phrasing content. */\n title: ReactNode;\n /** Optional CTA — usually a `<Button intent=\"link\">` or kit `<Link>`. Rendered at the block-end. */\n cta?: ReactNode;\n /** Surface treatment. */\n variant?: 'elevated' | 'outlined';\n /**\n * Accent colour. `auto` (default inside a `<BenefitCard.Row>`) rotates through the brand\n * palette by row index: violet → purple → magenta → blue → green → red, then wraps.\n * Outside a Row, `auto` falls back to `primary`.\n */\n accent?: AccentProp;\n /** Body content (description / list / inline copy). */\n children?: ReactNode;\n}\n\nexport interface BenefitCardRowProps extends Omit<\n HTMLAttributes<HTMLDivElement>,\n 'children'\n> {\n /** Number of columns at md+; defaults to 3. Collapses to 1 at < md. */\n columns?: 1 | 2 | 3 | 4;\n children?: ReactNode;\n}\n\n/* ------------------------------------------------------------------ */\n/* Accent resolution */\n/* ------------------------------------------------------------------ */\n\nfunction resolveAccent(\n accent: AccentProp,\n rowCtx: RowContextValue | null,\n): ResolvedAccent {\n if (accent !== 'auto') return accent;\n if (rowCtx) return ACCENT_WHEEL[rowCtx.index % ACCENT_WHEEL.length];\n return 'primary';\n}\n\n/* ------------------------------------------------------------------ */\n/* Row */\n/* */\n/* Wraps every child in a `RowContext.Provider` so the child can look */\n/* up its index and pick a wheel colour when `accent=\"auto\"`. */\n/* ------------------------------------------------------------------ */\n\nconst BenefitCardRow = forwardRef<HTMLDivElement, BenefitCardRowProps>(\n ({ columns = 3, children, className, ...rest }, ref) => {\n const items = Children.toArray(children);\n return (\n <div\n ref={ref}\n data-component=\"benefit-card-row\"\n className={rowVariants({ columns, className })}\n {...rest}\n >\n {items.map((child, index) => (\n <RowContext.Provider key={index} value={{ index }}>\n {child}\n </RowContext.Provider>\n ))}\n </div>\n );\n },\n);\nBenefitCardRow.displayName = 'BenefitCard.Row';\n\n/* ------------------------------------------------------------------ */\n/* Root */\n/* ------------------------------------------------------------------ */\n\nconst BenefitCardRoot = forwardRef<HTMLElement, BenefitCardProps>(\n (\n {\n step,\n icon,\n title,\n cta,\n variant = 'elevated',\n accent = 'auto',\n children,\n className,\n ...rest\n },\n ref,\n ) => {\n const rowCtx = useContext(RowContext);\n const resolved = resolveAccent(accent, rowCtx);\n const hasStep = typeof step === 'number';\n\n return (\n <article\n ref={ref}\n data-component=\"benefit-card\"\n data-accent={resolved}\n className={[\n cardVariants({ variant }),\n hoverShadowVariants({ accent: resolved }),\n className,\n ]\n .filter(Boolean)\n .join(' ')}\n {...rest}\n >\n {/* Gradient top strip — Treatment B visual signature. Sits above\n the card body via absolute positioning. */}\n <span\n aria-hidden=\"true\"\n data-part=\"accent-strip\"\n className={topStripVariants({ accent: resolved })}\n />\n <div className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-md)] ds:p-[var(--spacing-lg)] ds:flex-1\">\n {(icon || hasStep) && (\n <div className=\"ds:flex ds:items-start ds:justify-between ds:gap-[var(--spacing-sm)]\">\n {icon ? (\n <span\n aria-hidden=\"true\"\n className={iconChipVariants({ accent: resolved })}\n >\n {icon}\n </span>\n ) : (\n <span aria-hidden=\"true\" />\n )}\n {hasStep ? (\n <span\n aria-hidden=\"true\"\n data-part=\"step\"\n className={stepChipVariants({ accent: resolved })}\n >\n {String(step).padStart(2, '0')}\n </span>\n ) : null}\n </div>\n )}\n <h3 className=\"type-title-card ds:text-[var(--foreground)]\">\n {title}\n </h3>\n {children ? (\n <div className=\"type-body ds:text-[var(--muted-foreground)] ds:flex-1\">\n {children}\n </div>\n ) : null}\n {cta ? <div className=\"ds:mt-[var(--spacing-xs)]\">{cta}</div> : null}\n </div>\n </article>\n );\n },\n);\nBenefitCardRoot.displayName = 'BenefitCard';\n\n/* ------------------------------------------------------------------ */\n/* Compound export */\n/* ------------------------------------------------------------------ */\n\nexport const BenefitCard = Object.assign(BenefitCardRoot, {\n Row: BenefitCardRow,\n});\n"],"names":["ACCENT_WHEEL","RowContext","createContext","rowVariants","cva","cardVariants","topStripVariants","hoverShadowVariants","iconChipVariants","stepChipVariants","resolveAccent","accent","rowCtx","BenefitCardRow","forwardRef","columns","children","className","rest","ref","items","Children","jsx","child","index","BenefitCardRoot","step","icon","title","cta","variant","useContext","resolved","hasStep","jsxs","BenefitCard"],"mappings":"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"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { jsx as d } from "react/jsx-runtime";
|
|
2
|
-
import { forwardRef as t, useId as B, useState as
|
|
2
|
+
import { forwardRef as t, useId as B, useState as _, useCallback as v, useContext as k, createContext as I } from "react";
|
|
3
3
|
import { Slot as F } from "@radix-ui/react-slot";
|
|
4
4
|
import { c as M } from "./index-D2ZczOXr.js";
|
|
5
|
-
const u =
|
|
5
|
+
const u = I({
|
|
6
6
|
headerId: "",
|
|
7
7
|
interactive: !1,
|
|
8
8
|
registerHeader: () => {
|
|
@@ -15,10 +15,16 @@ const u = _({
|
|
|
15
15
|
].join(" "),
|
|
16
16
|
{
|
|
17
17
|
variants: {
|
|
18
|
+
// 0.31.5: accessible-theme bumps the border from 1px → 2px so
|
|
19
|
+
// the boundary reads at the strict-AA / AAA contrast bar — at
|
|
20
|
+
// 1px the `--card-border` (#00000080 light / #ffffff52 dark)
|
|
21
|
+
// clears 3:1 luminance but reads as a hairline on tall cards.
|
|
22
|
+
// Light + dark keep 1px. Forced-colours users get `border-2 +
|
|
23
|
+
// CanvasText` as a parallel safety net.
|
|
18
24
|
variant: {
|
|
19
|
-
default: "ds:bg-[var(--card)] ds:border ds:border-[color:var(--card-border)]",
|
|
20
|
-
outlined: "ds:bg-[var(--card)] ds:border ds:border-[color:var(--border)]",
|
|
21
|
-
elevated: "ds:bg-[var(--card)] ds:border ds:border-[color:var(--card-border)] ds:shadow-[var(--shadow-card)]"
|
|
25
|
+
default: "ds:bg-[var(--card)] ds:border ds:border-[color:var(--card-border)] ds:[.theme-accessible_&]:border-2",
|
|
26
|
+
outlined: "ds:bg-[var(--card)] ds:border ds:border-[color:var(--border)] ds:[.theme-accessible_&]:border-2",
|
|
27
|
+
elevated: "ds:bg-[var(--card)] ds:border ds:border-[color:var(--card-border)] ds:shadow-[var(--shadow-card)] ds:[.theme-accessible_&]:border-2"
|
|
22
28
|
},
|
|
23
29
|
interactive: {
|
|
24
30
|
true: [
|
|
@@ -47,9 +53,9 @@ const u = _({
|
|
|
47
53
|
}
|
|
48
54
|
), m = t(
|
|
49
55
|
({
|
|
50
|
-
variant:
|
|
56
|
+
variant: a = "default",
|
|
51
57
|
interactive: e = !1,
|
|
52
|
-
stretch:
|
|
58
|
+
stretch: r = !1,
|
|
53
59
|
asChild: i = !1,
|
|
54
60
|
className: l,
|
|
55
61
|
children: n,
|
|
@@ -57,7 +63,7 @@ const u = _({
|
|
|
57
63
|
onKeyDown: c,
|
|
58
64
|
...C
|
|
59
65
|
}, x) => {
|
|
60
|
-
const f = B(), [w, y] =
|
|
66
|
+
const f = B(), [w, y] = _(!1), N = v(() => y(!0), []), j = e ? {
|
|
61
67
|
...i ? {} : { role: "button", tabIndex: 0 },
|
|
62
68
|
onKeyDown: (o) => {
|
|
63
69
|
e && (o.key === "Enter" || o.key === " ") && (o.preventDefault(), o.currentTarget.click()), c == null || c(o);
|
|
@@ -75,9 +81,9 @@ const u = _({
|
|
|
75
81
|
"aria-labelledby": w ? f : void 0,
|
|
76
82
|
"data-component": "card",
|
|
77
83
|
className: R({
|
|
78
|
-
variant:
|
|
84
|
+
variant: a,
|
|
79
85
|
interactive: e ?? !1,
|
|
80
|
-
stretch:
|
|
86
|
+
stretch: r ?? !1,
|
|
81
87
|
className: l
|
|
82
88
|
}),
|
|
83
89
|
...j,
|
|
@@ -90,13 +96,13 @@ const u = _({
|
|
|
90
96
|
}
|
|
91
97
|
);
|
|
92
98
|
m.displayName = "Card";
|
|
93
|
-
const
|
|
94
|
-
({ className:
|
|
95
|
-
const { headerId: i, registerHeader: l } =
|
|
99
|
+
const b = t(
|
|
100
|
+
({ className: a, ...e }, r) => {
|
|
101
|
+
const { headerId: i, registerHeader: l } = k(u), n = v(
|
|
96
102
|
(s) => {
|
|
97
|
-
s && l(), typeof
|
|
103
|
+
s && l(), typeof r == "function" ? r(s) : r && (r.current = s);
|
|
98
104
|
},
|
|
99
|
-
[
|
|
105
|
+
[r, l]
|
|
100
106
|
);
|
|
101
107
|
return /* @__PURE__ */ d(
|
|
102
108
|
"div",
|
|
@@ -114,60 +120,60 @@ const p = t(
|
|
|
114
120
|
// chopped natural-language labels mid-character inside narrow
|
|
115
121
|
// contexts (DescriptionList rows in a Carousel slide).
|
|
116
122
|
"ds:[&>*]:break-normal ds:[&>*]:[overflow-wrap:break-word]",
|
|
117
|
-
|
|
123
|
+
a
|
|
118
124
|
].filter(Boolean).join(" "),
|
|
119
125
|
...e
|
|
120
126
|
}
|
|
121
127
|
);
|
|
122
128
|
}
|
|
123
129
|
);
|
|
124
|
-
|
|
125
|
-
const
|
|
126
|
-
({ className:
|
|
130
|
+
b.displayName = "Card.Header";
|
|
131
|
+
const p = t(
|
|
132
|
+
({ className: a, ...e }, r) => /* @__PURE__ */ d(
|
|
127
133
|
"div",
|
|
128
134
|
{
|
|
129
|
-
ref:
|
|
135
|
+
ref: r,
|
|
130
136
|
className: [
|
|
131
137
|
"ds:overflow-hidden ds:[&_img]:w-full ds:[&_img]:h-auto ds:[&_img]:[object-fit:cover] ds:[&_video]:w-full",
|
|
132
|
-
|
|
138
|
+
a
|
|
133
139
|
].filter(Boolean).join(" "),
|
|
134
140
|
...e
|
|
135
141
|
}
|
|
136
142
|
)
|
|
137
143
|
);
|
|
138
|
-
|
|
139
|
-
const
|
|
140
|
-
({ className:
|
|
144
|
+
p.displayName = "Card.Media";
|
|
145
|
+
const h = t(
|
|
146
|
+
({ className: a, ...e }, r) => /* @__PURE__ */ d(
|
|
141
147
|
"div",
|
|
142
148
|
{
|
|
143
|
-
ref:
|
|
144
|
-
className: ["ds:p-[var(--spacing-md)] ds:flex-1 ds:text-start",
|
|
149
|
+
ref: r,
|
|
150
|
+
className: ["ds:p-[var(--spacing-md)] ds:flex-1 ds:text-start", a].filter(Boolean).join(" "),
|
|
145
151
|
...e
|
|
146
152
|
}
|
|
147
153
|
)
|
|
148
154
|
);
|
|
149
|
-
|
|
150
|
-
const
|
|
151
|
-
({ className:
|
|
155
|
+
h.displayName = "Card.Body";
|
|
156
|
+
const g = t(
|
|
157
|
+
({ className: a, ...e }, r) => /* @__PURE__ */ d(
|
|
152
158
|
"div",
|
|
153
159
|
{
|
|
154
|
-
ref:
|
|
160
|
+
ref: r,
|
|
155
161
|
className: [
|
|
156
162
|
"ds:flex ds:items-center ds:gap-[var(--spacing-sm)] ds:p-[var(--spacing-md)] ds:pt-0",
|
|
157
|
-
|
|
163
|
+
a
|
|
158
164
|
].filter(Boolean).join(" "),
|
|
159
165
|
...e
|
|
160
166
|
}
|
|
161
167
|
)
|
|
162
168
|
);
|
|
163
|
-
|
|
169
|
+
g.displayName = "Card.Footer";
|
|
164
170
|
const O = Object.assign(m, {
|
|
165
|
-
Header:
|
|
166
|
-
Media:
|
|
167
|
-
Body:
|
|
168
|
-
Footer:
|
|
171
|
+
Header: b,
|
|
172
|
+
Media: p,
|
|
173
|
+
Body: h,
|
|
174
|
+
Footer: g
|
|
169
175
|
});
|
|
170
176
|
export {
|
|
171
177
|
O as C
|
|
172
178
|
};
|
|
173
|
-
//# sourceMappingURL=card-
|
|
179
|
+
//# sourceMappingURL=card-CNri9ssR.js.map
|