@acronis-platform/ui-react 0.62.0 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (190) hide show
  1. package/dist/components/ui/alert/alert.js +115 -57
  2. package/dist/components/ui/alert/alert.js.map +1 -1
  3. package/dist/components/ui/button-group/button-group.js +57 -0
  4. package/dist/components/ui/button-group/button-group.js.map +1 -0
  5. package/dist/components/ui/button-icon-menu/button-icon-menu.js +26 -0
  6. package/dist/components/ui/button-icon-menu/button-icon-menu.js.map +1 -0
  7. package/dist/components/ui/calendar-panel/calendar-panel.js.map +1 -1
  8. package/dist/components/ui/chip/chip.js +33 -33
  9. package/dist/components/ui/chip/chip.js.map +1 -1
  10. package/dist/components/ui/date-range-picker/date-range-picker-utils.js +11 -23
  11. package/dist/components/ui/date-range-picker/date-range-picker-utils.js.map +1 -1
  12. package/dist/components/ui/date-range-picker/date-range-picker.js +94 -134
  13. package/dist/components/ui/date-range-picker/date-range-picker.js.map +1 -1
  14. package/dist/components/ui/dropdown-menu/dropdown-menu.js +129 -72
  15. package/dist/components/ui/dropdown-menu/dropdown-menu.js.map +1 -1
  16. package/dist/components/ui/filter-chips/filter-chips.js +44 -0
  17. package/dist/components/ui/filter-chips/filter-chips.js.map +1 -0
  18. package/dist/components/ui/filter-search/filter-search.js +184 -138
  19. package/dist/components/ui/filter-search/filter-search.js.map +1 -1
  20. package/dist/components/ui/fitted-actions/fitted-actions.js +139 -0
  21. package/dist/components/ui/fitted-actions/fitted-actions.js.map +1 -0
  22. package/dist/components/ui/input-date-picker/input-date-picker.js +103 -93
  23. package/dist/components/ui/input-date-picker/input-date-picker.js.map +1 -1
  24. package/dist/components/ui/input-password/input-password.js +76 -66
  25. package/dist/components/ui/input-password/input-password.js.map +1 -1
  26. package/dist/components/ui/input-search/input-search.js +9 -9
  27. package/dist/components/ui/input-search/input-search.js.map +1 -1
  28. package/dist/components/ui/input-select/input-select.js +8 -8
  29. package/dist/components/ui/input-select/input-select.js.map +1 -1
  30. package/dist/components/ui/input-text/input-text.js +77 -66
  31. package/dist/components/ui/input-text/input-text.js.map +1 -1
  32. package/dist/components/ui/input-text-area/input-text-area.js +76 -66
  33. package/dist/components/ui/input-text-area/input-text-area.js.map +1 -1
  34. package/dist/components/ui/link/link.js +50 -35
  35. package/dist/components/ui/link/link.js.map +1 -1
  36. package/dist/components/ui/number-field/number-field.js +1 -1
  37. package/dist/components/ui/number-field/number-field.js.map +1 -1
  38. package/dist/components/ui/popover/popover.js +75 -56
  39. package/dist/components/ui/popover/popover.js.map +1 -1
  40. package/dist/components/ui/scroll-area/scroll-area.js +46 -30
  41. package/dist/components/ui/scroll-area/scroll-area.js.map +1 -1
  42. package/dist/components/ui/timer/timer.js +47 -0
  43. package/dist/components/ui/timer/timer.js.map +1 -0
  44. package/dist/components/ui/toast/toast.js +168 -61
  45. package/dist/components/ui/toast/toast.js.map +1 -1
  46. package/dist/components/ui/truncate-text/middle-truncate.js +20 -0
  47. package/dist/components/ui/truncate-text/middle-truncate.js.map +1 -0
  48. package/dist/components/ui/truncate-text/text-width.js +12 -0
  49. package/dist/components/ui/truncate-text/text-width.js.map +1 -0
  50. package/dist/components/ui/truncate-text/truncate-text.js +152 -0
  51. package/dist/components/ui/truncate-text/truncate-text.js.map +1 -0
  52. package/dist/index.js +505 -473
  53. package/dist/index.js.map +1 -1
  54. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/addDays.js +5 -5
  55. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/addDays.js.map +1 -1
  56. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/constants.js +3 -6
  57. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/constants.js.map +1 -1
  58. package/dist/react.js +505 -473
  59. package/dist/react.js.map +1 -1
  60. package/dist/src/components/ui/alert/alert.d.ts +34 -3
  61. package/dist/src/components/ui/alert/index.d.ts +2 -2
  62. package/dist/src/components/ui/button/button.d.ts +1 -1
  63. package/dist/src/components/ui/button-group/button-group.d.ts +38 -0
  64. package/dist/src/components/ui/button-group/index.d.ts +1 -0
  65. package/dist/src/components/ui/button-icon/button-icon.d.ts +1 -1
  66. package/dist/src/components/ui/button-icon-menu/button-icon-menu.d.ts +28 -0
  67. package/dist/src/components/ui/button-icon-menu/index.d.ts +1 -0
  68. package/dist/src/components/ui/button-menu/button-menu.d.ts +1 -1
  69. package/dist/src/components/ui/calendar-panel/calendar-panel.d.ts +2 -2
  70. package/dist/src/components/ui/chip/chip.d.ts +1 -1
  71. package/dist/src/components/ui/date-range-picker/date-range-picker-utils.d.ts +10 -16
  72. package/dist/src/components/ui/date-range-picker/date-range-picker.d.ts +46 -2
  73. package/dist/src/components/ui/dropdown-menu/dropdown-menu.d.ts +8 -1
  74. package/dist/src/components/ui/dropdown-menu/index.d.ts +1 -1
  75. package/dist/src/components/ui/filter-chips/filter-chips.d.ts +25 -0
  76. package/dist/src/components/ui/filter-chips/index.d.ts +1 -0
  77. package/dist/src/components/ui/filter-search/filter-search.d.ts +39 -1
  78. package/dist/src/components/ui/fitted-actions/fitted-actions.d.ts +50 -0
  79. package/dist/src/components/ui/fitted-actions/fitted-actions.docs.d.ts +45 -0
  80. package/dist/src/components/ui/fitted-actions/index.d.ts +1 -0
  81. package/dist/src/components/ui/link/index.d.ts +1 -1
  82. package/dist/src/components/ui/link/link.d.ts +22 -4
  83. package/dist/src/components/ui/metric/metric.d.ts +1 -1
  84. package/dist/src/components/ui/popover/popover.d.ts +30 -1
  85. package/dist/src/components/ui/popover/popover.docs.d.ts +27 -2
  86. package/dist/src/components/ui/scroll-area/scroll-area.d.ts +24 -0
  87. package/dist/src/components/ui/tag/tag.d.ts +1 -1
  88. package/dist/src/components/ui/timer/index.d.ts +1 -0
  89. package/dist/src/components/ui/timer/timer.d.ts +28 -0
  90. package/dist/src/components/ui/toast/index.d.ts +1 -1
  91. package/dist/src/components/ui/toast/toast.d.ts +51 -18
  92. package/dist/src/components/ui/toast/toast.docs.d.ts +4 -0
  93. package/dist/src/components/ui/trend-indicator/trend-indicator.d.ts +1 -1
  94. package/dist/src/components/ui/truncate-text/__tests__/middle-truncate.test.d.ts +1 -0
  95. package/dist/src/components/ui/truncate-text/index.d.ts +3 -0
  96. package/dist/src/components/ui/truncate-text/middle-truncate.d.ts +13 -0
  97. package/dist/src/components/ui/truncate-text/text-width.d.ts +11 -0
  98. package/dist/src/components/ui/truncate-text/truncate-text.d.ts +45 -0
  99. package/dist/src/components/ui/truncate-text/truncate-text.docs.d.ts +35 -0
  100. package/dist/src/index.d.ts +6 -0
  101. package/dist/ui-react.css +1 -1
  102. package/package.json +3 -3
  103. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/getDefaultOptions.js +0 -8
  104. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/getDefaultOptions.js.map +0 -1
  105. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/getISODay.js +0 -9
  106. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/getISODay.js.map +0 -1
  107. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/Parser.js +0 -23
  108. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/Parser.js.map +0 -1
  109. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/Setter.js +0 -42
  110. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/Setter.js.map +0 -1
  111. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/constants.js +0 -50
  112. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/constants.js.map +0 -1
  113. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/parsers/AMPMMidnightParser.js +0 -50
  114. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/parsers/AMPMMidnightParser.js.map +0 -1
  115. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/parsers/AMPMParser.js +0 -50
  116. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/parsers/AMPMParser.js.map +0 -1
  117. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/parsers/DateParser.js +0 -62
  118. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/parsers/DateParser.js.map +0 -1
  119. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/parsers/DayOfYearParser.js +0 -52
  120. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/parsers/DayOfYearParser.js.map +0 -1
  121. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/parsers/DayParser.js +0 -50
  122. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/parsers/DayParser.js.map +0 -1
  123. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/parsers/DayPeriodParser.js +0 -50
  124. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/parsers/DayPeriodParser.js.map +0 -1
  125. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/parsers/EraParser.js +0 -34
  126. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/parsers/EraParser.js.map +0 -1
  127. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/parsers/ExtendedYearParser.js +0 -22
  128. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/parsers/ExtendedYearParser.js.map +0 -1
  129. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/parsers/FractionOfSecondParser.js +0 -23
  130. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/parsers/FractionOfSecondParser.js.map +0 -1
  131. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/parsers/Hour0To11Parser.js +0 -33
  132. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/parsers/Hour0To11Parser.js.map +0 -1
  133. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/parsers/Hour0to23Parser.js +0 -33
  134. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/parsers/Hour0to23Parser.js.map +0 -1
  135. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/parsers/Hour1To24Parser.js +0 -34
  136. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/parsers/Hour1To24Parser.js.map +0 -1
  137. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/parsers/Hour1to12Parser.js +0 -34
  138. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/parsers/Hour1to12Parser.js.map +0 -1
  139. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/parsers/ISODayParser.js +0 -106
  140. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/parsers/ISODayParser.js.map +0 -1
  141. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/parsers/ISOTimezoneParser.js +0 -49
  142. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/parsers/ISOTimezoneParser.js.map +0 -1
  143. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/parsers/ISOTimezoneWithZParser.js +0 -49
  144. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/parsers/ISOTimezoneWithZParser.js.map +0 -1
  145. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/parsers/ISOWeekParser.js +0 -50
  146. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/parsers/ISOWeekParser.js.map +0 -1
  147. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/parsers/ISOWeekYearParser.js +0 -41
  148. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/parsers/ISOWeekYearParser.js.map +0 -1
  149. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/parsers/LocalDayParser.js +0 -81
  150. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/parsers/LocalDayParser.js.map +0 -1
  151. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/parsers/LocalWeekParser.js +0 -49
  152. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/parsers/LocalWeekParser.js.map +0 -1
  153. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/parsers/LocalWeekYearParser.js +0 -70
  154. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/parsers/LocalWeekYearParser.js.map +0 -1
  155. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/parsers/MinuteParser.js +0 -33
  156. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/parsers/MinuteParser.js.map +0 -1
  157. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/parsers/MonthParser.js +0 -78
  158. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/parsers/MonthParser.js.map +0 -1
  159. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/parsers/QuarterParser.js +0 -76
  160. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/parsers/QuarterParser.js.map +0 -1
  161. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/parsers/SecondParser.js +0 -33
  162. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/parsers/SecondParser.js.map +0 -1
  163. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/parsers/StandAloneLocalDayParser.js +0 -81
  164. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/parsers/StandAloneLocalDayParser.js.map +0 -1
  165. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/parsers/StandAloneMonthParser.js +0 -78
  166. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/parsers/StandAloneMonthParser.js.map +0 -1
  167. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/parsers/StandAloneQuarterParser.js +0 -76
  168. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/parsers/StandAloneQuarterParser.js.map +0 -1
  169. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/parsers/TimestampMillisecondsParser.js +0 -23
  170. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/parsers/TimestampMillisecondsParser.js.map +0 -1
  171. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/parsers/TimestampSecondsParser.js +0 -23
  172. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/parsers/TimestampSecondsParser.js.map +0 -1
  173. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/parsers/YearParser.js +0 -50
  174. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/parsers/YearParser.js.map +0 -1
  175. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/parsers.js +0 -68
  176. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/parsers.js.map +0 -1
  177. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/utils.js +0 -104
  178. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/utils.js.map +0 -1
  179. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse.js +0 -86
  180. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse.js.map +0 -1
  181. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/setDay.js +0 -12
  182. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/setDay.js.map +0 -1
  183. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/setISODay.js +0 -11
  184. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/setISODay.js.map +0 -1
  185. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/setISOWeek.js +0 -10
  186. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/setISOWeek.js.map +0 -1
  187. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/setWeek.js +0 -10
  188. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/setWeek.js.map +0 -1
  189. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/transpose.js +0 -18
  190. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/transpose.js.map +0 -1
@@ -1,99 +1,157 @@
1
- import { jsx as s } from "react/jsx-runtime";
2
- import * as e from "react";
3
- import { cva as i } from "../../../node_modules/.pnpm/class-variance-authority@0.7.1/node_modules/class-variance-authority/dist/index.js";
4
- import { cn as o } from "../../../lib/utils.js";
5
- const l = i(
6
- "relative flex w-full items-start gap-3 rounded-md border p-4 text-foreground",
1
+ import { jsx as t } from "react/jsx-runtime";
2
+ import * as o from "react";
3
+ import { cva as d } from "../../../node_modules/.pnpm/class-variance-authority@0.7.1/node_modules/class-variance-authority/dist/index.js";
4
+ import { TimesIcon as g } from "@acronis-platform/icons-react/stroke-mono";
5
+ import { DiamondWarningRedIcon as f, CircleWarningOrangeIcon as b, TriangleWarningYellowIcon as p, CircleCheckGreenIcon as u, CircleInfoBlueIcon as v } from "@acronis-platform/icons-react/stroke-multi";
6
+ import { cn as l } from "../../../lib/utils.js";
7
+ import { ButtonIcon as m } from "../button-icon/button-icon.js";
8
+ const x = d(
9
+ "relative flex w-full items-start overflow-clip [overflow-clip-margin:border-box] border-solid min-w-[var(--ui-alert-global-container-width-min)] gap-[var(--ui-alert-global-container-gap)] px-[var(--ui-alert-global-container-padding-x)] py-[var(--ui-alert-global-container-padding-y)] rounded-[var(--ui-alert-global-container-border-radius)] border-[length:var(--ui-alert-global-container-border-width)] bg-[var(--ui-alert-global-container-background)] before:absolute before:content-[''] before:-inset-y-px before:start-[-1px] before:w-[var(--ui-alert-global-container-status-width)]",
7
10
  {
8
11
  variants: {
9
12
  variant: {
10
- info: "border-[var(--ui-background-status-strong-info)] bg-[var(--ui-background-status-info)] [&_[data-slot=alert-icon]]:text-[var(--ui-background-status-strong-info)]",
11
- success: "border-[var(--ui-background-status-strong-success)] bg-[var(--ui-background-status-success)] [&_[data-slot=alert-icon]]:text-[var(--ui-background-status-strong-success)]",
12
- warning: "border-[var(--ui-background-status-strong-warning)] bg-[var(--ui-background-status-warning)] [&_[data-slot=alert-icon]]:text-[var(--ui-background-status-strong-warning)]",
13
- critical: "border-[var(--ui-background-status-strong-critical)] bg-[var(--ui-background-status-critical)] [&_[data-slot=alert-icon]]:text-[var(--ui-background-status-strong-critical)]",
14
- destructive: "border-[var(--ui-background-status-strong-danger)] bg-[var(--ui-background-status-danger)] [&_[data-slot=alert-icon]]:text-[var(--ui-background-status-strong-danger)]",
15
- ai: "border-[var(--ui-text-on-status-ai)] bg-[var(--ui-background-status-ai)] [&_[data-slot=alert-icon]]:text-[var(--ui-text-on-status-ai)]",
16
- neutral: "border-[var(--ui-background-status-strong-neutral)] bg-[var(--ui-background-status-neutral)] [&_[data-slot=alert-icon]]:text-[var(--ui-background-status-strong-neutral)]"
13
+ info: "border-[color:var(--ui-alert-info-border-color)] before:bg-[var(--ui-alert-info-left-line)]",
14
+ success: "border-[color:var(--ui-alert-success-border-color)] before:bg-[var(--ui-alert-success-left-line)]",
15
+ warning: "border-[color:var(--ui-alert-warning-border-color)] before:bg-[var(--ui-alert-warning-left-line)]",
16
+ critical: "border-[color:var(--ui-alert-critical-border-color)] before:bg-[var(--ui-alert-critical-left-line)]",
17
+ danger: "border-[color:var(--ui-alert-danger-border-color)] before:bg-[var(--ui-alert-danger-left-line)]"
17
18
  }
18
19
  },
19
20
  defaultVariants: {
20
21
  variant: "info"
21
22
  }
22
23
  }
23
- ), u = e.forwardRef(
24
- ({ className: t, variant: a, ...r }, n) => /* @__PURE__ */ s(
24
+ ), w = {
25
+ info: v,
26
+ success: u,
27
+ warning: p,
28
+ critical: b,
29
+ danger: f
30
+ }, i = o.createContext("info"), y = o.forwardRef(
31
+ ({ className: r, variant: a, ...e }, n) => /* @__PURE__ */ t(i.Provider, { value: a ?? "info", children: /* @__PURE__ */ t(
25
32
  "div",
26
33
  {
27
34
  ref: n,
28
35
  role: "alert",
29
36
  "data-slot": "alert",
30
- className: o(l({ variant: a }), t),
31
- ...r
37
+ "data-variant": a ?? "info",
38
+ className: l(x({ variant: a }), r),
39
+ ...e
32
40
  }
33
- )
41
+ ) })
34
42
  );
35
- u.displayName = "Alert";
36
- const c = e.forwardRef(({ className: t, ...a }, r) => (
37
- // Color is set by the Alert variant (targets [data-slot=alert-icon]). The icon
38
- // sits in a line-height-matched box (h-6 = leading-6) and is centered in it, so
39
- // it optically aligns with the first line of the title/description.
40
- /* @__PURE__ */ s(
41
- "div",
42
- {
43
- ref: r,
44
- "data-slot": "alert-icon",
45
- className: o("flex h-6 shrink-0 items-center", t),
46
- ...a
47
- }
48
- )
49
- ));
50
- c.displayName = "AlertIcon";
51
- const d = e.forwardRef(({ className: t, ...a }, r) => /* @__PURE__ */ s(
43
+ y.displayName = "Alert";
44
+ const A = o.forwardRef(({ className: r, children: a, ...e }, n) => {
45
+ const c = o.useContext(i), s = w[c];
46
+ return (
47
+ // The icon box's padding (4/8) is what optically aligns the 16px glyph with
48
+ // the first line of the title: glyph centre 8 + 8 = 16, title centre
49
+ // (AlertText's 4px padding) 4 + 12 = 16.
50
+ /* @__PURE__ */ t(
51
+ "div",
52
+ {
53
+ ref: n,
54
+ "data-slot": "alert-icon",
55
+ className: l(
56
+ "flex shrink-0 items-start px-[var(--ui-alert-global-icon-padding-x)] py-[var(--ui-alert-global-icon-padding-y)] [&_svg]:size-[var(--ui-alert-global-icon-size)] [&_svg]:shrink-0",
57
+ r
58
+ ),
59
+ ...e,
60
+ children: a ?? /* @__PURE__ */ t(s, { size: 16 })
61
+ }
62
+ )
63
+ );
64
+ });
65
+ A.displayName = "AlertIcon";
66
+ const h = o.forwardRef(({ className: r, ...a }, e) => /* @__PURE__ */ t(
52
67
  "div",
53
68
  {
54
- ref: r,
69
+ ref: e,
55
70
  "data-slot": "alert-content",
56
- className: o("flex min-w-0 flex-1 flex-col gap-0.5", t),
71
+ className: l(
72
+ "flex min-w-0 flex-1 flex-col items-start gap-[var(--ui-alert-global-content-gap)] px-[var(--ui-alert-global-content-padding-x)] py-[var(--ui-alert-global-content-padding-y)]",
73
+ r
74
+ ),
75
+ ...a
76
+ }
77
+ ));
78
+ h.displayName = "AlertContent";
79
+ const N = o.forwardRef(({ className: r, ...a }, e) => /* @__PURE__ */ t(
80
+ "div",
81
+ {
82
+ ref: e,
83
+ "data-slot": "alert-text",
84
+ className: l(
85
+ "flex w-full shrink-0 flex-col items-start gap-[var(--ui-alert-global-content-text-container-gap)] px-[var(--ui-alert-global-content-text-container-padding-x)] py-[var(--ui-alert-global-content-text-container-padding-y)] [word-break:break-word]",
86
+ r
87
+ ),
57
88
  ...a
58
89
  }
59
90
  ));
60
- d.displayName = "AlertContent";
61
- const g = e.forwardRef(({ className: t, ...a }, r) => /* @__PURE__ */ s(
91
+ N.displayName = "AlertText";
92
+ const C = o.forwardRef(({ className: r, ...a }, e) => /* @__PURE__ */ t(
62
93
  "h5",
63
94
  {
64
- ref: r,
95
+ ref: e,
65
96
  "data-slot": "alert-title",
66
- className: o("mb-0 text-sm font-semibold leading-6", t),
97
+ className: l(
98
+ "ui-typography-headings-lead mb-0 w-full text-[var(--ui-alert-global-content-text-container-title-color)]",
99
+ r
100
+ ),
67
101
  ...a
68
102
  }
69
103
  ));
70
- g.displayName = "AlertTitle";
71
- const b = e.forwardRef(({ className: t, ...a }, r) => /* @__PURE__ */ s(
72
- "div",
104
+ C.displayName = "AlertTitle";
105
+ const I = o.forwardRef(({ className: r, ...a }, e) => /* @__PURE__ */ t(
106
+ "p",
73
107
  {
74
- ref: r,
108
+ ref: e,
75
109
  "data-slot": "alert-description",
76
- className: o("text-sm font-normal leading-6", t),
110
+ className: l(
111
+ "ui-alert-global-content-text-container-description-text-style w-full text-[var(--ui-alert-global-content-text-container-description-color)]",
112
+ r
113
+ ),
77
114
  ...a
78
115
  }
79
116
  ));
80
- b.displayName = "AlertDescription";
81
- const f = e.forwardRef(({ className: t, ...a }, r) => /* @__PURE__ */ s(
117
+ I.displayName = "AlertDescription";
118
+ const R = o.forwardRef(({ className: r, ...a }, e) => /* @__PURE__ */ t(
82
119
  "div",
83
120
  {
84
- ref: r,
121
+ ref: e,
85
122
  "data-slot": "alert-actions",
86
- className: o("flex items-center gap-2", t),
123
+ className: l(
124
+ "flex w-full shrink-0 flex-wrap content-start items-start gap-x-[var(--ui-alert-global-content-actions-container-gap-x)] gap-y-[var(--ui-alert-global-content-actions-container-gap-y)] px-[var(--ui-alert-global-content-actions-container-padding-x)] py-[var(--ui-alert-global-content-actions-container-padding-y)]",
125
+ r
126
+ ),
87
127
  ...a
88
128
  }
89
129
  ));
90
- f.displayName = "AlertActions";
130
+ R.displayName = "AlertActions";
131
+ const k = o.forwardRef(
132
+ ({ className: r, ariaLabel: a = "Close", ...e }, n) => /* @__PURE__ */ t(
133
+ m,
134
+ {
135
+ ref: n,
136
+ "data-slot": "alert-close",
137
+ className: l("shrink-0", r),
138
+ ...e,
139
+ variant: "ghost",
140
+ "aria-label": a,
141
+ children: /* @__PURE__ */ t(g, {})
142
+ }
143
+ )
144
+ );
145
+ k.displayName = "AlertClose";
91
146
  export {
92
- u as Alert,
93
- f as AlertActions,
94
- d as AlertContent,
95
- b as AlertDescription,
96
- c as AlertIcon,
97
- g as AlertTitle
147
+ y as Alert,
148
+ R as AlertActions,
149
+ k as AlertClose,
150
+ h as AlertContent,
151
+ I as AlertDescription,
152
+ A as AlertIcon,
153
+ N as AlertText,
154
+ C as AlertTitle,
155
+ x as alertVariants
98
156
  };
99
157
  //# sourceMappingURL=alert.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"alert.js","sources":["../../../../src/components/ui/alert/alert.tsx"],"sourcesContent":["import * as React from 'react';\nimport { cva, type VariantProps } from 'class-variance-authority';\n\nimport { cn } from '@/lib/utils';\n\n// Ported from `@acronis-platform/shadcn-uikit`'s `alert`\n// (packages/ui-legacy/src/components/ui/alert.tsx) and reconciled with the Figma\n// design (node 5337-71774): a rounded banner with a *full* border in the strong\n// status color, a pale status surface, foreground text, and only the icon tinted\n// with the status color. No Base UI primitive — semantic markup with\n// `role=\"alert\"`. Each variant maps to the `--ui-*` status tokens: the pale\n// surface (`--ui-background-status-*`) + the saturated border/icon\n// (`--ui-background-status-strong-*`). `destructive` uses the danger tokens; `ai`\n// has no `strong` surface token, so it uses its solid text token for the\n// border + icon.\nconst alertVariants = cva(\n 'relative flex w-full items-start gap-3 rounded-md border p-4 text-foreground',\n {\n variants: {\n variant: {\n info: 'border-[var(--ui-background-status-strong-info)] bg-[var(--ui-background-status-info)] [&_[data-slot=alert-icon]]:text-[var(--ui-background-status-strong-info)]',\n success:\n 'border-[var(--ui-background-status-strong-success)] bg-[var(--ui-background-status-success)] [&_[data-slot=alert-icon]]:text-[var(--ui-background-status-strong-success)]',\n warning:\n 'border-[var(--ui-background-status-strong-warning)] bg-[var(--ui-background-status-warning)] [&_[data-slot=alert-icon]]:text-[var(--ui-background-status-strong-warning)]',\n critical:\n 'border-[var(--ui-background-status-strong-critical)] bg-[var(--ui-background-status-critical)] [&_[data-slot=alert-icon]]:text-[var(--ui-background-status-strong-critical)]',\n destructive:\n 'border-[var(--ui-background-status-strong-danger)] bg-[var(--ui-background-status-danger)] [&_[data-slot=alert-icon]]:text-[var(--ui-background-status-strong-danger)]',\n ai: 'border-[var(--ui-text-on-status-ai)] bg-[var(--ui-background-status-ai)] [&_[data-slot=alert-icon]]:text-[var(--ui-text-on-status-ai)]',\n neutral:\n 'border-[var(--ui-background-status-strong-neutral)] bg-[var(--ui-background-status-neutral)] [&_[data-slot=alert-icon]]:text-[var(--ui-background-status-strong-neutral)]',\n },\n },\n defaultVariants: {\n variant: 'info',\n },\n }\n);\n\nexport interface AlertProps\n extends React.HTMLAttributes<HTMLDivElement>,\n VariantProps<typeof alertVariants> {}\n\nconst Alert = React.forwardRef<HTMLDivElement, AlertProps>(\n ({ className, variant, ...props }, ref) => (\n <div\n ref={ref}\n role=\"alert\"\n data-slot=\"alert\"\n className={cn(alertVariants({ variant }), className)}\n {...props}\n />\n )\n);\nAlert.displayName = 'Alert';\n\nconst AlertIcon = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes<HTMLDivElement>\n>(({ className, ...props }, ref) => (\n // Color is set by the Alert variant (targets [data-slot=alert-icon]). The icon\n // sits in a line-height-matched box (h-6 = leading-6) and is centered in it, so\n // it optically aligns with the first line of the title/description.\n <div\n ref={ref}\n data-slot=\"alert-icon\"\n className={cn('flex h-6 shrink-0 items-center', className)}\n {...props}\n />\n));\nAlertIcon.displayName = 'AlertIcon';\n\nconst AlertContent = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes<HTMLDivElement>\n>(({ className, ...props }, ref) => (\n <div\n ref={ref}\n data-slot=\"alert-content\"\n className={cn('flex min-w-0 flex-1 flex-col gap-0.5', className)}\n {...props}\n />\n));\nAlertContent.displayName = 'AlertContent';\n\nconst AlertTitle = React.forwardRef<\n HTMLHeadingElement,\n React.HTMLAttributes<HTMLHeadingElement>\n>(({ className, ...props }, ref) => (\n <h5\n ref={ref}\n data-slot=\"alert-title\"\n className={cn('mb-0 text-sm font-semibold leading-6', className)}\n {...props}\n />\n));\nAlertTitle.displayName = 'AlertTitle';\n\nconst AlertDescription = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes<HTMLDivElement>\n>(({ className, ...props }, ref) => (\n <div\n ref={ref}\n data-slot=\"alert-description\"\n className={cn('text-sm font-normal leading-6', className)}\n {...props}\n />\n));\nAlertDescription.displayName = 'AlertDescription';\n\n// Action slot for alert buttons. Two placements (see the Figma): as a direct\n// child of Alert after AlertContent it sits at the right edge (AlertContent is\n// flex-1) — add `self-center` to center it vertically; placed inside AlertContent\n// (under the description) it flows below the text.\nconst AlertActions = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes<HTMLDivElement>\n>(({ className, ...props }, ref) => (\n <div\n ref={ref}\n data-slot=\"alert-actions\"\n className={cn('flex items-center gap-2', className)}\n {...props}\n />\n));\nAlertActions.displayName = 'AlertActions';\n\nexport {\n Alert,\n AlertIcon,\n AlertContent,\n AlertTitle,\n AlertDescription,\n AlertActions,\n};\n"],"names":["alertVariants","cva","Alert","React","className","variant","props","ref","jsx","cn","AlertIcon","AlertContent","AlertTitle","AlertDescription","AlertActions"],"mappings":";;;;AAeA,MAAMA,IAAgBC;AAAA,EACpB;AAAA,EACA;AAAA,IACE,UAAU;AAAA,MACR,SAAS;AAAA,QACP,MAAM;AAAA,QACN,SACE;AAAA,QACF,SACE;AAAA,QACF,UACE;AAAA,QACF,aACE;AAAA,QACF,IAAI;AAAA,QACJ,SACE;AAAA,MAAA;AAAA,IACJ;AAAA,IAEF,iBAAiB;AAAA,MACf,SAAS;AAAA,IAAA;AAAA,EACX;AAEJ,GAMMC,IAAQC,EAAM;AAAA,EAClB,CAAC,EAAE,WAAAC,GAAW,SAAAC,GAAS,GAAGC,EAAA,GAASC,MACjC,gBAAAC;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,KAAAD;AAAA,MACA,MAAK;AAAA,MACL,aAAU;AAAA,MACV,WAAWE,EAAGT,EAAc,EAAE,SAAAK,EAAA,CAAS,GAAGD,CAAS;AAAA,MAClD,GAAGE;AAAA,IAAA;AAAA,EAAA;AAGV;AACAJ,EAAM,cAAc;AAEpB,MAAMQ,IAAYP,EAAM,WAGtB,CAAC,EAAE,WAAAC,GAAW,GAAGE,KAASC;AAAA;AAAA;AAAA;AAAA,EAI1B,gBAAAC;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,KAAAD;AAAA,MACA,aAAU;AAAA,MACV,WAAWE,EAAG,kCAAkCL,CAAS;AAAA,MACxD,GAAGE;AAAA,IAAA;AAAA,EAAA;AAAA,CAEP;AACDI,EAAU,cAAc;AAExB,MAAMC,IAAeR,EAAM,WAGzB,CAAC,EAAE,WAAAC,GAAW,GAAGE,EAAA,GAASC,MAC1B,gBAAAC;AAAA,EAAC;AAAA,EAAA;AAAA,IACC,KAAAD;AAAA,IACA,aAAU;AAAA,IACV,WAAWE,EAAG,wCAAwCL,CAAS;AAAA,IAC9D,GAAGE;AAAA,EAAA;AACN,CACD;AACDK,EAAa,cAAc;AAE3B,MAAMC,IAAaT,EAAM,WAGvB,CAAC,EAAE,WAAAC,GAAW,GAAGE,EAAA,GAASC,MAC1B,gBAAAC;AAAA,EAAC;AAAA,EAAA;AAAA,IACC,KAAAD;AAAA,IACA,aAAU;AAAA,IACV,WAAWE,EAAG,wCAAwCL,CAAS;AAAA,IAC9D,GAAGE;AAAA,EAAA;AACN,CACD;AACDM,EAAW,cAAc;AAEzB,MAAMC,IAAmBV,EAAM,WAG7B,CAAC,EAAE,WAAAC,GAAW,GAAGE,EAAA,GAASC,MAC1B,gBAAAC;AAAA,EAAC;AAAA,EAAA;AAAA,IACC,KAAAD;AAAA,IACA,aAAU;AAAA,IACV,WAAWE,EAAG,iCAAiCL,CAAS;AAAA,IACvD,GAAGE;AAAA,EAAA;AACN,CACD;AACDO,EAAiB,cAAc;AAM/B,MAAMC,IAAeX,EAAM,WAGzB,CAAC,EAAE,WAAAC,GAAW,GAAGE,EAAA,GAASC,MAC1B,gBAAAC;AAAA,EAAC;AAAA,EAAA;AAAA,IACC,KAAAD;AAAA,IACA,aAAU;AAAA,IACV,WAAWE,EAAG,2BAA2BL,CAAS;AAAA,IACjD,GAAGE;AAAA,EAAA;AACN,CACD;AACDQ,EAAa,cAAc;"}
1
+ {"version":3,"file":"alert.js","sources":["../../../../src/components/ui/alert/alert.tsx"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { TimesIcon } from '@acronis-platform/icons-react/stroke-mono';\nimport {\n CircleCheckGreenIcon,\n CircleInfoBlueIcon,\n CircleWarningOrangeIcon,\n DiamondWarningRedIcon,\n TriangleWarningYellowIcon,\n type IconProps,\n} from '@acronis-platform/icons-react/stroke-multi';\n\nimport { cn } from '@/lib/utils';\nimport { ButtonIcon, type ButtonIconProps } from '../button-icon';\n\n// Mirrors the Figma \"Alert\" component set (node 7421:125155). The banner is a\n// *neutral* surface — not a status tint — with the severity carried by two\n// things: a 1px border in the status color and a 6px status line down the\n// leading edge. Geometry, colors, and spacing all come from the dedicated\n// `--ui-alert-*` tier (imported in `src/styles/index.css`).\n//\n// The status line is a `::before` pseudo-element rather than a DOM node: it is\n// never optional and never a slot, so a real element would only add markup for\n// consumers to get wrong. It is bled 1px outwards on three sides so it paints\n// *over* the border it sits on (matching the Figma, where the line covers the\n// leading border), and the root's clip rounds its square corners to the\n// container radius. `start-` keeps it on the leading edge under `dir=\"rtl\"`.\n//\n// `overflow-clip-margin: border-box` is load-bearing, not decoration. `overflow:\n// clip` alone clips at the *padding* box, which is exactly where the bleed has to\n// reach — and an absolutely positioned pseudo-element's containing block is that\n// same padding box — so the outward 1px gets shaved off and the line renders 5px\n// wide starting *inside* the border. Since the border and the line are different\n// tokens, that reads as two adjacent stripes rather than one 6px line. Moving the\n// clip edge out to the border box lets the bleed survive while still rounding the\n// corners.\n//\n// Typography comes from the generated classes: `ui-typography-headings-lead` for\n// the title (Inter Regular 18 / 24) and the Alert tier's own emitted class for the\n// description (Inter Regular 14 / 24) — the same pair Toast uses, since the two are\n// the same card. Only the *colors* are separate token references. Every other value\n// is a `var(--ui-alert-*)` reference, so a brand override is honored without\n// touching this file.\nconst alertVariants = cva(\n 'relative flex w-full items-start overflow-clip [overflow-clip-margin:border-box] border-solid ' +\n 'min-w-[var(--ui-alert-global-container-width-min)] ' +\n 'gap-[var(--ui-alert-global-container-gap)] ' +\n 'px-[var(--ui-alert-global-container-padding-x)] py-[var(--ui-alert-global-container-padding-y)] ' +\n 'rounded-[var(--ui-alert-global-container-border-radius)] ' +\n 'border-[length:var(--ui-alert-global-container-border-width)] ' +\n 'bg-[var(--ui-alert-global-container-background)] ' +\n \"before:absolute before:content-[''] before:-inset-y-px before:start-[-1px] \" +\n 'before:w-[var(--ui-alert-global-container-status-width)]',\n {\n variants: {\n variant: {\n info: 'border-[color:var(--ui-alert-info-border-color)] before:bg-[var(--ui-alert-info-left-line)]',\n success:\n 'border-[color:var(--ui-alert-success-border-color)] before:bg-[var(--ui-alert-success-left-line)]',\n warning:\n 'border-[color:var(--ui-alert-warning-border-color)] before:bg-[var(--ui-alert-warning-left-line)]',\n critical:\n 'border-[color:var(--ui-alert-critical-border-color)] before:bg-[var(--ui-alert-critical-left-line)]',\n danger:\n 'border-[color:var(--ui-alert-danger-border-color)] before:bg-[var(--ui-alert-danger-left-line)]',\n },\n },\n defaultVariants: {\n variant: 'info',\n },\n }\n);\n\nexport type AlertVariant = NonNullable<\n VariantProps<typeof alertVariants>['variant']\n>;\n\n// The Figma binds exactly one icon to each variant, and they are multicolor\n// (`stroke-multi`) glyphs that carry their own fills — so unlike the previous\n// monocolor port, nothing here tints them.\nconst STATUS_ICON: Record<AlertVariant, React.ComponentType<IconProps>> = {\n info: CircleInfoBlueIcon,\n success: CircleCheckGreenIcon,\n warning: TriangleWarningYellowIcon,\n critical: CircleWarningOrangeIcon,\n danger: DiamondWarningRedIcon,\n};\n\nconst AlertVariantContext = React.createContext<AlertVariant>('info');\n\nexport interface AlertProps\n extends\n React.HTMLAttributes<HTMLDivElement>,\n VariantProps<typeof alertVariants> {}\n\n/**\n * A status banner: neutral surface, a status-colored border, and a status line\n * down the leading edge. Compose it from `AlertIcon`, `AlertContent`\n * (`AlertText` + `AlertTitle` / `AlertDescription`, optionally `AlertActions`)\n * and `AlertClose`.\n */\nconst Alert = React.forwardRef<HTMLDivElement, AlertProps>(\n ({ className, variant, ...props }, ref) => (\n <AlertVariantContext.Provider value={variant ?? 'info'}>\n <div\n ref={ref}\n role=\"alert\"\n data-slot=\"alert\"\n data-variant={variant ?? 'info'}\n className={cn(alertVariants({ variant }), className)}\n {...props}\n />\n </AlertVariantContext.Provider>\n )\n);\nAlert.displayName = 'Alert';\n\n/**\n * The leading status icon. Renders the variant's own icon when given no\n * `children`; pass children to substitute a different glyph.\n */\nconst AlertIcon = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes<HTMLDivElement>\n>(({ className, children, ...props }, ref) => {\n const variant = React.useContext(AlertVariantContext);\n const StatusIcon = STATUS_ICON[variant];\n return (\n // The icon box's padding (4/8) is what optically aligns the 16px glyph with\n // the first line of the title: glyph centre 8 + 8 = 16, title centre\n // (AlertText's 4px padding) 4 + 12 = 16.\n <div\n ref={ref}\n data-slot=\"alert-icon\"\n className={cn(\n 'flex shrink-0 items-start px-[var(--ui-alert-global-icon-padding-x)] py-[var(--ui-alert-global-icon-padding-y)] [&_svg]:size-[var(--ui-alert-global-icon-size)] [&_svg]:shrink-0',\n className\n )}\n {...props}\n >\n {children ?? <StatusIcon size={16} />}\n </div>\n );\n});\nAlertIcon.displayName = 'AlertIcon';\n\nconst AlertContent = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes<HTMLDivElement>\n>(({ className, ...props }, ref) => (\n <div\n ref={ref}\n data-slot=\"alert-content\"\n className={cn(\n 'flex min-w-0 flex-1 flex-col items-start gap-[var(--ui-alert-global-content-gap)] px-[var(--ui-alert-global-content-padding-x)] py-[var(--ui-alert-global-content-padding-y)]',\n className\n )}\n {...props}\n />\n));\nAlertContent.displayName = 'AlertContent';\n\n/**\n * The title + description block. Its own vertical padding is what keeps the\n * text aligned with the icon, so keep the title and description inside it\n * rather than directly under `AlertContent`.\n */\nconst AlertText = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes<HTMLDivElement>\n>(({ className, ...props }, ref) => (\n <div\n ref={ref}\n data-slot=\"alert-text\"\n className={cn(\n 'flex w-full shrink-0 flex-col items-start gap-[var(--ui-alert-global-content-text-container-gap)] px-[var(--ui-alert-global-content-text-container-padding-x)] py-[var(--ui-alert-global-content-text-container-padding-y)] [word-break:break-word]',\n className\n )}\n {...props}\n />\n));\nAlertText.displayName = 'AlertText';\n\nconst AlertTitle = React.forwardRef<\n HTMLHeadingElement,\n React.HTMLAttributes<HTMLHeadingElement>\n>(({ className, ...props }, ref) => (\n <h5\n ref={ref}\n data-slot=\"alert-title\"\n className={cn(\n 'ui-typography-headings-lead mb-0 w-full text-[var(--ui-alert-global-content-text-container-title-color)]',\n className\n )}\n {...props}\n />\n));\nAlertTitle.displayName = 'AlertTitle';\n\nconst AlertDescription = React.forwardRef<\n HTMLParagraphElement,\n React.HTMLAttributes<HTMLParagraphElement>\n>(({ className, ...props }, ref) => (\n <p\n ref={ref}\n data-slot=\"alert-description\"\n className={cn(\n 'ui-alert-global-content-text-container-description-text-style w-full text-[var(--ui-alert-global-content-text-container-description-color)]',\n className\n )}\n {...props}\n />\n));\nAlertDescription.displayName = 'AlertDescription';\n\n/**\n * Action buttons under the text. Place inside `AlertContent` (after\n * `AlertText`), as the Figma does — the row wraps when it runs out of width.\n */\nconst AlertActions = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes<HTMLDivElement>\n>(({ className, ...props }, ref) => (\n <div\n ref={ref}\n data-slot=\"alert-actions\"\n className={cn(\n 'flex w-full shrink-0 flex-wrap content-start items-start gap-x-[var(--ui-alert-global-content-actions-container-gap-x)] gap-y-[var(--ui-alert-global-content-actions-container-gap-y)] px-[var(--ui-alert-global-content-actions-container-padding-x)] py-[var(--ui-alert-global-content-actions-container-padding-y)]',\n className\n )}\n {...props}\n />\n));\nAlertActions.displayName = 'AlertActions';\n\n// The spec pins this control to a ghost ButtonIcon with a times glyph, so the\n// props that would change that are omitted from the type instead of merely being\n// defaulted — `...props` spreads after them, so keeping them would let\n// `<AlertClose variant=\"secondary\" />` silently win over the documented behavior.\n//\n// `aria-label` needs the belt *and* braces. Omitting it from the type is not\n// enough: TypeScript deliberately skips checking hyphenated JSX attributes (the\n// same rule that lets `data-*` through), so `<AlertClose aria-label=\"X\" />` still\n// compiles. Pinning `aria-label` after the spread is what actually makes\n// `ariaLabel` authoritative.\nexport interface AlertCloseProps\n extends Omit<ButtonIconProps, 'children' | 'variant' | 'render' | 'aria-label'> {\n /** Accessible name for the dismiss control. */\n ariaLabel?: string;\n}\n\n/**\n * The trailing dismiss control. Rendering it is what makes an alert\n * dismissable — wire `onClick` to remove the alert. Name it with `ariaLabel`.\n */\nconst AlertClose = React.forwardRef<HTMLButtonElement, AlertCloseProps>(\n ({ className, ariaLabel = 'Close', ...props }, ref) => (\n <ButtonIcon\n ref={ref}\n data-slot=\"alert-close\"\n className={cn('shrink-0', className)}\n {...props}\n variant=\"ghost\"\n aria-label={ariaLabel}\n >\n <TimesIcon />\n </ButtonIcon>\n )\n);\nAlertClose.displayName = 'AlertClose';\n\nexport {\n Alert,\n AlertIcon,\n AlertContent,\n AlertText,\n AlertTitle,\n AlertDescription,\n AlertActions,\n AlertClose,\n alertVariants,\n};\n"],"names":["alertVariants","cva","STATUS_ICON","CircleInfoBlueIcon","CircleCheckGreenIcon","TriangleWarningYellowIcon","CircleWarningOrangeIcon","DiamondWarningRedIcon","AlertVariantContext","React","Alert","className","variant","props","ref","jsx","cn","AlertIcon","children","StatusIcon","AlertContent","AlertText","AlertTitle","AlertDescription","AlertActions","AlertClose","ariaLabel","ButtonIcon","TimesIcon"],"mappings":"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"}
@@ -0,0 +1,57 @@
1
+ import { jsx as e } from "react/jsx-runtime";
2
+ import * as n from "react";
3
+ import { Toolbar as u } from "@base-ui/react/toolbar";
4
+ import { cva as l } from "../../../node_modules/.pnpm/class-variance-authority@0.7.1/node_modules/class-variance-authority/dist/index.js";
5
+ import { cn as s } from "../../../lib/utils.js";
6
+ const b = l(
7
+ // `overflow-hidden` is load-bearing, not cosmetic: it clips the first/last
8
+ // item's hover/active fill and its inset focus ring to the container's own
9
+ // radius. Without it the square item corners poke out past the rounded box.
10
+ "inline-flex w-fit items-center overflow-hidden",
11
+ {
12
+ variants: {
13
+ variant: {
14
+ outlined: "rounded-[var(--ui-button-group-global-container-border-radius)] border-[length:var(--ui-button-group-global-container-border-width)] border-solid border-[color:var(--ui-button-group-global-container-border-color)]",
15
+ inlined: ""
16
+ }
17
+ },
18
+ defaultVariants: {
19
+ variant: "outlined"
20
+ }
21
+ }
22
+ ), d = l(
23
+ "inline-flex h-[var(--ui-button-group-global-box-height)] shrink-0 cursor-pointer items-center justify-center px-[var(--ui-button-group-global-box-padding-x)] py-[var(--ui-button-group-global-box-padding-y)] transition-colors bg-[var(--ui-button-group-global-box-color-idle)] text-[var(--ui-glyph-on-surface-primary)] border-solid border-[color:var(--ui-button-group-global-separator-color)] hover:bg-[var(--ui-button-group-global-box-color-hover)] active:bg-[var(--ui-button-group-global-box-color-active)] focus-visible:outline-none focus-visible:ring-[3px] focus-visible:ring-inset focus-visible:ring-[var(--ui-focus-primary)] data-[disabled]:pointer-events-none data-[disabled]:bg-[var(--ui-button-group-global-box-color-idle)] data-[disabled]:text-[var(--ui-glyph-on-surface-disabled)] [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0"
24
+ ), i = "border-e-[length:var(--ui-button-group-global-separator-border-width)]";
25
+ function g(o) {
26
+ return o === void 0 ? `${i} last:border-e-0` : o === "last" ? "" : i;
27
+ }
28
+ const p = n.forwardRef(
29
+ ({ className: o, variant: r, ...t }, a) => /* @__PURE__ */ e(
30
+ u.Root,
31
+ {
32
+ ref: a,
33
+ className: s(b({ variant: r, className: o })),
34
+ ...t
35
+ }
36
+ )
37
+ );
38
+ p.displayName = "ButtonGroup";
39
+ const c = n.forwardRef(({ className: o, order: r, ...t }, a) => /* @__PURE__ */ e(
40
+ u.Button,
41
+ {
42
+ ref: a,
43
+ className: s(
44
+ d({ className: g(r) }),
45
+ o
46
+ ),
47
+ ...t
48
+ }
49
+ ));
50
+ c.displayName = "ButtonGroupItem";
51
+ export {
52
+ p as ButtonGroup,
53
+ c as ButtonGroupItem,
54
+ d as buttonGroupItemVariants,
55
+ b as buttonGroupVariants
56
+ };
57
+ //# sourceMappingURL=button-group.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"button-group.js","sources":["../../../../src/components/ui/button-group/button-group.tsx"],"sourcesContent":["import * as React from 'react';\nimport {\n Toolbar as ToolbarPrimitive,\n type ToolbarButtonProps,\n type ToolbarRootProps,\n} from '@base-ui/react/toolbar';\nimport { cva, type VariantProps } from 'class-variance-authority';\n\nimport { cn } from '@/lib/utils';\n\n// Mirrors the Figma \"ButtonGroup\" component set (node 7975:3479) and its\n// \"ButtonGroupItem\" children (node 5558:17506): a compact cluster of icon-only\n// actions sharing one box, hairline-separated. The container's `variant`\n// (`outlined` / `inlined`) is the Figma variant property of the same name —\n// `outlined` draws the 1px container border + 4px radius, `inlined` draws\n// neither (for use inside a surface that already has its own chrome).\n//\n// Figma models the items' position as an `order` variant (first / middle /\n// last), which only ever controls whether the trailing separator is drawn.\n// That's derivable from the DOM, so it is NOT a prop here — `last:border-e-0`\n// drops the separator on the final item, which keeps the group variadic\n// (Figma's `ListItem` slot) instead of forcing callers to label positions.\n//\n// Built on Base UI's Toolbar so the cluster gets the WAI-ARIA toolbar pattern\n// for free: `role=\"toolbar\"`, a single Tab stop, and arrow-key roving tabindex\n// between the items. Base UI's `Toolbar.Root` doesn't forward\n// `enableHomeAndEndKeys` to its composite, so Home/End are unsupported — a Base\n// UI limitation, same as in `toolbar.tsx`.\nconst buttonGroupVariants = cva(\n // `overflow-hidden` is load-bearing, not cosmetic: it clips the first/last\n // item's hover/active fill and its inset focus ring to the container's own\n // radius. Without it the square item corners poke out past the rounded box.\n 'inline-flex w-fit items-center overflow-hidden',\n {\n variants: {\n variant: {\n outlined:\n 'rounded-[var(--ui-button-group-global-container-border-radius)] border-[length:var(--ui-button-group-global-container-border-width)] border-solid border-[color:var(--ui-button-group-global-container-border-color)]',\n inlined: '',\n },\n },\n defaultVariants: {\n variant: 'outlined',\n },\n }\n);\n\n// The focus ring is `ring-inset`: an outer ring would be clipped away by the\n// container's `overflow-hidden`. An inset box-shadow is clipped to the padding\n// edge, so the ring stops short of the 1px separator instead of painting over\n// it — which is exactly the 1px inset Figma's FocusRing layer draws by hand.\n//\n// Disabled is keyed off `data-[disabled]` rather than `:disabled` because the\n// item is never natively disabled (see `focusableWhenDisabled` below) — Base UI\n// exposes the state as `aria-disabled` + `data-disabled`, for a disabled item\n// and a disabled *group* alike. The design has no disabled state for this\n// component, so the glyph falls back to the shared\n// `--ui-glyph-on-surface-disabled` semantic token.\nconst buttonGroupItemVariants = cva(\n 'inline-flex h-[var(--ui-button-group-global-box-height)] shrink-0 cursor-pointer items-center justify-center px-[var(--ui-button-group-global-box-padding-x)] py-[var(--ui-button-group-global-box-padding-y)] transition-colors ' +\n 'bg-[var(--ui-button-group-global-box-color-idle)] text-[var(--ui-glyph-on-surface-primary)] ' +\n 'border-solid border-[color:var(--ui-button-group-global-separator-color)] ' +\n 'hover:bg-[var(--ui-button-group-global-box-color-hover)] active:bg-[var(--ui-button-group-global-box-color-active)] ' +\n 'focus-visible:outline-none focus-visible:ring-[3px] focus-visible:ring-inset focus-visible:ring-[var(--ui-focus-primary)] ' +\n 'data-[disabled]:pointer-events-none data-[disabled]:bg-[var(--ui-button-group-global-box-color-idle)] data-[disabled]:text-[var(--ui-glyph-on-surface-disabled)] ' +\n '[&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0'\n);\n\nconst SEPARATOR_WIDTH =\n 'border-e-[length:var(--ui-button-group-global-separator-border-width)]';\n\n// The separator is the item's own inline-end border, mirroring how Figma hangs\n// it off `ButtonGroupItem` rather than the container. `border-e-*` (not\n// `border-r-*`) so it flips under `dir=\"rtl\"`.\n//\n// By default the trailing separator is dropped via `:last-child`, which keeps\n// the group variadic (Figma's `ListItem` slot) instead of making callers restate\n// their own ordering. That derivation is resolved against the button's *real*\n// parent, though, so interposing a wrapper around each item would make every\n// button a `:last-child` and erase every separator. `order` is the escape hatch\n// for those compositions: given explicitly, it replaces the derivation outright\n// rather than layering on top of it — no `:last-child` rule is emitted at all,\n// so there is no specificity fight to reason about.\nfunction separatorClass(order: ButtonGroupItemOrder | undefined): string {\n if (order === undefined) return `${SEPARATOR_WIDTH} last:border-e-0`;\n return order === 'last' ? '' : SEPARATOR_WIDTH;\n}\n\nexport interface ButtonGroupProps\n // Base UI types `className` as `string | ((state) => string)`, but the value\n // is merged through `cn()` here, which can't call a function — narrow it.\n // `orientation` is omitted because the design is horizontal-only: a vertical\n // group would need the separator on the block axis and different corner\n // rounding, neither of which Figma specifies.\n extends Omit<ToolbarRootProps, 'className' | 'orientation'>,\n VariantProps<typeof buttonGroupVariants> {\n className?: string;\n}\n\n/**\n * A cluster of related icon-only actions sharing a single bordered box.\n *\n * Renders a `role=\"toolbar\"` container: the group is one Tab stop and the\n * arrow keys move between items. Give it an accessible name (`aria-label` or\n * `aria-labelledby`) describing what the actions have in common.\n */\nconst ButtonGroup = React.forwardRef<HTMLDivElement, ButtonGroupProps>(\n ({ className, variant, ...props }, ref) => (\n <ToolbarPrimitive.Root\n ref={ref}\n className={cn(buttonGroupVariants({ variant, className }))}\n {...props}\n />\n )\n);\nButtonGroup.displayName = 'ButtonGroup';\n\n/** Mirrors the Figma `ButtonGroupItem` `order` variant. */\nexport type ButtonGroupItemOrder = 'first' | 'middle' | 'last';\n\nexport interface ButtonGroupItemProps\n extends Omit<ToolbarButtonProps, 'className'> {\n className?: string;\n /**\n * Position within the group, mirroring the Figma `order` variant. Controls\n * one thing: whether the trailing separator is drawn (`last` omits it).\n *\n * Leave it unset — position is derived from the DOM. Only pass it when each\n * item is wrapped in another element, which defeats that derivation.\n */\n order?: ButtonGroupItemOrder;\n}\n\n/**\n * A single action inside a `ButtonGroup`. The icon is passed as `children`;\n * provide an `aria-label` (or `aria-labelledby`) so the control has an\n * accessible name.\n */\nconst ButtonGroupItem = React.forwardRef<\n HTMLButtonElement,\n ButtonGroupItemProps\n>(({ className, order, ...props }, ref) => (\n <ToolbarPrimitive.Button\n ref={ref}\n // `focusableWhenDisabled` is deliberately left at Base UI's default\n // (`true`), so a disabled item is `aria-disabled` rather than natively\n // disabled. Forcing the native attribute instead — to match how every other\n // disabled control in this library drops out of the tab order — breaks the\n // group outright when the FIRST item is disabled: the composite still parks\n // its single `tabIndex=0` on index 0, but the browser skips a natively\n // disabled button, so every item ends up unreachable and Tab never enters\n // the group at all. `Toolbar.Root` exposes no way to relocate that initial\n // tab stop, so the APG behaviour is the only correct option here. The item\n // is still inert: Base UI suppresses click and Enter/Space activation.\n className={cn(\n buttonGroupItemVariants({ className: separatorClass(order) }),\n className\n )}\n {...props}\n />\n));\nButtonGroupItem.displayName = 'ButtonGroupItem';\n\nexport {\n ButtonGroup,\n ButtonGroupItem,\n buttonGroupVariants,\n buttonGroupItemVariants,\n};\n"],"names":["buttonGroupVariants","cva","buttonGroupItemVariants","SEPARATOR_WIDTH","separatorClass","order","ButtonGroup","React","className","variant","props","ref","jsx","ToolbarPrimitive","cn","ButtonGroupItem"],"mappings":";;;;;AA4BA,MAAMA,IAAsBC;AAAA;AAAA;AAAA;AAAA,EAI1B;AAAA,EACA;AAAA,IACE,UAAU;AAAA,MACR,SAAS;AAAA,QACP,UACE;AAAA,QACF,SAAS;AAAA,MAAA;AAAA,IACX;AAAA,IAEF,iBAAiB;AAAA,MACf,SAAS;AAAA,IAAA;AAAA,EACX;AAEJ,GAaMC,IAA0BD;AAAA,EAC9B;AAOF,GAEME,IACJ;AAcF,SAASC,EAAeC,GAAiD;AACvE,SAAIA,MAAU,SAAkB,GAAGF,CAAe,qBAC3CE,MAAU,SAAS,KAAKF;AACjC;AAoBA,MAAMG,IAAcC,EAAM;AAAA,EACxB,CAAC,EAAE,WAAAC,GAAW,SAAAC,GAAS,GAAGC,EAAA,GAASC,MACjC,gBAAAC;AAAA,IAACC,EAAiB;AAAA,IAAjB;AAAA,MACC,KAAAF;AAAA,MACA,WAAWG,EAAGd,EAAoB,EAAE,SAAAS,GAAS,WAAAD,EAAA,CAAW,CAAC;AAAA,MACxD,GAAGE;AAAA,IAAA;AAAA,EAAA;AAGV;AACAJ,EAAY,cAAc;AAuB1B,MAAMS,IAAkBR,EAAM,WAG5B,CAAC,EAAE,WAAAC,GAAW,OAAAH,GAAO,GAAGK,KAASC,MACjC,gBAAAC;AAAA,EAACC,EAAiB;AAAA,EAAjB;AAAA,IACC,KAAAF;AAAA,IAWA,WAAWG;AAAA,MACTZ,EAAwB,EAAE,WAAWE,EAAeC,CAAK,GAAG;AAAA,MAC5DG;AAAA,IAAA;AAAA,IAED,GAAGE;AAAA,EAAA;AACN,CACD;AACDK,EAAgB,cAAc;"}
@@ -0,0 +1,26 @@
1
+ import { jsx as a } from "react/jsx-runtime";
2
+ import * as i from "react";
3
+ import { EllipsisIcon as c } from "@acronis-platform/icons-react/stroke-mono";
4
+ import { cn as p } from "../../../lib/utils.js";
5
+ import { ButtonIcon as s } from "../button-icon/button-icon.js";
6
+ const l = "data-[open]:bg-[var(--ui-button-icon-global-container-color-active)] data-[open]:text-[var(--ui-button-icon-global-icon-color-active)] data-[open]:border-[var(--ui-button-icon-secondary-container-border-color-active)]", d = i.forwardRef(
7
+ ({ className: t, open: o, ariaLabel: n = "More options", ...r }, e) => /* @__PURE__ */ a(
8
+ s,
9
+ {
10
+ ref: e,
11
+ variant: "secondary",
12
+ "aria-haspopup": "menu",
13
+ "aria-label": n,
14
+ "aria-expanded": o,
15
+ className: p(l, t),
16
+ ...o ? { "data-open": "" } : {},
17
+ ...r,
18
+ children: /* @__PURE__ */ a(c, { size: 16 })
19
+ }
20
+ )
21
+ );
22
+ d.displayName = "ButtonIconMenu";
23
+ export {
24
+ d as ButtonIconMenu
25
+ };
26
+ //# sourceMappingURL=button-icon-menu.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"button-icon-menu.js","sources":["../../../../src/components/ui/button-icon-menu/button-icon-menu.tsx"],"sourcesContent":["import * as React from 'react';\nimport { EllipsisIcon } from '@acronis-platform/icons-react/stroke-mono';\nimport type { useRender } from '@base-ui/react/use-render';\n\nimport { cn } from '@/lib/utils';\nimport { ButtonIcon } from '../button-icon';\n\n// Mirrors the Figma \"ButtonIconMenu\" component set: the kebab (\"more options\")\n// trigger — a 32×32 bordered icon button holding a fixed 16px Ellipsis glyph,\n// with idle / hover / active / disabled / focus states. The design has a single\n// `state` property (no variant/size axis) and draws every state from the\n// **ButtonIcon** token tier (`components/ButtonIcon/*`), always with the\n// `secondary` 1px container border — so this composes `ButtonIcon\n// variant=\"secondary\"` rather than restating those token references. A re-theme\n// of ButtonIcon then reaches this component for free, and the two can't drift.\n// Only the open treatment is added here: as in ButtonMenu, the Figma `active`\n// state doubles as the **open** state, so `data-open` — set from the `open` prop\n// — re-points the container fill, glyph, and border at their `*-active` tokens.\n// Geometry (32px box, 4px radius, 16px glyph) and the 3px `--ui-focus-primary`\n// ring flush to the edge come from ButtonIcon.\nconst openStateClasses =\n 'data-[open]:bg-[var(--ui-button-icon-global-container-color-active)] data-[open]:text-[var(--ui-button-icon-global-icon-color-active)] data-[open]:border-[var(--ui-button-icon-secondary-container-border-color-active)]';\n\nexport interface ButtonIconMenuProps extends Omit<\n React.ButtonHTMLAttributes<HTMLButtonElement>,\n 'children'\n> {\n /**\n * Whether the associated menu is open. Applies the open (`*-active`)\n * treatment and reflects `aria-expanded`. Control this in sync with the menu\n * you trigger.\n */\n open?: boolean;\n /**\n * Accessible name for the trigger. The button is icon-only, so it has no text\n * to name it — pass a localized string here.\n */\n ariaLabel?: string;\n /**\n * Replace the rendered `<button>` with another element or component\n * (Base UI composition). Accepts a React element or a render function —\n * the component's props and class names are merged onto it.\n */\n render?: useRender.RenderProp;\n}\n\n/**\n * Icon-only button that opens a menu of actions — the kebab / \"more options\"\n * trigger. The glyph is fixed (Ellipsis); for any other icon use `ButtonIcon`.\n * Pair it with the menu it controls and keep the `open` prop in sync.\n */\nconst ButtonIconMenu = React.forwardRef<HTMLButtonElement, ButtonIconMenuProps>(\n ({ className, open, ariaLabel = 'More options', ...props }, ref) => (\n <ButtonIcon\n ref={ref}\n variant=\"secondary\"\n aria-haspopup=\"menu\"\n aria-label={ariaLabel}\n aria-expanded={open}\n className={cn(openStateClasses, className)}\n // `data-open` drives the open (`*-active`) token switch via attribute\n // selectors; present only while open, and typed loosely because React's\n // button attribute map doesn't include arbitrary data-* keys as literals.\n {...(open ? ({ 'data-open': '' } as Record<string, string>) : {})}\n {...props}\n >\n <EllipsisIcon size={16} />\n </ButtonIcon>\n )\n);\nButtonIconMenu.displayName = 'ButtonIconMenu';\n\nexport { ButtonIconMenu };\n"],"names":["openStateClasses","ButtonIconMenu","React","className","open","ariaLabel","props","ref","jsx","ButtonIcon","cn","EllipsisIcon"],"mappings":";;;;;AAoBA,MAAMA,IACJ,6NA8BIC,IAAiBC,EAAM;AAAA,EAC3B,CAAC,EAAE,WAAAC,GAAW,MAAAC,GAAM,WAAAC,IAAY,gBAAgB,GAAGC,EAAA,GAASC,MAC1D,gBAAAC;AAAA,IAACC;AAAA,IAAA;AAAA,MACC,KAAAF;AAAA,MACA,SAAQ;AAAA,MACR,iBAAc;AAAA,MACd,cAAYF;AAAA,MACZ,iBAAeD;AAAA,MACf,WAAWM,EAAGV,GAAkBG,CAAS;AAAA,MAIxC,GAAIC,IAAQ,EAAE,aAAa,GAAA,IAAkC,CAAA;AAAA,MAC7D,GAAGE;AAAA,MAEJ,UAAA,gBAAAE,EAACG,GAAA,EAAa,MAAM,GAAA,CAAI;AAAA,IAAA;AAAA,EAAA;AAG9B;AACAV,EAAe,cAAc;"}
@@ -1 +1 @@
1
- {"version":3,"file":"calendar-panel.js","sources":["../../../../src/components/ui/calendar-panel/calendar-panel.tsx"],"sourcesContent":["import * as React from 'react';\nimport { addMonths, format } from 'date-fns';\nimport {\n DayPicker,\n useDayPicker,\n type DateRange,\n type DayButton,\n type DayPickerLocale,\n type Matcher,\n type MonthCaptionProps,\n} from 'react-day-picker';\n\nimport { cn } from '@/lib/utils';\nimport { Button } from '../button';\nimport { DialogFooterDefault } from '../dialog-footer-default';\nimport {\n InputSelect,\n InputSelectContent,\n InputSelectItem,\n InputSelectTrigger,\n InputSelectValue,\n} from '../input-select';\nimport {\n DEFAULT_YEAR_SPAN,\n buildModeProps,\n buildMonthItems,\n buildYearItems,\n clampNavigationTarget,\n resolveWeekStartsOn,\n resolveYearRange,\n type CalendarSelectItem,\n} from './calendar-panel-utils';\n\n// The Figma \"Calendar\" panel: a bordered, elevated day-picker panel themed by the\n// dedicated `--ui-calendar-*` tier. Its three variants are the three\n// `react-day-picker` selection modes, and each one changes the panel's structure:\n// • single — one 248px month, no footer.\n// • multiple — one 248px month + a Cancel/Apply footer.\n// • range — two 248px months side by side (divided by a vertical rule) sharing\n// one Cancel/Apply footer.\n// Figma's `state` axis (idle / selected) is demo-only — it is DayPicker's runtime\n// selection state, not a prop.\n//\n// The month/year pickers in the header are real `InputSelect` instances (as in the\n// design), wired through DayPicker's custom-component API: the whole `MonthCaption`\n// is replaced, rather than using `captionLayout=\"dropdown\"`'s native `<select>`\n// elements. Per-instance caption options (labels, year window, month formatter) reach\n// that override through `CalendarPanelCaptionContext`, since DayPicker instantiates\n// custom components itself and passes only its own props.\n//\n// Every cell — idle, hover, in-range, endpoint — is a flat square: this design has no\n// corner-radius differentiation, so there is deliberately no range-endpoint \"pill\"\n// rounding.\n\nexport type CalendarPanelVariant = 'single' | 'multiple' | 'range';\n\n/** Selected value, shaped by the active `variant`. */\nexport type CalendarPanelSelected = Date | Date[] | DateRange | undefined;\n\ninterface CalendarPanelCaptionContextValue {\n monthLabel: string;\n yearLabel: string;\n fromYear: number;\n toYear: number;\n formatMonthLabel: (date: Date) => string;\n endMonth: Date;\n numberOfMonths: number;\n}\n\nconst CalendarPanelCaptionContext =\n React.createContext<CalendarPanelCaptionContextValue | null>(null);\n\n/** One header dropdown (month or year) — an `InputSelect` over a fixed item list. */\nfunction CalendarHeaderSelect({\n items,\n value,\n ariaLabel,\n onValueChange,\n}: {\n items: CalendarSelectItem<number>[];\n value: number;\n ariaLabel: string;\n onValueChange: (next: number) => void;\n}) {\n return (\n <InputSelect\n items={items}\n value={value}\n onValueChange={(next) => onValueChange(Number(next))}\n >\n <InputSelectTrigger aria-label={ariaLabel} className=\"min-w-0 flex-1\">\n <InputSelectValue />\n </InputSelectTrigger>\n <InputSelectContent>\n {items.map((item) => (\n <InputSelectItem key={item.value} value={item.value}>\n {item.label}\n </InputSelectItem>\n ))}\n </InputSelectContent>\n </InputSelect>\n );\n}\nCalendarHeaderSelect.displayName = 'CalendarHeaderSelect';\n\n/**\n * The header of one month column: a month `InputSelect` and a year `InputSelect`.\n * Replaces DayPicker's `MonthCaption`.\n */\nfunction CalendarHeader({\n calendarMonth,\n displayIndex,\n className,\n ...props\n}: MonthCaptionProps) {\n const { goToMonth } = useDayPicker();\n const context = React.useContext(CalendarPanelCaptionContext);\n if (!context) {\n throw new Error('CalendarHeader must be rendered inside <CalendarPanel>.');\n }\n const { monthLabel, yearLabel, fromYear, toYear, formatMonthLabel, endMonth, numberOfMonths } =\n context;\n\n const date = calendarMonth.date;\n const month = date.getMonth();\n const year = date.getFullYear();\n\n const monthItems = React.useMemo(\n () => buildMonthItems(formatMonthLabel),\n [formatMonthLabel]\n );\n\n const yearItems = React.useMemo(\n () => buildYearItems(fromYear, toYear),\n [fromYear, toYear]\n );\n\n return (\n <header\n className={cn(\n 'flex items-center gap-[var(--ui-calendar-header-gap)] border-b-[length:var(--ui-calendar-header-border-width)] border-[color:var(--ui-calendar-header-border-color)] px-[var(--ui-calendar-header-padding-x)] py-[var(--ui-calendar-header-padding-y)] [border-bottom-style:var(--ui-calendar-header-border-style)]',\n className\n )}\n {...props}\n >\n <CalendarHeaderSelect\n items={monthItems}\n value={month}\n ariaLabel={monthLabel}\n onValueChange={(next) =>\n goToMonth(\n clampNavigationTarget(\n addMonths(new Date(year, next, 1), -displayIndex),\n endMonth,\n numberOfMonths\n )\n )\n }\n />\n <CalendarHeaderSelect\n items={yearItems}\n value={year}\n ariaLabel={yearLabel}\n onValueChange={(next) =>\n goToMonth(\n clampNavigationTarget(\n addMonths(new Date(next, month, 1), -displayIndex),\n endMonth,\n numberOfMonths\n )\n )\n }\n />\n </header>\n );\n}\nCalendarHeader.displayName = 'CalendarHeader';\n\n/**\n * One day cell (Figma's \"CalendarItem\") — a flat 32×32 square. `data-active`\n * (a selected day or either range endpoint) and `data-range-middle` are mutually\n * exclusive, so their backgrounds never compete.\n */\nfunction CalendarItem({\n className,\n day,\n modifiers,\n ...props\n}: React.ComponentProps<typeof DayButton>) {\n const ref = React.useRef<HTMLButtonElement>(null);\n React.useEffect(() => {\n if (modifiers.focused) ref.current?.focus();\n }, [modifiers.focused]);\n\n const isRangeMiddle = Boolean(modifiers.range_middle);\n const isActive = Boolean(modifiers.selected) && !isRangeMiddle;\n\n return (\n <button\n ref={ref}\n type=\"button\"\n data-day={day.date.toLocaleDateString()}\n data-active={isActive}\n data-range-middle={isRangeMiddle}\n className={cn(\n 'ui-calendar-value-text-style',\n 'flex size-[var(--ui-calendar-item-width-min)] min-h-[var(--ui-calendar-item-height-min)] min-w-[var(--ui-calendar-item-width-min)] cursor-pointer items-center justify-center border border-[color:var(--ui-calendar-item-border-idle)] bg-[var(--ui-calendar-item-color-idle)] p-0 text-[var(--ui-calendar-value-color-idle-primary)] outline-none transition-colors [font-variant-numeric:var(--ui-calendar-value-font-variant-numeric)]',\n 'not-data-[active=true]:hover:border-[color:var(--ui-calendar-item-border-hover)] not-data-[active=true]:hover:bg-[var(--ui-calendar-item-color-hover)]',\n 'data-[range-middle=true]:bg-[var(--ui-calendar-item-color-hover)] data-[range-middle=true]:text-[var(--ui-calendar-value-color-idle-primary)]',\n 'data-[active=true]:border-[color:var(--ui-calendar-item-border-active)] data-[active=true]:bg-[var(--ui-calendar-item-color-active)] data-[active=true]:text-[var(--ui-calendar-value-color-active)]',\n 'group-data-[focused=true]/day:relative group-data-[focused=true]/day:z-10 group-data-[focused=true]/day:ring-[3px] group-data-[focused=true]/day:ring-[var(--ui-focus-primary)]',\n 'disabled:pointer-events-none disabled:text-[var(--ui-calendar-value-color-disabled)]',\n className\n )}\n {...props}\n />\n );\n}\nCalendarItem.displayName = 'CalendarItem';\n\ninterface CalendarPanelSharedProps\n extends Omit<React.HTMLAttributes<HTMLDivElement>, 'onSelect' | 'defaultValue'> {\n /**\n * Text direction. Forwarded to `DayPicker` explicitly — an ancestor's `dir`\n * mirrors the panel's CSS layout automatically (logical properties), but\n * `react-day-picker` only flips its Arrow Left/Right keyboard roaming when\n * `dir` is passed to it directly, so it must also be passed here.\n */\n dir?: 'ltr' | 'rtl';\n /** Uncontrolled initial month shown. */\n defaultMonth?: Date;\n /** Controlled month shown (the first month, for `range`). */\n month?: Date;\n /** Called when the displayed month changes (header dropdowns). */\n onMonthChange?: (month: Date) => void;\n /** Days that cannot be selected. */\n disabled?: Matcher | Matcher[];\n /** Minimum number of selectable days (`multiple` / `range`; ignored for `single`). */\n min?: number;\n /** Maximum number of selectable days (`multiple` / `range`; ignored for `single`). */\n max?: number;\n /** Render the leading/trailing days of the adjacent months. */\n showOutsideDays?: boolean;\n /**\n * First day of the week (0 = Sunday). Defaults to `locale`'s own week start,\n * falling back to Monday (per the design) when no `locale` is given.\n */\n weekStartsOn?: 0 | 1 | 2 | 3 | 4 | 5 | 6;\n /**\n * First year offered by the year dropdown and the earliest month the grid\n * can navigate to. Defaults to 50 years back.\n */\n fromYear?: number;\n /**\n * Last year offered by the year dropdown and the latest month the grid can\n * navigate to. Defaults to 50 years ahead.\n */\n toYear?: number;\n /**\n * Localizes weekday names and DayPicker's default day-cell/caption accessible\n * labels (e.g. `import { es } from 'react-day-picker/locale'`). Defaults to\n * date-fns `enUS`. Does not translate `monthLabel`/`yearLabel`/`cancelLabel`/\n * `applyLabel`/`formatMonthLabel` — those are separate props the consumer\n * must localize themselves.\n */\n locale?: DayPickerLocale;\n /** Accessible name of the month dropdown. */\n monthLabel?: string;\n /** Accessible name of the year dropdown. */\n yearLabel?: string;\n /** Formats a month's name for the month dropdown. Defaults to `locale`-aware `date-fns` formatting. */\n formatMonthLabel?: (date: Date) => string;\n /** Footer \"Cancel\" button label (`multiple` / `range`). */\n cancelLabel?: string;\n /** Footer \"Apply\" button label (`multiple` / `range`). */\n applyLabel?: string;\n /** Called when the footer's Cancel button is pressed. */\n onCancel?: () => void;\n /** Called when the footer's Apply button is pressed. */\n onApply?: () => void;\n}\n\n/** `variant=\"single\"` (the default) — `selected` is a single optional `Date`. */\nexport interface CalendarPanelSingleProps extends CalendarPanelSharedProps {\n /** Selection mode + panel structure. `multiple`/`range` add the Cancel/Apply footer; `range` shows two months. */\n variant?: 'single';\n /** The selected date. Uncontrolled unless `onSelect` is provided. */\n selected?: Date;\n /** Called when the selection changes. Providing it makes `selected` controlled. */\n onSelect?: (selected: Date | undefined, triggerDate: Date) => void;\n}\n\n/** `variant=\"multiple\"` — `selected` is a `Date[]`, and the footer is shown. */\nexport interface CalendarPanelMultipleProps extends CalendarPanelSharedProps {\n variant: 'multiple';\n selected?: Date[];\n onSelect?: (selected: Date[] | undefined, triggerDate: Date) => void;\n}\n\n/** `variant=\"range\"` — `selected` is a `DateRange`, two months render, and the footer is shown. */\nexport interface CalendarPanelRangeProps extends CalendarPanelSharedProps {\n variant: 'range';\n selected?: DateRange;\n onSelect?: (selected: DateRange | undefined, triggerDate: Date) => void;\n}\n\n/**\n * `CalendarPanel`'s props, discriminated by `variant` — a `single` panel only\n * accepts a `Date`, `multiple` only a `Date[]`, `range` only a `DateRange`, so\n * mismatched `selected`/`onSelect` shapes are caught at the call site instead\n * of silently reaching `react-day-picker` with the wrong shape at runtime.\n */\nexport type CalendarPanelProps =\n | CalendarPanelSingleProps\n | CalendarPanelMultipleProps\n | CalendarPanelRangeProps;\n\nconst CalendarPanel = React.forwardRef<HTMLDivElement, CalendarPanelProps>(\n (\n {\n className,\n variant = 'single',\n selected,\n onSelect,\n defaultMonth,\n month,\n onMonthChange,\n disabled,\n min,\n max,\n showOutsideDays = true,\n weekStartsOn,\n fromYear,\n toYear,\n locale,\n monthLabel = 'Month',\n yearLabel = 'Year',\n formatMonthLabel,\n cancelLabel = 'Cancel',\n applyLabel = 'Apply',\n onCancel,\n onApply,\n dir,\n ...props\n },\n ref\n ) => {\n const currentYear = new Date().getFullYear();\n const { fromYear: resolvedFromYear, toYear: resolvedToYear } = resolveYearRange(\n fromYear,\n toYear,\n currentYear,\n DEFAULT_YEAR_SPAN\n );\n const resolvedWeekStartsOn = resolveWeekStartsOn(weekStartsOn, locale);\n const showFooter = variant !== 'single';\n const numberOfMonths = variant === 'range' ? 2 : 1;\n\n // Stable across renders when the consumer doesn't override `formatMonthLabel`,\n // so `captionContext` below doesn't get a new identity (and rebuild the month\n // dropdown items) on every render.\n const defaultFormatMonthLabel = React.useCallback(\n (date: Date) => format(date, 'MMMM', { locale }),\n [locale]\n );\n const resolvedFormatMonthLabel = formatMonthLabel ?? defaultFormatMonthLabel;\n\n // Bounds the header dropdowns' navigation to the same window their own\n // options list offers — without this, keyboard shortcuts (Shift+PageUp/\n // PageDown) and a controlled `month` can move the grid past `fromYear`/\n // `toYear` while the year dropdown still only lists that range.\n const startMonth = React.useMemo(() => new Date(resolvedFromYear, 0, 1), [resolvedFromYear]);\n const endMonth = React.useMemo(() => new Date(resolvedToYear, 11, 1), [resolvedToYear]);\n\n const captionContext = React.useMemo<CalendarPanelCaptionContextValue>(\n () => ({\n monthLabel,\n yearLabel,\n fromYear: resolvedFromYear,\n toYear: resolvedToYear,\n formatMonthLabel: resolvedFormatMonthLabel,\n endMonth,\n numberOfMonths,\n }),\n [\n monthLabel,\n yearLabel,\n resolvedFromYear,\n resolvedToYear,\n resolvedFormatMonthLabel,\n endMonth,\n numberOfMonths,\n ]\n );\n\n // `selected`/`onSelect` are already guaranteed consistent with `variant` by\n // the discriminated `CalendarPanelProps` union above — this is the one\n // place that bridges to `DayPickerProps`'s own (differently-shaped)\n // discriminated union.\n const modeProps = buildModeProps(\n variant,\n selected,\n onSelect as unknown as\n | ((selected: CalendarPanelSelected, triggerDate: Date) => void)\n | undefined,\n min,\n max\n );\n\n return (\n <div\n ref={ref}\n dir={dir}\n data-slot=\"calendar-panel\"\n data-variant={variant}\n className={cn(\n 'inline-flex w-fit flex-col overflow-hidden rounded-[var(--ui-calendar-container-border-radius)] border-[length:var(--ui-calendar-container-border-width)] border-[color:var(--ui-calendar-container-border-color)] bg-[var(--ui-calendar-container-color)] shadow-md [border-style:var(--ui-calendar-container-border-style)]',\n className\n )}\n {...props}\n >\n <CalendarPanelCaptionContext.Provider value={captionContext}>\n <DayPicker\n {...modeProps}\n dir={dir}\n defaultMonth={defaultMonth}\n month={month}\n onMonthChange={onMonthChange}\n disabled={disabled}\n startMonth={startMonth}\n endMonth={endMonth}\n showOutsideDays={showOutsideDays}\n weekStartsOn={resolvedWeekStartsOn}\n locale={locale}\n numberOfMonths={variant === 'range' ? 2 : 1}\n // The design navigates months through the header dropdowns only —\n // there are no prev/next chevrons.\n hideNavigation\n classNames={{\n root: 'flex',\n months: 'flex flex-row',\n // The vertical rule between the two `range` months is the first\n // column's inline-end border, so it mirrors under RTL.\n // Width = 7 day columns + 2 sides of body padding, derived from tokens\n // so it stays in sync if either is retokened.\n month:\n 'flex w-[calc(var(--ui-calendar-item-width-min)*7+var(--ui-calendar-body-padding-x)*2)] flex-col border-e-[length:var(--ui-calendar-body-border-width)] border-[color:var(--ui-calendar-body-border-color)] last:border-e-0 [border-inline-end-style:var(--ui-calendar-body-border-style)]',\n // `table-fixed` (rather than the default `auto`) is what makes the\n // 32px-per-column contract above actually hold: under `auto`\n // layout a single wide weekday abbreviation (e.g. some `ar`/`te`/\n // `kn` locales) widens its whole column past the fixed 248px month\n // width, which the panel's `overflow-hidden` then clips — silently\n // dropping a day column instead of just the label.\n month_grid:\n 'w-full table-fixed border-separate border-spacing-0 px-[var(--ui-calendar-body-padding-x)] py-[var(--ui-calendar-body-padding-y)]',\n weekday:\n 'ui-calendar-value-text-style size-[var(--ui-calendar-item-width-min)] overflow-hidden whitespace-nowrap p-0 text-center font-normal text-[var(--ui-calendar-value-color-idle-secondary)]',\n day: 'group/day size-[var(--ui-calendar-item-width-min)] p-0 text-center',\n outside: '[&_button]:text-[var(--ui-calendar-value-color-disabled)]',\n disabled: '[&_button]:text-[var(--ui-calendar-value-color-disabled)]',\n hidden: 'invisible',\n }}\n components={{\n MonthCaption: CalendarHeader,\n DayButton: CalendarItem,\n }}\n />\n </CalendarPanelCaptionContext.Provider>\n {showFooter && (\n <DialogFooterDefault>\n <Button variant=\"secondary\" onClick={onCancel}>\n {cancelLabel}\n </Button>\n <Button onClick={onApply}>{applyLabel}</Button>\n </DialogFooterDefault>\n )}\n </div>\n );\n }\n);\nCalendarPanel.displayName = 'CalendarPanel';\n\nexport { CalendarPanel, CalendarItem, CalendarHeader };\n"],"names":["CalendarPanelCaptionContext","React","CalendarHeaderSelect","items","value","ariaLabel","onValueChange","jsxs","InputSelect","next","jsx","InputSelectTrigger","InputSelectValue","InputSelectContent","item","InputSelectItem","CalendarHeader","calendarMonth","displayIndex","className","props","goToMonth","useDayPicker","context","monthLabel","yearLabel","fromYear","toYear","formatMonthLabel","endMonth","numberOfMonths","date","month","year","monthItems","buildMonthItems","yearItems","buildYearItems","cn","clampNavigationTarget","addMonths","CalendarItem","day","modifiers","ref","_a","isRangeMiddle","isActive","CalendarPanel","variant","selected","onSelect","defaultMonth","onMonthChange","disabled","min","max","showOutsideDays","weekStartsOn","locale","cancelLabel","applyLabel","onCancel","onApply","dir","currentYear","resolvedFromYear","resolvedToYear","resolveYearRange","DEFAULT_YEAR_SPAN","resolvedWeekStartsOn","resolveWeekStartsOn","showFooter","defaultFormatMonthLabel","format","resolvedFormatMonthLabel","startMonth","captionContext","modeProps","buildModeProps","DayPicker","DialogFooterDefault","Button"],"mappings":"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"}
1
+ {"version":3,"file":"calendar-panel.js","sources":["../../../../src/components/ui/calendar-panel/calendar-panel.tsx"],"sourcesContent":["import * as React from 'react';\nimport { addMonths, format } from 'date-fns';\nimport {\n DayPicker,\n useDayPicker,\n type DateRange,\n type DayButton,\n type DayPickerLocale,\n type Matcher,\n type MonthCaptionProps,\n} from 'react-day-picker';\n\nimport { cn } from '@/lib/utils';\nimport { Button } from '../button';\nimport { DialogFooterDefault } from '../dialog-footer-default';\nimport {\n InputSelect,\n InputSelectContent,\n InputSelectItem,\n InputSelectTrigger,\n InputSelectValue,\n} from '../input-select';\nimport {\n DEFAULT_YEAR_SPAN,\n buildModeProps,\n buildMonthItems,\n buildYearItems,\n clampNavigationTarget,\n resolveWeekStartsOn,\n resolveYearRange,\n type CalendarSelectItem,\n} from './calendar-panel-utils';\n\n// The Figma \"Calendar\" panel: a bordered, elevated day-picker panel themed by the\n// dedicated `--ui-calendar-*` tier. Its three variants are the three\n// `react-day-picker` selection modes, and each one changes the panel's structure:\n// • single — one 248px month, no footer.\n// • multiple — one 248px month + a Cancel/Apply footer.\n// • range — two 248px months side by side (divided by a vertical rule) sharing\n// one Cancel/Apply footer.\n// Figma's `state` axis (idle / selected) is demo-only — it is DayPicker's runtime\n// selection state, not a prop.\n//\n// The month/year pickers in the header are real `InputSelect` instances (as in the\n// design), wired through DayPicker's custom-component API: the whole `MonthCaption`\n// is replaced, rather than using `captionLayout=\"dropdown\"`'s native `<select>`\n// elements. Per-instance caption options (labels, year window, month formatter) reach\n// that override through `CalendarPanelCaptionContext`, since DayPicker instantiates\n// custom components itself and passes only its own props.\n//\n// Every cell — idle, hover, in-range, endpoint — is a flat square: this design has no\n// corner-radius differentiation, so there is deliberately no range-endpoint \"pill\"\n// rounding.\n\nexport type CalendarPanelVariant = 'single' | 'multiple' | 'range';\n\n/** Selected value, shaped by the active `variant`. */\nexport type CalendarPanelSelected = Date | Date[] | DateRange | undefined;\n\ninterface CalendarPanelCaptionContextValue {\n monthLabel: string;\n yearLabel: string;\n fromYear: number;\n toYear: number;\n formatMonthLabel: (date: Date) => string;\n endMonth: Date;\n numberOfMonths: number;\n}\n\nconst CalendarPanelCaptionContext =\n React.createContext<CalendarPanelCaptionContextValue | null>(null);\n\n/** One header dropdown (month or year) — an `InputSelect` over a fixed item list. */\nfunction CalendarHeaderSelect({\n items,\n value,\n ariaLabel,\n onValueChange,\n}: {\n items: CalendarSelectItem<number>[];\n value: number;\n ariaLabel: string;\n onValueChange: (next: number) => void;\n}) {\n return (\n <InputSelect\n items={items}\n value={value}\n onValueChange={(next) => onValueChange(Number(next))}\n >\n <InputSelectTrigger aria-label={ariaLabel} className=\"min-w-0 flex-1\">\n <InputSelectValue />\n </InputSelectTrigger>\n <InputSelectContent>\n {items.map((item) => (\n <InputSelectItem key={item.value} value={item.value}>\n {item.label}\n </InputSelectItem>\n ))}\n </InputSelectContent>\n </InputSelect>\n );\n}\nCalendarHeaderSelect.displayName = 'CalendarHeaderSelect';\n\n/**\n * The header of one month column: a month `InputSelect` and a year `InputSelect`.\n * Replaces DayPicker's `MonthCaption`.\n */\nfunction CalendarHeader({\n calendarMonth,\n displayIndex,\n className,\n ...props\n}: MonthCaptionProps) {\n const { goToMonth } = useDayPicker();\n const context = React.useContext(CalendarPanelCaptionContext);\n if (!context) {\n throw new Error('CalendarHeader must be rendered inside <CalendarPanel>.');\n }\n const { monthLabel, yearLabel, fromYear, toYear, formatMonthLabel, endMonth, numberOfMonths } =\n context;\n\n const date = calendarMonth.date;\n const month = date.getMonth();\n const year = date.getFullYear();\n\n const monthItems = React.useMemo(\n () => buildMonthItems(formatMonthLabel),\n [formatMonthLabel]\n );\n\n const yearItems = React.useMemo(\n () => buildYearItems(fromYear, toYear),\n [fromYear, toYear]\n );\n\n return (\n <header\n className={cn(\n 'flex items-center gap-[var(--ui-calendar-header-gap)] border-b-[length:var(--ui-calendar-header-border-width)] border-[color:var(--ui-calendar-header-border-color)] px-[var(--ui-calendar-header-padding-x)] py-[var(--ui-calendar-header-padding-y)] [border-bottom-style:var(--ui-calendar-header-border-style)]',\n className\n )}\n {...props}\n >\n <CalendarHeaderSelect\n items={monthItems}\n value={month}\n ariaLabel={monthLabel}\n onValueChange={(next) =>\n goToMonth(\n clampNavigationTarget(\n addMonths(new Date(year, next, 1), -displayIndex),\n endMonth,\n numberOfMonths\n )\n )\n }\n />\n <CalendarHeaderSelect\n items={yearItems}\n value={year}\n ariaLabel={yearLabel}\n onValueChange={(next) =>\n goToMonth(\n clampNavigationTarget(\n addMonths(new Date(next, month, 1), -displayIndex),\n endMonth,\n numberOfMonths\n )\n )\n }\n />\n </header>\n );\n}\nCalendarHeader.displayName = 'CalendarHeader';\n\n/**\n * One day cell (Figma's \"CalendarItem\") — a flat 32×32 square. `data-active`\n * (a selected day or either range endpoint) and `data-range-middle` are mutually\n * exclusive, so their backgrounds never compete.\n */\nfunction CalendarItem({\n className,\n day,\n modifiers,\n ...props\n}: React.ComponentProps<typeof DayButton>) {\n const ref = React.useRef<HTMLButtonElement>(null);\n React.useEffect(() => {\n if (modifiers.focused) ref.current?.focus();\n }, [modifiers.focused]);\n\n const isRangeMiddle = Boolean(modifiers.range_middle);\n const isActive = Boolean(modifiers.selected) && !isRangeMiddle;\n\n return (\n <button\n ref={ref}\n type=\"button\"\n data-day={day.date.toLocaleDateString()}\n data-active={isActive}\n data-range-middle={isRangeMiddle}\n className={cn(\n 'ui-calendar-value-text-style',\n 'flex size-[var(--ui-calendar-item-width-min)] min-h-[var(--ui-calendar-item-height-min)] min-w-[var(--ui-calendar-item-width-min)] cursor-pointer items-center justify-center border border-[color:var(--ui-calendar-item-border-idle)] bg-[var(--ui-calendar-item-color-idle)] p-0 text-[var(--ui-calendar-value-color-idle-primary)] outline-none transition-colors [font-variant-numeric:var(--ui-calendar-value-font-variant-numeric)]',\n 'not-data-[active=true]:hover:border-[color:var(--ui-calendar-item-border-hover)] not-data-[active=true]:hover:bg-[var(--ui-calendar-item-color-hover)]',\n 'data-[range-middle=true]:bg-[var(--ui-calendar-item-color-hover)] data-[range-middle=true]:text-[var(--ui-calendar-value-color-idle-primary)]',\n 'data-[active=true]:border-[color:var(--ui-calendar-item-border-active)] data-[active=true]:bg-[var(--ui-calendar-item-color-active)] data-[active=true]:text-[var(--ui-calendar-value-color-active)]',\n 'group-data-[focused=true]/day:relative group-data-[focused=true]/day:z-10 group-data-[focused=true]/day:ring-[3px] group-data-[focused=true]/day:ring-[var(--ui-focus-primary)]',\n 'disabled:pointer-events-none disabled:text-[var(--ui-calendar-value-color-disabled)]',\n className\n )}\n {...props}\n />\n );\n}\nCalendarItem.displayName = 'CalendarItem';\n\ninterface CalendarPanelSharedProps\n extends Omit<React.HTMLAttributes<HTMLDivElement>, 'onSelect' | 'defaultValue'> {\n /**\n * Text direction. Forwarded to `DayPicker` explicitly — an ancestor's `dir`\n * mirrors the panel's CSS layout automatically (logical properties), but\n * `react-day-picker` only flips its Arrow Left/Right keyboard roaming when\n * `dir` is passed to it directly, so it must also be passed here.\n */\n dir?: 'ltr' | 'rtl';\n /** Uncontrolled initial month shown. */\n defaultMonth?: Date;\n /** Controlled month shown (the first month, for `range`). */\n month?: Date;\n /** Called when the displayed month changes (header dropdowns). */\n onMonthChange?: (month: Date) => void;\n /** Days that cannot be selected. */\n disabled?: Matcher | Matcher[];\n /** Minimum count (`multiple` / `range`; ignored for `single`): for `multiple`, the number of selected dates; for `range`, the number of nights between start and end. */\n min?: number;\n /** Maximum count (`multiple` / `range`; ignored for `single`): for `multiple`, the number of selected dates; for `range`, the number of nights between start and end. */\n max?: number;\n /** Render the leading/trailing days of the adjacent months. */\n showOutsideDays?: boolean;\n /**\n * First day of the week (0 = Sunday). Defaults to `locale`'s own week start,\n * falling back to Monday (per the design) when no `locale` is given.\n */\n weekStartsOn?: 0 | 1 | 2 | 3 | 4 | 5 | 6;\n /**\n * First year offered by the year dropdown and the earliest month the grid\n * can navigate to. Defaults to 50 years back.\n */\n fromYear?: number;\n /**\n * Last year offered by the year dropdown and the latest month the grid can\n * navigate to. Defaults to 50 years ahead.\n */\n toYear?: number;\n /**\n * Localizes weekday names and DayPicker's default day-cell/caption accessible\n * labels (e.g. `import { es } from 'react-day-picker/locale'`). Defaults to\n * date-fns `enUS`. Does not translate `monthLabel`/`yearLabel`/`cancelLabel`/\n * `applyLabel`/`formatMonthLabel` — those are separate props the consumer\n * must localize themselves.\n */\n locale?: DayPickerLocale;\n /** Accessible name of the month dropdown. */\n monthLabel?: string;\n /** Accessible name of the year dropdown. */\n yearLabel?: string;\n /** Formats a month's name for the month dropdown. Defaults to `locale`-aware `date-fns` formatting. */\n formatMonthLabel?: (date: Date) => string;\n /** Footer \"Cancel\" button label (`multiple` / `range`). */\n cancelLabel?: string;\n /** Footer \"Apply\" button label (`multiple` / `range`). */\n applyLabel?: string;\n /** Called when the footer's Cancel button is pressed. */\n onCancel?: () => void;\n /** Called when the footer's Apply button is pressed. */\n onApply?: () => void;\n}\n\n/** `variant=\"single\"` (the default) — `selected` is a single optional `Date`. */\nexport interface CalendarPanelSingleProps extends CalendarPanelSharedProps {\n /** Selection mode + panel structure. `multiple`/`range` add the Cancel/Apply footer; `range` shows two months. */\n variant?: 'single';\n /** The selected date. Uncontrolled unless `onSelect` is provided. */\n selected?: Date;\n /** Called when the selection changes. Providing it makes `selected` controlled. */\n onSelect?: (selected: Date | undefined, triggerDate: Date) => void;\n}\n\n/** `variant=\"multiple\"` — `selected` is a `Date[]`, and the footer is shown. */\nexport interface CalendarPanelMultipleProps extends CalendarPanelSharedProps {\n variant: 'multiple';\n selected?: Date[];\n onSelect?: (selected: Date[] | undefined, triggerDate: Date) => void;\n}\n\n/** `variant=\"range\"` — `selected` is a `DateRange`, two months render, and the footer is shown. */\nexport interface CalendarPanelRangeProps extends CalendarPanelSharedProps {\n variant: 'range';\n selected?: DateRange;\n onSelect?: (selected: DateRange | undefined, triggerDate: Date) => void;\n}\n\n/**\n * `CalendarPanel`'s props, discriminated by `variant` — a `single` panel only\n * accepts a `Date`, `multiple` only a `Date[]`, `range` only a `DateRange`, so\n * mismatched `selected`/`onSelect` shapes are caught at the call site instead\n * of silently reaching `react-day-picker` with the wrong shape at runtime.\n */\nexport type CalendarPanelProps =\n | CalendarPanelSingleProps\n | CalendarPanelMultipleProps\n | CalendarPanelRangeProps;\n\nconst CalendarPanel = React.forwardRef<HTMLDivElement, CalendarPanelProps>(\n (\n {\n className,\n variant = 'single',\n selected,\n onSelect,\n defaultMonth,\n month,\n onMonthChange,\n disabled,\n min,\n max,\n showOutsideDays = true,\n weekStartsOn,\n fromYear,\n toYear,\n locale,\n monthLabel = 'Month',\n yearLabel = 'Year',\n formatMonthLabel,\n cancelLabel = 'Cancel',\n applyLabel = 'Apply',\n onCancel,\n onApply,\n dir,\n ...props\n },\n ref\n ) => {\n const currentYear = new Date().getFullYear();\n const { fromYear: resolvedFromYear, toYear: resolvedToYear } = resolveYearRange(\n fromYear,\n toYear,\n currentYear,\n DEFAULT_YEAR_SPAN\n );\n const resolvedWeekStartsOn = resolveWeekStartsOn(weekStartsOn, locale);\n const showFooter = variant !== 'single';\n const numberOfMonths = variant === 'range' ? 2 : 1;\n\n // Stable across renders when the consumer doesn't override `formatMonthLabel`,\n // so `captionContext` below doesn't get a new identity (and rebuild the month\n // dropdown items) on every render.\n const defaultFormatMonthLabel = React.useCallback(\n (date: Date) => format(date, 'MMMM', { locale }),\n [locale]\n );\n const resolvedFormatMonthLabel = formatMonthLabel ?? defaultFormatMonthLabel;\n\n // Bounds the header dropdowns' navigation to the same window their own\n // options list offers — without this, keyboard shortcuts (Shift+PageUp/\n // PageDown) and a controlled `month` can move the grid past `fromYear`/\n // `toYear` while the year dropdown still only lists that range.\n const startMonth = React.useMemo(() => new Date(resolvedFromYear, 0, 1), [resolvedFromYear]);\n const endMonth = React.useMemo(() => new Date(resolvedToYear, 11, 1), [resolvedToYear]);\n\n const captionContext = React.useMemo<CalendarPanelCaptionContextValue>(\n () => ({\n monthLabel,\n yearLabel,\n fromYear: resolvedFromYear,\n toYear: resolvedToYear,\n formatMonthLabel: resolvedFormatMonthLabel,\n endMonth,\n numberOfMonths,\n }),\n [\n monthLabel,\n yearLabel,\n resolvedFromYear,\n resolvedToYear,\n resolvedFormatMonthLabel,\n endMonth,\n numberOfMonths,\n ]\n );\n\n // `selected`/`onSelect` are already guaranteed consistent with `variant` by\n // the discriminated `CalendarPanelProps` union above — this is the one\n // place that bridges to `DayPickerProps`'s own (differently-shaped)\n // discriminated union.\n const modeProps = buildModeProps(\n variant,\n selected,\n onSelect as unknown as\n | ((selected: CalendarPanelSelected, triggerDate: Date) => void)\n | undefined,\n min,\n max\n );\n\n return (\n <div\n ref={ref}\n dir={dir}\n data-slot=\"calendar-panel\"\n data-variant={variant}\n className={cn(\n 'inline-flex w-fit flex-col overflow-hidden rounded-[var(--ui-calendar-container-border-radius)] border-[length:var(--ui-calendar-container-border-width)] border-[color:var(--ui-calendar-container-border-color)] bg-[var(--ui-calendar-container-color)] shadow-md [border-style:var(--ui-calendar-container-border-style)]',\n className\n )}\n {...props}\n >\n <CalendarPanelCaptionContext.Provider value={captionContext}>\n <DayPicker\n {...modeProps}\n dir={dir}\n defaultMonth={defaultMonth}\n month={month}\n onMonthChange={onMonthChange}\n disabled={disabled}\n startMonth={startMonth}\n endMonth={endMonth}\n showOutsideDays={showOutsideDays}\n weekStartsOn={resolvedWeekStartsOn}\n locale={locale}\n numberOfMonths={variant === 'range' ? 2 : 1}\n // The design navigates months through the header dropdowns only —\n // there are no prev/next chevrons.\n hideNavigation\n classNames={{\n root: 'flex',\n months: 'flex flex-row',\n // The vertical rule between the two `range` months is the first\n // column's inline-end border, so it mirrors under RTL.\n // Width = 7 day columns + 2 sides of body padding, derived from tokens\n // so it stays in sync if either is retokened.\n month:\n 'flex w-[calc(var(--ui-calendar-item-width-min)*7+var(--ui-calendar-body-padding-x)*2)] flex-col border-e-[length:var(--ui-calendar-body-border-width)] border-[color:var(--ui-calendar-body-border-color)] last:border-e-0 [border-inline-end-style:var(--ui-calendar-body-border-style)]',\n // `table-fixed` (rather than the default `auto`) is what makes the\n // 32px-per-column contract above actually hold: under `auto`\n // layout a single wide weekday abbreviation (e.g. some `ar`/`te`/\n // `kn` locales) widens its whole column past the fixed 248px month\n // width, which the panel's `overflow-hidden` then clips — silently\n // dropping a day column instead of just the label.\n month_grid:\n 'w-full table-fixed border-separate border-spacing-0 px-[var(--ui-calendar-body-padding-x)] py-[var(--ui-calendar-body-padding-y)]',\n weekday:\n 'ui-calendar-value-text-style size-[var(--ui-calendar-item-width-min)] overflow-hidden whitespace-nowrap p-0 text-center font-normal text-[var(--ui-calendar-value-color-idle-secondary)]',\n day: 'group/day size-[var(--ui-calendar-item-width-min)] p-0 text-center',\n outside: '[&_button]:text-[var(--ui-calendar-value-color-disabled)]',\n disabled: '[&_button]:text-[var(--ui-calendar-value-color-disabled)]',\n hidden: 'invisible',\n }}\n components={{\n MonthCaption: CalendarHeader,\n DayButton: CalendarItem,\n }}\n />\n </CalendarPanelCaptionContext.Provider>\n {showFooter && (\n <DialogFooterDefault>\n <Button variant=\"secondary\" onClick={onCancel}>\n {cancelLabel}\n </Button>\n <Button onClick={onApply}>{applyLabel}</Button>\n </DialogFooterDefault>\n )}\n </div>\n );\n }\n);\nCalendarPanel.displayName = 'CalendarPanel';\n\nexport { CalendarPanel, CalendarItem, CalendarHeader };\n"],"names":["CalendarPanelCaptionContext","React","CalendarHeaderSelect","items","value","ariaLabel","onValueChange","jsxs","InputSelect","next","jsx","InputSelectTrigger","InputSelectValue","InputSelectContent","item","InputSelectItem","CalendarHeader","calendarMonth","displayIndex","className","props","goToMonth","useDayPicker","context","monthLabel","yearLabel","fromYear","toYear","formatMonthLabel","endMonth","numberOfMonths","date","month","year","monthItems","buildMonthItems","yearItems","buildYearItems","cn","clampNavigationTarget","addMonths","CalendarItem","day","modifiers","ref","_a","isRangeMiddle","isActive","CalendarPanel","variant","selected","onSelect","defaultMonth","onMonthChange","disabled","min","max","showOutsideDays","weekStartsOn","locale","cancelLabel","applyLabel","onCancel","onApply","dir","currentYear","resolvedFromYear","resolvedToYear","resolveYearRange","DEFAULT_YEAR_SPAN","resolvedWeekStartsOn","resolveWeekStartsOn","showFooter","defaultFormatMonthLabel","format","resolvedFormatMonthLabel","startMonth","captionContext","modeProps","buildModeProps","DayPicker","DialogFooterDefault","Button"],"mappings":"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"}