@mieweb/ui 0.10.0-dev.32 → 0.10.0-dev.34

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.
Files changed (140) hide show
  1. package/dist/{chunk-VPIYTQCV.cjs → chunk-2I4IRQQG.cjs} +12 -5
  2. package/dist/chunk-2I4IRQQG.cjs.map +1 -0
  3. package/dist/{chunk-CMF7VCGP.js → chunk-2X54ZLT6.js} +3 -3
  4. package/dist/{chunk-CMF7VCGP.js.map → chunk-2X54ZLT6.js.map} +1 -1
  5. package/dist/{chunk-FKGFOBC2.js → chunk-434L5RYF.js} +4 -4
  6. package/dist/{chunk-FKGFOBC2.js.map → chunk-434L5RYF.js.map} +1 -1
  7. package/dist/{chunk-TPWKM7JH.js → chunk-43K7OQ3E.js} +3 -3
  8. package/dist/{chunk-TPWKM7JH.js.map → chunk-43K7OQ3E.js.map} +1 -1
  9. package/dist/chunk-522WJIVI.js +99 -0
  10. package/dist/chunk-522WJIVI.js.map +1 -0
  11. package/dist/{chunk-O4WGSOJI.js → chunk-56VTM4OX.js} +3 -3
  12. package/dist/{chunk-O4WGSOJI.js.map → chunk-56VTM4OX.js.map} +1 -1
  13. package/dist/{chunk-LRRSD7LR.js → chunk-5HKZR6UG.js} +3 -3
  14. package/dist/{chunk-LRRSD7LR.js.map → chunk-5HKZR6UG.js.map} +1 -1
  15. package/dist/{chunk-EMRWTCCN.cjs → chunk-6WX2OR3U.cjs} +15 -2
  16. package/dist/chunk-6WX2OR3U.cjs.map +1 -0
  17. package/dist/chunk-7E46YDOT.cjs +122 -0
  18. package/dist/chunk-7E46YDOT.cjs.map +1 -0
  19. package/dist/{chunk-57G3O552.cjs → chunk-AJPFQF3H.cjs} +7 -7
  20. package/dist/{chunk-57G3O552.cjs.map → chunk-AJPFQF3H.cjs.map} +1 -1
  21. package/dist/{chunk-I2MMUFCN.cjs → chunk-ARIJ5OHW.cjs} +9 -24
  22. package/dist/chunk-ARIJ5OHW.cjs.map +1 -0
  23. package/dist/{chunk-VOYLX32A.cjs → chunk-CLQW724U.cjs} +4 -4
  24. package/dist/{chunk-VOYLX32A.cjs.map → chunk-CLQW724U.cjs.map} +1 -1
  25. package/dist/{chunk-VNEAQCY2.js → chunk-DGHS5IVD.js} +19 -22
  26. package/dist/chunk-DGHS5IVD.js.map +1 -0
  27. package/dist/{chunk-OZ5CKVQN.js → chunk-FDA3R5E7.js} +15 -2
  28. package/dist/chunk-FDA3R5E7.js.map +1 -0
  29. package/dist/{chunk-LSMS6DY7.cjs → chunk-FSWHZY3T.cjs} +18 -21
  30. package/dist/chunk-FSWHZY3T.cjs.map +1 -0
  31. package/dist/{chunk-ISUIKUX7.cjs → chunk-H3P7POFC.cjs} +7 -7
  32. package/dist/{chunk-ISUIKUX7.cjs.map → chunk-H3P7POFC.cjs.map} +1 -1
  33. package/dist/{chunk-462XSCP3.cjs → chunk-HCIXGFWR.cjs} +4 -4
  34. package/dist/{chunk-462XSCP3.cjs.map → chunk-HCIXGFWR.cjs.map} +1 -1
  35. package/dist/{chunk-FCV7GBNQ.cjs → chunk-HNNWWLKY.cjs} +33 -33
  36. package/dist/{chunk-FCV7GBNQ.cjs.map → chunk-HNNWWLKY.cjs.map} +1 -1
  37. package/dist/{chunk-BIQ7GSO2.js → chunk-JMAZ2GKT.js} +3 -3
  38. package/dist/{chunk-BIQ7GSO2.js.map → chunk-JMAZ2GKT.js.map} +1 -1
  39. package/dist/{chunk-T4L7Q5FA.cjs → chunk-LC3JL2HB.cjs} +6 -2
  40. package/dist/chunk-LC3JL2HB.cjs.map +1 -0
  41. package/dist/{chunk-3RXZWHCU.js → chunk-LDBNUJB7.js} +3 -3
  42. package/dist/{chunk-3RXZWHCU.js.map → chunk-LDBNUJB7.js.map} +1 -1
  43. package/dist/{chunk-ADW7ZYCY.cjs → chunk-LRAAJRE7.cjs} +4 -4
  44. package/dist/{chunk-ADW7ZYCY.cjs.map → chunk-LRAAJRE7.cjs.map} +1 -1
  45. package/dist/{chunk-ILDLYRTP.js → chunk-MHR2OS5I.js} +4 -4
  46. package/dist/{chunk-ILDLYRTP.js.map → chunk-MHR2OS5I.js.map} +1 -1
  47. package/dist/{chunk-6M63CM7X.cjs → chunk-O6BJMVGT.cjs} +21 -21
  48. package/dist/{chunk-6M63CM7X.cjs.map → chunk-O6BJMVGT.cjs.map} +1 -1
  49. package/dist/{chunk-ORCCJ5VY.cjs → chunk-OIMXMPH2.cjs} +4 -4
  50. package/dist/{chunk-ORCCJ5VY.cjs.map → chunk-OIMXMPH2.cjs.map} +1 -1
  51. package/dist/{chunk-CEQJGUAS.js → chunk-P4E3K3ND.js} +12 -5
  52. package/dist/chunk-P4E3K3ND.js.map +1 -0
  53. package/dist/{chunk-6JSFT2J5.js → chunk-RLVYWUXG.js} +9 -24
  54. package/dist/chunk-RLVYWUXG.js.map +1 -0
  55. package/dist/{chunk-YRHBSSQ3.cjs → chunk-RV45J2ZT.cjs} +4 -4
  56. package/dist/{chunk-YRHBSSQ3.cjs.map → chunk-RV45J2ZT.cjs.map} +1 -1
  57. package/dist/{chunk-3DLLTITK.js → chunk-S2JZL4JC.js} +3 -3
  58. package/dist/{chunk-3DLLTITK.js.map → chunk-S2JZL4JC.js.map} +1 -1
  59. package/dist/{chunk-ENMXHZNE.js → chunk-TWQSMUE6.js} +6 -2
  60. package/dist/chunk-TWQSMUE6.js.map +1 -0
  61. package/dist/{chunk-GNOQFTLL.cjs → chunk-UTIPENPW.cjs} +6 -6
  62. package/dist/{chunk-GNOQFTLL.cjs.map → chunk-UTIPENPW.cjs.map} +1 -1
  63. package/dist/{chunk-CPPUT74P.cjs → chunk-VV2U36T6.cjs} +9 -9
  64. package/dist/{chunk-CPPUT74P.cjs.map → chunk-VV2U36T6.cjs.map} +1 -1
  65. package/dist/{chunk-EPTP3VKT.js → chunk-WFL4N5PC.js} +3 -3
  66. package/dist/{chunk-EPTP3VKT.js.map → chunk-WFL4N5PC.js.map} +1 -1
  67. package/dist/{chunk-H3QPREIJ.js → chunk-X3RSNAMX.js} +3 -3
  68. package/dist/{chunk-H3QPREIJ.js.map → chunk-X3RSNAMX.js.map} +1 -1
  69. package/dist/{chunk-T4JYUICS.js → chunk-Y7ZJZLJY.js} +3 -3
  70. package/dist/{chunk-T4JYUICS.js.map → chunk-Y7ZJZLJY.js.map} +1 -1
  71. package/dist/{chunk-P55LNEDH.cjs → chunk-ZSNFL736.cjs} +4 -4
  72. package/dist/{chunk-P55LNEDH.cjs.map → chunk-ZSNFL736.cjs.map} +1 -1
  73. package/dist/components/ActionPlan/index.cjs +5 -5
  74. package/dist/components/ActionPlan/index.js +3 -3
  75. package/dist/components/AlertDialog/index.cjs +6 -6
  76. package/dist/components/AlertDialog/index.js +2 -2
  77. package/dist/components/AssociationList/index.cjs +4 -4
  78. package/dist/components/AssociationList/index.js +2 -2
  79. package/dist/components/Badge/index.cjs +3 -3
  80. package/dist/components/Badge/index.d.cts +15 -1
  81. package/dist/components/Badge/index.d.ts +15 -1
  82. package/dist/components/Badge/index.js +1 -1
  83. package/dist/components/CompletenessMeter/index.cjs +5 -4
  84. package/dist/components/CompletenessMeter/index.js +2 -1
  85. package/dist/components/KeyboardShortcutsOverlay/index.cjs +4 -4
  86. package/dist/components/KeyboardShortcutsOverlay/index.js +2 -2
  87. package/dist/components/MediaEditor/index.cjs +7 -7
  88. package/dist/components/MediaEditor/index.js +2 -2
  89. package/dist/components/MediaFeed/index.cjs +3 -3
  90. package/dist/components/MediaFeed/index.js +2 -2
  91. package/dist/components/Modal/index.cjs +9 -9
  92. package/dist/components/Modal/index.js +1 -1
  93. package/dist/components/Progress/index.cjs +6 -6
  94. package/dist/components/Progress/index.d.cts +7 -1
  95. package/dist/components/Progress/index.d.ts +7 -1
  96. package/dist/components/Progress/index.js +1 -1
  97. package/dist/components/RadialExplorer/index.cjs +3 -3
  98. package/dist/components/RadialExplorer/index.js +2 -2
  99. package/dist/components/RecordHeader/index.cjs +4 -4
  100. package/dist/components/RecordHeader/index.d.cts +11 -1
  101. package/dist/components/RecordHeader/index.d.ts +11 -1
  102. package/dist/components/RecordHeader/index.js +2 -2
  103. package/dist/components/RecordLayout/index.cjs +4 -4
  104. package/dist/components/RecordLayout/index.js +2 -2
  105. package/dist/components/SuperChat/index.cjs +5 -5
  106. package/dist/components/SuperChat/index.js +3 -3
  107. package/dist/components/TagEditor/index.cjs +5 -3
  108. package/dist/components/TagEditor/index.js +3 -1
  109. package/dist/components/VideoCard/index.cjs +4 -4
  110. package/dist/components/VideoCard/index.js +2 -2
  111. package/dist/datavis.cjs +2 -2
  112. package/dist/datavis.js +1 -1
  113. package/dist/esheet.cjs +6 -6
  114. package/dist/esheet.js +3 -3
  115. package/dist/index.cjs +300 -314
  116. package/dist/index.cjs.map +1 -1
  117. package/dist/index.d.cts +22 -2
  118. package/dist/index.d.ts +22 -2
  119. package/dist/index.js +29 -43
  120. package/dist/index.js.map +1 -1
  121. package/dist/styles.css +1 -1
  122. package/dist/tailwind-preset.cjs +4 -4
  123. package/dist/tailwind-preset.js +1 -1
  124. package/dist/templates.cjs +31 -31
  125. package/dist/templates.js +2 -2
  126. package/package.json +1 -1
  127. package/dist/chunk-6JSFT2J5.js.map +0 -1
  128. package/dist/chunk-BMSG4NBH.js +0 -56
  129. package/dist/chunk-BMSG4NBH.js.map +0 -1
  130. package/dist/chunk-CEQJGUAS.js.map +0 -1
  131. package/dist/chunk-EMRWTCCN.cjs.map +0 -1
  132. package/dist/chunk-ENMXHZNE.js.map +0 -1
  133. package/dist/chunk-I2MMUFCN.cjs.map +0 -1
  134. package/dist/chunk-LSMS6DY7.cjs.map +0 -1
  135. package/dist/chunk-OZ5CKVQN.js.map +0 -1
  136. package/dist/chunk-T4L7Q5FA.cjs.map +0 -1
  137. package/dist/chunk-VNEAQCY2.js.map +0 -1
  138. package/dist/chunk-VPIYTQCV.cjs.map +0 -1
  139. package/dist/chunk-YVL3XATO.cjs +0 -79
  140. package/dist/chunk-YVL3XATO.cjs.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/components/VideoCard/VideoCard.tsx"],"names":[],"mappings":"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","file":"chunk-TPWKM7JH.js","sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport { Play, VolumeX } from 'lucide-react';\nimport { cn } from '../../utils/cn';\nimport { Badge } from '../Badge';\nimport { useYouTubeHoverPreview } from '../../hooks/useYouTubeHoverPreview';\n\n// =============================================================================\n// PlayButton\n// =============================================================================\n\nexport interface PlayButtonProps extends React.HTMLAttributes<HTMLSpanElement> {\n /** Disc diameter. Default `md` (56px). */\n size?: 'sm' | 'md' | 'lg';\n /**\n * Show the spinning brand ring. Default `hover` — the ring appears and spins\n * only while the nearest `.group` ancestor is hovered; `always` keeps it on.\n */\n ring?: 'hover' | 'always' | 'none';\n}\n\nconst DISC_SIZE = {\n sm: 'h-10 w-10',\n md: 'h-14 w-14',\n lg: 'h-20 w-20',\n} as const;\nconst ICON_SIZE = { sm: 'h-4 w-4', md: 'h-6 w-6', lg: 'h-8 w-8' } as const;\n\n/**\n * The branded play affordance: a white disc with a filled brand triangle and a\n * conic-gradient ring that lights up and spins on hover. Decorative — the\n * surrounding card/link carries the accessible label.\n */\nexport function PlayButton({\n size = 'md',\n ring = 'hover',\n className,\n ...props\n}: PlayButtonProps) {\n return (\n <span\n data-slot=\"play-button\"\n aria-hidden=\"true\"\n className={cn(\n 'relative inline-flex items-center justify-center',\n DISC_SIZE[size],\n className\n )}\n {...props}\n >\n {ring !== 'none' && (\n <span\n className={cn(\n 'pointer-events-none absolute -inset-2 rounded-full transition-opacity duration-300',\n 'motion-safe:animate-[mie-spin_1.4s_linear_infinite]',\n '[background:conic-gradient(from_0deg,transparent_0deg,var(--mieweb-primary-500)_90deg,var(--mieweb-primary-300)_240deg,var(--mieweb-primary-200)_320deg,transparent_360deg)]',\n '[mask:radial-gradient(farthest-side,transparent_calc(100%-4px),#000_calc(100%-4px))]',\n '[-webkit-mask:radial-gradient(farthest-side,transparent_calc(100%-4px),#000_calc(100%-4px))]',\n 'drop-shadow-[0_0_5px_color-mix(in_srgb,var(--mieweb-primary-400)_60%,transparent)]',\n ring === 'hover'\n ? 'opacity-0 group-hover:opacity-100 group-focus-visible:opacity-100'\n : 'opacity-100'\n )}\n />\n )}\n <span\n className={cn(\n 'relative flex items-center justify-center rounded-full bg-white/90 shadow-lg transition-transform group-hover:scale-110',\n DISC_SIZE[size]\n )}\n >\n <Play\n // rtl-ignore -- optical centering of the play triangle, which points right in RTL media players too\n className={cn('text-primary-600 ml-0.5', ICON_SIZE[size])}\n fill=\"currentColor\"\n />\n </span>\n </span>\n );\n}\n\n// =============================================================================\n// VideoCard\n// =============================================================================\n\nexport interface VideoCardProps {\n /** Video title — also the accessible name (\"Watch: {title}\"). */\n title: string;\n /** Navigates on click. Omit to render a `<button>` driven by `onClick`. */\n href?: string;\n onClick?: React.MouseEventHandler<HTMLElement>;\n /** Anchor target (e.g. `_blank`). */\n target?: string;\n /** Enables the muted hover preview and the default YouTube thumbnail. */\n youtubeId?: string;\n /** Thumbnail URL. Defaults to the YouTube `hqdefault` when `youtubeId` is set. */\n thumbnailUrl?: string;\n /** Thumbnail alt. Defaults to `title`. */\n thumbnailAlt?: string;\n /** Duration label, e.g. `34 min` or `2:44`. */\n duration?: string;\n /** Word before the duration in the pill. Default `Watch` → \"Watch · 34 min\". Pass `null` for just the duration. */\n durationPrefix?: string | null;\n /** Turn the hover preview off even when `youtubeId` is set. */\n preview?: boolean;\n /** Label shown on the pill while the muted preview plays. Default `Silent`. */\n silentLabel?: string;\n /** Slot above the title in the body — a category `Badge`, for instance. */\n eyebrow?: React.ReactNode;\n description?: string;\n /** Slot below the description — speaker, view count, date. */\n footer?: React.ReactNode;\n /**\n * `card` renders thumbnail + body; `plate` renders only the media plate\n * (for heroes and detail panels where the copy lives elsewhere).\n */\n variant?: 'card' | 'plate';\n /** Heading level for the title in `card` variant. Default `h3`. */\n headingLevel?: 'h2' | 'h3' | 'h4';\n className?: string;\n}\n\n/**\n * A video thumbnail card with the branded `PlayButton`, a \"Watch · 34 min\"\n * duration pill and — when a `youtubeId` is supplied — a muted, looping\n * hover preview with a progress bar, exactly as YouTube's own grid behaves.\n * Ported from the Enterprise Health video library and hero HUD.\n *\n * @example\n * ```tsx\n * <VideoCard\n * title=\"Ozwell AI in the exam room\"\n * href=\"/videos/ozwell-ai/\"\n * youtubeId=\"dQw4w9WgXcQ\"\n * duration=\"2:44\"\n * eyebrow={<Badge variant=\"secondary\" size=\"sm\">Demo</Badge>}\n * description=\"Documentation and surveillance, native to the platform.\"\n * />\n * ```\n */\nexport function VideoCard({\n title,\n href,\n onClick,\n target,\n youtubeId,\n thumbnailUrl,\n thumbnailAlt,\n duration,\n durationPrefix = 'Watch',\n preview = true,\n silentLabel = 'Silent',\n eyebrow,\n description,\n footer,\n variant = 'card',\n headingLevel: Heading = 'h3',\n className,\n}: VideoCardProps) {\n const thumb =\n thumbnailUrl ??\n (youtubeId\n ? `https://i.ytimg.com/vi/${youtubeId}/hqdefault.jpg`\n : undefined);\n\n const hover = useYouTubeHoverPreview(youtubeId, { enabled: preview });\n const playing = hover.preview === 'playing';\n\n const pill =\n duration && (durationPrefix ? `${durationPrefix} · ${duration}` : duration);\n\n const media = (\n <div\n data-slot=\"video-card-media\"\n className=\"bg-primary-950 relative aspect-video overflow-hidden\"\n >\n {thumb && (\n <img\n src={thumb}\n alt={thumbnailAlt ?? title}\n loading=\"lazy\"\n decoding=\"async\"\n className=\"absolute inset-0 h-full w-full object-cover transition-transform duration-300 group-hover:scale-105\"\n />\n )}\n\n {/* Muted preview player — fades in once frames are flowing. pointer-events-none\n so clicks fall through to the card. */}\n <div\n ref={hover.hostRef}\n aria-hidden=\"true\"\n className={cn(\n 'bg-primary-950 pointer-events-none absolute inset-0 overflow-hidden transition-opacity duration-500',\n '[&_iframe]:absolute [&_iframe]:inset-0 [&_iframe]:h-full [&_iframe]:w-full [&_iframe]:border-0',\n playing ? 'opacity-100' : 'opacity-0'\n )}\n />\n\n {playing && (\n <span className=\"absolute start-2 top-2 inline-flex items-center gap-1 rounded bg-black/55 px-1.5 py-0.5 text-[11px] font-medium text-white backdrop-blur-sm\">\n <VolumeX className=\"h-3 w-3\" aria-hidden=\"true\" />\n {silentLabel}\n </span>\n )}\n\n <div\n className={cn(\n 'bg-primary-950/20 group-hover:bg-primary-950/30 absolute inset-0 flex items-center justify-center transition-all duration-300',\n playing && 'opacity-0'\n )}\n >\n <PlayButton size={variant === 'plate' ? 'lg' : 'md'} />\n </div>\n\n {pill && !playing && (\n <Badge\n data-slot=\"video-card-duration\"\n size=\"sm\"\n className=\"absolute end-2 bottom-2 bg-black/60 py-1 text-white backdrop-blur-sm dark:bg-black/60 dark:text-white\"\n >\n {pill}\n </Badge>\n )}\n\n {hover.preview !== 'idle' && (\n <div className=\"absolute inset-x-0 bottom-0 h-1 bg-white/20\">\n <div\n className=\"h-full rounded-e-full bg-[linear-gradient(90deg,var(--mieweb-primary-500),var(--mieweb-primary-300))] transition-[width] duration-200 ease-linear\"\n style={{ width: `${Math.max(hover.progress * 100, 1.5)}%` }}\n />\n </div>\n )}\n </div>\n );\n\n // A real heading is only valid in the link variant — `<button>` accepts\n // phrasing content only, so the button variant gets a styled block span.\n const TitleTag = href ? Heading : 'span';\n\n const body = variant === 'card' && (\n <div data-slot=\"video-card-body\" className=\"p-4 text-start\">\n {eyebrow && <div className=\"mb-2 flex items-center gap-2\">{eyebrow}</div>}\n <TitleTag className=\"text-foreground group-hover:text-primary-700 dark:group-hover:text-primary-300 block text-lg font-semibold transition-colors\">\n {title}\n </TitleTag>\n {description && (\n <p className=\"text-muted-foreground mt-1 line-clamp-2 text-sm\">\n {description}\n </p>\n )}\n {footer && (\n <div className=\"text-muted-foreground mt-2 text-sm\">{footer}</div>\n )}\n </div>\n );\n\n const shell = cn(\n 'group block w-full overflow-hidden no-underline transition-shadow',\n 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2',\n variant === 'card'\n ? 'rounded-xl border border-border bg-card text-card-foreground shadow-md hover:shadow-lg'\n : 'rounded-xl shadow-lg',\n className\n );\n\n const interaction = {\n onMouseEnter: hover.handleEnter,\n onMouseLeave: hover.stopPreview,\n onFocus: hover.handleEnter,\n onBlur: hover.stopPreview,\n 'aria-label': `Watch: ${title}`,\n 'data-slot': 'video-card',\n 'data-preview': hover.preview,\n };\n\n if (href) {\n return (\n <a\n href={href}\n target={target}\n rel={target === '_blank' ? 'noopener noreferrer' : undefined}\n onClick={onClick}\n className={shell}\n {...interaction}\n >\n {media}\n {body}\n </a>\n );\n }\n return (\n <button type=\"button\" onClick={onClick} className={shell} {...interaction}>\n {media}\n {body}\n </button>\n );\n}\n"]}
1
+ {"version":3,"sources":["../src/components/VideoCard/VideoCard.tsx"],"names":[],"mappings":"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","file":"chunk-43K7OQ3E.js","sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport { Play, VolumeX } from 'lucide-react';\nimport { cn } from '../../utils/cn';\nimport { Badge } from '../Badge';\nimport { useYouTubeHoverPreview } from '../../hooks/useYouTubeHoverPreview';\n\n// =============================================================================\n// PlayButton\n// =============================================================================\n\nexport interface PlayButtonProps extends React.HTMLAttributes<HTMLSpanElement> {\n /** Disc diameter. Default `md` (56px). */\n size?: 'sm' | 'md' | 'lg';\n /**\n * Show the spinning brand ring. Default `hover` — the ring appears and spins\n * only while the nearest `.group` ancestor is hovered; `always` keeps it on.\n */\n ring?: 'hover' | 'always' | 'none';\n}\n\nconst DISC_SIZE = {\n sm: 'h-10 w-10',\n md: 'h-14 w-14',\n lg: 'h-20 w-20',\n} as const;\nconst ICON_SIZE = { sm: 'h-4 w-4', md: 'h-6 w-6', lg: 'h-8 w-8' } as const;\n\n/**\n * The branded play affordance: a white disc with a filled brand triangle and a\n * conic-gradient ring that lights up and spins on hover. Decorative — the\n * surrounding card/link carries the accessible label.\n */\nexport function PlayButton({\n size = 'md',\n ring = 'hover',\n className,\n ...props\n}: PlayButtonProps) {\n return (\n <span\n data-slot=\"play-button\"\n aria-hidden=\"true\"\n className={cn(\n 'relative inline-flex items-center justify-center',\n DISC_SIZE[size],\n className\n )}\n {...props}\n >\n {ring !== 'none' && (\n <span\n className={cn(\n 'pointer-events-none absolute -inset-2 rounded-full transition-opacity duration-300',\n 'motion-safe:animate-[mie-spin_1.4s_linear_infinite]',\n '[background:conic-gradient(from_0deg,transparent_0deg,var(--mieweb-primary-500)_90deg,var(--mieweb-primary-300)_240deg,var(--mieweb-primary-200)_320deg,transparent_360deg)]',\n '[mask:radial-gradient(farthest-side,transparent_calc(100%-4px),#000_calc(100%-4px))]',\n '[-webkit-mask:radial-gradient(farthest-side,transparent_calc(100%-4px),#000_calc(100%-4px))]',\n 'drop-shadow-[0_0_5px_color-mix(in_srgb,var(--mieweb-primary-400)_60%,transparent)]',\n ring === 'hover'\n ? 'opacity-0 group-hover:opacity-100 group-focus-visible:opacity-100'\n : 'opacity-100'\n )}\n />\n )}\n <span\n className={cn(\n 'relative flex items-center justify-center rounded-full bg-white/90 shadow-lg transition-transform group-hover:scale-110',\n DISC_SIZE[size]\n )}\n >\n <Play\n // rtl-ignore -- optical centering of the play triangle, which points right in RTL media players too\n className={cn('text-primary-600 ml-0.5', ICON_SIZE[size])}\n fill=\"currentColor\"\n />\n </span>\n </span>\n );\n}\n\n// =============================================================================\n// VideoCard\n// =============================================================================\n\nexport interface VideoCardProps {\n /** Video title — also the accessible name (\"Watch: {title}\"). */\n title: string;\n /** Navigates on click. Omit to render a `<button>` driven by `onClick`. */\n href?: string;\n onClick?: React.MouseEventHandler<HTMLElement>;\n /** Anchor target (e.g. `_blank`). */\n target?: string;\n /** Enables the muted hover preview and the default YouTube thumbnail. */\n youtubeId?: string;\n /** Thumbnail URL. Defaults to the YouTube `hqdefault` when `youtubeId` is set. */\n thumbnailUrl?: string;\n /** Thumbnail alt. Defaults to `title`. */\n thumbnailAlt?: string;\n /** Duration label, e.g. `34 min` or `2:44`. */\n duration?: string;\n /** Word before the duration in the pill. Default `Watch` → \"Watch · 34 min\". Pass `null` for just the duration. */\n durationPrefix?: string | null;\n /** Turn the hover preview off even when `youtubeId` is set. */\n preview?: boolean;\n /** Label shown on the pill while the muted preview plays. Default `Silent`. */\n silentLabel?: string;\n /** Slot above the title in the body — a category `Badge`, for instance. */\n eyebrow?: React.ReactNode;\n description?: string;\n /** Slot below the description — speaker, view count, date. */\n footer?: React.ReactNode;\n /**\n * `card` renders thumbnail + body; `plate` renders only the media plate\n * (for heroes and detail panels where the copy lives elsewhere).\n */\n variant?: 'card' | 'plate';\n /** Heading level for the title in `card` variant. Default `h3`. */\n headingLevel?: 'h2' | 'h3' | 'h4';\n className?: string;\n}\n\n/**\n * A video thumbnail card with the branded `PlayButton`, a \"Watch · 34 min\"\n * duration pill and — when a `youtubeId` is supplied — a muted, looping\n * hover preview with a progress bar, exactly as YouTube's own grid behaves.\n * Ported from the Enterprise Health video library and hero HUD.\n *\n * @example\n * ```tsx\n * <VideoCard\n * title=\"Ozwell AI in the exam room\"\n * href=\"/videos/ozwell-ai/\"\n * youtubeId=\"dQw4w9WgXcQ\"\n * duration=\"2:44\"\n * eyebrow={<Badge variant=\"secondary\" size=\"sm\">Demo</Badge>}\n * description=\"Documentation and surveillance, native to the platform.\"\n * />\n * ```\n */\nexport function VideoCard({\n title,\n href,\n onClick,\n target,\n youtubeId,\n thumbnailUrl,\n thumbnailAlt,\n duration,\n durationPrefix = 'Watch',\n preview = true,\n silentLabel = 'Silent',\n eyebrow,\n description,\n footer,\n variant = 'card',\n headingLevel: Heading = 'h3',\n className,\n}: VideoCardProps) {\n const thumb =\n thumbnailUrl ??\n (youtubeId\n ? `https://i.ytimg.com/vi/${youtubeId}/hqdefault.jpg`\n : undefined);\n\n const hover = useYouTubeHoverPreview(youtubeId, { enabled: preview });\n const playing = hover.preview === 'playing';\n\n const pill =\n duration && (durationPrefix ? `${durationPrefix} · ${duration}` : duration);\n\n const media = (\n <div\n data-slot=\"video-card-media\"\n className=\"bg-primary-950 relative aspect-video overflow-hidden\"\n >\n {thumb && (\n <img\n src={thumb}\n alt={thumbnailAlt ?? title}\n loading=\"lazy\"\n decoding=\"async\"\n className=\"absolute inset-0 h-full w-full object-cover transition-transform duration-300 group-hover:scale-105\"\n />\n )}\n\n {/* Muted preview player — fades in once frames are flowing. pointer-events-none\n so clicks fall through to the card. */}\n <div\n ref={hover.hostRef}\n aria-hidden=\"true\"\n className={cn(\n 'bg-primary-950 pointer-events-none absolute inset-0 overflow-hidden transition-opacity duration-500',\n '[&_iframe]:absolute [&_iframe]:inset-0 [&_iframe]:h-full [&_iframe]:w-full [&_iframe]:border-0',\n playing ? 'opacity-100' : 'opacity-0'\n )}\n />\n\n {playing && (\n <span className=\"absolute start-2 top-2 inline-flex items-center gap-1 rounded bg-black/55 px-1.5 py-0.5 text-[11px] font-medium text-white backdrop-blur-sm\">\n <VolumeX className=\"h-3 w-3\" aria-hidden=\"true\" />\n {silentLabel}\n </span>\n )}\n\n <div\n className={cn(\n 'bg-primary-950/20 group-hover:bg-primary-950/30 absolute inset-0 flex items-center justify-center transition-all duration-300',\n playing && 'opacity-0'\n )}\n >\n <PlayButton size={variant === 'plate' ? 'lg' : 'md'} />\n </div>\n\n {pill && !playing && (\n <Badge\n data-slot=\"video-card-duration\"\n size=\"sm\"\n className=\"absolute end-2 bottom-2 bg-black/60 py-1 text-white backdrop-blur-sm dark:bg-black/60 dark:text-white\"\n >\n {pill}\n </Badge>\n )}\n\n {hover.preview !== 'idle' && (\n <div className=\"absolute inset-x-0 bottom-0 h-1 bg-white/20\">\n <div\n className=\"h-full rounded-e-full bg-[linear-gradient(90deg,var(--mieweb-primary-500),var(--mieweb-primary-300))] transition-[width] duration-200 ease-linear\"\n style={{ width: `${Math.max(hover.progress * 100, 1.5)}%` }}\n />\n </div>\n )}\n </div>\n );\n\n // A real heading is only valid in the link variant — `<button>` accepts\n // phrasing content only, so the button variant gets a styled block span.\n const TitleTag = href ? Heading : 'span';\n\n const body = variant === 'card' && (\n <div data-slot=\"video-card-body\" className=\"p-4 text-start\">\n {eyebrow && <div className=\"mb-2 flex items-center gap-2\">{eyebrow}</div>}\n <TitleTag className=\"text-foreground group-hover:text-primary-700 dark:group-hover:text-primary-300 block text-lg font-semibold transition-colors\">\n {title}\n </TitleTag>\n {description && (\n <p className=\"text-muted-foreground mt-1 line-clamp-2 text-sm\">\n {description}\n </p>\n )}\n {footer && (\n <div className=\"text-muted-foreground mt-2 text-sm\">{footer}</div>\n )}\n </div>\n );\n\n const shell = cn(\n 'group block w-full overflow-hidden no-underline transition-shadow',\n 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2',\n variant === 'card'\n ? 'rounded-xl border border-border bg-card text-card-foreground shadow-md hover:shadow-lg'\n : 'rounded-xl shadow-lg',\n className\n );\n\n const interaction = {\n onMouseEnter: hover.handleEnter,\n onMouseLeave: hover.stopPreview,\n onFocus: hover.handleEnter,\n onBlur: hover.stopPreview,\n 'aria-label': `Watch: ${title}`,\n 'data-slot': 'video-card',\n 'data-preview': hover.preview,\n };\n\n if (href) {\n return (\n <a\n href={href}\n target={target}\n rel={target === '_blank' ? 'noopener noreferrer' : undefined}\n onClick={onClick}\n className={shell}\n {...interaction}\n >\n {media}\n {body}\n </a>\n );\n }\n return (\n <button type=\"button\" onClick={onClick} className={shell} {...interaction}>\n {media}\n {body}\n </button>\n );\n}\n"]}
@@ -0,0 +1,99 @@
1
+ import { cn } from './chunk-TQONQSJO.js';
2
+ import * as React from 'react';
3
+ import { cva } from 'class-variance-authority';
4
+ import { X } from 'lucide-react';
5
+ import { jsxs, jsx } from 'react/jsx-runtime';
6
+
7
+ var badgeVariants = cva(
8
+ [
9
+ "inline-flex items-center justify-center",
10
+ "font-medium",
11
+ "rounded-full",
12
+ "transition-colors duration-150"
13
+ ],
14
+ {
15
+ variants: {
16
+ variant: {
17
+ default: "bg-primary-100 text-primary-900 dark:bg-primary-900 dark:text-primary-100",
18
+ secondary: "bg-neutral-100 text-neutral-900 dark:bg-neutral-800 dark:text-neutral-100",
19
+ success: "bg-green-100 text-green-900 dark:bg-green-900 dark:text-green-100",
20
+ warning: "bg-yellow-100 text-yellow-900 dark:bg-yellow-900 dark:text-yellow-100",
21
+ danger: "bg-red-100 text-red-900 dark:bg-red-900 dark:text-red-100",
22
+ outline: "border border-current bg-transparent"
23
+ },
24
+ size: {
25
+ sm: "text-xs",
26
+ md: "text-sm",
27
+ lg: "text-base"
28
+ },
29
+ // Padding lives in compound variants so the remove button can sit
30
+ // closer to the end edge without fighting the symmetric `px-*`.
31
+ // No root gap: the remove button carries its own `ms-1` so icon and
32
+ // multi-node children keep their normal spacing.
33
+ removable: {
34
+ true: "",
35
+ false: ""
36
+ }
37
+ },
38
+ compoundVariants: [
39
+ { size: "sm", removable: false, className: "px-2 py-0.5" },
40
+ { size: "sm", removable: true, className: "ps-2 pe-0.5 py-0.5" },
41
+ { size: "md", removable: false, className: "px-2.5 py-0.5" },
42
+ { size: "md", removable: true, className: "ps-2.5 pe-1 py-0.5" },
43
+ { size: "lg", removable: false, className: "px-3 py-1" },
44
+ { size: "lg", removable: true, className: "ps-3 pe-1.5 py-1" }
45
+ ],
46
+ defaultVariants: {
47
+ variant: "default",
48
+ size: "md",
49
+ removable: false
50
+ }
51
+ }
52
+ );
53
+ var Badge = React.forwardRef(
54
+ ({
55
+ className,
56
+ variant,
57
+ size,
58
+ icon,
59
+ onRemove,
60
+ removeLabel = "Remove",
61
+ removeDisabled,
62
+ children,
63
+ ...props
64
+ }, ref) => {
65
+ return /* @__PURE__ */ jsxs(
66
+ "span",
67
+ {
68
+ ref,
69
+ "data-slot": "badge",
70
+ className: cn(
71
+ badgeVariants({ variant, size, removable: !!onRemove }),
72
+ className
73
+ ),
74
+ ...props,
75
+ children: [
76
+ icon && /* @__PURE__ */ jsx("span", { className: "me-1 shrink-0", children: icon }),
77
+ children,
78
+ onRemove && /* @__PURE__ */ jsx(
79
+ "button",
80
+ {
81
+ type: "button",
82
+ "data-slot": "badge-remove",
83
+ "aria-label": removeLabel,
84
+ disabled: removeDisabled,
85
+ onClick: onRemove,
86
+ className: "focus-visible:ring-ring ms-1 shrink-0 rounded-full p-0.5 hover:bg-black/10 focus-visible:ring-2 focus-visible:outline-none disabled:opacity-50 dark:hover:bg-white/10",
87
+ children: /* @__PURE__ */ jsx(X, { "aria-hidden": "true", className: "h-3 w-3" })
88
+ }
89
+ )
90
+ ]
91
+ }
92
+ );
93
+ }
94
+ );
95
+ Badge.displayName = "Badge";
96
+
97
+ export { Badge, badgeVariants };
98
+ //# sourceMappingURL=chunk-522WJIVI.js.map
99
+ //# sourceMappingURL=chunk-522WJIVI.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/Badge/Badge.tsx"],"names":[],"mappings":"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","file":"chunk-522WJIVI.js","sourcesContent":["import * as React from 'react';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { X } from 'lucide-react';\nimport { cn } from '../../utils/cn';\n\nconst badgeVariants = cva(\n [\n 'inline-flex items-center justify-center',\n 'font-medium',\n 'rounded-full',\n 'transition-colors duration-150',\n ],\n {\n variants: {\n variant: {\n default:\n 'bg-primary-100 text-primary-900 dark:bg-primary-900 dark:text-primary-100',\n secondary:\n 'bg-neutral-100 text-neutral-900 dark:bg-neutral-800 dark:text-neutral-100',\n success:\n 'bg-green-100 text-green-900 dark:bg-green-900 dark:text-green-100',\n warning:\n 'bg-yellow-100 text-yellow-900 dark:bg-yellow-900 dark:text-yellow-100',\n danger: 'bg-red-100 text-red-900 dark:bg-red-900 dark:text-red-100',\n outline: 'border border-current bg-transparent',\n },\n size: {\n sm: 'text-xs',\n md: 'text-sm',\n lg: 'text-base',\n },\n // Padding lives in compound variants so the remove button can sit\n // closer to the end edge without fighting the symmetric `px-*`.\n // No root gap: the remove button carries its own `ms-1` so icon and\n // multi-node children keep their normal spacing.\n removable: {\n true: '',\n false: '',\n },\n },\n compoundVariants: [\n { size: 'sm', removable: false, className: 'px-2 py-0.5' },\n { size: 'sm', removable: true, className: 'ps-2 pe-0.5 py-0.5' },\n { size: 'md', removable: false, className: 'px-2.5 py-0.5' },\n { size: 'md', removable: true, className: 'ps-2.5 pe-1 py-0.5' },\n { size: 'lg', removable: false, className: 'px-3 py-1' },\n { size: 'lg', removable: true, className: 'ps-3 pe-1.5 py-1' },\n ],\n defaultVariants: {\n variant: 'default',\n size: 'md',\n removable: false,\n },\n }\n);\n\nexport interface BadgeProps\n extends\n React.HTMLAttributes<HTMLSpanElement>,\n Omit<VariantProps<typeof badgeVariants>, 'removable'> {\n /** Optional icon before the text */\n icon?: React.ReactNode;\n /** Renders a remove button after the text; the badge becomes a chip. */\n onRemove?: (event: React.MouseEvent<HTMLButtonElement>) => void;\n /**\n * Accessible name of the remove button. Always pass a translated string;\n * the English default only guards against a missing label.\n */\n removeLabel?: string;\n /** Disables the remove button. */\n removeDisabled?: boolean;\n}\n\n/**\n * A badge component for displaying status, labels, or counts.\n * With `onRemove` it becomes a removable chip.\n *\n * @example\n * ```tsx\n * <Badge variant=\"success\">Active</Badge>\n * <Badge variant=\"warning\" size=\"sm\">Pending</Badge>\n * <Badge variant=\"danger\" icon={<AlertIcon />}>Error</Badge>\n * <Badge onRemove={() => clear(tag)} removeLabel={t('removeTag', { tag })}>\n * {tag}\n * </Badge>\n * ```\n */\nconst Badge = React.forwardRef<HTMLSpanElement, BadgeProps>(\n (\n {\n className,\n variant,\n size,\n icon,\n onRemove,\n removeLabel = 'Remove',\n removeDisabled,\n children,\n ...props\n },\n ref\n ) => {\n return (\n <span\n ref={ref}\n data-slot=\"badge\"\n className={cn(\n badgeVariants({ variant, size, removable: !!onRemove }),\n className\n )}\n {...props}\n >\n {icon && <span className=\"me-1 shrink-0\">{icon}</span>}\n {children}\n {onRemove && (\n <button\n type=\"button\"\n data-slot=\"badge-remove\"\n aria-label={removeLabel}\n disabled={removeDisabled}\n onClick={onRemove}\n className=\"focus-visible:ring-ring ms-1 shrink-0 rounded-full p-0.5 hover:bg-black/10 focus-visible:ring-2 focus-visible:outline-none disabled:opacity-50 dark:hover:bg-white/10\"\n >\n <X aria-hidden=\"true\" className=\"h-3 w-3\" />\n </button>\n )}\n </span>\n );\n }\n);\n\nBadge.displayName = 'Badge';\n\nexport { Badge, badgeVariants };\n"]}
@@ -1,4 +1,4 @@
1
- import { Modal, ModalBody, ModalFooter } from './chunk-ENMXHZNE.js';
1
+ import { Modal, ModalBody, ModalFooter } from './chunk-TWQSMUE6.js';
2
2
  import { isStorybookDocsMode } from './chunk-VSQF22GL.js';
3
3
  import { Button } from './chunk-WFBUBT54.js';
4
4
  import { cn } from './chunk-TQONQSJO.js';
@@ -257,5 +257,5 @@ function useConfirm() {
257
257
  }
258
258
 
259
259
  export { AlertDialog, ConfirmDialogProvider, defaultAlertDialogLabels, useConfirm };
260
- //# sourceMappingURL=chunk-O4WGSOJI.js.map
261
- //# sourceMappingURL=chunk-O4WGSOJI.js.map
260
+ //# sourceMappingURL=chunk-56VTM4OX.js.map
261
+ //# sourceMappingURL=chunk-56VTM4OX.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/components/AlertDialog/AlertDialog.tsx","../src/components/AlertDialog/ConfirmDialogProvider.tsx"],"names":["React2","jsxs","jsx"],"mappings":"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","file":"chunk-O4WGSOJI.js","sourcesContent":["import * as React from 'react';\nimport { cva } from 'class-variance-authority';\nimport { AlertTriangle, CheckCircle2, Info } from 'lucide-react';\nimport { cn } from '../../utils/cn';\nimport { isStorybookDocsMode } from '../../utils/environment';\nimport { Modal, ModalBody, ModalFooter, type ModalProps } from '../Modal';\nimport { Button } from '../Button';\n\nexport type AlertDialogVariant =\n | 'default'\n | 'destructive'\n | 'warning'\n | 'success'\n | 'info';\n\nexport interface AlertDialogLabels {\n /** Cancel button */\n cancel: string;\n /** Action button */\n action: string;\n /** Action button while an async `onAction` is pending */\n busy: string;\n /** Action button of `useConfirm().alert()` */\n acknowledge: string;\n}\n\nexport const defaultAlertDialogLabels: AlertDialogLabels = {\n cancel: 'Cancel',\n action: 'Continue',\n busy: 'Working…',\n acknowledge: 'OK',\n};\n\nconst iconVariants = cva(\n 'flex h-10 w-10 shrink-0 items-center justify-center rounded-full',\n {\n variants: {\n variant: {\n destructive: 'bg-destructive/10 text-destructive',\n warning: 'bg-warning/15 text-warning-700 dark:text-warning-400',\n success: 'bg-success/10 text-success-700 dark:text-success-400',\n info: 'bg-info/10 text-info-700 dark:text-info-400',\n },\n },\n }\n);\n\nconst VARIANT_ICONS = {\n destructive: AlertTriangle,\n warning: AlertTriangle,\n success: CheckCircle2,\n info: Info,\n} as const;\n\nexport interface AlertDialogProps extends Pick<\n ModalProps,\n 'open' | 'onOpenChange'\n> {\n /** Dialog title */\n title: React.ReactNode;\n /** Optional descriptive body text */\n description?: React.ReactNode;\n /** Custom body content (rendered below the description) */\n children?: React.ReactNode;\n /** Label for the cancel button; overrides `labels.cancel` */\n cancelLabel?: React.ReactNode;\n /** Label for the confirm/action button; overrides `labels.action` */\n actionLabel?: React.ReactNode;\n /**\n * Called when the action button is clicked. Return a Promise to show a busy\n * state; the dialog closes when it resolves and stays open if it rejects.\n */\n onAction?: () => void | Promise<unknown>;\n /** Called when the cancel button is clicked */\n onCancel?: () => void;\n /** Tone of the dialog: icon, action button colour and initial focus */\n variant?: AlertDialogVariant;\n /** Disables the action button */\n actionDisabled?: boolean;\n /** Hides the cancel button */\n hideCancel?: boolean;\n /** User-facing strings; English defaults in `defaultAlertDialogLabels` */\n labels?: Partial<AlertDialogLabels>;\n /** Additional class name for the dialog content */\n className?: string;\n}\n\nfunction isPromiseLike(value: unknown): value is PromiseLike<unknown> {\n return (\n typeof value === 'object' &&\n value !== null &&\n typeof (value as PromiseLike<unknown>).then === 'function'\n );\n}\n\n/**\n * A modal dialog (`role=\"alertdialog\"`) that interrupts the user with\n * important content and expects a response. Built on top of {@link Modal}.\n *\n * It does not close on overlay click or Escape — the user must explicitly\n * choose an action.\n *\n * @example\n * ```tsx\n * <AlertDialog\n * open={open}\n * onOpenChange={setOpen}\n * title=\"Delete case?\"\n * description=\"This action cannot be undone.\"\n * variant=\"destructive\"\n * actionLabel=\"Delete\"\n * onAction={() => deleteCase(id)}\n * />\n * ```\n */\nfunction AlertDialog({\n open,\n onOpenChange,\n title,\n description,\n children,\n cancelLabel,\n actionLabel,\n onAction,\n onCancel,\n variant = 'default',\n actionDisabled,\n hideCancel,\n labels,\n className,\n}: AlertDialogProps) {\n const text = { ...defaultAlertDialogLabels, ...labels };\n const id = React.useId();\n const titleId = `${id}-title`;\n const descriptionId = `${id}-description`;\n const [busy, setBusy] = React.useState(false);\n const bodyRef = React.useRef<HTMLDivElement>(null);\n const cancelRef = React.useRef<HTMLButtonElement>(null);\n const actionRef = React.useRef<HTMLButtonElement>(null);\n const cautious = variant === 'destructive' || variant === 'warning';\n const iconVariant = variant === 'default' ? null : variant;\n const Icon = iconVariant && VARIANT_ICONS[iconVariant];\n\n // Modal has no role prop; upgrade its dialog element. React never resets it\n // because the role Modal renders does not change.\n React.useLayoutEffect(() => {\n if (!open) return;\n bodyRef.current\n ?.closest('[data-slot=\"modal\"]')\n ?.setAttribute('role', 'alertdialog');\n }, [open]);\n\n // Layout effect so the opener is captured before Modal's trap moves focus.\n React.useLayoutEffect(() => {\n if (!open) return;\n const opener = document.activeElement;\n return () => {\n if (opener instanceof HTMLElement && opener.isConnected) opener.focus();\n };\n }, [open]);\n\n // Parent effects run after Modal's, so this overrides its first-element focus.\n React.useEffect(() => {\n if (!open || isStorybookDocsMode()) return;\n (cautious && !hideCancel ? cancelRef : actionRef).current?.focus();\n }, [open, cautious, hideCancel]);\n\n const handleCancel = () => {\n onCancel?.();\n onOpenChange(false);\n };\n\n // Closing (or reusing) the dialog orphans any in-flight action: its\n // continuation must not clear the busy state or close a newer dialog.\n const actionGen = React.useRef(0);\n React.useEffect(() => {\n if (!open) {\n actionGen.current += 1;\n setBusy(false);\n }\n }, [open]);\n\n const handleAction = async () => {\n let result: unknown;\n try {\n result = onAction?.();\n } catch {\n requestAnimationFrame(() => actionRef.current?.focus());\n return;\n }\n if (!isPromiseLike(result)) return;\n const gen = ++actionGen.current;\n setBusy(true);\n try {\n await result;\n if (gen !== actionGen.current) return;\n setBusy(false);\n onOpenChange(false);\n } catch {\n if (gen !== actionGen.current) return;\n setBusy(false);\n // Disabling the button dropped focus; return it once re-enabled.\n requestAnimationFrame(() => actionRef.current?.focus());\n }\n };\n\n return (\n <Modal\n open={open}\n onOpenChange={onOpenChange}\n size=\"sm\"\n closeOnOverlayClick={false}\n closeOnEscape={false}\n className={className}\n aria-labelledby={titleId}\n aria-describedby={description ? descriptionId : undefined}\n >\n <ModalBody\n ref={bodyRef}\n data-variant={variant}\n aria-busy={busy || undefined}\n className=\"flex items-start gap-4 px-6 py-5\"\n >\n {Icon && iconVariant && (\n <span\n data-slot=\"alert-dialog-icon\"\n className={iconVariants({ variant: iconVariant })}\n >\n <Icon className=\"h-5 w-5\" aria-hidden=\"true\" />\n </span>\n )}\n <div className=\"min-w-0 flex-1\">\n <h2\n id={titleId}\n data-slot=\"alert-dialog-title\"\n className=\"text-lg font-semibold tracking-tight\"\n >\n {title}\n </h2>\n {description && (\n <p\n id={descriptionId}\n data-slot=\"alert-dialog-description\"\n className={cn('text-muted-foreground mt-2 text-sm')}\n >\n {description}\n </p>\n )}\n {children}\n </div>\n </ModalBody>\n <ModalFooter>\n {!hideCancel && (\n <Button\n ref={cancelRef}\n variant=\"secondary\"\n onClick={handleCancel}\n disabled={busy}\n >\n {cancelLabel ?? text.cancel}\n </Button>\n )}\n <Button\n ref={actionRef}\n variant={variant === 'destructive' ? 'danger' : 'primary'}\n onClick={handleAction}\n disabled={actionDisabled}\n isLoading={busy}\n loadingText={text.busy}\n >\n {actionLabel ?? text.action}\n </Button>\n </ModalFooter>\n </Modal>\n );\n}\n\nAlertDialog.displayName = 'AlertDialog';\n\nexport { AlertDialog };\n","import * as React from 'react';\nimport {\n AlertDialog,\n defaultAlertDialogLabels,\n type AlertDialogLabels,\n type AlertDialogVariant,\n} from './AlertDialog';\n\nexport interface ConfirmOptions {\n title: React.ReactNode;\n description?: React.ReactNode;\n actionLabel?: React.ReactNode;\n cancelLabel?: React.ReactNode;\n variant?: AlertDialogVariant;\n}\n\nexport type AlertOptions = Omit<ConfirmOptions, 'cancelLabel'>;\n\nexport interface ConfirmApi {\n /** Resolves `true` when the user confirms, `false` when they cancel. */\n confirm: (options: ConfirmOptions) => Promise<boolean>;\n /** Shows a dialog with only an acknowledge button; resolves when dismissed. */\n alert: (options: AlertOptions) => Promise<void>;\n}\n\nexport interface ConfirmDialogProviderProps {\n children: React.ReactNode;\n /** Default strings for every dialog the provider opens */\n labels?: Partial<AlertDialogLabels>;\n}\n\ninterface PendingDialog extends ConfirmOptions {\n mode: 'confirm' | 'alert';\n}\n\nconst ConfirmContext = React.createContext<ConfirmApi | null>(null);\n\n/**\n * Renders one {@link AlertDialog} and exposes it imperatively through\n * {@link useConfirm}. Mount once near the app root.\n */\nexport function ConfirmDialogProvider({\n children,\n labels,\n}: ConfirmDialogProviderProps) {\n const [request, setRequest] = React.useState<PendingDialog | null>(null);\n const [open, setOpen] = React.useState(false);\n const resolveRef = React.useRef<((confirmed: boolean) => void) | null>(null);\n\n const settle = React.useCallback((confirmed: boolean) => {\n resolveRef.current?.(confirmed);\n resolveRef.current = null;\n setOpen(false);\n }, []);\n\n // If the provider unmounts with a dialog open, settle the promise as\n // cancelled so callers awaiting confirm() aren't suspended forever.\n React.useEffect(\n () => () => {\n resolveRef.current?.(false);\n resolveRef.current = null;\n },\n []\n );\n\n const api = React.useMemo<ConfirmApi>(() => {\n const show = (next: PendingDialog) =>\n new Promise<boolean>((resolve) => {\n // A newer request replaces an unanswered one, which counts as cancelled.\n resolveRef.current?.(false);\n resolveRef.current = resolve;\n setRequest(next);\n setOpen(true);\n });\n return {\n confirm: (options) => show({ ...options, mode: 'confirm' }),\n alert: async (options) => {\n await show({ variant: 'info', ...options, mode: 'alert' });\n },\n };\n }, []);\n\n const text = { ...defaultAlertDialogLabels, ...labels };\n const isAlert = request?.mode === 'alert';\n\n return (\n <ConfirmContext.Provider value={api}>\n {children}\n {request && (\n <AlertDialog\n open={open}\n onOpenChange={(next) => {\n if (!next) settle(false);\n }}\n title={request.title}\n description={request.description}\n variant={request.variant}\n labels={labels}\n hideCancel={isAlert}\n cancelLabel={request.cancelLabel}\n actionLabel={\n request.actionLabel ?? (isAlert ? text.acknowledge : undefined)\n }\n onAction={() => settle(true)}\n />\n )}\n </ConfirmContext.Provider>\n );\n}\n\n/**\n * Promise-based confirm/alert dialogs. Requires a {@link ConfirmDialogProvider}\n * ancestor.\n *\n * @example\n * ```tsx\n * const { confirm } = useConfirm();\n * if (await confirm({ title: 'Delete case?', variant: 'destructive' })) remove();\n * ```\n */\nexport function useConfirm(): ConfirmApi {\n const api = React.useContext(ConfirmContext);\n if (!api) {\n throw new Error('useConfirm must be used within a <ConfirmDialogProvider>');\n }\n return api;\n}\n"]}
1
+ {"version":3,"sources":["../src/components/AlertDialog/AlertDialog.tsx","../src/components/AlertDialog/ConfirmDialogProvider.tsx"],"names":["React2","jsxs","jsx"],"mappings":"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","file":"chunk-56VTM4OX.js","sourcesContent":["import * as React from 'react';\nimport { cva } from 'class-variance-authority';\nimport { AlertTriangle, CheckCircle2, Info } from 'lucide-react';\nimport { cn } from '../../utils/cn';\nimport { isStorybookDocsMode } from '../../utils/environment';\nimport { Modal, ModalBody, ModalFooter, type ModalProps } from '../Modal';\nimport { Button } from '../Button';\n\nexport type AlertDialogVariant =\n | 'default'\n | 'destructive'\n | 'warning'\n | 'success'\n | 'info';\n\nexport interface AlertDialogLabels {\n /** Cancel button */\n cancel: string;\n /** Action button */\n action: string;\n /** Action button while an async `onAction` is pending */\n busy: string;\n /** Action button of `useConfirm().alert()` */\n acknowledge: string;\n}\n\nexport const defaultAlertDialogLabels: AlertDialogLabels = {\n cancel: 'Cancel',\n action: 'Continue',\n busy: 'Working…',\n acknowledge: 'OK',\n};\n\nconst iconVariants = cva(\n 'flex h-10 w-10 shrink-0 items-center justify-center rounded-full',\n {\n variants: {\n variant: {\n destructive: 'bg-destructive/10 text-destructive',\n warning: 'bg-warning/15 text-warning-700 dark:text-warning-400',\n success: 'bg-success/10 text-success-700 dark:text-success-400',\n info: 'bg-info/10 text-info-700 dark:text-info-400',\n },\n },\n }\n);\n\nconst VARIANT_ICONS = {\n destructive: AlertTriangle,\n warning: AlertTriangle,\n success: CheckCircle2,\n info: Info,\n} as const;\n\nexport interface AlertDialogProps extends Pick<\n ModalProps,\n 'open' | 'onOpenChange'\n> {\n /** Dialog title */\n title: React.ReactNode;\n /** Optional descriptive body text */\n description?: React.ReactNode;\n /** Custom body content (rendered below the description) */\n children?: React.ReactNode;\n /** Label for the cancel button; overrides `labels.cancel` */\n cancelLabel?: React.ReactNode;\n /** Label for the confirm/action button; overrides `labels.action` */\n actionLabel?: React.ReactNode;\n /**\n * Called when the action button is clicked. Return a Promise to show a busy\n * state; the dialog closes when it resolves and stays open if it rejects.\n */\n onAction?: () => void | Promise<unknown>;\n /** Called when the cancel button is clicked */\n onCancel?: () => void;\n /** Tone of the dialog: icon, action button colour and initial focus */\n variant?: AlertDialogVariant;\n /** Disables the action button */\n actionDisabled?: boolean;\n /** Hides the cancel button */\n hideCancel?: boolean;\n /** User-facing strings; English defaults in `defaultAlertDialogLabels` */\n labels?: Partial<AlertDialogLabels>;\n /** Additional class name for the dialog content */\n className?: string;\n}\n\nfunction isPromiseLike(value: unknown): value is PromiseLike<unknown> {\n return (\n typeof value === 'object' &&\n value !== null &&\n typeof (value as PromiseLike<unknown>).then === 'function'\n );\n}\n\n/**\n * A modal dialog (`role=\"alertdialog\"`) that interrupts the user with\n * important content and expects a response. Built on top of {@link Modal}.\n *\n * It does not close on overlay click or Escape — the user must explicitly\n * choose an action.\n *\n * @example\n * ```tsx\n * <AlertDialog\n * open={open}\n * onOpenChange={setOpen}\n * title=\"Delete case?\"\n * description=\"This action cannot be undone.\"\n * variant=\"destructive\"\n * actionLabel=\"Delete\"\n * onAction={() => deleteCase(id)}\n * />\n * ```\n */\nfunction AlertDialog({\n open,\n onOpenChange,\n title,\n description,\n children,\n cancelLabel,\n actionLabel,\n onAction,\n onCancel,\n variant = 'default',\n actionDisabled,\n hideCancel,\n labels,\n className,\n}: AlertDialogProps) {\n const text = { ...defaultAlertDialogLabels, ...labels };\n const id = React.useId();\n const titleId = `${id}-title`;\n const descriptionId = `${id}-description`;\n const [busy, setBusy] = React.useState(false);\n const bodyRef = React.useRef<HTMLDivElement>(null);\n const cancelRef = React.useRef<HTMLButtonElement>(null);\n const actionRef = React.useRef<HTMLButtonElement>(null);\n const cautious = variant === 'destructive' || variant === 'warning';\n const iconVariant = variant === 'default' ? null : variant;\n const Icon = iconVariant && VARIANT_ICONS[iconVariant];\n\n // Modal has no role prop; upgrade its dialog element. React never resets it\n // because the role Modal renders does not change.\n React.useLayoutEffect(() => {\n if (!open) return;\n bodyRef.current\n ?.closest('[data-slot=\"modal\"]')\n ?.setAttribute('role', 'alertdialog');\n }, [open]);\n\n // Layout effect so the opener is captured before Modal's trap moves focus.\n React.useLayoutEffect(() => {\n if (!open) return;\n const opener = document.activeElement;\n return () => {\n if (opener instanceof HTMLElement && opener.isConnected) opener.focus();\n };\n }, [open]);\n\n // Parent effects run after Modal's, so this overrides its first-element focus.\n React.useEffect(() => {\n if (!open || isStorybookDocsMode()) return;\n (cautious && !hideCancel ? cancelRef : actionRef).current?.focus();\n }, [open, cautious, hideCancel]);\n\n const handleCancel = () => {\n onCancel?.();\n onOpenChange(false);\n };\n\n // Closing (or reusing) the dialog orphans any in-flight action: its\n // continuation must not clear the busy state or close a newer dialog.\n const actionGen = React.useRef(0);\n React.useEffect(() => {\n if (!open) {\n actionGen.current += 1;\n setBusy(false);\n }\n }, [open]);\n\n const handleAction = async () => {\n let result: unknown;\n try {\n result = onAction?.();\n } catch {\n requestAnimationFrame(() => actionRef.current?.focus());\n return;\n }\n if (!isPromiseLike(result)) return;\n const gen = ++actionGen.current;\n setBusy(true);\n try {\n await result;\n if (gen !== actionGen.current) return;\n setBusy(false);\n onOpenChange(false);\n } catch {\n if (gen !== actionGen.current) return;\n setBusy(false);\n // Disabling the button dropped focus; return it once re-enabled.\n requestAnimationFrame(() => actionRef.current?.focus());\n }\n };\n\n return (\n <Modal\n open={open}\n onOpenChange={onOpenChange}\n size=\"sm\"\n closeOnOverlayClick={false}\n closeOnEscape={false}\n className={className}\n aria-labelledby={titleId}\n aria-describedby={description ? descriptionId : undefined}\n >\n <ModalBody\n ref={bodyRef}\n data-variant={variant}\n aria-busy={busy || undefined}\n className=\"flex items-start gap-4 px-6 py-5\"\n >\n {Icon && iconVariant && (\n <span\n data-slot=\"alert-dialog-icon\"\n className={iconVariants({ variant: iconVariant })}\n >\n <Icon className=\"h-5 w-5\" aria-hidden=\"true\" />\n </span>\n )}\n <div className=\"min-w-0 flex-1\">\n <h2\n id={titleId}\n data-slot=\"alert-dialog-title\"\n className=\"text-lg font-semibold tracking-tight\"\n >\n {title}\n </h2>\n {description && (\n <p\n id={descriptionId}\n data-slot=\"alert-dialog-description\"\n className={cn('text-muted-foreground mt-2 text-sm')}\n >\n {description}\n </p>\n )}\n {children}\n </div>\n </ModalBody>\n <ModalFooter>\n {!hideCancel && (\n <Button\n ref={cancelRef}\n variant=\"secondary\"\n onClick={handleCancel}\n disabled={busy}\n >\n {cancelLabel ?? text.cancel}\n </Button>\n )}\n <Button\n ref={actionRef}\n variant={variant === 'destructive' ? 'danger' : 'primary'}\n onClick={handleAction}\n disabled={actionDisabled}\n isLoading={busy}\n loadingText={text.busy}\n >\n {actionLabel ?? text.action}\n </Button>\n </ModalFooter>\n </Modal>\n );\n}\n\nAlertDialog.displayName = 'AlertDialog';\n\nexport { AlertDialog };\n","import * as React from 'react';\nimport {\n AlertDialog,\n defaultAlertDialogLabels,\n type AlertDialogLabels,\n type AlertDialogVariant,\n} from './AlertDialog';\n\nexport interface ConfirmOptions {\n title: React.ReactNode;\n description?: React.ReactNode;\n actionLabel?: React.ReactNode;\n cancelLabel?: React.ReactNode;\n variant?: AlertDialogVariant;\n}\n\nexport type AlertOptions = Omit<ConfirmOptions, 'cancelLabel'>;\n\nexport interface ConfirmApi {\n /** Resolves `true` when the user confirms, `false` when they cancel. */\n confirm: (options: ConfirmOptions) => Promise<boolean>;\n /** Shows a dialog with only an acknowledge button; resolves when dismissed. */\n alert: (options: AlertOptions) => Promise<void>;\n}\n\nexport interface ConfirmDialogProviderProps {\n children: React.ReactNode;\n /** Default strings for every dialog the provider opens */\n labels?: Partial<AlertDialogLabels>;\n}\n\ninterface PendingDialog extends ConfirmOptions {\n mode: 'confirm' | 'alert';\n}\n\nconst ConfirmContext = React.createContext<ConfirmApi | null>(null);\n\n/**\n * Renders one {@link AlertDialog} and exposes it imperatively through\n * {@link useConfirm}. Mount once near the app root.\n */\nexport function ConfirmDialogProvider({\n children,\n labels,\n}: ConfirmDialogProviderProps) {\n const [request, setRequest] = React.useState<PendingDialog | null>(null);\n const [open, setOpen] = React.useState(false);\n const resolveRef = React.useRef<((confirmed: boolean) => void) | null>(null);\n\n const settle = React.useCallback((confirmed: boolean) => {\n resolveRef.current?.(confirmed);\n resolveRef.current = null;\n setOpen(false);\n }, []);\n\n // If the provider unmounts with a dialog open, settle the promise as\n // cancelled so callers awaiting confirm() aren't suspended forever.\n React.useEffect(\n () => () => {\n resolveRef.current?.(false);\n resolveRef.current = null;\n },\n []\n );\n\n const api = React.useMemo<ConfirmApi>(() => {\n const show = (next: PendingDialog) =>\n new Promise<boolean>((resolve) => {\n // A newer request replaces an unanswered one, which counts as cancelled.\n resolveRef.current?.(false);\n resolveRef.current = resolve;\n setRequest(next);\n setOpen(true);\n });\n return {\n confirm: (options) => show({ ...options, mode: 'confirm' }),\n alert: async (options) => {\n await show({ variant: 'info', ...options, mode: 'alert' });\n },\n };\n }, []);\n\n const text = { ...defaultAlertDialogLabels, ...labels };\n const isAlert = request?.mode === 'alert';\n\n return (\n <ConfirmContext.Provider value={api}>\n {children}\n {request && (\n <AlertDialog\n open={open}\n onOpenChange={(next) => {\n if (!next) settle(false);\n }}\n title={request.title}\n description={request.description}\n variant={request.variant}\n labels={labels}\n hideCancel={isAlert}\n cancelLabel={request.cancelLabel}\n actionLabel={\n request.actionLabel ?? (isAlert ? text.acknowledge : undefined)\n }\n onAction={() => settle(true)}\n />\n )}\n </ConfirmContext.Provider>\n );\n}\n\n/**\n * Promise-based confirm/alert dialogs. Requires a {@link ConfirmDialogProvider}\n * ancestor.\n *\n * @example\n * ```tsx\n * const { confirm } = useConfirm();\n * if (await confirm({ title: 'Delete case?', variant: 'destructive' })) remove();\n * ```\n */\nexport function useConfirm(): ConfirmApi {\n const api = React.useContext(ConfirmContext);\n if (!api) {\n throw new Error('useConfirm must be used within a <ConfirmDialogProvider>');\n }\n return api;\n}\n"]}
@@ -1,7 +1,7 @@
1
1
  import { usePendingOverrides } from './chunk-FTEZNCRI.js';
2
2
  import { RecordState } from './chunk-Y424YL55.js';
3
3
  import { Avatar } from './chunk-TI3TQQ7F.js';
4
- import { Badge } from './chunk-BMSG4NBH.js';
4
+ import { Badge } from './chunk-522WJIVI.js';
5
5
  import { Button } from './chunk-WFBUBT54.js';
6
6
  import { cn } from './chunk-TQONQSJO.js';
7
7
  import * as React from 'react';
@@ -244,5 +244,5 @@ var AssociationList = React.forwardRef(
244
244
  AssociationList.displayName = "AssociationList";
245
245
 
246
246
  export { AssociationList, defaultAssociationListLabels };
247
- //# sourceMappingURL=chunk-LRRSD7LR.js.map
248
- //# sourceMappingURL=chunk-LRRSD7LR.js.map
247
+ //# sourceMappingURL=chunk-5HKZR6UG.js.map
248
+ //# sourceMappingURL=chunk-5HKZR6UG.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/components/AssociationList/AssociationList.tsx"],"names":[],"mappings":"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","file":"chunk-LRRSD7LR.js","sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport { LoaderCircle, Plus, X } from 'lucide-react';\nimport { cn } from '../../utils/cn';\nimport { Avatar } from '../Avatar';\nimport { Badge } from '../Badge';\nimport { Button } from '../Button';\nimport { RecordState } from '../ActivityFeed/RecordState';\nimport { usePendingOverrides } from '../ActivityFeed/usePendingOverrides';\n\n// =============================================================================\n// Types\n// =============================================================================\n\nexport interface AssociationListItem {\n id: string;\n name: string;\n subtitle?: string;\n avatarUrl?: string;\n}\n\nexport interface AssociationListLabels {\n loading: string;\n empty: string;\n error: string;\n retry: string;\n add: string;\n /** Accessible name of an item's remove button. */\n remove: (name: string) => string;\n showAll: (count: number) => string;\n showLess: string;\n}\n\nexport const defaultAssociationListLabels: AssociationListLabels = {\n loading: 'Loading',\n empty: 'None yet',\n error: 'Could not load these records',\n retry: 'Try again',\n add: 'Add',\n remove: (name) => `Remove ${name}`,\n showAll: (count) => `Show all (${count})`,\n showLess: 'Show less',\n};\n\nexport type AssociationListSlot =\n | 'header'\n | 'list'\n | 'item'\n | 'toggle'\n | 'state';\n\nexport interface AssociationListProps extends Omit<\n React.HTMLAttributes<HTMLElement>,\n 'children' | 'title'\n> {\n /** Card heading, e.g. \"Contacts\". */\n title: string;\n items: AssociationListItem[];\n loading?: boolean;\n error?: Error | null;\n onRetry?: () => void;\n /** Items shown before \"Show all\". Defaults to 5. */\n maxVisible?: number;\n onOpen?: (id: string, item: AssociationListItem) => void;\n getHref?: (id: string, item: AssociationListItem) => string;\n /** Renders the header's add button. */\n onAdd?: () => void;\n /** Confirmation is the caller's; the row shows pending until the promise settles. */\n onRemove?: (id: string, item: AssociationListItem) => void | Promise<void>;\n /** Trailing content per row, e.g. a role badge. */\n renderItemMeta?: (item: AssociationListItem) => React.ReactNode;\n emptyState?: React.ReactNode;\n labels?: Partial<AssociationListLabels>;\n classNames?: Partial<Record<AssociationListSlot, string>>;\n headingLevel?: 'h2' | 'h3' | 'h4';\n}\n\n// =============================================================================\n// Component\n// =============================================================================\n\n/**\n * A card of records related to the current one. Declared\n * `parameters.catalog.collection` — its load states are part of the API.\n */\nexport const AssociationList = React.forwardRef<\n HTMLElement,\n AssociationListProps\n>(\n (\n {\n title,\n items,\n loading = false,\n error = null,\n onRetry,\n maxVisible = 5,\n onOpen,\n getHref,\n onAdd,\n onRemove,\n renderItemMeta,\n emptyState,\n labels,\n classNames,\n headingLevel: Heading = 'h3',\n className,\n ...rest\n },\n ref\n ) => {\n const text = { ...defaultAssociationListLabels, ...labels };\n const headingId = React.useId();\n const listId = React.useId();\n const [expanded, setExpanded] = React.useState(false);\n const [pending, runRemove] = usePendingOverrides<true>();\n\n const shown = expanded ? items : items.slice(0, maxVisible);\n const linkClasses =\n 'text-foreground block truncate rounded-sm text-sm font-medium hover:underline focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring';\n\n let body: React.ReactNode;\n if (error) {\n body = (\n <RecordState\n kind=\"error\"\n slot=\"association-list-state\"\n message={text.error}\n retryLabel={text.retry}\n onRetry={onRetry}\n className={cn('py-6', classNames?.state)}\n />\n );\n } else if (loading) {\n body = (\n <RecordState\n kind=\"loading\"\n slot=\"association-list-state\"\n message={text.loading}\n rows={2}\n className={classNames?.state}\n />\n );\n } else if (items.length === 0) {\n body = emptyState ?? (\n <RecordState\n kind=\"empty\"\n slot=\"association-list-state\"\n message={text.empty}\n className={cn('py-6', classNames?.state)}\n />\n );\n } else {\n body = (\n <>\n <ul\n id={listId}\n data-slot=\"association-list-list\"\n className={cn('divide-border divide-y', classNames?.list)}\n >\n {shown.map((item) => {\n const isPending = pending.has(item.id);\n const href = getHref?.(item.id, item);\n let name: React.ReactNode = (\n <span className=\"text-foreground block truncate text-sm font-medium\">\n {item.name}\n </span>\n );\n if (href) {\n name = (\n <a\n href={href}\n className={linkClasses}\n onClick={(event) => {\n if (\n !onOpen ||\n event.metaKey ||\n event.ctrlKey ||\n event.shiftKey ||\n event.button !== 0\n )\n return;\n event.preventDefault();\n onOpen(item.id, item);\n }}\n >\n {item.name}\n </a>\n );\n } else if (onOpen) {\n name = (\n <button\n type=\"button\"\n className={cn(linkClasses, 'max-w-full text-start')}\n onClick={() => onOpen(item.id, item)}\n >\n {item.name}\n </button>\n );\n }\n return (\n <li\n key={item.id}\n data-slot=\"association-list-item\"\n aria-busy={isPending || undefined}\n className={cn(\n 'flex items-center gap-3 px-4 py-2.5',\n isPending && 'opacity-60',\n classNames?.item\n )}\n >\n <Avatar\n size=\"sm\"\n name={item.name}\n src={item.avatarUrl}\n alt=\"\"\n aria-hidden\n className=\"shrink-0\"\n />\n <div className=\"min-w-0 flex-1\">\n {name}\n {item.subtitle && (\n <span className=\"text-muted-foreground block truncate text-xs\">\n {item.subtitle}\n </span>\n )}\n </div>\n {renderItemMeta?.(item)}\n {onRemove && (\n <button\n type=\"button\"\n aria-label={text.remove(item.name)}\n title={text.remove(item.name)}\n disabled={isPending}\n onClick={() =>\n void runRemove(item.id, true, () =>\n onRemove(item.id, item)\n )\n }\n className={cn(\n 'text-muted-foreground hover:bg-muted hover:text-foreground shrink-0 rounded-md p-1.5',\n 'focus-visible:ring-ring focus-visible:ring-2 focus-visible:outline-none'\n )}\n >\n {isPending ? (\n <LoaderCircle\n className=\"size-4 animate-spin motion-reduce:animate-none\"\n aria-hidden\n />\n ) : (\n <X className=\"size-4\" aria-hidden />\n )}\n </button>\n )}\n </li>\n );\n })}\n </ul>\n {items.length > maxVisible && (\n <div className=\"border-border border-t px-2 py-1.5\">\n <Button\n variant=\"ghost\"\n size=\"sm\"\n fullWidth\n aria-expanded={expanded}\n aria-controls={listId}\n data-slot=\"association-list-toggle\"\n className={classNames?.toggle}\n onClick={() => setExpanded((e) => !e)}\n >\n {expanded ? text.showLess : text.showAll(items.length)}\n </Button>\n </div>\n )}\n </>\n );\n }\n\n return (\n <section\n ref={ref}\n aria-labelledby={headingId}\n data-slot=\"association-list\"\n className={cn(\n 'border-border bg-card overflow-hidden rounded-lg border',\n className\n )}\n {...rest}\n >\n <div\n data-slot=\"association-list-header\"\n className={cn(\n 'border-border flex items-center gap-2 border-b px-4 py-2.5',\n classNames?.header\n )}\n >\n <Heading\n id={headingId}\n className=\"text-foreground min-w-0 flex-1 truncate text-sm font-semibold\"\n >\n {title}\n </Heading>\n {!loading && !error && (\n <Badge size=\"sm\" variant=\"secondary\">\n {items.length}\n </Badge>\n )}\n {onAdd && (\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onClick={onAdd}\n leftIcon={<Plus className=\"size-4\" aria-hidden />}\n >\n {text.add}\n </Button>\n )}\n </div>\n {body}\n </section>\n );\n }\n);\n\nAssociationList.displayName = 'AssociationList';\n"]}
1
+ {"version":3,"sources":["../src/components/AssociationList/AssociationList.tsx"],"names":[],"mappings":"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","file":"chunk-5HKZR6UG.js","sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport { LoaderCircle, Plus, X } from 'lucide-react';\nimport { cn } from '../../utils/cn';\nimport { Avatar } from '../Avatar';\nimport { Badge } from '../Badge';\nimport { Button } from '../Button';\nimport { RecordState } from '../ActivityFeed/RecordState';\nimport { usePendingOverrides } from '../ActivityFeed/usePendingOverrides';\n\n// =============================================================================\n// Types\n// =============================================================================\n\nexport interface AssociationListItem {\n id: string;\n name: string;\n subtitle?: string;\n avatarUrl?: string;\n}\n\nexport interface AssociationListLabels {\n loading: string;\n empty: string;\n error: string;\n retry: string;\n add: string;\n /** Accessible name of an item's remove button. */\n remove: (name: string) => string;\n showAll: (count: number) => string;\n showLess: string;\n}\n\nexport const defaultAssociationListLabels: AssociationListLabels = {\n loading: 'Loading',\n empty: 'None yet',\n error: 'Could not load these records',\n retry: 'Try again',\n add: 'Add',\n remove: (name) => `Remove ${name}`,\n showAll: (count) => `Show all (${count})`,\n showLess: 'Show less',\n};\n\nexport type AssociationListSlot =\n | 'header'\n | 'list'\n | 'item'\n | 'toggle'\n | 'state';\n\nexport interface AssociationListProps extends Omit<\n React.HTMLAttributes<HTMLElement>,\n 'children' | 'title'\n> {\n /** Card heading, e.g. \"Contacts\". */\n title: string;\n items: AssociationListItem[];\n loading?: boolean;\n error?: Error | null;\n onRetry?: () => void;\n /** Items shown before \"Show all\". Defaults to 5. */\n maxVisible?: number;\n onOpen?: (id: string, item: AssociationListItem) => void;\n getHref?: (id: string, item: AssociationListItem) => string;\n /** Renders the header's add button. */\n onAdd?: () => void;\n /** Confirmation is the caller's; the row shows pending until the promise settles. */\n onRemove?: (id: string, item: AssociationListItem) => void | Promise<void>;\n /** Trailing content per row, e.g. a role badge. */\n renderItemMeta?: (item: AssociationListItem) => React.ReactNode;\n emptyState?: React.ReactNode;\n labels?: Partial<AssociationListLabels>;\n classNames?: Partial<Record<AssociationListSlot, string>>;\n headingLevel?: 'h2' | 'h3' | 'h4';\n}\n\n// =============================================================================\n// Component\n// =============================================================================\n\n/**\n * A card of records related to the current one. Declared\n * `parameters.catalog.collection` — its load states are part of the API.\n */\nexport const AssociationList = React.forwardRef<\n HTMLElement,\n AssociationListProps\n>(\n (\n {\n title,\n items,\n loading = false,\n error = null,\n onRetry,\n maxVisible = 5,\n onOpen,\n getHref,\n onAdd,\n onRemove,\n renderItemMeta,\n emptyState,\n labels,\n classNames,\n headingLevel: Heading = 'h3',\n className,\n ...rest\n },\n ref\n ) => {\n const text = { ...defaultAssociationListLabels, ...labels };\n const headingId = React.useId();\n const listId = React.useId();\n const [expanded, setExpanded] = React.useState(false);\n const [pending, runRemove] = usePendingOverrides<true>();\n\n const shown = expanded ? items : items.slice(0, maxVisible);\n const linkClasses =\n 'text-foreground block truncate rounded-sm text-sm font-medium hover:underline focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring';\n\n let body: React.ReactNode;\n if (error) {\n body = (\n <RecordState\n kind=\"error\"\n slot=\"association-list-state\"\n message={text.error}\n retryLabel={text.retry}\n onRetry={onRetry}\n className={cn('py-6', classNames?.state)}\n />\n );\n } else if (loading) {\n body = (\n <RecordState\n kind=\"loading\"\n slot=\"association-list-state\"\n message={text.loading}\n rows={2}\n className={classNames?.state}\n />\n );\n } else if (items.length === 0) {\n body = emptyState ?? (\n <RecordState\n kind=\"empty\"\n slot=\"association-list-state\"\n message={text.empty}\n className={cn('py-6', classNames?.state)}\n />\n );\n } else {\n body = (\n <>\n <ul\n id={listId}\n data-slot=\"association-list-list\"\n className={cn('divide-border divide-y', classNames?.list)}\n >\n {shown.map((item) => {\n const isPending = pending.has(item.id);\n const href = getHref?.(item.id, item);\n let name: React.ReactNode = (\n <span className=\"text-foreground block truncate text-sm font-medium\">\n {item.name}\n </span>\n );\n if (href) {\n name = (\n <a\n href={href}\n className={linkClasses}\n onClick={(event) => {\n if (\n !onOpen ||\n event.metaKey ||\n event.ctrlKey ||\n event.shiftKey ||\n event.button !== 0\n )\n return;\n event.preventDefault();\n onOpen(item.id, item);\n }}\n >\n {item.name}\n </a>\n );\n } else if (onOpen) {\n name = (\n <button\n type=\"button\"\n className={cn(linkClasses, 'max-w-full text-start')}\n onClick={() => onOpen(item.id, item)}\n >\n {item.name}\n </button>\n );\n }\n return (\n <li\n key={item.id}\n data-slot=\"association-list-item\"\n aria-busy={isPending || undefined}\n className={cn(\n 'flex items-center gap-3 px-4 py-2.5',\n isPending && 'opacity-60',\n classNames?.item\n )}\n >\n <Avatar\n size=\"sm\"\n name={item.name}\n src={item.avatarUrl}\n alt=\"\"\n aria-hidden\n className=\"shrink-0\"\n />\n <div className=\"min-w-0 flex-1\">\n {name}\n {item.subtitle && (\n <span className=\"text-muted-foreground block truncate text-xs\">\n {item.subtitle}\n </span>\n )}\n </div>\n {renderItemMeta?.(item)}\n {onRemove && (\n <button\n type=\"button\"\n aria-label={text.remove(item.name)}\n title={text.remove(item.name)}\n disabled={isPending}\n onClick={() =>\n void runRemove(item.id, true, () =>\n onRemove(item.id, item)\n )\n }\n className={cn(\n 'text-muted-foreground hover:bg-muted hover:text-foreground shrink-0 rounded-md p-1.5',\n 'focus-visible:ring-ring focus-visible:ring-2 focus-visible:outline-none'\n )}\n >\n {isPending ? (\n <LoaderCircle\n className=\"size-4 animate-spin motion-reduce:animate-none\"\n aria-hidden\n />\n ) : (\n <X className=\"size-4\" aria-hidden />\n )}\n </button>\n )}\n </li>\n );\n })}\n </ul>\n {items.length > maxVisible && (\n <div className=\"border-border border-t px-2 py-1.5\">\n <Button\n variant=\"ghost\"\n size=\"sm\"\n fullWidth\n aria-expanded={expanded}\n aria-controls={listId}\n data-slot=\"association-list-toggle\"\n className={classNames?.toggle}\n onClick={() => setExpanded((e) => !e)}\n >\n {expanded ? text.showLess : text.showAll(items.length)}\n </Button>\n </div>\n )}\n </>\n );\n }\n\n return (\n <section\n ref={ref}\n aria-labelledby={headingId}\n data-slot=\"association-list\"\n className={cn(\n 'border-border bg-card overflow-hidden rounded-lg border',\n className\n )}\n {...rest}\n >\n <div\n data-slot=\"association-list-header\"\n className={cn(\n 'border-border flex items-center gap-2 border-b px-4 py-2.5',\n classNames?.header\n )}\n >\n <Heading\n id={headingId}\n className=\"text-foreground min-w-0 flex-1 truncate text-sm font-semibold\"\n >\n {title}\n </Heading>\n {!loading && !error && (\n <Badge size=\"sm\" variant=\"secondary\">\n {items.length}\n </Badge>\n )}\n {onAdd && (\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onClick={onAdd}\n leftIcon={<Plus className=\"size-4\" aria-hidden />}\n >\n {text.add}\n </Button>\n )}\n </div>\n {body}\n </section>\n );\n }\n);\n\nAssociationList.displayName = 'AssociationList';\n"]}
@@ -469,6 +469,11 @@ var miewebUISafelist = [
469
469
  "start-0",
470
470
  "end-0",
471
471
  "ps-4",
472
+ // Badge removable-chip paddings (ps/pe compound variants)
473
+ "ps-2.5",
474
+ "pe-0.5",
475
+ "pe-1",
476
+ "pe-1.5",
472
477
  "start-2",
473
478
  "end-2",
474
479
  "border-e",
@@ -1258,6 +1263,11 @@ var miewebUISafelist = [
1258
1263
  "hover:text-gray-700",
1259
1264
  "hover:text-gray-900",
1260
1265
  "max-h-[calc(100dvh-10rem)]",
1266
+ // Modal full-screen mobile safe-area insets (reset at sm)
1267
+ "pt-[var(--mieweb-safe-area-top,env(safe-area-inset-top))]",
1268
+ "pb-[var(--mieweb-safe-area-bottom,env(safe-area-inset-bottom))]",
1269
+ "sm:pt-0",
1270
+ "sm:pb-0",
1261
1271
  "md:flex",
1262
1272
  "sm:block",
1263
1273
  "dark:border-b",
@@ -1296,6 +1306,7 @@ var miewebUISafelist = [
1296
1306
  "dark:bg-primary-800",
1297
1307
  "dark:bg-primary-900/60",
1298
1308
  "dark:hover:bg-white/10",
1309
+ "hover:bg-black/10",
1299
1310
  "group-open:rotate-180",
1300
1311
  "rtl:-scale-x-100",
1301
1312
  "after:absolute",
@@ -1325,6 +1336,8 @@ var miewebUISafelist = [
1325
1336
  "md:top-[var(--record-layout-sticky-top,1rem)]",
1326
1337
  "motion-reduce:animate-none",
1327
1338
  "motion-safe:duration-300",
1339
+ "motion-safe:transition-all",
1340
+ "motion-safe:ease-out",
1328
1341
  "motion-safe:enabled:hover:scale-110",
1329
1342
  "motion-safe:transition-[opacity,box-shadow]",
1330
1343
  "motion-safe:transition-[width]",
@@ -1659,5 +1672,5 @@ var tailwind_preset_default = miewebUIPreset;
1659
1672
  exports.miewebUIPreset = miewebUIPreset;
1660
1673
  exports.miewebUISafelist = miewebUISafelist;
1661
1674
  exports.tailwind_preset_default = tailwind_preset_default;
1662
- //# sourceMappingURL=chunk-EMRWTCCN.cjs.map
1663
- //# sourceMappingURL=chunk-EMRWTCCN.cjs.map
1675
+ //# sourceMappingURL=chunk-6WX2OR3U.cjs.map
1676
+ //# sourceMappingURL=chunk-6WX2OR3U.cjs.map