@tribepad/themis 1.0.11 → 1.0.12

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 (221) hide show
  1. package/dist/elements/Accordion/Accordion.types.d.ts +44 -4
  2. package/dist/elements/Accordion/Accordion.types.d.ts.map +1 -1
  3. package/dist/elements/Accordion/index.js +1 -1
  4. package/dist/elements/Accordion/index.js.map +1 -1
  5. package/dist/elements/Accordion/index.mjs +1 -1
  6. package/dist/elements/Accordion/index.mjs.map +1 -1
  7. package/dist/elements/AlertDialog/AlertDialog.types.d.ts +19 -2
  8. package/dist/elements/AlertDialog/AlertDialog.types.d.ts.map +1 -1
  9. package/dist/elements/AlertDialog/index.js +1 -1
  10. package/dist/elements/AlertDialog/index.js.map +1 -1
  11. package/dist/elements/AlertDialog/index.mjs +1 -1
  12. package/dist/elements/AlertDialog/index.mjs.map +1 -1
  13. package/dist/elements/Avatar/Avatar.d.ts +1 -21
  14. package/dist/elements/Avatar/Avatar.d.ts.map +1 -1
  15. package/dist/elements/Avatar/Avatar.types.d.ts +30 -11
  16. package/dist/elements/Avatar/Avatar.types.d.ts.map +1 -1
  17. package/dist/elements/Avatar/AvatarGroup.d.ts +1 -17
  18. package/dist/elements/Avatar/AvatarGroup.d.ts.map +1 -1
  19. package/dist/elements/Avatar/index.js +1 -1
  20. package/dist/elements/Avatar/index.js.map +1 -1
  21. package/dist/elements/Avatar/index.mjs +1 -1
  22. package/dist/elements/Avatar/index.mjs.map +1 -1
  23. package/dist/elements/Badge/Badge.types.d.ts +16 -9
  24. package/dist/elements/Badge/Badge.types.d.ts.map +1 -1
  25. package/dist/elements/Badge/index.js +1 -1
  26. package/dist/elements/Badge/index.js.map +1 -1
  27. package/dist/elements/Badge/index.mjs +1 -1
  28. package/dist/elements/Badge/index.mjs.map +1 -1
  29. package/dist/elements/Breadcrumbs/Breadcrumbs.d.ts +2 -34
  30. package/dist/elements/Breadcrumbs/Breadcrumbs.d.ts.map +1 -1
  31. package/dist/elements/Breadcrumbs/Breadcrumbs.types.d.ts +25 -2
  32. package/dist/elements/Breadcrumbs/Breadcrumbs.types.d.ts.map +1 -1
  33. package/dist/elements/Breadcrumbs/index.js +1 -1
  34. package/dist/elements/Breadcrumbs/index.js.map +1 -1
  35. package/dist/elements/Breadcrumbs/index.mjs +1 -1
  36. package/dist/elements/Breadcrumbs/index.mjs.map +1 -1
  37. package/dist/elements/Button/Button.d.ts +1 -24
  38. package/dist/elements/Button/Button.d.ts.map +1 -1
  39. package/dist/elements/Button/Button.types.d.ts +28 -7
  40. package/dist/elements/Button/Button.types.d.ts.map +1 -1
  41. package/dist/elements/ButtonGroup/ButtonGroup.d.ts +3 -14
  42. package/dist/elements/ButtonGroup/ButtonGroup.d.ts.map +1 -1
  43. package/dist/elements/ButtonGroup/ButtonGroup.types.d.ts +14 -5
  44. package/dist/elements/ButtonGroup/ButtonGroup.types.d.ts.map +1 -1
  45. package/dist/elements/ButtonGroup/index.js +1 -1
  46. package/dist/elements/ButtonGroup/index.js.map +1 -1
  47. package/dist/elements/ButtonGroup/index.mjs +1 -1
  48. package/dist/elements/ButtonGroup/index.mjs.map +1 -1
  49. package/dist/elements/Carousel/Carousel.types.d.ts +26 -7
  50. package/dist/elements/Carousel/Carousel.types.d.ts.map +1 -1
  51. package/dist/elements/Chart/Chart.d.ts +2 -40
  52. package/dist/elements/Chart/Chart.d.ts.map +1 -1
  53. package/dist/elements/Chart/Chart.types.d.ts +25 -10
  54. package/dist/elements/Chart/Chart.types.d.ts.map +1 -1
  55. package/dist/elements/Chart/index.js +1 -1
  56. package/dist/elements/Chart/index.js.map +1 -1
  57. package/dist/elements/Chart/index.mjs +1 -1
  58. package/dist/elements/Chart/index.mjs.map +1 -1
  59. package/dist/elements/Checkbox/Checkbox.d.ts +1 -31
  60. package/dist/elements/Checkbox/Checkbox.d.ts.map +1 -1
  61. package/dist/elements/Checkbox/Checkbox.types.d.ts +33 -1
  62. package/dist/elements/Checkbox/Checkbox.types.d.ts.map +1 -1
  63. package/dist/elements/Checkbox/index.js +1 -1
  64. package/dist/elements/Checkbox/index.js.map +1 -1
  65. package/dist/elements/Checkbox/index.mjs +1 -1
  66. package/dist/elements/Checkbox/index.mjs.map +1 -1
  67. package/dist/elements/CheckboxGroup/CheckboxGroup.d.ts +1 -26
  68. package/dist/elements/CheckboxGroup/CheckboxGroup.d.ts.map +1 -1
  69. package/dist/elements/CheckboxGroup/CheckboxGroup.types.d.ts +48 -4
  70. package/dist/elements/CheckboxGroup/CheckboxGroup.types.d.ts.map +1 -1
  71. package/dist/elements/CheckboxGroup/index.js +1 -1
  72. package/dist/elements/CheckboxGroup/index.js.map +1 -1
  73. package/dist/elements/CheckboxGroup/index.mjs +1 -1
  74. package/dist/elements/CheckboxGroup/index.mjs.map +1 -1
  75. package/dist/elements/Combobox/Combobox.d.ts +1 -30
  76. package/dist/elements/Combobox/Combobox.d.ts.map +1 -1
  77. package/dist/elements/Combobox/Combobox.types.d.ts +38 -4
  78. package/dist/elements/Combobox/Combobox.types.d.ts.map +1 -1
  79. package/dist/elements/Combobox/index.js +1 -1
  80. package/dist/elements/Combobox/index.js.map +1 -1
  81. package/dist/elements/Combobox/index.mjs +1 -1
  82. package/dist/elements/Combobox/index.mjs.map +1 -1
  83. package/dist/elements/Dropdown/Dropdown.d.ts +10 -124
  84. package/dist/elements/Dropdown/Dropdown.d.ts.map +1 -1
  85. package/dist/elements/Dropdown/Dropdown.types.d.ts +53 -8
  86. package/dist/elements/Dropdown/Dropdown.types.d.ts.map +1 -1
  87. package/dist/elements/FileField/FileField.d.ts +2 -39
  88. package/dist/elements/FileField/FileField.d.ts.map +1 -1
  89. package/dist/elements/FileField/FileField.types.d.ts +31 -13
  90. package/dist/elements/FileField/FileField.types.d.ts.map +1 -1
  91. package/dist/elements/FileField/index.js +1 -1
  92. package/dist/elements/FileField/index.js.map +1 -1
  93. package/dist/elements/FileField/index.mjs +1 -1
  94. package/dist/elements/FileField/index.mjs.map +1 -1
  95. package/dist/elements/FormLayout/FormLayout.d.ts +2 -37
  96. package/dist/elements/FormLayout/FormLayout.d.ts.map +1 -1
  97. package/dist/elements/FormLayout/FormLayout.types.d.ts +19 -3
  98. package/dist/elements/FormLayout/FormLayout.types.d.ts.map +1 -1
  99. package/dist/elements/MatrixGrid/MatrixGrid.d.ts +2 -29
  100. package/dist/elements/MatrixGrid/MatrixGrid.d.ts.map +1 -1
  101. package/dist/elements/MatrixGrid/MatrixGrid.types.d.ts +22 -1
  102. package/dist/elements/MatrixGrid/MatrixGrid.types.d.ts.map +1 -1
  103. package/dist/elements/MatrixGrid/index.js +1 -1
  104. package/dist/elements/MatrixGrid/index.js.map +1 -1
  105. package/dist/elements/MatrixGrid/index.mjs +1 -1
  106. package/dist/elements/MatrixGrid/index.mjs.map +1 -1
  107. package/dist/elements/Modal/Modal.types.d.ts +69 -9
  108. package/dist/elements/Modal/Modal.types.d.ts.map +1 -1
  109. package/dist/elements/Pagination/Pagination.d.ts +2 -28
  110. package/dist/elements/Pagination/Pagination.d.ts.map +1 -1
  111. package/dist/elements/Pagination/Pagination.types.d.ts +26 -1
  112. package/dist/elements/Pagination/Pagination.types.d.ts.map +1 -1
  113. package/dist/elements/Pagination/index.js +1 -1
  114. package/dist/elements/Pagination/index.js.map +1 -1
  115. package/dist/elements/Pagination/index.mjs +1 -1
  116. package/dist/elements/Pagination/index.mjs.map +1 -1
  117. package/dist/elements/Panel/Panel.types.d.ts +67 -9
  118. package/dist/elements/Panel/Panel.types.d.ts.map +1 -1
  119. package/dist/elements/PasswordField/PasswordField.d.ts +2 -26
  120. package/dist/elements/PasswordField/PasswordField.d.ts.map +1 -1
  121. package/dist/elements/PasswordField/PasswordField.types.d.ts +27 -2
  122. package/dist/elements/PasswordField/PasswordField.types.d.ts.map +1 -1
  123. package/dist/elements/PasswordField/index.js +1 -1
  124. package/dist/elements/PasswordField/index.js.map +1 -1
  125. package/dist/elements/PasswordField/index.mjs +1 -1
  126. package/dist/elements/PasswordField/index.mjs.map +1 -1
  127. package/dist/elements/RadioGroup/RadioGroup.d.ts +1 -26
  128. package/dist/elements/RadioGroup/RadioGroup.d.ts.map +1 -1
  129. package/dist/elements/RadioGroup/RadioGroup.types.d.ts +43 -4
  130. package/dist/elements/RadioGroup/RadioGroup.types.d.ts.map +1 -1
  131. package/dist/elements/RadioGroup/index.js +1 -1
  132. package/dist/elements/RadioGroup/index.js.map +1 -1
  133. package/dist/elements/RadioGroup/index.mjs +1 -1
  134. package/dist/elements/RadioGroup/index.mjs.map +1 -1
  135. package/dist/elements/RatingScale/RatingScale.d.ts +2 -30
  136. package/dist/elements/RatingScale/RatingScale.d.ts.map +1 -1
  137. package/dist/elements/RatingScale/RatingScale.types.d.ts +29 -1
  138. package/dist/elements/RatingScale/RatingScale.types.d.ts.map +1 -1
  139. package/dist/elements/RatingScale/index.js +1 -1
  140. package/dist/elements/RatingScale/index.js.map +1 -1
  141. package/dist/elements/RatingScale/index.mjs +1 -1
  142. package/dist/elements/RatingScale/index.mjs.map +1 -1
  143. package/dist/elements/SearchField/SearchField.d.ts +2 -26
  144. package/dist/elements/SearchField/SearchField.d.ts.map +1 -1
  145. package/dist/elements/SearchField/SearchField.types.d.ts +26 -2
  146. package/dist/elements/SearchField/SearchField.types.d.ts.map +1 -1
  147. package/dist/elements/SearchField/index.js +1 -1
  148. package/dist/elements/SearchField/index.js.map +1 -1
  149. package/dist/elements/SearchField/index.mjs +1 -1
  150. package/dist/elements/SearchField/index.mjs.map +1 -1
  151. package/dist/elements/Select/Select.d.ts +3 -61
  152. package/dist/elements/Select/Select.d.ts.map +1 -1
  153. package/dist/elements/Select/Select.types.d.ts +52 -4
  154. package/dist/elements/Select/Select.types.d.ts.map +1 -1
  155. package/dist/elements/Select/index.js +1 -1
  156. package/dist/elements/Select/index.js.map +1 -1
  157. package/dist/elements/Select/index.mjs +1 -1
  158. package/dist/elements/Select/index.mjs.map +1 -1
  159. package/dist/elements/SituationalJudgement/SituationalJudgement.d.ts +2 -28
  160. package/dist/elements/SituationalJudgement/SituationalJudgement.d.ts.map +1 -1
  161. package/dist/elements/SituationalJudgement/SituationalJudgement.types.d.ts +23 -1
  162. package/dist/elements/SituationalJudgement/SituationalJudgement.types.d.ts.map +1 -1
  163. package/dist/elements/SituationalJudgement/index.js +1 -1
  164. package/dist/elements/SituationalJudgement/index.js.map +1 -1
  165. package/dist/elements/SituationalJudgement/index.mjs +1 -1
  166. package/dist/elements/SituationalJudgement/index.mjs.map +1 -1
  167. package/dist/elements/Skeleton/Skeleton.types.d.ts +11 -6
  168. package/dist/elements/Skeleton/Skeleton.types.d.ts.map +1 -1
  169. package/dist/elements/Skeleton/index.js +1 -1
  170. package/dist/elements/Skeleton/index.js.map +1 -1
  171. package/dist/elements/Skeleton/index.mjs +1 -1
  172. package/dist/elements/Skeleton/index.mjs.map +1 -1
  173. package/dist/elements/Switch/Switch.types.d.ts +31 -7
  174. package/dist/elements/Switch/Switch.types.d.ts.map +1 -1
  175. package/dist/elements/Switch/index.js +1 -1
  176. package/dist/elements/Switch/index.js.map +1 -1
  177. package/dist/elements/Switch/index.mjs +1 -1
  178. package/dist/elements/Switch/index.mjs.map +1 -1
  179. package/dist/elements/Table/Table.d.ts +7 -79
  180. package/dist/elements/Table/Table.d.ts.map +1 -1
  181. package/dist/elements/Table/Table.types.d.ts +82 -17
  182. package/dist/elements/Table/Table.types.d.ts.map +1 -1
  183. package/dist/elements/Table/index.js +1 -1
  184. package/dist/elements/Table/index.js.map +1 -1
  185. package/dist/elements/Table/index.mjs +1 -1
  186. package/dist/elements/Table/index.mjs.map +1 -1
  187. package/dist/elements/Tabs/Tabs.types.d.ts +61 -5
  188. package/dist/elements/Tabs/Tabs.types.d.ts.map +1 -1
  189. package/dist/elements/Tabs/index.js +1 -1
  190. package/dist/elements/Tabs/index.js.map +1 -1
  191. package/dist/elements/Tabs/index.mjs +1 -1
  192. package/dist/elements/Tabs/index.mjs.map +1 -1
  193. package/dist/elements/TextField/TextField.d.ts +6 -71
  194. package/dist/elements/TextField/TextField.d.ts.map +1 -1
  195. package/dist/elements/TextField/TextField.types.d.ts +76 -12
  196. package/dist/elements/TextField/TextField.types.d.ts.map +1 -1
  197. package/dist/elements/TextField/index.js +1 -1
  198. package/dist/elements/TextField/index.js.map +1 -1
  199. package/dist/elements/TextField/index.mjs +1 -1
  200. package/dist/elements/TextField/index.mjs.map +1 -1
  201. package/dist/elements/Toast/Toast.types.d.ts +12 -20
  202. package/dist/elements/Toast/Toast.types.d.ts.map +1 -1
  203. package/dist/elements/Toast/Toaster.d.ts +2 -5
  204. package/dist/elements/Toast/Toaster.d.ts.map +1 -1
  205. package/dist/elements/Toast/index.js +1 -1
  206. package/dist/elements/Toast/index.js.map +1 -1
  207. package/dist/elements/Toast/index.mjs +1 -1
  208. package/dist/elements/Toast/index.mjs.map +1 -1
  209. package/dist/elements/Tooltip/Tooltip.types.d.ts +39 -4
  210. package/dist/elements/Tooltip/Tooltip.types.d.ts.map +1 -1
  211. package/dist/elements/Tooltip/index.js +1 -1
  212. package/dist/elements/Tooltip/index.js.map +1 -1
  213. package/dist/elements/Tooltip/index.mjs +1 -1
  214. package/dist/elements/Tooltip/index.mjs.map +1 -1
  215. package/dist/elements/index.js.map +1 -1
  216. package/dist/elements/index.mjs.map +1 -1
  217. package/dist/index.js +2 -2
  218. package/dist/index.js.map +1 -1
  219. package/dist/index.mjs +2 -2
  220. package/dist/index.mjs.map +1 -1
  221. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/utils/cn.ts","../../../src/styles/shared-variants.ts","../../../src/elements/Modal/Modal.styles.ts","../../../src/elements/Modal/Modal.tsx","../../../src/elements/Button/Button.styles.ts","../../../src/styles/interaction-states.ts","../../../src/elements/ButtonGroup/ButtonGroupContext.tsx","../../../src/elements/ButtonGroup/ButtonGroup.variants.ts","../../../src/elements/Button/Button.tsx","../../../src/elements/AlertDialog/AlertDialog.styles.ts","../../../src/elements/AlertDialog/AlertDialog.tsx","../../../src/schemas/BaseComponentProps.ts","../../../src/elements/AlertDialog/AlertDialog.types.ts"],"names":["cn","inputs","twMerge","clsx","MODAL_ANIMATION_IN","MODAL_ANIMATION_OUT","MODAL_SLIDE_IN","MODAL_SLIDE_OUT","MODAL_OVERLAY_IN","MODAL_OVERLAY_OUT","REDUCED_MOTION","modalContentVariants","cva","modalOverlayVariants","ModalContext","createContext","ModalRoot","children","defaultOpen","isOpen","onOpenChange","role","childArray","Children","hasTrigger","child","isValidElement","ModalTrigger","hasContent","ModalContent","triggerChild","contentChild","triggerElement","unwrappedTrigger","unwrappedContent","jsx","jsxs","AriaDialogTrigger","size","animation","animationDuration","isDismissable","isKeyboardDismissDisabled","showClose","className","useContext","overlayClasses","modalClasses","mergedModalClasses","AriaModalOverlay","AriaModal","AriaDialog","close","Fragment","AriaButton","X","ModalOverlay","_props","ModalHeader","ModalTitle","as","Heading","ModalDescription","ModalFooter","ModalClose","state","OverlayTriggerStateContext","childElement","handlePress","existingOnPress","cloneElement","Modal","buttonOuterVariants","buttonVisualVariants","PRESSED_STYLES","HOVER_STYLES","HIGH_CONTRAST_HOVER","HIGH_CONTRAST_PRESSED","ButtonGroupContext","useButtonGroupContext","ButtonGroupItemContext","useButtonGroupItemContext","buttonGroupItemVariants","Button","memo","forwardRef","buttonVisualClassName","variant","visualSize","fullWidth","loading","loadingText","shortcut","isDisabled","paywall","paywallRedirect","paywallDescription","onPress","props","ref","paywallDescriptionId","useId","groupContext","itemContext","effectiveVariant","effectiveSize","effectiveIsDisabled","isInVerticalGroup","effectiveFullWidth","positionClassName","effectiveVisualSize","e","renderProps","Loader2","Zap","alertDialogContentVariants","AlertDialog","trigger","title","description","cancelLabel","cancelIcon","actionLabel","actionIcon","actionVariant","onAction","BaseComponentPropsSchema","z","AlertDialogVariantSchema","AlertDialogSizeSchema","AlertDialogPropsSchema"],"mappings":"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","file":"index.mjs","sourcesContent":["/**\n * Class Name Utility\n * Merges Tailwind CSS classes with conflict resolution\n *\n * Combines clsx for conditional classes and tailwind-merge for deduplication\n *\n * @example\n * cn('px-2 py-1', 'px-4') // => 'py-1 px-4' (px-4 overrides px-2)\n * cn('text-red-500', condition && 'text-blue-500') // => conditional application\n */\n\nimport { clsx, type ClassValue } from 'clsx';\nimport { twMerge } from 'tailwind-merge';\n\nexport function cn(...inputs: ClassValue[]): string {\n return twMerge(clsx(inputs));\n}\n","/**\n * Shared CVA Variant Utilities\n *\n * Common patterns extracted from component variants for consistency and reduced bundle size.\n * Use these constants in CVA definitions to ensure consistent styling across Themis.\n *\n * @see interaction-states.ts for interaction-specific styles (focus, hover, pressed)\n */\n\n// =============================================================================\n// Focus Ring Patterns\n// =============================================================================\n\n/**\n * Focus-within ring (for container elements with focusable children)\n * Use when the container should show focus when any child is focused\n */\nexport const FOCUS_WITHIN_RING = [\n 'focus-within:outline-none',\n 'focus-within:ring-2',\n 'focus-within:ring-[var(--ring)]',\n 'focus-within:ring-offset-2',\n] as const;\n\n/**\n * Focus-visible ring (for directly focusable elements)\n * Use for buttons, inputs, and other interactive elements\n */\nexport const FOCUS_VISIBLE_RING = [\n 'focus-visible:outline-none',\n 'focus-visible:ring-2',\n 'focus-visible:ring-[var(--ring)]',\n 'focus-visible:ring-offset-2',\n] as const;\n\n/**\n * Standard focus ring (for elements using :focus pseudo-class)\n * Prefer focus-visible when possible for better UX\n */\nexport const FOCUS_RING = [\n 'focus:outline-none',\n 'focus:ring-2',\n 'focus:ring-[var(--ring)]',\n] as const;\n\n/**\n * Focus with background change (for segments, cells, menu items)\n */\nexport const FOCUS_HIGHLIGHT = [\n 'focus:outline-none',\n 'focus:bg-[var(--accent)]',\n 'focus:text-[var(--accent-foreground)]',\n] as const;\n\n// =============================================================================\n// Disabled State Patterns\n// =============================================================================\n\n/**\n * Standard disabled state using disabled attribute\n */\nexport const DISABLED_STANDARD = [\n 'disabled:pointer-events-none',\n 'disabled:opacity-50',\n] as const;\n\n/**\n * Disabled state using data attribute (React Aria pattern)\n */\nexport const DISABLED_DATA_ATTR = [\n 'data-[disabled]:pointer-events-none',\n 'data-[disabled]:opacity-50',\n 'data-[disabled]:cursor-not-allowed',\n] as const;\n\n// =============================================================================\n// Size-Based Text Variants\n// =============================================================================\n\n/**\n * Small text size scale (xs -> sm -> base)\n */\nexport const TEXT_SIZE_SMALL_SCALE = {\n sm: 'text-xs',\n default: 'text-sm',\n lg: 'text-base',\n} as const;\n\n/**\n * Medium text size scale (sm -> base -> lg)\n */\nexport const TEXT_SIZE_MEDIUM_SCALE = {\n sm: 'text-sm',\n default: 'text-base',\n lg: 'text-lg',\n} as const;\n\n// =============================================================================\n// Touch Target Utilities\n// =============================================================================\n\n/**\n * WCAG 2.2 AAA minimum touch target (44x44px)\n */\nexport const TOUCH_TARGET_MIN = [\n 'min-h-[44px]',\n 'min-w-[44px]',\n] as const;\n\n/**\n * Common button/cell sizes with touch target compliance\n */\nexport const INTERACTIVE_SIZES = {\n sm: 'h-9 w-9', // 36px - desktop only, NOT AAA compliant\n default: 'h-11 w-11', // 44px - AAA compliant\n lg: 'h-14 w-14', // 56px - AAA compliant, enhanced\n} as const;\n\n/**\n * Height-only sizes for fields and inputs\n */\nexport const FIELD_HEIGHTS = {\n sm: 'h-9', // 36px\n default: 'h-11', // 44px\n lg: 'h-14', // 56px\n} as const;\n\n// =============================================================================\n// Message/Feedback Patterns\n// =============================================================================\n\n/**\n * Error message styling\n */\nexport const ERROR_MESSAGE_BASE = [\n 'flex',\n 'items-center',\n 'gap-1.5',\n 'text-[var(--destructive-background)]',\n] as const;\n\n/**\n * Success message styling\n */\nexport const SUCCESS_MESSAGE_BASE = [\n 'flex',\n 'items-center',\n 'gap-1.5',\n 'text-[var(--success-background)]',\n] as const;\n\n/**\n * Description/helper text styling\n */\nexport const DESCRIPTION_BASE = [\n 'text-[var(--menu-muted)]',\n] as const;\n\n/**\n * Label base styling\n */\nexport const LABEL_BASE = [\n 'font-medium',\n 'text-[var(--content-foreground)]',\n] as const;\n\n/**\n * Required indicator pattern\n */\nexport const REQUIRED_INDICATOR = \"after:content-['*'] after:ml-0.5 after:text-[var(--destructive-background)]\";\n\n// =============================================================================\n// Animation Patterns\n// =============================================================================\n\n/**\n * Popover/dropdown entry animation\n */\nexport const POPOVER_ANIMATION_IN = [\n 'data-[entering]:animate-in',\n 'data-[entering]:fade-in-0',\n 'data-[entering]:zoom-in-95',\n] as const;\n\n/**\n * Popover/dropdown exit animation\n */\nexport const POPOVER_ANIMATION_OUT = [\n 'data-[exiting]:animate-out',\n 'data-[exiting]:fade-out-0',\n 'data-[exiting]:zoom-out-95',\n] as const;\n\n/**\n * Modal content enter animation (fade + zoom)\n * Uses React Aria data-[entering]/data-[exiting] attributes\n */\nexport const MODAL_ANIMATION_IN = [\n 'data-[entering]:animate-in',\n 'data-[entering]:fade-in-0',\n 'data-[entering]:zoom-in-95',\n 'data-[entering]:duration-200',\n 'data-[entering]:ease-out',\n] as const;\n\n/**\n * Modal content exit animation (fade + zoom)\n * Uses React Aria data-[entering]/data-[exiting] attributes\n */\nexport const MODAL_ANIMATION_OUT = [\n 'data-[exiting]:animate-out',\n 'data-[exiting]:fade-out-0',\n 'data-[exiting]:zoom-out-95',\n 'data-[exiting]:duration-150',\n 'data-[exiting]:ease-in',\n] as const;\n\n/**\n * Modal slide enter animation (fade + slide up)\n */\nexport const MODAL_SLIDE_IN = [\n 'data-[entering]:animate-in',\n 'data-[entering]:fade-in-0',\n 'data-[entering]:slide-in-from-bottom-4',\n 'data-[entering]:duration-200',\n 'data-[entering]:ease-out',\n] as const;\n\n/**\n * Modal slide exit animation (fade + slide down)\n */\nexport const MODAL_SLIDE_OUT = [\n 'data-[exiting]:animate-out',\n 'data-[exiting]:fade-out-0',\n 'data-[exiting]:slide-out-to-bottom-4',\n 'data-[exiting]:duration-150',\n 'data-[exiting]:ease-in',\n] as const;\n\n/**\n * Modal overlay enter/exit animation (fade only)\n */\nexport const MODAL_OVERLAY_IN = [\n 'data-[entering]:animate-in',\n 'data-[entering]:fade-in-0',\n 'data-[entering]:duration-200',\n] as const;\n\nexport const MODAL_OVERLAY_OUT = [\n 'data-[exiting]:animate-out',\n 'data-[exiting]:fade-out-0',\n 'data-[exiting]:duration-150',\n] as const;\n\n/**\n * Reduced motion support (WCAG 2.2)\n */\nexport const REDUCED_MOTION = [\n 'motion-reduce:transition-none',\n 'motion-reduce:animate-none',\n] as const;\n\n/**\n * Standard transition for colors\n */\nexport const TRANSITION_COLORS = [\n 'transition-colors',\n 'duration-200',\n] as const;\n\n/**\n * Fast transition for interactions\n */\nexport const TRANSITION_FAST = [\n 'transition-colors',\n 'duration-150',\n] as const;\n\n// =============================================================================\n// Hover State Patterns\n// =============================================================================\n\n/**\n * Accent background on hover (for interactive items)\n */\nexport const HOVER_ACCENT = [\n 'hover:bg-[var(--accent)]',\n 'hover:text-[var(--accent-foreground)]',\n] as const;\n\n// =============================================================================\n// Helper Functions\n// =============================================================================\n\n/**\n * Combines multiple style arrays into a flat array for CVA base styles\n */\nexport function combineStyles(...styles: (readonly string[] | string)[]): string[] {\n return styles.flatMap(s => Array.isArray(s) ? [...s] : [s]);\n}\n","import { cva, type VariantProps } from 'class-variance-authority';\nimport {\n MODAL_ANIMATION_IN,\n MODAL_ANIMATION_OUT,\n MODAL_SLIDE_IN,\n MODAL_SLIDE_OUT,\n MODAL_OVERLAY_IN,\n MODAL_OVERLAY_OUT,\n REDUCED_MOTION,\n} from '../../styles/shared-variants';\n\n/**\n * CVA Variants for Modal.Content\n *\n * Size and animation variant definitions for the modal content container.\n * Uses React Aria data-[entering]/data-[exiting] attributes for enter+exit animations.\n * Uses CSS custom properties for all colours to support theming.\n *\n * @see Modal.types.ts (ModalSize, ModalAnimation)\n */\nexport const modalContentVariants = cva(\n [\n // Base styles\n 'relative',\n 'bg-[var(--content-background)]',\n 'text-[var(--content-foreground)]',\n 'rounded-lg',\n 'shadow-lg',\n 'p-6',\n 'w-full',\n 'outline-none',\n // Responsive: full-width on mobile with padding, constrained on desktop\n 'mx-4',\n 'sm:mx-0',\n // Reduced motion support\n ...REDUCED_MOTION,\n ],\n {\n variants: {\n size: {\n sm: 'max-w-sm', // 300px\n md: 'max-w-md', // 425px\n lg: 'max-w-lg', // 600px\n xl: 'max-w-2xl', // 800px\n full: 'max-w-full min-h-screen rounded-none', // Full screen\n },\n animation: {\n 'fade-zoom': [\n ...MODAL_ANIMATION_IN,\n ...MODAL_ANIMATION_OUT,\n ],\n fade: [\n 'data-[entering]:animate-in',\n 'data-[entering]:fade-in-0',\n 'data-[entering]:duration-200',\n 'data-[entering]:ease-out',\n 'data-[exiting]:animate-out',\n 'data-[exiting]:fade-out-0',\n 'data-[exiting]:duration-150',\n 'data-[exiting]:ease-in',\n ],\n slide: [\n ...MODAL_SLIDE_IN,\n ...MODAL_SLIDE_OUT,\n ],\n none: '',\n },\n },\n defaultVariants: {\n size: 'md',\n animation: 'fade-zoom',\n },\n }\n);\n\n/**\n * CVA Variants for Modal Overlay\n *\n * Animation variant definitions for the modal backdrop overlay.\n * Uses React Aria data-[entering]/data-[exiting] attributes for enter+exit animations.\n * Uses CSS custom properties for all colours to support theming.\n */\nexport const modalOverlayVariants = cva(\n [\n // Base overlay styles\n 'fixed',\n 'inset-0',\n 'z-50',\n 'flex',\n 'items-center',\n 'justify-center',\n 'bg-black/50',\n 'backdrop-blur-sm',\n // Reduced motion support\n ...REDUCED_MOTION,\n ],\n {\n variants: {\n animation: {\n 'fade-zoom': [...MODAL_OVERLAY_IN, ...MODAL_OVERLAY_OUT],\n fade: [...MODAL_OVERLAY_IN, ...MODAL_OVERLAY_OUT],\n slide: [...MODAL_OVERLAY_IN, ...MODAL_OVERLAY_OUT],\n none: '',\n },\n },\n defaultVariants: {\n animation: 'fade-zoom',\n },\n }\n);\n\n/**\n * Type exports for variant props\n * Allows TypeScript inference of variant combinations\n */\nexport type ModalContentVariantProps = VariantProps<typeof modalContentVariants>;\nexport type ModalOverlayVariantProps = VariantProps<typeof modalOverlayVariants>;\n","'use client';\n\n/**\n * Modal Component - Implementation\n *\n * Accessible modal dialog component combining React Aria primitives with ShadCN styling.\n * Follows Themis library patterns with compound component structure.\n *\n * @see PRD.md (Full requirements)\n * @see Modal.types.ts (Zod schemas)\n * @see RESEARCH.md (React Aria patterns)\n */\n\nimport {\n Children,\n isValidElement,\n cloneElement,\n useContext,\n createContext,\n type ReactElement,\n type ReactNode,\n} from 'react';\nimport {\n DialogTrigger as AriaDialogTrigger,\n Modal as AriaModal,\n ModalOverlay as AriaModalOverlay,\n Dialog as AriaDialog,\n Heading,\n Button as AriaButton,\n OverlayTriggerStateContext,\n} from 'react-aria-components';\nimport { X } from 'lucide-react';\nimport { cn } from '../../utils/cn';\nimport { modalContentVariants, modalOverlayVariants } from './Modal.styles';\nimport type {\n ModalProps,\n ModalTriggerProps,\n ModalContentProps,\n ModalOverlayProps,\n ModalHeaderProps,\n ModalTitleProps,\n ModalDescriptionProps,\n ModalFooterProps,\n ModalCloseProps,\n} from './Modal.types';\n\n/**\n * Modal Context\n * Passes role prop from Modal root to Modal.Content\n */\ninterface ModalContextValue {\n role?: 'dialog' | 'alertdialog';\n}\n\nconst ModalContext = createContext<ModalContextValue | undefined>(undefined);\n\n/**\n * Modal Root Component\n *\n * Manages modal open/close state and validates required children structure.\n * Must contain exactly one Modal.Trigger and one Modal.Content.\n *\n * Unwraps compound component children and passes them to React Aria's DialogTrigger.\n *\n * @see PRD.md FR-001 (Modal Root Requirements)\n * @see PRD.md FR-012 (Controlled Mode)\n * @see PRD.md FR-013 (Uncontrolled Mode)\n */\nfunction ModalRoot({ children, defaultOpen, isOpen, onOpenChange, role = 'dialog' }: ModalProps): ReactElement {\n const childArray = Children.toArray(children);\n\n // Validate children structure in development only\n if (process.env.NODE_ENV !== 'production') {\n const hasTrigger = childArray.some(\n (child) =>\n isValidElement(child) &&\n (child.type === ModalTrigger ||\n (child.type as { displayName?: string }).displayName === 'ModalTrigger')\n );\n\n const hasContent = childArray.some(\n (child) =>\n isValidElement(child) &&\n (child.type === ModalContent ||\n (child.type as { displayName?: string }).displayName === 'ModalContent')\n );\n\n if (!hasTrigger || !hasContent) {\n throw new Error(\n 'Modal requires exactly one Modal.Trigger and one Modal.Content as children'\n );\n }\n }\n\n // Find trigger and content children\n const triggerChild = childArray.find(\n (child) =>\n isValidElement(child) &&\n (child.type === ModalTrigger ||\n (child.type as { displayName?: string }).displayName === 'ModalTrigger')\n );\n\n const contentChild = childArray.find(\n (child) =>\n isValidElement(child) &&\n (child.type === ModalContent ||\n (child.type as { displayName?: string }).displayName === 'ModalContent')\n );\n\n // Extract the actual children from Modal.Trigger and Modal.Content\n // React Aria's DialogTrigger expects direct Button and Modal children\n const triggerElement = triggerChild as ReactElement;\n const unwrappedTrigger = isValidElement(triggerElement)\n ? ((triggerElement.props as unknown as { children?: ReactNode }).children as ReactNode)\n : null;\n const unwrappedContent = contentChild as ReactElement;\n\n return (\n <ModalContext.Provider value={{ role }}>\n <AriaDialogTrigger\n defaultOpen={defaultOpen}\n isOpen={isOpen}\n onOpenChange={onOpenChange}\n >\n {unwrappedTrigger}\n {unwrappedContent}\n </AriaDialogTrigger>\n </ModalContext.Provider>\n );\n}\n\nModalRoot.displayName = 'Modal';\n\n/**\n * Modal.Trigger Component\n *\n * Wraps a single child element (typically Button) with modal trigger behavior.\n * Handles click events to open modal and manages ARIA attributes.\n *\n * React Aria's DialogTrigger (used in Modal root) automatically applies:\n * - aria-haspopup=\"dialog\"\n * - aria-expanded (true/false based on state)\n * - onClick handler to toggle modal\n *\n * @see PRD.md FR-002 (Trigger Requirements)\n * @see RESEARCH.md Section 2 (React Aria Integration)\n */\nfunction ModalTrigger({ children }: ModalTriggerProps): ReactElement {\n // React Aria's DialogTrigger (in Modal root) automatically adds ARIA attributes\n // to the first child component. We pass through the child element directly.\n return children as ReactElement;\n}\n\nModalTrigger.displayName = 'ModalTrigger';\n\n/**\n * Modal.Content Component\n *\n * Renders the modal content with overlay backdrop.\n * Uses React Aria's Modal and ModalOverlay for accessibility.\n * Applies CVA variants for size and animation.\n *\n * @see PRD.md FR-003 (Content Requirements)\n * @see PRD.md TR-001 (CVA Variant Styling)\n * @see RESEARCH.md Section 2 (React Aria Integration)\n */\nfunction ModalContent({\n children,\n size = 'md',\n animation = 'fade-zoom',\n animationDuration = 200,\n isDismissable = true,\n isKeyboardDismissDisabled = false,\n showClose = true,\n className,\n}: ModalContentProps): ReactElement {\n // Get role from context\n const context = useContext(ModalContext);\n const role = context?.role ?? 'dialog';\n\n // Generate overlay classes with animation variant\n const overlayClasses = modalOverlayVariants({ animation });\n\n // Generate modal classes with size and animation variants, merged with custom className\n const modalClasses = modalContentVariants({ size, animation });\n const mergedModalClasses = cn(modalClasses, className);\n\n return (\n <AriaModalOverlay\n isDismissable={isDismissable}\n isKeyboardDismissDisabled={isKeyboardDismissDisabled}\n className={overlayClasses}\n >\n <AriaModal\n className={mergedModalClasses}\n style={{\n transitionDuration: `${animationDuration}ms`,\n }}\n >\n <AriaDialog role={role} className=\"outline-none\">\n {({ close }) => (\n <>\n {showClose && (\n <AriaButton\n onPress={close}\n className=\"absolute right-0 top-0 flex items-center justify-center rounded-sm opacity-70 ring-offset-[var(--content-background)] transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-[var(--ring)] focus:ring-offset-2 disabled:pointer-events-none min-h-[44px] min-w-[44px]\"\n aria-label=\"Close modal\"\n >\n <X className=\"h-4 w-4\" aria-hidden=\"true\" />\n </AriaButton>\n )}\n {children}\n </>\n )}\n </AriaDialog>\n </AriaModal>\n </AriaModalOverlay>\n );\n}\n\nModalContent.displayName = 'ModalContent';\n\n/**\n * Modal.Overlay Component (Placeholder - not exposed in public API)\n * Overlay is managed internally by Modal.Content via AriaModalOverlay\n */\nfunction ModalOverlay(_props: ModalOverlayProps): null {\n return null;\n}\n\nModalOverlay.displayName = 'ModalOverlay';\n\n/**\n * Modal.Header Component\n *\n * Container for modal header content (typically Title and Description).\n * Applies consistent spacing and layout.\n *\n * @see PRD.md FR-005 (Header Requirements)\n */\nfunction ModalHeader({ children, className }: ModalHeaderProps): ReactElement {\n return <div className={cn('flex flex-col space-y-1.5 text-center sm:text-left', className)}>{children}</div>;\n}\n\nModalHeader.displayName = 'ModalHeader';\n\n/**\n * Modal.Title Component\n *\n * Renders modal title using React Aria's Heading component.\n * Automatically links to modal via aria-labelledby.\n *\n * @see PRD.md FR-006 (Title Requirements)\n * @see PRD.md AR-002 (ARIA Attributes - auto-labelledby)\n */\nfunction ModalTitle({ children, as = 'h2', className }: ModalTitleProps): ReactElement {\n return (\n <Heading slot=\"title\" level={parseInt(as[1] ?? '2')} className={cn('text-lg font-semibold leading-none tracking-tight', className)}>\n {children}\n </Heading>\n );\n}\n\nModalTitle.displayName = 'ModalTitle';\n\n/**\n * Modal.Description Component\n *\n * Renders description text that automatically links to modal via aria-describedby.\n * Uses muted text color for visual hierarchy.\n *\n * @see PRD.md FR-007 (Description Requirements)\n * @see PRD.md AR-002 (ARIA Attributes - auto-describedby)\n */\nfunction ModalDescription({ children, className }: ModalDescriptionProps): ReactElement {\n return (\n <p slot=\"description\" className={cn('text-sm text-[var(--menu-muted)]', className)}>\n {children}\n </p>\n );\n}\n\nModalDescription.displayName = 'ModalDescription';\n\n/**\n * Modal.Footer Component\n *\n * Container for modal action buttons (Cancel, Confirm, etc.).\n * Aligns buttons to the right with consistent spacing.\n * Responsive: stacks vertically on mobile, horizontal on desktop.\n *\n * @see PRD.md FR-008 (Footer Requirements)\n * @see PRD.md DS-003 (Spacing - footer button gap)\n */\nfunction ModalFooter({ children, className }: ModalFooterProps): ReactElement {\n return <div className={cn('flex flex-col-reverse sm:flex-row sm:justify-end gap-2', className)}>{children}</div>;\n}\n\nModalFooter.displayName = 'ModalFooter';\n\n/**\n * Modal.Close Component\n *\n * Wraps a child element (typically Button) with modal close behavior.\n * Uses OverlayTriggerStateContext from React Aria to access close function.\n *\n * @see PRD.md FR-009 (Close Requirements)\n */\nfunction ModalClose({ children }: ModalCloseProps): ReactElement {\n // Access the overlay trigger state from React Aria context\n const state = useContext(OverlayTriggerStateContext);\n\n if (!state) {\n throw new Error('Modal.Close must be used inside Modal.Content');\n }\n\n // Clone the child element and add/merge the onPress handler to close the modal\n if (!isValidElement(children)) {\n throw new Error('Modal.Close requires a valid React element as a child');\n }\n\n // Cast to ReactElement after validation\n const childElement = children as ReactElement;\n\n const handlePress = (): void => {\n state.close();\n };\n\n // Merge with existing onPress if present\n const existingOnPress = (childElement.props as unknown as { onPress?: () => void })?.onPress;\n const mergedOnPress = existingOnPress\n ? (): void => {\n existingOnPress();\n handlePress();\n }\n : handlePress;\n\n // cloneElement with onPress override - use unknown for flexible typing\n return cloneElement(childElement, { onPress: mergedOnPress } as unknown as Partial<typeof childElement.props>);\n}\n\nModalClose.displayName = 'ModalClose';\n\n/**\n * Re-export CVA variants from Modal.styles.ts for backwards compatibility.\n * Consumers importing { modalContentVariants, modalOverlayVariants } from './Modal'\n * will continue to work.\n */\nexport { modalContentVariants, modalOverlayVariants } from './Modal.styles';\n\n/**\n * Compound Component Export\n *\n * Follows Themis library pattern using Object.assign() for compound components.\n * Enables usage like Modal.Trigger, Modal.Content, etc.\n *\n * @deprecated The Object.assign compound pattern will be removed in v2.\n * Use the direct named exports (ModalTrigger, ModalContent, etc.) instead.\n * This pattern is kept for backwards compatibility only.\n *\n * @see RESEARCH.md Section 1 (Compound Component Pattern)\n */\nexport const Modal = Object.assign(ModalRoot, {\n Trigger: ModalTrigger,\n Content: ModalContent,\n Overlay: ModalOverlay,\n Header: ModalHeader,\n Title: ModalTitle,\n Description: ModalDescription,\n Footer: ModalFooter,\n Close: ModalClose,\n});\n\n// Named exports for individual components\nexport {\n ModalRoot,\n ModalTrigger,\n ModalContent,\n ModalOverlay,\n ModalHeader,\n ModalTitle,\n ModalDescription,\n ModalFooter,\n ModalClose,\n};\n","import { cva } from 'class-variance-authority';\n\n/**\n * Layer 1: Transparent outer touch target (44x44px minimum)\n * Handles WCAG 2.2 AAA touch target requirement\n * Always transparent, centers the visual button inside\n * IMPORTANT: Focus ring stays on Layer 1 for AAA compliance (2.4.13)\n *\n * In vertical ButtonGroups, uses items-stretch so the visual layer (Layer 2)\n * can fill the full touch target height, eliminating gaps between buttons.\n */\nexport const buttonOuterVariants = cva(\n \"inline-flex justify-center min-h-[44px] min-w-[44px] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--ring)] focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:pointer-events-none disabled:opacity-50\",\n {\n variants: {\n fullWidth: {\n true: \"w-full\",\n false: \"\",\n },\n inVerticalGroup: {\n true: \"items-stretch\",\n false: \"items-center\",\n },\n },\n defaultVariants: {\n fullWidth: false,\n inVerticalGroup: false,\n },\n }\n);\n\n/**\n * Layer 2: Visual button appearance (adjustable size)\n * Provides the visual appearance with configurable size\n * Can be smaller than touch target for use cases like carousel dots\n * NOTE: NO focus-visible styles here - focus ring is on Layer 1\n */\nexport const buttonVisualVariants = cva(\n \"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0 relative cursor-pointer\",\n {\n variants: {\n variant: {\n default:\n \"bg-[var(--primary-action)] text-[var(--primary-action-foreground)] shadow-md hover:bg-[var(--primary-action-hover)] data-[pressed]:bg-[var(--primary-action)]/80\",\n destructive:\n \"bg-[var(--destructive-background)] text-[var(--destructive-foreground)] shadow-md hover:bg-[var(--destructive-background)]/90 data-[pressed]:bg-[var(--destructive-background)]/80\",\n outline:\n \"border border-[var(--input-border)] bg-[var(--page-background)] hover:bg-[var(--input-border)] data-[pressed]:bg-[var(--input-border)]\",\n secondary:\n \"bg-[var(--secondary)] text-[var(--secondary-foreground)] shadow-md hover:bg-[var(--secondary)]/80 data-[pressed]:bg-[var(--secondary)]/70\",\n ghost:\n \"hover:bg-[var(--accent)] hover:text-[var(--accent-foreground)] data-[pressed]:bg-[var(--accent)]\",\n link: \"text-[var(--text-link)] underline-offset-4 hover:underline data-[pressed]:text-[var(--text-link-hover)]\",\n },\n fullWidth: {\n true: \"w-full\",\n false: \"\",\n },\n visualSize: {\n default: \"h-10 px-4 py-2\",\n sm: \"h-9 rounded-md px-3 text-xs\",\n lg: \"h-11 rounded-md px-8\",\n icon: \"h-10 w-10\",\n dot: \"h-5 w-5 rounded-full p-0 min-h-0 min-w-0\",\n },\n paywall: {\n true: \"!bg-[var(--paywall)] !text-[var(--paywall-foreground)] !shadow-md hover:!bg-[var(--paywall)]/90 !cursor-not-allowed !border-transparent\",\n false: \"\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n visualSize: \"default\",\n paywall: false,\n },\n }\n);\n\n/**\n * @deprecated Use buttonVisualVariants instead. This alias is kept for backward compatibility.\n */\nexport const buttonVariants = buttonVisualVariants;\n","/**\n * Global Interaction State Styles\n *\n * Consistent interaction patterns across all Themis components.\n * These styles ensure WCAG 2.2 AAA compliance and predictable UX.\n *\n * @see spec.md FR-010 (Visible focus ring for keyboard navigation)\n * @see spec.md FR-031 (Pressed state feedback)\n * @see spec.md FR-012 (High contrast mode support)\n * @see constitution.md Principle IV (Accessibility First)\n */\n\n/**\n * Focus state styles (FR-010)\n * Visible focus ring for keyboard navigation - WCAG 2.2 Level AAA\n *\n * Components can override by extending these styles:\n * @example\n * cn(FOCUS_STYLES, \"ring-4\") // Increases ring width to 4px\n */\nexport const FOCUS_STYLES = \"data-[focus-visible]:ring-2 data-[focus-visible]:ring-[var(--themis-ring)] data-[focus-visible]:ring-offset-2\";\n\n/**\n * Pressed/Active state styles (FR-031)\n * Visual feedback for press interactions\n *\n * Components can override the scale amount:\n * @example\n * cn(PRESSED_STYLES_BASE, \"data-[pressed]:scale-[0.95]\") // More pronounced scale\n */\nexport const PRESSED_STYLES = \"data-[pressed]:scale-[0.97]\";\n\n/**\n * Base pressed styles without scale (for components that need different feedback)\n */\nexport const PRESSED_STYLES_BASE = \"data-[pressed]:transition-transform data-[pressed]:duration-100\";\n\n/**\n * Hover state styles\n * Elevation change on hover for better affordance\n *\n * Components can override shadow depth:\n * @example\n * cn(HOVER_STYLES_BASE, \"data-[hovered]:shadow-lg\") // Larger shadow\n */\nexport const HOVER_STYLES = \"data-[hovered]:shadow-md\";\n\n/**\n * Base hover styles without shadow (for components that use different hover effects)\n */\nexport const HOVER_STYLES_BASE = \"data-[hovered]:transition-shadow data-[hovered]:duration-200\";\n\n/**\n * High contrast mode focus (FR-012)\n * Enhanced outlines for users requiring high contrast\n *\n * Uses 'hc:' prefix for prefers-contrast: more media query\n */\nexport const HIGH_CONTRAST_FOCUS = \"hc:data-[focus-visible]:outline hc:data-[focus-visible]:outline-4 hc:data-[focus-visible]:outline-offset-2 hc:data-[focus-visible]:outline-foreground\";\n\n/**\n * High contrast mode hover (FR-012)\n * Enhanced outlines for hover in high contrast mode\n */\nexport const HIGH_CONTRAST_HOVER = \"hc:data-[hovered]:outline hc:data-[hovered]:outline-2 hc:data-[hovered]:outline-foreground\";\n\n/**\n * High contrast mode pressed state\n * Enhanced outlines for pressed state in high contrast mode\n */\nexport const HIGH_CONTRAST_PRESSED = \"hc:data-[pressed]:outline hc:data-[pressed]:outline-2 hc:data-[pressed]:outline-offset-1 hc:data-[pressed]:outline-foreground\";\n\n/**\n * Combined high contrast styles\n * Use this for components that need all high contrast interaction states\n */\nexport const HIGH_CONTRAST_INTERACTIONS = `${HIGH_CONTRAST_FOCUS} ${HIGH_CONTRAST_HOVER} ${HIGH_CONTRAST_PRESSED}`;\n\n/**\n * Disabled state styles\n * Consistent disabled appearance across all components\n */\nexport const DISABLED_STYLES = \"disabled:pointer-events-none disabled:opacity-50\";\n\n/**\n * Default interaction bundle\n * Most common combination for interactive components\n *\n * Includes: focus ring, pressed scale, hover shadow, high contrast enhancements\n *\n * @example\n * <button className={cn(DEFAULT_INTERACTIONS, \"bg-primary\")}>Click</button>\n */\nexport const DEFAULT_INTERACTIONS = `${FOCUS_STYLES} ${PRESSED_STYLES} ${HOVER_STYLES} ${HIGH_CONTRAST_FOCUS} ${HIGH_CONTRAST_HOVER} ${HIGH_CONTRAST_PRESSED}`;\n\n/**\n * Subtle interaction bundle\n * For components that need less pronounced feedback\n *\n * Includes: focus ring and high contrast, but no hover shadow or pressed scale\n */\nexport const SUBTLE_INTERACTIONS = `${FOCUS_STYLES} ${HIGH_CONTRAST_FOCUS}`;\n\n/**\n * Non-interactive element styles\n * For elements that should indicate they are not interactive\n */\nexport const NON_INTERACTIVE = \"cursor-default select-none\";\n","\"use client\";\n\nimport { createContext, useContext } from 'react';\nimport type {\n ButtonGroupContextValue,\n ButtonGroupItemContextValue,\n} from './ButtonGroup.types';\n\n/**\n * ButtonGroup Context System (Two-Level)\n *\n * Provides a two-level context pattern for ButtonGroup:\n *\n * 1. ButtonGroupContext (group-level):\n * - Provides: orientation, variant, size, isDisabled\n * - Consumed by: Button (for prop inheritance), Separator (for orientation)\n *\n * 2. ButtonGroupItemContext (item-level):\n * - Provides: position ('first' | 'middle' | 'last' | 'only')\n * - Consumed by: Button (for border-radius styling)\n *\n * Both contexts return null when not in a provider, allowing Button\n * to work standalone without any group context.\n *\n * @see plan.md for architecture details\n * @see ButtonGroup.tsx for Provider implementation\n */\n\n// =============================================================================\n// Group-Level Context\n// =============================================================================\n\n/**\n * Context for group-level props (orientation, variant, size, isDisabled)\n * Default value is null to indicate \"not in a group\"\n */\nconst ButtonGroupContext = createContext<ButtonGroupContextValue | null>(null);\n\nButtonGroupContext.displayName = 'ButtonGroupContext';\n\n/**\n * Hook to access group-level context\n * @returns ButtonGroupContextValue if inside a ButtonGroup, null otherwise\n */\nexport function useButtonGroupContext(): ButtonGroupContextValue | null {\n return useContext(ButtonGroupContext);\n}\n\n// =============================================================================\n// Item-Level Context\n// =============================================================================\n\n/**\n * Context for per-button position information\n * Default value is null to indicate \"not wrapped with position context\"\n */\nconst ButtonGroupItemContext =\n createContext<ButtonGroupItemContextValue | null>(null);\n\nButtonGroupItemContext.displayName = 'ButtonGroupItemContext';\n\n/**\n * Hook to access item-level context (position)\n * @returns ButtonGroupItemContextValue if wrapped with position context, null otherwise\n */\nexport function useButtonGroupItemContext(): ButtonGroupItemContextValue | null {\n return useContext(ButtonGroupItemContext);\n}\n\n// =============================================================================\n// Exports\n// =============================================================================\n\nexport { ButtonGroupContext, ButtonGroupItemContext };\n","import { cva } from 'class-variance-authority';\n\n/**\n * ButtonGroup CVA Variants\n *\n * Defines Class Variance Authority (CVA) variants for:\n * - ButtonGroup container (orientation-based layout)\n * - ButtonGroupItem (position-based border-radius)\n * - ButtonGroupSeparator (orientation-based styling)\n *\n * @see plan.md Phase 1: Design & Contracts - CVA Variants\n * @see constitution.md Principle V (Component Quality Standards)\n */\n\n// =============================================================================\n// Container Variants\n// =============================================================================\n\n/**\n * ButtonGroup container variants\n * Controls the layout direction based on orientation\n * Uses gap-0 to ensure buttons are connected (share borders)\n */\nexport const buttonGroupVariants = cva('inline-flex items-center gap-0', {\n variants: {\n orientation: {\n horizontal: 'flex-row',\n vertical: 'flex-col w-full',\n },\n },\n defaultVariants: {\n orientation: 'horizontal',\n },\n});\n\n// =============================================================================\n// Item Position Variants\n// =============================================================================\n\n/**\n * ButtonGroupItem position variants\n * Applied to Button's visual layer (Layer 2) for position-aware border-radius\n *\n * Compound variants handle both orientation and position combinations:\n * - Horizontal: left/right borders and radii\n * - Vertical: top/bottom borders and radii\n */\nexport const buttonGroupItemVariants = cva('', {\n variants: {\n orientation: {\n // min-w-[44px] ensures visual layer fills touch target width (for icon buttons)\n horizontal: 'min-w-[44px]',\n // flex (overrides inline-flex) + min-h-[44px] makes visual layer fill touch target,\n // eliminating gaps between stacked buttons in vertical orientation\n vertical: 'flex min-h-[44px]',\n },\n position: {\n first: '',\n middle: '',\n last: '',\n only: '', // Single button - no modifications needed\n },\n },\n compoundVariants: [\n // ==========================================================================\n // Horizontal Orientation\n // ==========================================================================\n {\n orientation: 'horizontal',\n position: 'first',\n className: 'rounded-r-none border-r-0',\n },\n {\n orientation: 'horizontal',\n position: 'middle',\n className: 'rounded-none border-r-0',\n },\n {\n orientation: 'horizontal',\n position: 'last',\n className: 'rounded-l-none',\n },\n // ==========================================================================\n // Vertical Orientation\n // Note: w-full is handled by Button's effectiveFullWidth for both layers\n // ==========================================================================\n {\n orientation: 'vertical',\n position: 'first',\n className: 'rounded-b-none border-b-0',\n },\n {\n orientation: 'vertical',\n position: 'middle',\n className: 'rounded-none border-b-0',\n },\n {\n orientation: 'vertical',\n position: 'last',\n className: 'rounded-t-none',\n },\n ],\n defaultVariants: {\n orientation: 'horizontal',\n position: 'only',\n },\n});\n\n// =============================================================================\n// Separator Variants\n// =============================================================================\n\n/**\n * ButtonGroupSeparator variants\n * Orientation-aware visual divider between button groups\n */\nexport const buttonGroupSeparatorVariants = cva('bg-[var(--border)]', {\n variants: {\n orientation: {\n horizontal: 'w-px h-6 mx-1',\n vertical: 'h-px w-full my-1',\n },\n },\n defaultVariants: {\n orientation: 'horizontal',\n },\n});\n","\"use client\";\n\n/**\n * Button Component - 3-Layer Architecture\n * Accessible button with React Aria primitives and CVA styling\n *\n * Architecture:\n * - Layer 1: Touch Target (44x44px WCAG AAA compliant, transparent)\n * - Layer 2: Visual Button (configurable size, colors, borders)\n * - Layer 3: Content & Effects (text, icons, ripple, loading spinner)\n *\n * @see 3layer-plan.md for architecture details\n * @see spec.md FR-029 to FR-037 (Button Component Requirements)\n * @see spec.md FR-009 (WCAG 2.2 AAA - 7:1 contrast ratio)\n * @see spec.md FR-014 (44x44px minimum touch targets)\n * @see constitution.md Principle IV (Accessibility First)\n */\n\nimport { forwardRef, memo, useId } from 'react';\nimport {\n Button as AriaButton,\n type ButtonProps as AriaButtonProps,\n} from 'react-aria-components';\nimport { Loader2, Zap } from 'lucide-react';\nimport { cn } from '../../utils/cn';\nimport type { ButtonProps } from './Button.types';\nimport { buttonOuterVariants, buttonVisualVariants, buttonVariants } from './Button.styles';\nimport { PRESSED_STYLES, HOVER_STYLES, HIGH_CONTRAST_HOVER, HIGH_CONTRAST_PRESSED } from '../../styles/interaction-states';\nimport {\n useButtonGroupContext,\n useButtonGroupItemContext,\n} from '../ButtonGroup/ButtonGroupContext';\nimport { buttonGroupItemVariants } from '../ButtonGroup/ButtonGroup.variants';\n\n/**\n * Button Component - 3-Layer Architecture\n * Fully accessible button with React Aria and themed styling\n *\n * Layer 1: Touch Target (AriaButton) - 44x44px WCAG AAA compliant\n * Layer 2: Visual Button (span) - configurable appearance\n * Layer 3: Content (children) - text, icons, effects\n */\nconst Button = memo(forwardRef<HTMLButtonElement, ButtonProps>(\n (\n {\n className,\n buttonVisualClassName,\n variant,\n size,\n visualSize,\n fullWidth,\n loading = false,\n loadingText = \"Loading...\",\n shortcut,\n children,\n isDisabled,\n paywall = false,\n paywallRedirect,\n paywallDescription,\n onPress,\n ...props\n },\n ref\n ) => {\n const paywallDescriptionId = useId();\n\n // ==========================================================================\n // ButtonGroup Context Integration\n // ==========================================================================\n\n // Consume group-level context (variant, size, isDisabled, orientation)\n const groupContext = useButtonGroupContext();\n\n // Consume item-level context (position for border-radius styling)\n const itemContext = useButtonGroupItemContext();\n\n // Merge context values with props (props take precedence)\n const effectiveVariant = variant ?? groupContext?.variant ?? 'default';\n const effectiveSize = size ?? groupContext?.size;\n const effectiveIsDisabled = isDisabled ?? groupContext?.isDisabled ?? false;\n\n // In vertical groups, buttons should be full width automatically\n const isInVerticalGroup = groupContext?.orientation === 'vertical';\n const effectiveFullWidth = fullWidth || isInVerticalGroup;\n\n // Position styling for ButtonGroup (only applied when in a group)\n const positionClassName = itemContext\n ? buttonGroupItemVariants({\n orientation: groupContext?.orientation ?? 'horizontal',\n position: itemContext.position,\n })\n : '';\n\n // Default visualSize to size for backward compatibility\n const effectiveVisualSize = visualSize ?? effectiveSize ?? 'default';\n\n // AAA Accessibility: Warn in dev/test if icon/dot variant lacks accessible name\n if (process.env.NODE_ENV !== 'production') {\n if (\n (effectiveVisualSize === 'dot' || effectiveVisualSize === 'icon') &&\n !props['aria-label'] &&\n !children\n ) {\n console.warn(\n '[Button] visualSize=\"dot\" or \"icon\" requires aria-label when no visible text is provided (WCAG 1.1.1)'\n );\n }\n }\n\n /**\n * Handle button press - intercepts action when paywalled\n * If paywalled with redirect URL, opens in new tab\n * Otherwise, calls the normal onPress handler\n */\n const handlePress = (e: Parameters<NonNullable<AriaButtonProps['onPress']>>[0]): void => {\n if (paywall) {\n if (paywallRedirect) {\n window.open(paywallRedirect, '_blank', 'noopener,noreferrer');\n }\n // Don't call onPress when paywalled\n return;\n }\n onPress?.(e);\n };\n\n // Only set isDisabled when we have a reason to disable\n // Otherwise, let slot system control disabled state (e.g., in NumberField)\n const computedIsDisabled = effectiveIsDisabled || loading || undefined;\n\n return (\n <AriaButton\n ref={ref}\n isDisabled={computedIsDisabled}\n aria-disabled={paywall ? true : undefined}\n aria-describedby={paywall ? paywallDescriptionId : undefined}\n onPress={handlePress}\n className={cn(buttonOuterVariants({ fullWidth: effectiveFullWidth, inVerticalGroup: isInVerticalGroup }), className)}\n {...props}\n >\n {(renderProps) => (\n /* Layer 2: Visual Button */\n <span\n className={cn(\n buttonVisualVariants({\n variant: effectiveVariant,\n visualSize: effectiveVisualSize,\n paywall,\n fullWidth: effectiveFullWidth,\n }),\n // Position styling from ButtonGroup context (border-radius adjustments)\n positionClassName,\n buttonVisualClassName,\n // Layer 2 interaction styles (no focus - focus ring is on Layer 1)\n PRESSED_STYLES,\n HOVER_STYLES,\n HIGH_CONTRAST_HOVER,\n HIGH_CONTRAST_PRESSED\n )}\n data-pressed={renderProps.isPressed || undefined}\n >\n {/* Layer 3: Content & Effects */}\n\n {/* FR-033: Loading spinner with screen reader announcement */}\n {/* Uses motion-safe: for WCAG 2.3.3 AAA (Animation from Interactions) */}\n {loading && (\n <>\n <Loader2 className=\"motion-safe:animate-spin\" aria-hidden=\"true\" />\n <span className=\"sr-only\" aria-live=\"polite\">\n {loadingText}\n </span>\n </>\n )}\n\n {/* Hide children during loading */}\n {!loading && children}\n\n {/* Paywall: Lightning bolt icon */}\n {paywall && (\n <Zap\n data-testid=\"zap-icon\"\n aria-hidden=\"true\"\n className=\"ml-1\"\n />\n )}\n\n {/* Paywall: Screen reader description */}\n {paywall && (\n <span id={paywallDescriptionId} className=\"sr-only\">\n Premium feature: {paywallDescription || \"Upgrade required to access this feature\"}\n </span>\n )}\n\n {/* FR-034: Keyboard shortcut display on focus */}\n {renderProps.isFocusVisible && shortcut && (\n <kbd className=\"ml-auto hidden text-xs opacity-60 lg:inline\">\n {shortcut}\n </kbd>\n )}\n\n {/* Touch/press ripple effect - FR-031: Pressed state feedback */}\n {/* Uses motion-safe: for WCAG 2.3.3 AAA (Animation from Interactions) */}\n {renderProps.isPressed && (\n <span\n className=\"absolute inset-0 rounded-[inherit] bg-current opacity-10 motion-safe:animate-in motion-safe:zoom-in-95\"\n aria-hidden=\"true\"\n />\n )}\n </span>\n )}\n </AriaButton>\n );\n }\n));\n\nButton.displayName = \"Button\";\n\nexport { Button, buttonVariants, buttonOuterVariants, buttonVisualVariants };\nexport type { ButtonProps } from './Button.types';\n","import { cva, type VariantProps } from 'class-variance-authority';\n\n/**\n * CVA Variants for AlertDialog content panel\n *\n * Only defines the destructive border variant. Base styling comes from\n * the underlying Modal component.\n */\nexport const alertDialogContentVariants = cva(\n 'border border-[var(--border)]',\n {\n variants: {\n variant: {\n default: '',\n destructive: 'border-[var(--destructive-background)]',\n },\n },\n defaultVariants: {\n variant: 'default',\n },\n }\n);\n\n/**\n * Type exports for variant props\n */\nexport type AlertDialogContentVariantProps = VariantProps<typeof alertDialogContentVariants>;\n","'use client';\n\n/**\n * AlertDialog Component\n *\n * A strict confirmation dialog for destructive or important actions.\n * Thin wrapper around the Modal component with role=\"alertdialog\".\n *\n * Unlike Modal (which is a flexible compound component), AlertDialog has a\n * fixed structure: title, optional description, optional children, and a\n * footer with cancel + action buttons. The footer is not customizable —\n * only the button labels, icons, and variants are configurable via props.\n *\n * Key differences from Modal:\n * - No backdrop dismiss (isDismissable: false)\n * - No Escape key dismiss (isKeyboardDismissDisabled: true)\n * - No close (X) button\n * - Fixed footer layout (cancel + action)\n * - Flat prop API instead of compound components\n *\n * WCAG 2.2 AAA compliant:\n * - role=\"alertdialog\" for screen reader announcements\n * - Focus trapped within dialog\n * - aria-labelledby linked to title\n * - aria-describedby linked to description\n * - All buttons use Themis Button (three-layer architecture, 44x44px touch targets)\n *\n * @example\n * ```tsx\n * <AlertDialog\n * trigger={<Button variant=\"destructive\">Delete</Button>}\n * title=\"Delete Account?\"\n * description=\"This action cannot be undone.\"\n * actionLabel=\"Delete Account\"\n * onAction={handleDelete}\n * />\n * ```\n */\n\nimport { type ReactElement } from 'react';\nimport {\n Modal,\n ModalTrigger,\n ModalContent,\n ModalHeader,\n ModalTitle,\n ModalDescription,\n ModalFooter,\n ModalClose,\n} from '../Modal/Modal';\nimport { Button } from '../Button/Button';\nimport type { AlertDialogProps } from './AlertDialog.types';\nimport { alertDialogContentVariants } from './AlertDialog.styles';\n\nexport function AlertDialog({\n trigger,\n isOpen,\n defaultOpen = false,\n onOpenChange,\n title,\n description,\n children,\n variant = 'default',\n size = 'md',\n cancelLabel = 'Cancel',\n cancelIcon,\n actionLabel,\n actionIcon,\n actionVariant = 'destructive',\n onAction,\n className,\n}: AlertDialogProps): ReactElement {\n // Map AlertDialog sizes to Modal sizes (AlertDialog uses sm/md/lg, Modal uses sm/md/lg/xl/full)\n const modalSize = size;\n\n return (\n <Modal\n role=\"alertdialog\"\n isOpen={isOpen}\n defaultOpen={defaultOpen}\n onOpenChange={onOpenChange}\n >\n <ModalTrigger>\n {trigger}\n </ModalTrigger>\n <ModalContent\n size={modalSize}\n isDismissable={false}\n isKeyboardDismissDisabled={true}\n showClose={false}\n animation=\"fade-zoom\"\n animationDuration={200}\n className={alertDialogContentVariants({ variant }) + (className ? ` ${className}` : '')}\n >\n <ModalHeader>\n <ModalTitle as=\"h2\">{title}</ModalTitle>\n {description && <ModalDescription>{description}</ModalDescription>}\n </ModalHeader>\n\n {children}\n\n <ModalFooter>\n <ModalClose>\n <Button variant=\"secondary\">\n {cancelIcon && <span className=\"mr-2\" aria-hidden=\"true\">{cancelIcon}</span>}\n {cancelLabel}\n </Button>\n </ModalClose>\n <ModalClose>\n <Button variant={actionVariant} onPress={onAction}>\n {actionIcon && <span className=\"mr-2\" aria-hidden=\"true\">{actionIcon}</span>}\n {actionLabel}\n </Button>\n </ModalClose>\n </ModalFooter>\n </ModalContent>\n </Modal>\n );\n}\n\nAlertDialog.displayName = 'AlertDialog';\n","import { z } from 'zod';\n\n/**\n * Base props schema for all Themis components\n * Ensures consistent accessibility and styling APIs across the library\n *\n * @see spec.md FR-009 to FR-014 (Accessibility Requirements)\n * @see constitution.md Principle IV (Accessibility First - WCAG 2.2 AA minimum)\n */\nexport const BaseComponentPropsSchema = z.object({\n // Styling\n className: z.string().optional(),\n\n // React\n children: z.any().optional(), // ReactNode not directly supported by Zod\n id: z.string().optional(),\n\n // Accessibility (WCAG 2.2 AA requirements)\n 'aria-label': z.string().optional(),\n 'aria-labelledby': z.string().optional(),\n 'aria-describedby': z.string().optional(),\n 'aria-live': z.enum(['off', 'polite', 'assertive']).optional(),\n 'aria-hidden': z.boolean().optional(),\n\n // Testing & Development\n 'data-testid': z.string().optional(),\n});\n\nexport type BaseComponentProps = z.infer<typeof BaseComponentPropsSchema>;\n","import { z } from 'zod';\nimport { BaseComponentPropsSchema } from '../../schemas/BaseComponentProps';\nimport type { ReactNode } from 'react';\n\n/**\n * AlertDialog variant schema\n */\nexport const AlertDialogVariantSchema = z.enum(['default', 'destructive']);\nexport type AlertDialogVariant = z.infer<typeof AlertDialogVariantSchema>;\n\n/**\n * AlertDialog size schema\n */\nexport const AlertDialogSizeSchema = z.enum(['sm', 'md', 'lg']);\nexport type AlertDialogSize = z.infer<typeof AlertDialogSizeSchema>;\n\n/**\n * AlertDialog props schema\n *\n * A strict, flat API for confirmation dialogs. Wraps Modal with\n * role=\"alertdialog\", no backdrop dismiss, no Escape dismiss, no close button.\n * Footer is fixed: cancel button (left) + action button (right).\n */\nexport const AlertDialogPropsSchema = BaseComponentPropsSchema.extend({\n /** Trigger element that opens the dialog (typically a Button) */\n trigger: z.custom<ReactNode>(),\n\n /** Whether the dialog is open (controlled mode) */\n isOpen: z.boolean().optional(),\n\n /** Default open state (uncontrolled mode) */\n defaultOpen: z.boolean().optional().default(false),\n\n /** Callback when open state changes */\n onOpenChange: z.custom<(isOpen: boolean) => void>().optional(),\n\n /** Dialog title (required — alerts must have a clear heading) */\n title: z.string(),\n\n /** Dialog description text */\n description: z.string().optional(),\n\n /** Optional extra content between description and footer */\n children: z.custom<ReactNode>().optional(),\n\n /** Visual variant of the dialog */\n variant: AlertDialogVariantSchema.optional().default('default'),\n\n /** Size of the dialog */\n size: AlertDialogSizeSchema.optional().default('md'),\n\n /** Cancel button label */\n cancelLabel: z.string().optional().default('Cancel'),\n\n /** Cancel button icon (rendered before label) */\n cancelIcon: z.custom<ReactNode>().optional(),\n\n /** Action button label (required — alert must have an explicit action) */\n actionLabel: z.string(),\n\n /** Action button icon (rendered before label) */\n actionIcon: z.custom<ReactNode>().optional(),\n\n /** Action button variant */\n actionVariant: z.enum(['default', 'destructive']).optional().default('destructive'),\n\n /** Callback when the action button is pressed (fires before dialog closes) */\n onAction: z.custom<() => void>().optional(),\n});\n\nexport type AlertDialogProps = z.infer<typeof AlertDialogPropsSchema> & {\n trigger: ReactNode;\n children?: ReactNode;\n cancelIcon?: ReactNode;\n actionIcon?: ReactNode;\n};\n"]}
1
+ {"version":3,"sources":["../../../src/utils/cn.ts","../../../src/styles/shared-variants.ts","../../../src/elements/Modal/Modal.styles.ts","../../../src/elements/Modal/Modal.tsx","../../../src/elements/Button/Button.styles.ts","../../../src/styles/interaction-states.ts","../../../src/elements/ButtonGroup/ButtonGroupContext.tsx","../../../src/elements/ButtonGroup/ButtonGroup.variants.ts","../../../src/elements/Button/Button.tsx","../../../src/elements/AlertDialog/AlertDialog.styles.ts","../../../src/elements/AlertDialog/AlertDialog.tsx","../../../src/schemas/BaseComponentProps.ts","../../../src/elements/AlertDialog/AlertDialog.types.ts"],"names":["cn","inputs","twMerge","clsx","MODAL_ANIMATION_IN","MODAL_ANIMATION_OUT","MODAL_SLIDE_IN","MODAL_SLIDE_OUT","MODAL_OVERLAY_IN","MODAL_OVERLAY_OUT","REDUCED_MOTION","modalContentVariants","cva","modalOverlayVariants","ModalContext","createContext","ModalRoot","children","defaultOpen","isOpen","onOpenChange","role","childArray","Children","hasTrigger","child","isValidElement","ModalTrigger","hasContent","ModalContent","triggerChild","contentChild","triggerElement","unwrappedTrigger","unwrappedContent","jsx","jsxs","AriaDialogTrigger","size","animation","animationDuration","isDismissable","isKeyboardDismissDisabled","showClose","className","useContext","overlayClasses","modalClasses","mergedModalClasses","AriaModalOverlay","AriaModal","AriaDialog","close","Fragment","AriaButton","X","ModalOverlay","_props","ModalHeader","ModalTitle","as","Heading","ModalDescription","ModalFooter","ModalClose","state","OverlayTriggerStateContext","childElement","handlePress","existingOnPress","cloneElement","Modal","buttonOuterVariants","buttonVisualVariants","PRESSED_STYLES","HOVER_STYLES","HIGH_CONTRAST_HOVER","HIGH_CONTRAST_PRESSED","ButtonGroupContext","useButtonGroupContext","ButtonGroupItemContext","useButtonGroupItemContext","buttonGroupItemVariants","Button","memo","forwardRef","buttonVisualClassName","variant","visualSize","fullWidth","loading","loadingText","shortcut","isDisabled","paywall","paywallRedirect","paywallDescription","onPress","props","ref","paywallDescriptionId","useId","groupContext","itemContext","effectiveVariant","effectiveSize","effectiveIsDisabled","isInVerticalGroup","effectiveFullWidth","positionClassName","effectiveVisualSize","e","renderProps","Loader2","Zap","alertDialogContentVariants","AlertDialog","trigger","title","description","cancelLabel","cancelIcon","actionLabel","actionIcon","actionVariant","onAction","BaseComponentPropsSchema","z","AlertDialogVariantSchema","AlertDialogSizeSchema","AlertDialogPropsSchema"],"mappings":"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","file":"index.mjs","sourcesContent":["/**\n * Class Name Utility\n * Merges Tailwind CSS classes with conflict resolution\n *\n * Combines clsx for conditional classes and tailwind-merge for deduplication\n *\n * @example\n * cn('px-2 py-1', 'px-4') // => 'py-1 px-4' (px-4 overrides px-2)\n * cn('text-red-500', condition && 'text-blue-500') // => conditional application\n */\n\nimport { clsx, type ClassValue } from 'clsx';\nimport { twMerge } from 'tailwind-merge';\n\nexport function cn(...inputs: ClassValue[]): string {\n return twMerge(clsx(inputs));\n}\n","/**\n * Shared CVA Variant Utilities\n *\n * Common patterns extracted from component variants for consistency and reduced bundle size.\n * Use these constants in CVA definitions to ensure consistent styling across Themis.\n *\n * @see interaction-states.ts for interaction-specific styles (focus, hover, pressed)\n */\n\n// =============================================================================\n// Focus Ring Patterns\n// =============================================================================\n\n/**\n * Focus-within ring (for container elements with focusable children)\n * Use when the container should show focus when any child is focused\n */\nexport const FOCUS_WITHIN_RING = [\n 'focus-within:outline-none',\n 'focus-within:ring-2',\n 'focus-within:ring-[var(--ring)]',\n 'focus-within:ring-offset-2',\n] as const;\n\n/**\n * Focus-visible ring (for directly focusable elements)\n * Use for buttons, inputs, and other interactive elements\n */\nexport const FOCUS_VISIBLE_RING = [\n 'focus-visible:outline-none',\n 'focus-visible:ring-2',\n 'focus-visible:ring-[var(--ring)]',\n 'focus-visible:ring-offset-2',\n] as const;\n\n/**\n * Standard focus ring (for elements using :focus pseudo-class)\n * Prefer focus-visible when possible for better UX\n */\nexport const FOCUS_RING = [\n 'focus:outline-none',\n 'focus:ring-2',\n 'focus:ring-[var(--ring)]',\n] as const;\n\n/**\n * Focus with background change (for segments, cells, menu items)\n */\nexport const FOCUS_HIGHLIGHT = [\n 'focus:outline-none',\n 'focus:bg-[var(--accent)]',\n 'focus:text-[var(--accent-foreground)]',\n] as const;\n\n// =============================================================================\n// Disabled State Patterns\n// =============================================================================\n\n/**\n * Standard disabled state using disabled attribute\n */\nexport const DISABLED_STANDARD = [\n 'disabled:pointer-events-none',\n 'disabled:opacity-50',\n] as const;\n\n/**\n * Disabled state using data attribute (React Aria pattern)\n */\nexport const DISABLED_DATA_ATTR = [\n 'data-[disabled]:pointer-events-none',\n 'data-[disabled]:opacity-50',\n 'data-[disabled]:cursor-not-allowed',\n] as const;\n\n// =============================================================================\n// Size-Based Text Variants\n// =============================================================================\n\n/**\n * Small text size scale (xs -> sm -> base)\n */\nexport const TEXT_SIZE_SMALL_SCALE = {\n sm: 'text-xs',\n default: 'text-sm',\n lg: 'text-base',\n} as const;\n\n/**\n * Medium text size scale (sm -> base -> lg)\n */\nexport const TEXT_SIZE_MEDIUM_SCALE = {\n sm: 'text-sm',\n default: 'text-base',\n lg: 'text-lg',\n} as const;\n\n// =============================================================================\n// Touch Target Utilities\n// =============================================================================\n\n/**\n * WCAG 2.2 AAA minimum touch target (44x44px)\n */\nexport const TOUCH_TARGET_MIN = [\n 'min-h-[44px]',\n 'min-w-[44px]',\n] as const;\n\n/**\n * Common button/cell sizes with touch target compliance\n */\nexport const INTERACTIVE_SIZES = {\n sm: 'h-9 w-9', // 36px - desktop only, NOT AAA compliant\n default: 'h-11 w-11', // 44px - AAA compliant\n lg: 'h-14 w-14', // 56px - AAA compliant, enhanced\n} as const;\n\n/**\n * Height-only sizes for fields and inputs\n */\nexport const FIELD_HEIGHTS = {\n sm: 'h-9', // 36px\n default: 'h-11', // 44px\n lg: 'h-14', // 56px\n} as const;\n\n// =============================================================================\n// Message/Feedback Patterns\n// =============================================================================\n\n/**\n * Error message styling\n */\nexport const ERROR_MESSAGE_BASE = [\n 'flex',\n 'items-center',\n 'gap-1.5',\n 'text-[var(--destructive-background)]',\n] as const;\n\n/**\n * Success message styling\n */\nexport const SUCCESS_MESSAGE_BASE = [\n 'flex',\n 'items-center',\n 'gap-1.5',\n 'text-[var(--success-background)]',\n] as const;\n\n/**\n * Description/helper text styling\n */\nexport const DESCRIPTION_BASE = [\n 'text-[var(--menu-muted)]',\n] as const;\n\n/**\n * Label base styling\n */\nexport const LABEL_BASE = [\n 'font-medium',\n 'text-[var(--content-foreground)]',\n] as const;\n\n/**\n * Required indicator pattern\n */\nexport const REQUIRED_INDICATOR = \"after:content-['*'] after:ml-0.5 after:text-[var(--destructive-background)]\";\n\n// =============================================================================\n// Animation Patterns\n// =============================================================================\n\n/**\n * Popover/dropdown entry animation\n */\nexport const POPOVER_ANIMATION_IN = [\n 'data-[entering]:animate-in',\n 'data-[entering]:fade-in-0',\n 'data-[entering]:zoom-in-95',\n] as const;\n\n/**\n * Popover/dropdown exit animation\n */\nexport const POPOVER_ANIMATION_OUT = [\n 'data-[exiting]:animate-out',\n 'data-[exiting]:fade-out-0',\n 'data-[exiting]:zoom-out-95',\n] as const;\n\n/**\n * Modal content enter animation (fade + zoom)\n * Uses React Aria data-[entering]/data-[exiting] attributes\n */\nexport const MODAL_ANIMATION_IN = [\n 'data-[entering]:animate-in',\n 'data-[entering]:fade-in-0',\n 'data-[entering]:zoom-in-95',\n 'data-[entering]:duration-200',\n 'data-[entering]:ease-out',\n] as const;\n\n/**\n * Modal content exit animation (fade + zoom)\n * Uses React Aria data-[entering]/data-[exiting] attributes\n */\nexport const MODAL_ANIMATION_OUT = [\n 'data-[exiting]:animate-out',\n 'data-[exiting]:fade-out-0',\n 'data-[exiting]:zoom-out-95',\n 'data-[exiting]:duration-150',\n 'data-[exiting]:ease-in',\n] as const;\n\n/**\n * Modal slide enter animation (fade + slide up)\n */\nexport const MODAL_SLIDE_IN = [\n 'data-[entering]:animate-in',\n 'data-[entering]:fade-in-0',\n 'data-[entering]:slide-in-from-bottom-4',\n 'data-[entering]:duration-200',\n 'data-[entering]:ease-out',\n] as const;\n\n/**\n * Modal slide exit animation (fade + slide down)\n */\nexport const MODAL_SLIDE_OUT = [\n 'data-[exiting]:animate-out',\n 'data-[exiting]:fade-out-0',\n 'data-[exiting]:slide-out-to-bottom-4',\n 'data-[exiting]:duration-150',\n 'data-[exiting]:ease-in',\n] as const;\n\n/**\n * Modal overlay enter/exit animation (fade only)\n */\nexport const MODAL_OVERLAY_IN = [\n 'data-[entering]:animate-in',\n 'data-[entering]:fade-in-0',\n 'data-[entering]:duration-200',\n] as const;\n\nexport const MODAL_OVERLAY_OUT = [\n 'data-[exiting]:animate-out',\n 'data-[exiting]:fade-out-0',\n 'data-[exiting]:duration-150',\n] as const;\n\n/**\n * Reduced motion support (WCAG 2.2)\n */\nexport const REDUCED_MOTION = [\n 'motion-reduce:transition-none',\n 'motion-reduce:animate-none',\n] as const;\n\n/**\n * Standard transition for colors\n */\nexport const TRANSITION_COLORS = [\n 'transition-colors',\n 'duration-200',\n] as const;\n\n/**\n * Fast transition for interactions\n */\nexport const TRANSITION_FAST = [\n 'transition-colors',\n 'duration-150',\n] as const;\n\n// =============================================================================\n// Hover State Patterns\n// =============================================================================\n\n/**\n * Accent background on hover (for interactive items)\n */\nexport const HOVER_ACCENT = [\n 'hover:bg-[var(--accent)]',\n 'hover:text-[var(--accent-foreground)]',\n] as const;\n\n// =============================================================================\n// Helper Functions\n// =============================================================================\n\n/**\n * Combines multiple style arrays into a flat array for CVA base styles\n */\nexport function combineStyles(...styles: (readonly string[] | string)[]): string[] {\n return styles.flatMap(s => Array.isArray(s) ? [...s] : [s]);\n}\n","import { cva, type VariantProps } from 'class-variance-authority';\nimport {\n MODAL_ANIMATION_IN,\n MODAL_ANIMATION_OUT,\n MODAL_SLIDE_IN,\n MODAL_SLIDE_OUT,\n MODAL_OVERLAY_IN,\n MODAL_OVERLAY_OUT,\n REDUCED_MOTION,\n} from '../../styles/shared-variants';\n\n/**\n * CVA Variants for Modal.Content\n *\n * Size and animation variant definitions for the modal content container.\n * Uses React Aria data-[entering]/data-[exiting] attributes for enter+exit animations.\n * Uses CSS custom properties for all colours to support theming.\n *\n * @see Modal.types.ts (ModalSize, ModalAnimation)\n */\nexport const modalContentVariants = cva(\n [\n // Base styles\n 'relative',\n 'bg-[var(--content-background)]',\n 'text-[var(--content-foreground)]',\n 'rounded-lg',\n 'shadow-lg',\n 'p-6',\n 'w-full',\n 'outline-none',\n // Responsive: full-width on mobile with padding, constrained on desktop\n 'mx-4',\n 'sm:mx-0',\n // Reduced motion support\n ...REDUCED_MOTION,\n ],\n {\n variants: {\n size: {\n sm: 'max-w-sm', // 300px\n md: 'max-w-md', // 425px\n lg: 'max-w-lg', // 600px\n xl: 'max-w-2xl', // 800px\n full: 'max-w-full min-h-screen rounded-none', // Full screen\n },\n animation: {\n 'fade-zoom': [\n ...MODAL_ANIMATION_IN,\n ...MODAL_ANIMATION_OUT,\n ],\n fade: [\n 'data-[entering]:animate-in',\n 'data-[entering]:fade-in-0',\n 'data-[entering]:duration-200',\n 'data-[entering]:ease-out',\n 'data-[exiting]:animate-out',\n 'data-[exiting]:fade-out-0',\n 'data-[exiting]:duration-150',\n 'data-[exiting]:ease-in',\n ],\n slide: [\n ...MODAL_SLIDE_IN,\n ...MODAL_SLIDE_OUT,\n ],\n none: '',\n },\n },\n defaultVariants: {\n size: 'md',\n animation: 'fade-zoom',\n },\n }\n);\n\n/**\n * CVA Variants for Modal Overlay\n *\n * Animation variant definitions for the modal backdrop overlay.\n * Uses React Aria data-[entering]/data-[exiting] attributes for enter+exit animations.\n * Uses CSS custom properties for all colours to support theming.\n */\nexport const modalOverlayVariants = cva(\n [\n // Base overlay styles\n 'fixed',\n 'inset-0',\n 'z-50',\n 'flex',\n 'items-center',\n 'justify-center',\n 'bg-black/50',\n 'backdrop-blur-sm',\n // Reduced motion support\n ...REDUCED_MOTION,\n ],\n {\n variants: {\n animation: {\n 'fade-zoom': [...MODAL_OVERLAY_IN, ...MODAL_OVERLAY_OUT],\n fade: [...MODAL_OVERLAY_IN, ...MODAL_OVERLAY_OUT],\n slide: [...MODAL_OVERLAY_IN, ...MODAL_OVERLAY_OUT],\n none: '',\n },\n },\n defaultVariants: {\n animation: 'fade-zoom',\n },\n }\n);\n\n/**\n * Type exports for variant props\n * Allows TypeScript inference of variant combinations\n */\nexport type ModalContentVariantProps = VariantProps<typeof modalContentVariants>;\nexport type ModalOverlayVariantProps = VariantProps<typeof modalOverlayVariants>;\n","'use client';\n\n/**\n * Modal Component - Implementation\n *\n * Accessible modal dialog component combining React Aria primitives with ShadCN styling.\n * Follows Themis library patterns with compound component structure.\n *\n * @see PRD.md (Full requirements)\n * @see Modal.types.ts (Zod schemas)\n * @see RESEARCH.md (React Aria patterns)\n */\n\nimport {\n Children,\n isValidElement,\n cloneElement,\n useContext,\n createContext,\n type ReactElement,\n type ReactNode,\n} from 'react';\nimport {\n DialogTrigger as AriaDialogTrigger,\n Modal as AriaModal,\n ModalOverlay as AriaModalOverlay,\n Dialog as AriaDialog,\n Heading,\n Button as AriaButton,\n OverlayTriggerStateContext,\n} from 'react-aria-components';\nimport { X } from 'lucide-react';\nimport { cn } from '../../utils/cn';\nimport { modalContentVariants, modalOverlayVariants } from './Modal.styles';\nimport type {\n ModalProps,\n ModalTriggerProps,\n ModalContentProps,\n ModalOverlayProps,\n ModalHeaderProps,\n ModalTitleProps,\n ModalDescriptionProps,\n ModalFooterProps,\n ModalCloseProps,\n} from './Modal.types';\n\n/**\n * Modal Context\n * Passes role prop from Modal root to Modal.Content\n */\ninterface ModalContextValue {\n role?: 'dialog' | 'alertdialog';\n}\n\nconst ModalContext = createContext<ModalContextValue | undefined>(undefined);\n\n/**\n * Modal Root Component\n *\n * Manages modal open/close state and validates required children structure.\n * Must contain exactly one Modal.Trigger and one Modal.Content.\n *\n * Unwraps compound component children and passes them to React Aria's DialogTrigger.\n *\n * @see PRD.md FR-001 (Modal Root Requirements)\n * @see PRD.md FR-012 (Controlled Mode)\n * @see PRD.md FR-013 (Uncontrolled Mode)\n */\nfunction ModalRoot({ children, defaultOpen, isOpen, onOpenChange, role = 'dialog' }: ModalProps): ReactElement {\n const childArray = Children.toArray(children);\n\n // Validate children structure in development only\n if (process.env.NODE_ENV !== 'production') {\n const hasTrigger = childArray.some(\n (child) =>\n isValidElement(child) &&\n (child.type === ModalTrigger ||\n (child.type as { displayName?: string }).displayName === 'ModalTrigger')\n );\n\n const hasContent = childArray.some(\n (child) =>\n isValidElement(child) &&\n (child.type === ModalContent ||\n (child.type as { displayName?: string }).displayName === 'ModalContent')\n );\n\n if (!hasTrigger || !hasContent) {\n throw new Error(\n 'Modal requires exactly one Modal.Trigger and one Modal.Content as children'\n );\n }\n }\n\n // Find trigger and content children\n const triggerChild = childArray.find(\n (child) =>\n isValidElement(child) &&\n (child.type === ModalTrigger ||\n (child.type as { displayName?: string }).displayName === 'ModalTrigger')\n );\n\n const contentChild = childArray.find(\n (child) =>\n isValidElement(child) &&\n (child.type === ModalContent ||\n (child.type as { displayName?: string }).displayName === 'ModalContent')\n );\n\n // Extract the actual children from Modal.Trigger and Modal.Content\n // React Aria's DialogTrigger expects direct Button and Modal children\n const triggerElement = triggerChild as ReactElement;\n const unwrappedTrigger = isValidElement(triggerElement)\n ? ((triggerElement.props as unknown as { children?: ReactNode }).children as ReactNode)\n : null;\n const unwrappedContent = contentChild as ReactElement;\n\n return (\n <ModalContext.Provider value={{ role }}>\n <AriaDialogTrigger\n defaultOpen={defaultOpen}\n isOpen={isOpen}\n onOpenChange={onOpenChange}\n >\n {unwrappedTrigger}\n {unwrappedContent}\n </AriaDialogTrigger>\n </ModalContext.Provider>\n );\n}\n\nModalRoot.displayName = 'Modal';\n\n/**\n * Modal.Trigger Component\n *\n * Wraps a single child element (typically Button) with modal trigger behavior.\n * Handles click events to open modal and manages ARIA attributes.\n *\n * React Aria's DialogTrigger (used in Modal root) automatically applies:\n * - aria-haspopup=\"dialog\"\n * - aria-expanded (true/false based on state)\n * - onClick handler to toggle modal\n *\n * @see PRD.md FR-002 (Trigger Requirements)\n * @see RESEARCH.md Section 2 (React Aria Integration)\n */\nfunction ModalTrigger({ children }: ModalTriggerProps): ReactElement {\n // React Aria's DialogTrigger (in Modal root) automatically adds ARIA attributes\n // to the first child component. We pass through the child element directly.\n return children as ReactElement;\n}\n\nModalTrigger.displayName = 'ModalTrigger';\n\n/**\n * Modal.Content Component\n *\n * Renders the modal content with overlay backdrop.\n * Uses React Aria's Modal and ModalOverlay for accessibility.\n * Applies CVA variants for size and animation.\n *\n * @see PRD.md FR-003 (Content Requirements)\n * @see PRD.md TR-001 (CVA Variant Styling)\n * @see RESEARCH.md Section 2 (React Aria Integration)\n */\nfunction ModalContent({\n children,\n size = 'md',\n animation = 'fade-zoom',\n animationDuration = 200,\n isDismissable = true,\n isKeyboardDismissDisabled = false,\n showClose = true,\n className,\n}: ModalContentProps): ReactElement {\n // Get role from context\n const context = useContext(ModalContext);\n const role = context?.role ?? 'dialog';\n\n // Generate overlay classes with animation variant\n const overlayClasses = modalOverlayVariants({ animation });\n\n // Generate modal classes with size and animation variants, merged with custom className\n const modalClasses = modalContentVariants({ size, animation });\n const mergedModalClasses = cn(modalClasses, className);\n\n return (\n <AriaModalOverlay\n isDismissable={isDismissable}\n isKeyboardDismissDisabled={isKeyboardDismissDisabled}\n className={overlayClasses}\n >\n <AriaModal\n className={mergedModalClasses}\n style={{\n transitionDuration: `${animationDuration}ms`,\n }}\n >\n <AriaDialog role={role} className=\"outline-none\">\n {({ close }) => (\n <>\n {showClose && (\n <AriaButton\n onPress={close}\n className=\"absolute right-0 top-0 flex items-center justify-center rounded-sm opacity-70 ring-offset-[var(--content-background)] transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-[var(--ring)] focus:ring-offset-2 disabled:pointer-events-none min-h-[44px] min-w-[44px]\"\n aria-label=\"Close modal\"\n >\n <X className=\"h-4 w-4\" aria-hidden=\"true\" />\n </AriaButton>\n )}\n {children}\n </>\n )}\n </AriaDialog>\n </AriaModal>\n </AriaModalOverlay>\n );\n}\n\nModalContent.displayName = 'ModalContent';\n\n/**\n * Modal.Overlay Component (Placeholder - not exposed in public API)\n * Overlay is managed internally by Modal.Content via AriaModalOverlay\n */\nfunction ModalOverlay(_props: ModalOverlayProps): null {\n return null;\n}\n\nModalOverlay.displayName = 'ModalOverlay';\n\n/**\n * Modal.Header Component\n *\n * Container for modal header content (typically Title and Description).\n * Applies consistent spacing and layout.\n *\n * @see PRD.md FR-005 (Header Requirements)\n */\nfunction ModalHeader({ children, className }: ModalHeaderProps): ReactElement {\n return <div className={cn('flex flex-col space-y-1.5 text-center sm:text-left', className)}>{children}</div>;\n}\n\nModalHeader.displayName = 'ModalHeader';\n\n/**\n * Modal.Title Component\n *\n * Renders modal title using React Aria's Heading component.\n * Automatically links to modal via aria-labelledby.\n *\n * @see PRD.md FR-006 (Title Requirements)\n * @see PRD.md AR-002 (ARIA Attributes - auto-labelledby)\n */\nfunction ModalTitle({ children, as = 'h2', className }: ModalTitleProps): ReactElement {\n return (\n <Heading slot=\"title\" level={parseInt(as[1] ?? '2')} className={cn('text-lg font-semibold leading-none tracking-tight', className)}>\n {children}\n </Heading>\n );\n}\n\nModalTitle.displayName = 'ModalTitle';\n\n/**\n * Modal.Description Component\n *\n * Renders description text that automatically links to modal via aria-describedby.\n * Uses muted text color for visual hierarchy.\n *\n * @see PRD.md FR-007 (Description Requirements)\n * @see PRD.md AR-002 (ARIA Attributes - auto-describedby)\n */\nfunction ModalDescription({ children, className }: ModalDescriptionProps): ReactElement {\n return (\n <p slot=\"description\" className={cn('text-sm text-[var(--menu-muted)]', className)}>\n {children}\n </p>\n );\n}\n\nModalDescription.displayName = 'ModalDescription';\n\n/**\n * Modal.Footer Component\n *\n * Container for modal action buttons (Cancel, Confirm, etc.).\n * Aligns buttons to the right with consistent spacing.\n * Responsive: stacks vertically on mobile, horizontal on desktop.\n *\n * @see PRD.md FR-008 (Footer Requirements)\n * @see PRD.md DS-003 (Spacing - footer button gap)\n */\nfunction ModalFooter({ children, className }: ModalFooterProps): ReactElement {\n return <div className={cn('flex flex-col-reverse sm:flex-row sm:justify-end gap-2', className)}>{children}</div>;\n}\n\nModalFooter.displayName = 'ModalFooter';\n\n/**\n * Modal.Close Component\n *\n * Wraps a child element (typically Button) with modal close behavior.\n * Uses OverlayTriggerStateContext from React Aria to access close function.\n *\n * @see PRD.md FR-009 (Close Requirements)\n */\nfunction ModalClose({ children }: ModalCloseProps): ReactElement {\n // Access the overlay trigger state from React Aria context\n const state = useContext(OverlayTriggerStateContext);\n\n if (!state) {\n throw new Error('Modal.Close must be used inside Modal.Content');\n }\n\n // Clone the child element and add/merge the onPress handler to close the modal\n if (!isValidElement(children)) {\n throw new Error('Modal.Close requires a valid React element as a child');\n }\n\n // Cast to ReactElement after validation\n const childElement = children as ReactElement;\n\n const handlePress = (): void => {\n state.close();\n };\n\n // Merge with existing onPress if present\n const existingOnPress = (childElement.props as unknown as { onPress?: () => void })?.onPress;\n const mergedOnPress = existingOnPress\n ? (): void => {\n existingOnPress();\n handlePress();\n }\n : handlePress;\n\n // cloneElement with onPress override - use unknown for flexible typing\n return cloneElement(childElement, { onPress: mergedOnPress } as unknown as Partial<typeof childElement.props>);\n}\n\nModalClose.displayName = 'ModalClose';\n\n/**\n * Re-export CVA variants from Modal.styles.ts for backwards compatibility.\n * Consumers importing { modalContentVariants, modalOverlayVariants } from './Modal'\n * will continue to work.\n */\nexport { modalContentVariants, modalOverlayVariants } from './Modal.styles';\n\n/**\n * Compound Component Export\n *\n * Follows Themis library pattern using Object.assign() for compound components.\n * Enables usage like Modal.Trigger, Modal.Content, etc.\n *\n * @deprecated The Object.assign compound pattern will be removed in v2.\n * Use the direct named exports (ModalTrigger, ModalContent, etc.) instead.\n * This pattern is kept for backwards compatibility only.\n *\n * @see RESEARCH.md Section 1 (Compound Component Pattern)\n */\nexport const Modal = Object.assign(ModalRoot, {\n Trigger: ModalTrigger,\n Content: ModalContent,\n Overlay: ModalOverlay,\n Header: ModalHeader,\n Title: ModalTitle,\n Description: ModalDescription,\n Footer: ModalFooter,\n Close: ModalClose,\n});\n\n// Named exports for individual components\nexport {\n ModalRoot,\n ModalTrigger,\n ModalContent,\n ModalOverlay,\n ModalHeader,\n ModalTitle,\n ModalDescription,\n ModalFooter,\n ModalClose,\n};\n","import { cva } from 'class-variance-authority';\n\n/**\n * Layer 1: Transparent outer touch target (44x44px minimum)\n * Handles WCAG 2.2 AAA touch target requirement\n * Always transparent, centers the visual button inside\n * IMPORTANT: Focus ring stays on Layer 1 for AAA compliance (2.4.13)\n *\n * In vertical ButtonGroups, uses items-stretch so the visual layer (Layer 2)\n * can fill the full touch target height, eliminating gaps between buttons.\n */\nexport const buttonOuterVariants = cva(\n \"inline-flex justify-center min-h-[44px] min-w-[44px] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--ring)] focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:pointer-events-none disabled:opacity-50\",\n {\n variants: {\n fullWidth: {\n true: \"w-full\",\n false: \"\",\n },\n inVerticalGroup: {\n true: \"items-stretch\",\n false: \"items-center\",\n },\n },\n defaultVariants: {\n fullWidth: false,\n inVerticalGroup: false,\n },\n }\n);\n\n/**\n * Layer 2: Visual button appearance (adjustable size)\n * Provides the visual appearance with configurable size\n * Can be smaller than touch target for use cases like carousel dots\n * NOTE: NO focus-visible styles here - focus ring is on Layer 1\n */\nexport const buttonVisualVariants = cva(\n \"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0 relative cursor-pointer\",\n {\n variants: {\n variant: {\n default:\n \"bg-[var(--primary-action)] text-[var(--primary-action-foreground)] shadow-md hover:bg-[var(--primary-action-hover)] data-[pressed]:bg-[var(--primary-action)]/80\",\n destructive:\n \"bg-[var(--destructive-background)] text-[var(--destructive-foreground)] shadow-md hover:bg-[var(--destructive-background)]/90 data-[pressed]:bg-[var(--destructive-background)]/80\",\n outline:\n \"border border-[var(--input-border)] bg-[var(--page-background)] hover:bg-[var(--input-border)] data-[pressed]:bg-[var(--input-border)]\",\n secondary:\n \"bg-[var(--secondary)] text-[var(--secondary-foreground)] shadow-md hover:bg-[var(--secondary)]/80 data-[pressed]:bg-[var(--secondary)]/70\",\n ghost:\n \"hover:bg-[var(--accent)] hover:text-[var(--accent-foreground)] data-[pressed]:bg-[var(--accent)]\",\n link: \"text-[var(--text-link)] underline-offset-4 hover:underline data-[pressed]:text-[var(--text-link-hover)]\",\n },\n fullWidth: {\n true: \"w-full\",\n false: \"\",\n },\n visualSize: {\n default: \"h-10 px-4 py-2\",\n sm: \"h-9 rounded-md px-3 text-xs\",\n lg: \"h-11 rounded-md px-8\",\n icon: \"h-10 w-10\",\n dot: \"h-5 w-5 rounded-full p-0 min-h-0 min-w-0\",\n },\n paywall: {\n true: \"!bg-[var(--paywall)] !text-[var(--paywall-foreground)] !shadow-md hover:!bg-[var(--paywall)]/90 !cursor-not-allowed !border-transparent\",\n false: \"\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n visualSize: \"default\",\n paywall: false,\n },\n }\n);\n\n/**\n * @deprecated Use buttonVisualVariants instead. This alias is kept for backward compatibility.\n */\nexport const buttonVariants = buttonVisualVariants;\n","/**\n * Global Interaction State Styles\n *\n * Consistent interaction patterns across all Themis components.\n * These styles ensure WCAG 2.2 AAA compliance and predictable UX.\n *\n * @see spec.md FR-010 (Visible focus ring for keyboard navigation)\n * @see spec.md FR-031 (Pressed state feedback)\n * @see spec.md FR-012 (High contrast mode support)\n * @see constitution.md Principle IV (Accessibility First)\n */\n\n/**\n * Focus state styles (FR-010)\n * Visible focus ring for keyboard navigation - WCAG 2.2 Level AAA\n *\n * Components can override by extending these styles:\n * @example\n * cn(FOCUS_STYLES, \"ring-4\") // Increases ring width to 4px\n */\nexport const FOCUS_STYLES = \"data-[focus-visible]:ring-2 data-[focus-visible]:ring-[var(--themis-ring)] data-[focus-visible]:ring-offset-2\";\n\n/**\n * Pressed/Active state styles (FR-031)\n * Visual feedback for press interactions\n *\n * Components can override the scale amount:\n * @example\n * cn(PRESSED_STYLES_BASE, \"data-[pressed]:scale-[0.95]\") // More pronounced scale\n */\nexport const PRESSED_STYLES = \"data-[pressed]:scale-[0.97]\";\n\n/**\n * Base pressed styles without scale (for components that need different feedback)\n */\nexport const PRESSED_STYLES_BASE = \"data-[pressed]:transition-transform data-[pressed]:duration-100\";\n\n/**\n * Hover state styles\n * Elevation change on hover for better affordance\n *\n * Components can override shadow depth:\n * @example\n * cn(HOVER_STYLES_BASE, \"data-[hovered]:shadow-lg\") // Larger shadow\n */\nexport const HOVER_STYLES = \"data-[hovered]:shadow-md\";\n\n/**\n * Base hover styles without shadow (for components that use different hover effects)\n */\nexport const HOVER_STYLES_BASE = \"data-[hovered]:transition-shadow data-[hovered]:duration-200\";\n\n/**\n * High contrast mode focus (FR-012)\n * Enhanced outlines for users requiring high contrast\n *\n * Uses 'hc:' prefix for prefers-contrast: more media query\n */\nexport const HIGH_CONTRAST_FOCUS = \"hc:data-[focus-visible]:outline hc:data-[focus-visible]:outline-4 hc:data-[focus-visible]:outline-offset-2 hc:data-[focus-visible]:outline-foreground\";\n\n/**\n * High contrast mode hover (FR-012)\n * Enhanced outlines for hover in high contrast mode\n */\nexport const HIGH_CONTRAST_HOVER = \"hc:data-[hovered]:outline hc:data-[hovered]:outline-2 hc:data-[hovered]:outline-foreground\";\n\n/**\n * High contrast mode pressed state\n * Enhanced outlines for pressed state in high contrast mode\n */\nexport const HIGH_CONTRAST_PRESSED = \"hc:data-[pressed]:outline hc:data-[pressed]:outline-2 hc:data-[pressed]:outline-offset-1 hc:data-[pressed]:outline-foreground\";\n\n/**\n * Combined high contrast styles\n * Use this for components that need all high contrast interaction states\n */\nexport const HIGH_CONTRAST_INTERACTIONS = `${HIGH_CONTRAST_FOCUS} ${HIGH_CONTRAST_HOVER} ${HIGH_CONTRAST_PRESSED}`;\n\n/**\n * Disabled state styles\n * Consistent disabled appearance across all components\n */\nexport const DISABLED_STYLES = \"disabled:pointer-events-none disabled:opacity-50\";\n\n/**\n * Default interaction bundle\n * Most common combination for interactive components\n *\n * Includes: focus ring, pressed scale, hover shadow, high contrast enhancements\n *\n * @example\n * <button className={cn(DEFAULT_INTERACTIONS, \"bg-primary\")}>Click</button>\n */\nexport const DEFAULT_INTERACTIONS = `${FOCUS_STYLES} ${PRESSED_STYLES} ${HOVER_STYLES} ${HIGH_CONTRAST_FOCUS} ${HIGH_CONTRAST_HOVER} ${HIGH_CONTRAST_PRESSED}`;\n\n/**\n * Subtle interaction bundle\n * For components that need less pronounced feedback\n *\n * Includes: focus ring and high contrast, but no hover shadow or pressed scale\n */\nexport const SUBTLE_INTERACTIONS = `${FOCUS_STYLES} ${HIGH_CONTRAST_FOCUS}`;\n\n/**\n * Non-interactive element styles\n * For elements that should indicate they are not interactive\n */\nexport const NON_INTERACTIVE = \"cursor-default select-none\";\n","\"use client\";\n\nimport { createContext, useContext } from 'react';\nimport type {\n ButtonGroupContextValue,\n ButtonGroupItemContextValue,\n} from './ButtonGroup.types';\n\n/**\n * ButtonGroup Context System (Two-Level)\n *\n * Provides a two-level context pattern for ButtonGroup:\n *\n * 1. ButtonGroupContext (group-level):\n * - Provides: orientation, variant, size, isDisabled\n * - Consumed by: Button (for prop inheritance), Separator (for orientation)\n *\n * 2. ButtonGroupItemContext (item-level):\n * - Provides: position ('first' | 'middle' | 'last' | 'only')\n * - Consumed by: Button (for border-radius styling)\n *\n * Both contexts return null when not in a provider, allowing Button\n * to work standalone without any group context.\n *\n * @see plan.md for architecture details\n * @see ButtonGroup.tsx for Provider implementation\n */\n\n// =============================================================================\n// Group-Level Context\n// =============================================================================\n\n/**\n * Context for group-level props (orientation, variant, size, isDisabled)\n * Default value is null to indicate \"not in a group\"\n */\nconst ButtonGroupContext = createContext<ButtonGroupContextValue | null>(null);\n\nButtonGroupContext.displayName = 'ButtonGroupContext';\n\n/**\n * Hook to access group-level context\n * @returns ButtonGroupContextValue if inside a ButtonGroup, null otherwise\n */\nexport function useButtonGroupContext(): ButtonGroupContextValue | null {\n return useContext(ButtonGroupContext);\n}\n\n// =============================================================================\n// Item-Level Context\n// =============================================================================\n\n/**\n * Context for per-button position information\n * Default value is null to indicate \"not wrapped with position context\"\n */\nconst ButtonGroupItemContext =\n createContext<ButtonGroupItemContextValue | null>(null);\n\nButtonGroupItemContext.displayName = 'ButtonGroupItemContext';\n\n/**\n * Hook to access item-level context (position)\n * @returns ButtonGroupItemContextValue if wrapped with position context, null otherwise\n */\nexport function useButtonGroupItemContext(): ButtonGroupItemContextValue | null {\n return useContext(ButtonGroupItemContext);\n}\n\n// =============================================================================\n// Exports\n// =============================================================================\n\nexport { ButtonGroupContext, ButtonGroupItemContext };\n","import { cva } from 'class-variance-authority';\n\n/**\n * ButtonGroup CVA Variants\n *\n * Defines Class Variance Authority (CVA) variants for:\n * - ButtonGroup container (orientation-based layout)\n * - ButtonGroupItem (position-based border-radius)\n * - ButtonGroupSeparator (orientation-based styling)\n *\n * @see plan.md Phase 1: Design & Contracts - CVA Variants\n * @see constitution.md Principle V (Component Quality Standards)\n */\n\n// =============================================================================\n// Container Variants\n// =============================================================================\n\n/**\n * ButtonGroup container variants\n * Controls the layout direction based on orientation\n * Uses gap-0 to ensure buttons are connected (share borders)\n */\nexport const buttonGroupVariants = cva('inline-flex items-center gap-0', {\n variants: {\n orientation: {\n horizontal: 'flex-row',\n vertical: 'flex-col w-full',\n },\n },\n defaultVariants: {\n orientation: 'horizontal',\n },\n});\n\n// =============================================================================\n// Item Position Variants\n// =============================================================================\n\n/**\n * ButtonGroupItem position variants\n * Applied to Button's visual layer (Layer 2) for position-aware border-radius\n *\n * Compound variants handle both orientation and position combinations:\n * - Horizontal: left/right borders and radii\n * - Vertical: top/bottom borders and radii\n */\nexport const buttonGroupItemVariants = cva('', {\n variants: {\n orientation: {\n // min-w-[44px] ensures visual layer fills touch target width (for icon buttons)\n horizontal: 'min-w-[44px]',\n // flex (overrides inline-flex) + min-h-[44px] makes visual layer fill touch target,\n // eliminating gaps between stacked buttons in vertical orientation\n vertical: 'flex min-h-[44px]',\n },\n position: {\n first: '',\n middle: '',\n last: '',\n only: '', // Single button - no modifications needed\n },\n },\n compoundVariants: [\n // ==========================================================================\n // Horizontal Orientation\n // ==========================================================================\n {\n orientation: 'horizontal',\n position: 'first',\n className: 'rounded-r-none border-r-0',\n },\n {\n orientation: 'horizontal',\n position: 'middle',\n className: 'rounded-none border-r-0',\n },\n {\n orientation: 'horizontal',\n position: 'last',\n className: 'rounded-l-none',\n },\n // ==========================================================================\n // Vertical Orientation\n // Note: w-full is handled by Button's effectiveFullWidth for both layers\n // ==========================================================================\n {\n orientation: 'vertical',\n position: 'first',\n className: 'rounded-b-none border-b-0',\n },\n {\n orientation: 'vertical',\n position: 'middle',\n className: 'rounded-none border-b-0',\n },\n {\n orientation: 'vertical',\n position: 'last',\n className: 'rounded-t-none',\n },\n ],\n defaultVariants: {\n orientation: 'horizontal',\n position: 'only',\n },\n});\n\n// =============================================================================\n// Separator Variants\n// =============================================================================\n\n/**\n * ButtonGroupSeparator variants\n * Orientation-aware visual divider between button groups\n */\nexport const buttonGroupSeparatorVariants = cva('bg-[var(--border)]', {\n variants: {\n orientation: {\n horizontal: 'w-px h-6 mx-1',\n vertical: 'h-px w-full my-1',\n },\n },\n defaultVariants: {\n orientation: 'horizontal',\n },\n});\n","\"use client\";\n\n/**\n * Button Component - 3-Layer Architecture\n * Accessible button with React Aria primitives and CVA styling\n *\n * Architecture:\n * - Layer 1: Touch Target (44x44px WCAG AAA compliant, transparent)\n * - Layer 2: Visual Button (configurable size, colors, borders)\n * - Layer 3: Content & Effects (text, icons, ripple, loading spinner)\n *\n * @see 3layer-plan.md for architecture details\n * @see spec.md FR-029 to FR-037 (Button Component Requirements)\n * @see spec.md FR-009 (WCAG 2.2 AAA - 7:1 contrast ratio)\n * @see spec.md FR-014 (44x44px minimum touch targets)\n * @see constitution.md Principle IV (Accessibility First)\n */\n\nimport { forwardRef, memo, useId } from 'react';\nimport {\n Button as AriaButton,\n type ButtonProps as AriaButtonProps,\n} from 'react-aria-components';\nimport { Loader2, Zap } from 'lucide-react';\nimport { cn } from '../../utils/cn';\nimport type { ButtonProps } from './Button.types';\nimport { buttonOuterVariants, buttonVisualVariants, buttonVariants } from './Button.styles';\nimport { PRESSED_STYLES, HOVER_STYLES, HIGH_CONTRAST_HOVER, HIGH_CONTRAST_PRESSED } from '../../styles/interaction-states';\nimport {\n useButtonGroupContext,\n useButtonGroupItemContext,\n} from '../ButtonGroup/ButtonGroupContext';\nimport { buttonGroupItemVariants } from '../ButtonGroup/ButtonGroup.variants';\n\n/**\n * Button Component - 3-Layer Architecture\n * Fully accessible button with React Aria and themed styling\n *\n * Layer 1: Touch Target (AriaButton) - 44x44px WCAG AAA compliant\n * Layer 2: Visual Button (span) - configurable appearance\n * Layer 3: Content (children) - text, icons, effects\n */\nconst Button = memo(forwardRef<HTMLButtonElement, ButtonProps>(\n (\n {\n className,\n buttonVisualClassName,\n variant,\n size,\n visualSize,\n fullWidth,\n loading = false,\n loadingText = \"Loading...\",\n shortcut,\n children,\n isDisabled,\n paywall = false,\n paywallRedirect,\n paywallDescription,\n onPress,\n ...props\n },\n ref\n ) => {\n const paywallDescriptionId = useId();\n\n // ==========================================================================\n // ButtonGroup Context Integration\n // ==========================================================================\n\n // Consume group-level context (variant, size, isDisabled, orientation)\n const groupContext = useButtonGroupContext();\n\n // Consume item-level context (position for border-radius styling)\n const itemContext = useButtonGroupItemContext();\n\n // Merge context values with props (props take precedence)\n const effectiveVariant = variant ?? groupContext?.variant ?? 'default';\n const effectiveSize = size ?? groupContext?.size;\n const effectiveIsDisabled = isDisabled ?? groupContext?.isDisabled ?? false;\n\n // In vertical groups, buttons should be full width automatically\n const isInVerticalGroup = groupContext?.orientation === 'vertical';\n const effectiveFullWidth = fullWidth || isInVerticalGroup;\n\n // Position styling for ButtonGroup (only applied when in a group)\n const positionClassName = itemContext\n ? buttonGroupItemVariants({\n orientation: groupContext?.orientation ?? 'horizontal',\n position: itemContext.position,\n })\n : '';\n\n // Default visualSize to size for backward compatibility\n const effectiveVisualSize = visualSize ?? effectiveSize ?? 'default';\n\n // AAA Accessibility: Warn in dev/test if icon/dot variant lacks accessible name\n if (process.env.NODE_ENV !== 'production') {\n if (\n (effectiveVisualSize === 'dot' || effectiveVisualSize === 'icon') &&\n !props['aria-label'] &&\n !children\n ) {\n console.warn(\n '[Button] visualSize=\"dot\" or \"icon\" requires aria-label when no visible text is provided (WCAG 1.1.1)'\n );\n }\n }\n\n /**\n * Handle button press - intercepts action when paywalled\n * If paywalled with redirect URL, opens in new tab\n * Otherwise, calls the normal onPress handler\n */\n const handlePress = (e: Parameters<NonNullable<AriaButtonProps['onPress']>>[0]): void => {\n if (paywall) {\n if (paywallRedirect) {\n window.open(paywallRedirect, '_blank', 'noopener,noreferrer');\n }\n // Don't call onPress when paywalled\n return;\n }\n onPress?.(e);\n };\n\n // Only set isDisabled when we have a reason to disable\n // Otherwise, let slot system control disabled state (e.g., in NumberField)\n const computedIsDisabled = effectiveIsDisabled || loading || undefined;\n\n return (\n <AriaButton\n ref={ref}\n isDisabled={computedIsDisabled}\n aria-disabled={paywall ? true : undefined}\n aria-describedby={paywall ? paywallDescriptionId : undefined}\n onPress={handlePress}\n className={cn(buttonOuterVariants({ fullWidth: effectiveFullWidth, inVerticalGroup: isInVerticalGroup }), className)}\n {...props}\n >\n {(renderProps) => (\n /* Layer 2: Visual Button */\n <span\n className={cn(\n buttonVisualVariants({\n variant: effectiveVariant,\n visualSize: effectiveVisualSize,\n paywall,\n fullWidth: effectiveFullWidth,\n }),\n // Position styling from ButtonGroup context (border-radius adjustments)\n positionClassName,\n buttonVisualClassName,\n // Layer 2 interaction styles (no focus - focus ring is on Layer 1)\n PRESSED_STYLES,\n HOVER_STYLES,\n HIGH_CONTRAST_HOVER,\n HIGH_CONTRAST_PRESSED\n )}\n data-pressed={renderProps.isPressed || undefined}\n >\n {/* Layer 3: Content & Effects */}\n\n {/* FR-033: Loading spinner with screen reader announcement */}\n {/* Uses motion-safe: for WCAG 2.3.3 AAA (Animation from Interactions) */}\n {loading && (\n <>\n <Loader2 className=\"motion-safe:animate-spin\" aria-hidden=\"true\" />\n <span className=\"sr-only\" aria-live=\"polite\">\n {loadingText}\n </span>\n </>\n )}\n\n {/* Hide children during loading */}\n {!loading && children}\n\n {/* Paywall: Lightning bolt icon */}\n {paywall && (\n <Zap\n data-testid=\"zap-icon\"\n aria-hidden=\"true\"\n className=\"ml-1\"\n />\n )}\n\n {/* Paywall: Screen reader description */}\n {paywall && (\n <span id={paywallDescriptionId} className=\"sr-only\">\n Premium feature: {paywallDescription || \"Upgrade required to access this feature\"}\n </span>\n )}\n\n {/* FR-034: Keyboard shortcut display on focus */}\n {renderProps.isFocusVisible && shortcut && (\n <kbd className=\"ml-auto hidden text-xs opacity-60 lg:inline\">\n {shortcut}\n </kbd>\n )}\n\n {/* Touch/press ripple effect - FR-031: Pressed state feedback */}\n {/* Uses motion-safe: for WCAG 2.3.3 AAA (Animation from Interactions) */}\n {renderProps.isPressed && (\n <span\n className=\"absolute inset-0 rounded-[inherit] bg-current opacity-10 motion-safe:animate-in motion-safe:zoom-in-95\"\n aria-hidden=\"true\"\n />\n )}\n </span>\n )}\n </AriaButton>\n );\n }\n));\n\nButton.displayName = \"Button\";\n\nexport { Button, buttonVariants, buttonOuterVariants, buttonVisualVariants };\nexport type { ButtonProps } from './Button.types';\n","import { cva, type VariantProps } from 'class-variance-authority';\n\n/**\n * CVA Variants for AlertDialog content panel\n *\n * Only defines the destructive border variant. Base styling comes from\n * the underlying Modal component.\n */\nexport const alertDialogContentVariants = cva(\n 'border border-[var(--border)]',\n {\n variants: {\n variant: {\n default: '',\n destructive: 'border-[var(--destructive-background)]',\n },\n },\n defaultVariants: {\n variant: 'default',\n },\n }\n);\n\n/**\n * Type exports for variant props\n */\nexport type AlertDialogContentVariantProps = VariantProps<typeof alertDialogContentVariants>;\n","'use client';\n\n/**\n * AlertDialog Component\n *\n * A strict confirmation dialog for destructive or important actions.\n * Thin wrapper around the Modal component with role=\"alertdialog\".\n *\n * Unlike Modal (which is a flexible compound component), AlertDialog has a\n * fixed structure: title, optional description, optional children, and a\n * footer with cancel + action buttons. The footer is not customizable —\n * only the button labels, icons, and variants are configurable via props.\n *\n * Key differences from Modal:\n * - No backdrop dismiss (isDismissable: false)\n * - No Escape key dismiss (isKeyboardDismissDisabled: true)\n * - No close (X) button\n * - Fixed footer layout (cancel + action)\n * - Flat prop API instead of compound components\n *\n * WCAG 2.2 AAA compliant:\n * - role=\"alertdialog\" for screen reader announcements\n * - Focus trapped within dialog\n * - aria-labelledby linked to title\n * - aria-describedby linked to description\n * - All buttons use Themis Button (three-layer architecture, 44x44px touch targets)\n *\n * @example\n * ```tsx\n * <AlertDialog\n * trigger={<Button variant=\"destructive\">Delete</Button>}\n * title=\"Delete Account?\"\n * description=\"This action cannot be undone.\"\n * actionLabel=\"Delete Account\"\n * onAction={handleDelete}\n * />\n * ```\n */\n\nimport { type ReactElement } from 'react';\nimport {\n Modal,\n ModalTrigger,\n ModalContent,\n ModalHeader,\n ModalTitle,\n ModalDescription,\n ModalFooter,\n ModalClose,\n} from '../Modal/Modal';\nimport { Button } from '../Button/Button';\nimport type { AlertDialogProps } from './AlertDialog.types';\nimport { alertDialogContentVariants } from './AlertDialog.styles';\n\nexport function AlertDialog({\n trigger,\n isOpen,\n defaultOpen = false,\n onOpenChange,\n title,\n description,\n children,\n variant = 'default',\n size = 'md',\n cancelLabel = 'Cancel',\n cancelIcon,\n actionLabel,\n actionIcon,\n actionVariant = 'destructive',\n onAction,\n className,\n}: AlertDialogProps): ReactElement {\n // Map AlertDialog sizes to Modal sizes (AlertDialog uses sm/md/lg, Modal uses sm/md/lg/xl/full)\n const modalSize = size;\n\n return (\n <Modal\n role=\"alertdialog\"\n isOpen={isOpen}\n defaultOpen={defaultOpen}\n onOpenChange={onOpenChange}\n >\n <ModalTrigger>\n {trigger}\n </ModalTrigger>\n <ModalContent\n size={modalSize}\n isDismissable={false}\n isKeyboardDismissDisabled={true}\n showClose={false}\n animation=\"fade-zoom\"\n animationDuration={200}\n className={alertDialogContentVariants({ variant }) + (className ? ` ${className}` : '')}\n >\n <ModalHeader>\n <ModalTitle as=\"h2\">{title}</ModalTitle>\n {description && <ModalDescription>{description}</ModalDescription>}\n </ModalHeader>\n\n {children}\n\n <ModalFooter>\n <ModalClose>\n <Button variant=\"secondary\">\n {cancelIcon && <span className=\"mr-2\" aria-hidden=\"true\">{cancelIcon}</span>}\n {cancelLabel}\n </Button>\n </ModalClose>\n <ModalClose>\n <Button variant={actionVariant} onPress={onAction}>\n {actionIcon && <span className=\"mr-2\" aria-hidden=\"true\">{actionIcon}</span>}\n {actionLabel}\n </Button>\n </ModalClose>\n </ModalFooter>\n </ModalContent>\n </Modal>\n );\n}\n\nAlertDialog.displayName = 'AlertDialog';\n","import { z } from 'zod';\n\n/**\n * Base props schema for all Themis components\n * Ensures consistent accessibility and styling APIs across the library\n *\n * @see spec.md FR-009 to FR-014 (Accessibility Requirements)\n * @see constitution.md Principle IV (Accessibility First - WCAG 2.2 AA minimum)\n */\nexport const BaseComponentPropsSchema = z.object({\n // Styling\n className: z.string().optional(),\n\n // React\n children: z.any().optional(), // ReactNode not directly supported by Zod\n id: z.string().optional(),\n\n // Accessibility (WCAG 2.2 AA requirements)\n 'aria-label': z.string().optional(),\n 'aria-labelledby': z.string().optional(),\n 'aria-describedby': z.string().optional(),\n 'aria-live': z.enum(['off', 'polite', 'assertive']).optional(),\n 'aria-hidden': z.boolean().optional(),\n\n // Testing & Development\n 'data-testid': z.string().optional(),\n});\n\nexport type BaseComponentProps = z.infer<typeof BaseComponentPropsSchema>;\n","import { z } from 'zod';\nimport { BaseComponentPropsSchema } from '../../schemas/BaseComponentProps';\nimport type { ReactNode } from 'react';\n\n/**\n * AlertDialog variant schema\n */\nexport const AlertDialogVariantSchema = z.enum(['default', 'destructive']);\nexport type AlertDialogVariant = z.infer<typeof AlertDialogVariantSchema>;\n\n/**\n * AlertDialog size schema\n */\nexport const AlertDialogSizeSchema = z.enum(['sm', 'md', 'lg']);\nexport type AlertDialogSize = z.infer<typeof AlertDialogSizeSchema>;\n\n/**\n * AlertDialog props schema\n *\n * A strict, flat API for confirmation dialogs. Wraps Modal with\n * role=\"alertdialog\", no backdrop dismiss, no Escape dismiss, no close button.\n * Footer is fixed: cancel button (left) + action button (right).\n */\nexport const AlertDialogPropsSchema = BaseComponentPropsSchema.extend({\n /** Trigger element that opens the dialog (typically a Button) */\n trigger: z.custom<ReactNode>(),\n\n /** Whether the dialog is open (controlled mode) */\n isOpen: z.boolean().optional(),\n\n /** Default open state (uncontrolled mode) */\n defaultOpen: z.boolean().optional().default(false),\n\n /** Callback when open state changes */\n onOpenChange: z.custom<(isOpen: boolean) => void>().optional(),\n\n /** Dialog title (required — alerts must have a clear heading) */\n title: z.string(),\n\n /** Dialog description text */\n description: z.string().optional(),\n\n /** Optional extra content between description and footer */\n children: z.custom<ReactNode>().optional(),\n\n /** Visual variant of the dialog */\n variant: AlertDialogVariantSchema.optional().default('default'),\n\n /** Size of the dialog */\n size: AlertDialogSizeSchema.optional().default('md'),\n\n /** Cancel button label */\n cancelLabel: z.string().optional().default('Cancel'),\n\n /** Cancel button icon (rendered before label) */\n cancelIcon: z.custom<ReactNode>().optional(),\n\n /** Action button label (required — alert must have an explicit action) */\n actionLabel: z.string(),\n\n /** Action button icon (rendered before label) */\n actionIcon: z.custom<ReactNode>().optional(),\n\n /** Action button variant */\n actionVariant: z.enum(['default', 'destructive']).optional().default('destructive'),\n\n /** Callback when the action button is pressed (fires before dialog closes) */\n onAction: z.custom<() => void>().optional(),\n});\n\nexport interface AlertDialogProps {\n className?: string;\n id?: string;\n 'aria-label'?: string;\n 'aria-labelledby'?: string;\n 'aria-describedby'?: string;\n 'data-testid'?: string;\n trigger: ReactNode;\n isOpen?: boolean;\n defaultOpen?: boolean;\n onOpenChange?: (isOpen: boolean) => void;\n title: string;\n description?: string;\n children?: ReactNode;\n variant?: AlertDialogVariant;\n size?: AlertDialogSize;\n cancelLabel?: string;\n cancelIcon?: ReactNode;\n actionLabel: string;\n actionIcon?: ReactNode;\n actionVariant?: 'default' | 'destructive';\n onAction?: () => void;\n}\n"]}
@@ -25,27 +25,7 @@ export declare const avatarVisualVariants: (props?: ({
25
25
  * Layer 2: Visual Avatar - configurable appearance
26
26
  * Layer 3: Content - image, initials, or loading skeleton
27
27
  */
28
- declare const Avatar: import("react").NamedExoticComponent<Omit<{
29
- alt: string;
30
- size: "default" | "sm" | "lg";
31
- shape: "circle" | "rounded";
32
- className?: string | undefined;
33
- children?: any;
34
- id?: string | undefined;
35
- 'aria-label'?: string | undefined;
36
- 'aria-labelledby'?: string | undefined;
37
- 'aria-describedby'?: string | undefined;
38
- 'aria-live'?: "off" | "polite" | "assertive" | undefined;
39
- 'aria-hidden'?: boolean | undefined;
40
- 'data-testid'?: string | undefined;
41
- src?: string | undefined;
42
- name?: string | undefined;
43
- status?: "online" | "offline" | "busy" | "away" | undefined;
44
- onPress?: import("zod/v4/core").$InferOuterFunctionType<import("zod/v4/core").$ZodFunctionArgs, import("zod/v4/core").$ZodFunctionOut> | undefined;
45
- }, "onPress"> & {
46
- onPress?: (e: import("react-aria").PressEvent) => void;
47
- _groupIndex?: number;
48
- } & import("react").RefAttributes<HTMLDivElement>>;
28
+ declare const Avatar: import("react").NamedExoticComponent<AvatarProps & import("react").RefAttributes<HTMLDivElement>>;
49
29
  export { Avatar };
50
30
  export type { AvatarProps, AvatarSize, AvatarShape, AvatarStatus };
51
31
  //# sourceMappingURL=Avatar.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Avatar.d.ts","sourceRoot":"","sources":["../../../src/elements/Avatar/Avatar.tsx"],"names":[],"mappings":"AAoBA,OAAO,KAAK,EACV,WAAW,EACX,UAAU,EACV,WAAW,EACX,YAAY,EAEb,MAAM,gBAAgB,CAAC;AA0BxB;;;;GAIG;AACH,eAAO,MAAM,mBAAmB;;;8EA8B/B,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,oBAAoB;;;;8EAgChC,CAAC;AAEF;;;;;;;GAOG;AACH,QAAA,MAAM,MAAM;;;;;;;;;;;;;;;;;;;;kDAkIX,CAAC;AAIF,OAAO,EAAE,MAAM,EAAE,CAAC;AAClB,YAAY,EAAE,WAAW,EAAE,UAAU,EAAE,WAAW,EAAE,YAAY,EAAE,CAAC"}
1
+ {"version":3,"file":"Avatar.d.ts","sourceRoot":"","sources":["../../../src/elements/Avatar/Avatar.tsx"],"names":[],"mappings":"AAoBA,OAAO,KAAK,EACV,WAAW,EACX,UAAU,EACV,WAAW,EACX,YAAY,EAEb,MAAM,gBAAgB,CAAC;AA0BxB;;;;GAIG;AACH,eAAO,MAAM,mBAAmB;;;8EA8B/B,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,oBAAoB;;;;8EAgChC,CAAC;AAEF;;;;;;;GAOG;AACH,QAAA,MAAM,MAAM,mGAkIX,CAAC;AAIF,OAAO,EAAE,MAAM,EAAE,CAAC;AAClB,YAAY,EAAE,WAAW,EAAE,UAAU,EAAE,WAAW,EAAE,YAAY,EAAE,CAAC"}
@@ -1,4 +1,5 @@
1
1
  import { z } from 'zod';
2
+ import type { ReactNode } from 'react';
2
3
  import type { PressEvent } from 'react-aria-components';
3
4
  /**
4
5
  * Avatar size schema
@@ -90,16 +91,25 @@ export declare const AvatarPropsSchema: z.ZodObject<{
90
91
  }>>;
91
92
  onPress: z.ZodOptional<z.ZodFunction<z.core.$ZodFunctionArgs, z.core.$ZodFunctionOut>>;
92
93
  }, z.core.$strip>;
93
- export type AvatarProps = Omit<z.infer<typeof AvatarPropsSchema>, 'onPress'> & {
94
- /** Click handler for actionable avatar */
94
+ export interface AvatarProps {
95
+ className?: string;
96
+ children?: unknown;
97
+ id?: string;
98
+ 'aria-label'?: string;
99
+ 'aria-labelledby'?: string;
100
+ 'aria-describedby'?: string;
101
+ 'aria-hidden'?: boolean;
102
+ 'data-testid'?: string;
103
+ src?: string;
104
+ alt: string;
105
+ name?: string;
106
+ size?: AvatarSize;
107
+ shape?: AvatarShape;
108
+ status?: AvatarStatus;
95
109
  onPress?: (e: PressEvent) => void;
96
- /**
97
- * Internal: Position index within AvatarGroup (0-indexed)
98
- * Used to progressively darken backgrounds in groups
99
- * @internal Set by AvatarGroup, do not use directly
100
- */
110
+ /** @internal Set by AvatarGroup, do not use directly */
101
111
  _groupIndex?: number;
102
- };
112
+ }
103
113
  /**
104
114
  * Avatar group props schema extending BaseComponentProps
105
115
  *
@@ -133,10 +143,19 @@ export declare const AvatarGroupPropsSchema: z.ZodObject<{
133
143
  }>>>;
134
144
  onPress: z.ZodOptional<z.ZodFunction<z.core.$ZodFunctionArgs, z.core.$ZodFunctionOut>>;
135
145
  }, z.core.$strip>;
136
- export type AvatarGroupProps = Omit<z.infer<typeof AvatarGroupPropsSchema>, 'onPress'> & {
137
- /** Click handler for the entire group */
146
+ export interface AvatarGroupProps {
147
+ className?: string;
148
+ children?: ReactNode;
149
+ id?: string;
150
+ 'aria-label'?: string;
151
+ 'aria-labelledby'?: string;
152
+ 'aria-describedby'?: string;
153
+ 'data-testid'?: string;
154
+ max?: number;
155
+ shape?: AvatarShape;
156
+ size?: AvatarSize;
138
157
  onPress?: (e: PressEvent) => void;
139
- };
158
+ }
140
159
  /**
141
160
  * Internal loading state for avatar images
142
161
  * @see plan.md Clarification 4 (Loading State)
@@ -1 +1 @@
1
- {"version":3,"file":"Avatar.types.d.ts","sourceRoot":"","sources":["../../../src/elements/Avatar/Avatar.types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAGxD;;;;;;;;;;GAUG;AACH,eAAO,MAAM,gBAAgB;;;;EAAkC,CAAC;AAChE,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAE1D;;;;GAIG;AACH,eAAO,MAAM,iBAAiB;;;EAAgC,CAAC;AAC/D,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAE5D;;;;;;;;GAQG;AACH,eAAO,MAAM,kBAAkB;;;;;EAAgD,CAAC;AAChF,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAE9D;;;GAGG;AACH,eAAO,MAAM,sBAAsB,EAAE,MAAM,CAAC,UAAU,EAAE,MAAM,CAI7D,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAiC5B,CAAC;AAEH,MAAM,MAAM,WAAW,GAAG,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,EAAE,SAAS,CAAC,GAAG;IAC7E,0CAA0C;IAC1C,OAAO,CAAC,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,IAAI,CAAC;IAClC;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;;iBA0BjC,CAAC;AAEH,MAAM,MAAM,gBAAgB,GAAG,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,EAAE,SAAS,CAAC,GAAG;IACvF,yCAAyC;IACzC,OAAO,CAAC,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,IAAI,CAAC;CACnC,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,kBAAkB,GAAG,SAAS,GAAG,QAAQ,GAAG,OAAO,CAAC"}
1
+ {"version":3,"file":"Avatar.types.d.ts","sourceRoot":"","sources":["../../../src/elements/Avatar/Avatar.types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACvC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAGxD;;;;;;;;;;GAUG;AACH,eAAO,MAAM,gBAAgB;;;;EAAkC,CAAC;AAChE,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAE1D;;;;GAIG;AACH,eAAO,MAAM,iBAAiB;;;EAAgC,CAAC;AAC/D,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAE5D;;;;;;;;GAQG;AACH,eAAO,MAAM,kBAAkB;;;;;EAAgD,CAAC;AAChF,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAE9D;;;GAGG;AACH,eAAO,MAAM,sBAAsB,EAAE,MAAM,CAAC,UAAU,EAAE,MAAM,CAI7D,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAiC5B,CAAC;AAEH,MAAM,WAAW,WAAW;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,OAAO,CAAC,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,IAAI,CAAC;IAClC,wDAAwD;IACxD,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;;;;;GAMG;AACH,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;;iBA0BjC,CAAC;AAEH,MAAM,WAAW,gBAAgB;IAC/B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,OAAO,CAAC,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,IAAI,CAAC;CACnC;AAED;;;GAGG;AACH,MAAM,MAAM,kBAAkB,GAAG,SAAS,GAAG,QAAQ,GAAG,OAAO,CAAC"}
@@ -10,23 +10,7 @@ declare const avatarOverflowVariants: (props?: ({
10
10
  * AvatarGroup Component
11
11
  * Groups multiple Avatar components with overlap and overflow handling
12
12
  */
13
- declare const AvatarGroup: import("react").NamedExoticComponent<Omit<{
14
- max: number;
15
- shape: "circle" | "rounded";
16
- size: "default" | "sm" | "lg";
17
- className?: string | undefined;
18
- children?: any;
19
- id?: string | undefined;
20
- 'aria-label'?: string | undefined;
21
- 'aria-labelledby'?: string | undefined;
22
- 'aria-describedby'?: string | undefined;
23
- 'aria-live'?: "off" | "polite" | "assertive" | undefined;
24
- 'aria-hidden'?: boolean | undefined;
25
- 'data-testid'?: string | undefined;
26
- onPress?: import("zod/v4/core").$InferOuterFunctionType<import("zod/v4/core").$ZodFunctionArgs, import("zod/v4/core").$ZodFunctionOut> | undefined;
27
- }, "onPress"> & {
28
- onPress?: (e: import("react-aria").PressEvent) => void;
29
- } & import("react").RefAttributes<HTMLDivElement>>;
13
+ declare const AvatarGroup: import("react").NamedExoticComponent<AvatarGroupProps & import("react").RefAttributes<HTMLDivElement>>;
30
14
  export { AvatarGroup, avatarOverflowVariants };
31
15
  export type { AvatarGroupProps };
32
16
  //# sourceMappingURL=AvatarGroup.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"AvatarGroup.d.ts","sourceRoot":"","sources":["../../../src/elements/Avatar/AvatarGroup.tsx"],"names":[],"mappings":"AA6BA,OAAO,KAAK,EAAE,gBAAgB,EAA2B,MAAM,gBAAgB,CAAC;AAYhF;;GAEG;AACH,QAAA,MAAM,sBAAsB;;;8EA0B3B,CAAC;AAwBF;;;GAGG;AACH,QAAA,MAAM,WAAW;;;;;;;;;;;;;;;;kDAyKhB,CAAC;AAIF,OAAO,EAAE,WAAW,EAAE,sBAAsB,EAAE,CAAC;AAC/C,YAAY,EAAE,gBAAgB,EAAE,CAAC"}
1
+ {"version":3,"file":"AvatarGroup.d.ts","sourceRoot":"","sources":["../../../src/elements/Avatar/AvatarGroup.tsx"],"names":[],"mappings":"AA6BA,OAAO,KAAK,EAAE,gBAAgB,EAA2B,MAAM,gBAAgB,CAAC;AAYhF;;GAEG;AACH,QAAA,MAAM,sBAAsB;;;8EA0B3B,CAAC;AAwBF;;;GAGG;AACH,QAAA,MAAM,WAAW,wGAyKhB,CAAC;AAIF,OAAO,EAAE,WAAW,EAAE,sBAAsB,EAAE,CAAC;AAC/C,YAAY,EAAE,gBAAgB,EAAE,CAAC"}
@@ -1,3 +1,3 @@
1
1
  "use client";
2
- 'use strict';var react=require('react'),reactAriaComponents=require('react-aria-components'),classVarianceAuthority=require('class-variance-authority'),clsx=require('clsx'),tailwindMerge=require('tailwind-merge'),jsxRuntime=require('react/jsx-runtime'),zod=require('zod');function e(...t){return tailwindMerge.twMerge(clsx.clsx(t))}function aa(t){if(!t||!t.trim())return "";let a=t.trim().split(/\s+/).filter(Boolean);if(a.length===0)return "";let r=a[0];if(a.length===1)return r?r.charAt(0).toUpperCase():"";let n=a[a.length-1],p=r?r.charAt(0).toUpperCase():"",l=n?n.charAt(0).toUpperCase():"";return p+l}var R=classVarianceAuthority.cva("relative inline-flex items-center justify-center",{variants:{size:{sm:"min-h-[44px] min-w-[44px]",default:"min-h-[44px] min-w-[44px]",lg:"min-h-[48px] min-w-[48px]"},interactive:{true:["cursor-pointer","focus-visible:outline-none","focus-visible:ring-2","focus-visible:ring-[var(--ring)]","focus-visible:ring-offset-2","focus-visible:ring-offset-[var(--page-background)]","motion-safe:transition-transform","motion-safe:duration-150","motion-safe:ease-out","motion-safe:hover:scale-105"],false:""}},defaultVariants:{size:"default",interactive:false}}),_=classVarianceAuthority.cva(["relative inline-flex items-center justify-center","overflow-hidden","bg-[var(--accent-background)]","text-[var(--accent-foreground)]","font-medium","select-none"],{variants:{size:{sm:"h-8 w-8 text-xs",default:"h-11 w-11 text-sm",lg:"h-12 w-12 text-base"},shape:{circle:"rounded-full",rounded:"rounded-lg"},status:{online:"ring-[3px] ring-[var(--status-online,#22c55e)]",offline:"ring-[3px] ring-[var(--status-offline,#6b7280)]",busy:"ring-[3px] ring-[var(--status-busy,#ef4444)]",away:"ring-[3px] ring-[var(--status-away,#eab308)]"}},defaultVariants:{size:"default",shape:"circle"}}),I=react.memo(react.forwardRef(({src:t,alt:a,name:r,size:n="default",shape:p="circle",status:l,onPress:g,className:A,id:P,"data-testid":b,"aria-label":h,"aria-labelledby":y,"aria-describedby":S,_groupIndex:c},f)=>{let[u,d]=react.useState(t?"loading":"error"),w=react.useCallback(()=>{d("loaded");},[]),V=react.useCallback(()=>{d("error");},[]),z=aa(r),m=!!g,E=h||(m&&l?`${a}, ${l}`:void 0),i=c!==void 0?1-c*.05:void 0,v=jsxRuntime.jsxs("div",{"data-testid":"avatar-visual",className:e(_({size:n,shape:p,status:l})),style:i!==void 0?{filter:`brightness(${i})`}:void 0,children:[u==="loading"&&jsxRuntime.jsx("div",{"data-testid":"avatar-skeleton",className:e("absolute inset-0 animate-pulse bg-[var(--accent-background)]",p==="circle"?"rounded-full":"rounded-lg"),"aria-hidden":"true"}),t&&u!=="error"&&jsxRuntime.jsx("img",{src:t,alt:m?"":a,onLoad:w,onError:V,className:e("h-full w-full object-cover",u==="loading"&&"invisible")}),u==="error"&&z&&jsxRuntime.jsx("span",{"aria-hidden":"true",children:z})]});return m?jsxRuntime.jsx(reactAriaComponents.Button,{ref:f,id:P,"data-testid":b||"avatar-outer","aria-label":E||a,"aria-labelledby":y,"aria-describedby":S,onPress:g,className:e(R({size:n,interactive:true}),A),children:v}):jsxRuntime.jsx("div",{ref:f,id:P,"data-testid":b||"avatar-outer","aria-label":h,"aria-labelledby":y,"aria-describedby":S,className:e(R({size:n,interactive:false}),A),children:v})}));I.displayName="Avatar";var ia={sm:"-ml-2",default:"-ml-3",lg:"-ml-4"},U=classVarianceAuthority.cva(["relative inline-flex items-center justify-center","bg-[var(--secondary)]","text-[var(--secondary-foreground)]","font-semibold","select-none","border-2 border-[var(--page-background)]"],{variants:{size:{sm:"h-8 w-8 text-xs",default:"h-11 w-11 text-sm",lg:"h-12 w-12 text-base"},shape:{circle:"rounded-full",rounded:"rounded-lg"}},defaultVariants:{size:"default",shape:"circle"}}),H=classVarianceAuthority.cva("inline-flex items-center",{variants:{interactive:{true:["cursor-pointer","focus-visible:outline-none","focus-visible:ring-2","focus-visible:ring-[var(--ring)]","focus-visible:ring-offset-2","focus-visible:ring-offset-[var(--page-background)]"],false:""}},defaultVariants:{interactive:false}}),Y=react.memo(react.forwardRef(({max:t=3,shape:a="circle",size:r="default",onPress:n,className:p,children:l,id:g,"data-testid":A,"aria-label":P,"aria-labelledby":b,"aria-describedby":h},y)=>{let S=react.Children.toArray(l),c=S.length,f=Math.min(c,t),u=c-f,d=!!n,w=ia[r];process.env.NODE_ENV!=="production"&&d&&react.Children.forEach(l,i=>{react.isValidElement(i)&&i.props.onPress&&console.warn("[AvatarGroup] onPress on individual avatars is ignored when AvatarGroup has onPress. Actions are mutually exclusive - use group onPress OR individual onPress, not both.");});let V=S.slice(0,f).map((i,v)=>{if(!react.isValidElement(i))return null;let L=i.props,q=f-v,D=d?void 0:L.onPress;return jsxRuntime.jsx("div",{"data-testid":"avatar-group-item",className:e("relative","border-2 border-[var(--page-background)]",a==="circle"?"rounded-full":"rounded-lg",v>0&&w,!d&&["motion-safe:transition-transform","motion-safe:duration-150","motion-safe:ease-out","motion-safe:hover:scale-[1.15]","motion-safe:hover:z-10"]),style:{zIndex:q},children:react.cloneElement(i,{size:r,shape:a,onPress:D,_groupIndex:v,className:e(L.className,"!min-h-0 !min-w-0")})},v)}),z=u>0?jsxRuntime.jsxs("div",{"data-testid":"avatar-overflow",className:e(U({size:r,shape:a}),w),style:{zIndex:0},"aria-hidden":"true",children:["+",u]}):null,m=P||`${c} ${c===1?"member":"members"}`,E=jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[V,z]});return d?jsxRuntime.jsx(reactAriaComponents.Button,{ref:y,id:g,"data-testid":A,"aria-label":m,"aria-labelledby":b,"aria-describedby":h,onPress:n,className:e(H({interactive:true}),p),children:E}):jsxRuntime.jsx("div",{ref:y,id:g,"data-testid":A,role:"group","aria-label":m,"aria-labelledby":b,"aria-describedby":h,className:e(H({interactive:false}),p),children:E})}));Y.displayName="AvatarGroup";var B=zod.z.object({className:zod.z.string().optional(),children:zod.z.any().optional(),id:zod.z.string().optional(),"aria-label":zod.z.string().optional(),"aria-labelledby":zod.z.string().optional(),"aria-describedby":zod.z.string().optional(),"aria-live":zod.z.enum(["off","polite","assertive"]).optional(),"aria-hidden":zod.z.boolean().optional(),"data-testid":zod.z.string().optional()});var G=zod.z.enum(["sm","default","lg"]),N=zod.z.enum(["circle","rounded"]),Z=zod.z.enum(["online","offline","busy","away"]),la={sm:8,default:12,lg:16},pa=B.extend({src:zod.z.string().optional(),alt:zod.z.string().min(1,"alt is required for accessibility"),name:zod.z.string().optional(),size:G.optional().default("default"),shape:N.optional().default("circle"),status:Z.optional(),onPress:zod.z.function().optional()}),ca=B.extend({max:zod.z.number().int().positive().optional().default(3),shape:N.optional().default("circle"),size:G.optional().default("default"),onPress:zod.z.function().optional()});exports.AVATAR_OVERLAP_BY_SIZE=la;exports.Avatar=I;exports.AvatarGroup=Y;exports.AvatarGroupPropsSchema=ca;exports.AvatarPropsSchema=pa;exports.AvatarShapeSchema=N;exports.AvatarSizeSchema=G;exports.AvatarStatusSchema=Z;exports.avatarOuterVariants=R;exports.avatarOverflowVariants=U;exports.avatarVisualVariants=_;//# sourceMappingURL=index.js.map
2
+ 'use strict';var react=require('react'),reactAriaComponents=require('react-aria-components'),classVarianceAuthority=require('class-variance-authority'),clsx=require('clsx'),tailwindMerge=require('tailwind-merge'),jsxRuntime=require('react/jsx-runtime'),zod=require('zod');function e(...t){return tailwindMerge.twMerge(clsx.clsx(t))}function aa(t){if(!t||!t.trim())return "";let a=t.trim().split(/\s+/).filter(Boolean);if(a.length===0)return "";let r=a[0];if(a.length===1)return r?r.charAt(0).toUpperCase():"";let i=a[a.length-1],c=r?r.charAt(0).toUpperCase():"",l=i?i.charAt(0).toUpperCase():"";return c+l}var R=classVarianceAuthority.cva("relative inline-flex items-center justify-center",{variants:{size:{sm:"min-h-[44px] min-w-[44px]",default:"min-h-[44px] min-w-[44px]",lg:"min-h-[48px] min-w-[48px]"},interactive:{true:["cursor-pointer","focus-visible:outline-none","focus-visible:ring-2","focus-visible:ring-[var(--ring)]","focus-visible:ring-offset-2","focus-visible:ring-offset-[var(--page-background)]","motion-safe:transition-transform","motion-safe:duration-150","motion-safe:ease-out","motion-safe:hover:scale-105"],false:""}},defaultVariants:{size:"default",interactive:false}}),I=classVarianceAuthority.cva(["relative inline-flex items-center justify-center","overflow-hidden","bg-[var(--accent-background)]","text-[var(--accent-foreground)]","font-medium","select-none"],{variants:{size:{sm:"h-8 w-8 text-xs",default:"h-11 w-11 text-sm",lg:"h-12 w-12 text-base"},shape:{circle:"rounded-full",rounded:"rounded-lg"},status:{online:"ring-[3px] ring-[var(--status-online,#22c55e)]",offline:"ring-[3px] ring-[var(--status-offline,#6b7280)]",busy:"ring-[3px] ring-[var(--status-busy,#ef4444)]",away:"ring-[3px] ring-[var(--status-away,#eab308)]"}},defaultVariants:{size:"default",shape:"circle"}}),O=react.memo(react.forwardRef(({src:t,alt:a,name:r,size:i="default",shape:c="circle",status:l,onPress:g,className:b,id:P,"data-testid":A,"aria-label":h,"aria-labelledby":S,"aria-describedby":y,_groupIndex:d},f)=>{let[p,u]=react.useState(t?"loading":"error"),z=react.useCallback(()=>{u("loaded");},[]),V=react.useCallback(()=>{u("error");},[]),w=aa(r),m=!!g,E=h||(m&&l?`${a}, ${l}`:void 0),n=d!==void 0?1-d*.05:void 0,v=jsxRuntime.jsxs("div",{"data-testid":"avatar-visual",className:e(I({size:i,shape:c,status:l})),style:n!==void 0?{filter:`brightness(${n})`}:void 0,children:[p==="loading"&&jsxRuntime.jsx("div",{"data-testid":"avatar-skeleton",className:e("absolute inset-0 animate-pulse bg-[var(--accent-background)]",c==="circle"?"rounded-full":"rounded-lg"),"aria-hidden":"true"}),t&&p!=="error"&&jsxRuntime.jsx("img",{src:t,alt:m?"":a,onLoad:z,onError:V,className:e("h-full w-full object-cover",p==="loading"&&"invisible")}),p==="error"&&w&&jsxRuntime.jsx("span",{"aria-hidden":"true",children:w})]});return m?jsxRuntime.jsx(reactAriaComponents.Button,{ref:f,id:P,"data-testid":A||"avatar-outer","aria-label":E||a,"aria-labelledby":S,"aria-describedby":y,onPress:g,className:e(R({size:i,interactive:true}),b),children:v}):jsxRuntime.jsx("div",{ref:f,id:P,"data-testid":A||"avatar-outer","aria-label":h,"aria-labelledby":S,"aria-describedby":y,className:e(R({size:i,interactive:false}),b),children:v})}));O.displayName="Avatar";var na={sm:"-ml-2",default:"-ml-3",lg:"-ml-4"},U=classVarianceAuthority.cva(["relative inline-flex items-center justify-center","bg-[var(--secondary)]","text-[var(--secondary-foreground)]","font-semibold","select-none","border-2 border-[var(--page-background)]"],{variants:{size:{sm:"h-8 w-8 text-xs",default:"h-11 w-11 text-sm",lg:"h-12 w-12 text-base"},shape:{circle:"rounded-full",rounded:"rounded-lg"}},defaultVariants:{size:"default",shape:"circle"}}),H=classVarianceAuthority.cva("inline-flex items-center",{variants:{interactive:{true:["cursor-pointer","focus-visible:outline-none","focus-visible:ring-2","focus-visible:ring-[var(--ring)]","focus-visible:ring-offset-2","focus-visible:ring-offset-[var(--page-background)]"],false:""}},defaultVariants:{interactive:false}}),Y=react.memo(react.forwardRef(({max:t=3,shape:a="circle",size:r="default",onPress:i,className:c,children:l,id:g,"data-testid":b,"aria-label":P,"aria-labelledby":A,"aria-describedby":h},S)=>{let y=react.Children.toArray(l),d=y.length,f=Math.min(d,t),p=d-f,u=!!i,z=na[r];process.env.NODE_ENV!=="production"&&u&&react.Children.forEach(l,n=>{react.isValidElement(n)&&n.props.onPress&&console.warn("[AvatarGroup] onPress on individual avatars is ignored when AvatarGroup has onPress. Actions are mutually exclusive - use group onPress OR individual onPress, not both.");});let V=y.slice(0,f).map((n,v)=>{if(!react.isValidElement(n))return null;let L=n.props,q=f-v,D=u?void 0:L.onPress;return jsxRuntime.jsx("div",{"data-testid":"avatar-group-item",className:e("relative","border-2 border-[var(--page-background)]",a==="circle"?"rounded-full":"rounded-lg",v>0&&z,!u&&["motion-safe:transition-transform","motion-safe:duration-150","motion-safe:ease-out","motion-safe:hover:scale-[1.15]","motion-safe:hover:z-10"]),style:{zIndex:q},children:react.cloneElement(n,{size:r,shape:a,onPress:D,_groupIndex:v,className:e(L.className,"!min-h-0 !min-w-0")})},v)}),w=p>0?jsxRuntime.jsxs("div",{"data-testid":"avatar-overflow",className:e(U({size:r,shape:a}),z),style:{zIndex:0},"aria-hidden":"true",children:["+",p]}):null,m=P||`${d} ${d===1?"member":"members"}`,E=jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[V,w]});return u?jsxRuntime.jsx(reactAriaComponents.Button,{ref:S,id:g,"data-testid":b,"aria-label":m,"aria-labelledby":A,"aria-describedby":h,onPress:i,className:e(H({interactive:true}),c),children:E}):jsxRuntime.jsx("div",{ref:S,id:g,"data-testid":b,role:"group","aria-label":m,"aria-labelledby":A,"aria-describedby":h,className:e(H({interactive:false}),c),children:E})}));Y.displayName="AvatarGroup";var C=zod.z.object({className:zod.z.string().optional(),children:zod.z.any().optional(),id:zod.z.string().optional(),"aria-label":zod.z.string().optional(),"aria-labelledby":zod.z.string().optional(),"aria-describedby":zod.z.string().optional(),"aria-live":zod.z.enum(["off","polite","assertive"]).optional(),"aria-hidden":zod.z.boolean().optional(),"data-testid":zod.z.string().optional()});var B=zod.z.enum(["sm","default","lg"]),G=zod.z.enum(["circle","rounded"]),Z=zod.z.enum(["online","offline","busy","away"]),la={sm:8,default:12,lg:16},ca=C.extend({src:zod.z.string().optional(),alt:zod.z.string().min(1,"alt is required for accessibility"),name:zod.z.string().optional(),size:B.optional().default("default"),shape:G.optional().default("circle"),status:Z.optional(),onPress:zod.z.function().optional()}),da=C.extend({max:zod.z.number().int().positive().optional().default(3),shape:G.optional().default("circle"),size:B.optional().default("default"),onPress:zod.z.function().optional()});exports.AVATAR_OVERLAP_BY_SIZE=la;exports.Avatar=O;exports.AvatarGroup=Y;exports.AvatarGroupPropsSchema=da;exports.AvatarPropsSchema=ca;exports.AvatarShapeSchema=G;exports.AvatarSizeSchema=B;exports.AvatarStatusSchema=Z;exports.avatarOuterVariants=R;exports.avatarOverflowVariants=U;exports.avatarVisualVariants=I;//# sourceMappingURL=index.js.map
3
3
  //# sourceMappingURL=index.js.map