@acronis-platform/ui-react 0.61.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 (204) 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-utils.js +63 -0
  8. package/dist/components/ui/calendar-panel/calendar-panel-utils.js.map +1 -0
  9. package/dist/components/ui/calendar-panel/calendar-panel.js +260 -0
  10. package/dist/components/ui/calendar-panel/calendar-panel.js.map +1 -0
  11. package/dist/components/ui/chip/chip.js +33 -33
  12. package/dist/components/ui/chip/chip.js.map +1 -1
  13. package/dist/components/ui/date-range-picker/date-range-picker-utils.js +11 -23
  14. package/dist/components/ui/date-range-picker/date-range-picker-utils.js.map +1 -1
  15. package/dist/components/ui/date-range-picker/date-range-picker.js +94 -134
  16. package/dist/components/ui/date-range-picker/date-range-picker.js.map +1 -1
  17. package/dist/components/ui/dropdown-menu/dropdown-menu.js +129 -72
  18. package/dist/components/ui/dropdown-menu/dropdown-menu.js.map +1 -1
  19. package/dist/components/ui/filter-cards/filter-cards.js +25 -0
  20. package/dist/components/ui/filter-cards/filter-cards.js.map +1 -0
  21. package/dist/components/ui/filter-chips/filter-chips.js +44 -0
  22. package/dist/components/ui/filter-chips/filter-chips.js.map +1 -0
  23. package/dist/components/ui/filter-search/filter-search.js +184 -138
  24. package/dist/components/ui/filter-search/filter-search.js.map +1 -1
  25. package/dist/components/ui/fitted-actions/fitted-actions.js +139 -0
  26. package/dist/components/ui/fitted-actions/fitted-actions.js.map +1 -0
  27. package/dist/components/ui/input-date-picker/input-date-picker.js +103 -93
  28. package/dist/components/ui/input-date-picker/input-date-picker.js.map +1 -1
  29. package/dist/components/ui/input-password/input-password.js +76 -66
  30. package/dist/components/ui/input-password/input-password.js.map +1 -1
  31. package/dist/components/ui/input-search/input-search.js +9 -9
  32. package/dist/components/ui/input-search/input-search.js.map +1 -1
  33. package/dist/components/ui/input-select/input-select.js +8 -8
  34. package/dist/components/ui/input-select/input-select.js.map +1 -1
  35. package/dist/components/ui/input-text/input-text.js +77 -66
  36. package/dist/components/ui/input-text/input-text.js.map +1 -1
  37. package/dist/components/ui/input-text-area/input-text-area.js +76 -66
  38. package/dist/components/ui/input-text-area/input-text-area.js.map +1 -1
  39. package/dist/components/ui/link/link.js +50 -35
  40. package/dist/components/ui/link/link.js.map +1 -1
  41. package/dist/components/ui/number-field/number-field.js +1 -1
  42. package/dist/components/ui/number-field/number-field.js.map +1 -1
  43. package/dist/components/ui/popover/popover.js +75 -56
  44. package/dist/components/ui/popover/popover.js.map +1 -1
  45. package/dist/components/ui/resizable/resizable.js +23 -11
  46. package/dist/components/ui/resizable/resizable.js.map +1 -1
  47. package/dist/components/ui/scroll-area/scroll-area.js +46 -30
  48. package/dist/components/ui/scroll-area/scroll-area.js.map +1 -1
  49. package/dist/components/ui/sidebar-secondary/sidebar-secondary.js.map +1 -1
  50. package/dist/components/ui/timer/timer.js +47 -0
  51. package/dist/components/ui/timer/timer.js.map +1 -0
  52. package/dist/components/ui/toast/toast.js +168 -61
  53. package/dist/components/ui/toast/toast.js.map +1 -1
  54. package/dist/components/ui/truncate-text/middle-truncate.js +20 -0
  55. package/dist/components/ui/truncate-text/middle-truncate.js.map +1 -0
  56. package/dist/components/ui/truncate-text/text-width.js +12 -0
  57. package/dist/components/ui/truncate-text/text-width.js.map +1 -0
  58. package/dist/components/ui/truncate-text/truncate-text.js +152 -0
  59. package/dist/components/ui/truncate-text/truncate-text.js.map +1 -0
  60. package/dist/index.js +507 -469
  61. package/dist/index.js.map +1 -1
  62. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/addDays.js +5 -5
  63. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/addDays.js.map +1 -1
  64. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/constants.js +3 -6
  65. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/constants.js.map +1 -1
  66. package/dist/node_modules/.pnpm/react-day-picker@10.0.1_@types_react@19.2.15_react@19.2.6/node_modules/react-day-picker/dist/esm/useDayPicker.js +3 -3
  67. package/dist/react.js +507 -469
  68. package/dist/react.js.map +1 -1
  69. package/dist/src/components/ui/alert/alert.d.ts +34 -3
  70. package/dist/src/components/ui/alert/index.d.ts +2 -2
  71. package/dist/src/components/ui/button/button.d.ts +1 -1
  72. package/dist/src/components/ui/button-group/button-group.d.ts +38 -0
  73. package/dist/src/components/ui/button-group/index.d.ts +1 -0
  74. package/dist/src/components/ui/button-icon/button-icon.d.ts +1 -1
  75. package/dist/src/components/ui/button-icon-menu/button-icon-menu.d.ts +28 -0
  76. package/dist/src/components/ui/button-icon-menu/index.d.ts +1 -0
  77. package/dist/src/components/ui/button-menu/button-menu.d.ts +1 -1
  78. package/dist/src/components/ui/calendar-panel/__tests__/calendar-panel-utils.test.d.ts +1 -0
  79. package/dist/src/components/ui/calendar-panel/calendar-panel-utils.d.ts +55 -0
  80. package/dist/src/components/ui/calendar-panel/calendar-panel.d.ts +112 -0
  81. package/dist/src/components/ui/calendar-panel/index.d.ts +1 -0
  82. package/dist/src/components/ui/chip/chip.d.ts +1 -1
  83. package/dist/src/components/ui/date-range-picker/date-range-picker-utils.d.ts +10 -16
  84. package/dist/src/components/ui/date-range-picker/date-range-picker.d.ts +46 -2
  85. package/dist/src/components/ui/dropdown-menu/dropdown-menu.d.ts +8 -1
  86. package/dist/src/components/ui/dropdown-menu/index.d.ts +1 -1
  87. package/dist/src/components/ui/filter-cards/filter-cards.d.ts +11 -0
  88. package/dist/src/components/ui/filter-cards/index.d.ts +1 -0
  89. package/dist/src/components/ui/filter-chips/filter-chips.d.ts +25 -0
  90. package/dist/src/components/ui/filter-chips/index.d.ts +1 -0
  91. package/dist/src/components/ui/filter-search/filter-search.d.ts +39 -1
  92. package/dist/src/components/ui/fitted-actions/fitted-actions.d.ts +50 -0
  93. package/dist/src/components/ui/fitted-actions/fitted-actions.docs.d.ts +45 -0
  94. package/dist/src/components/ui/fitted-actions/index.d.ts +1 -0
  95. package/dist/src/components/ui/link/index.d.ts +1 -1
  96. package/dist/src/components/ui/link/link.d.ts +22 -4
  97. package/dist/src/components/ui/metric/metric.d.ts +1 -1
  98. package/dist/src/components/ui/popover/popover.d.ts +30 -1
  99. package/dist/src/components/ui/popover/popover.docs.d.ts +27 -2
  100. package/dist/src/components/ui/scroll-area/scroll-area.d.ts +24 -0
  101. package/dist/src/components/ui/tag/tag.d.ts +1 -1
  102. package/dist/src/components/ui/timer/index.d.ts +1 -0
  103. package/dist/src/components/ui/timer/timer.d.ts +28 -0
  104. package/dist/src/components/ui/toast/index.d.ts +1 -1
  105. package/dist/src/components/ui/toast/toast.d.ts +51 -18
  106. package/dist/src/components/ui/toast/toast.docs.d.ts +4 -0
  107. package/dist/src/components/ui/trend-indicator/trend-indicator.d.ts +1 -1
  108. package/dist/src/components/ui/truncate-text/__tests__/middle-truncate.test.d.ts +1 -0
  109. package/dist/src/components/ui/truncate-text/index.d.ts +3 -0
  110. package/dist/src/components/ui/truncate-text/middle-truncate.d.ts +13 -0
  111. package/dist/src/components/ui/truncate-text/text-width.d.ts +11 -0
  112. package/dist/src/components/ui/truncate-text/truncate-text.d.ts +45 -0
  113. package/dist/src/components/ui/truncate-text/truncate-text.docs.d.ts +35 -0
  114. package/dist/src/index.d.ts +8 -0
  115. package/dist/ui-react.css +1 -1
  116. package/package.json +4 -4
  117. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/getDefaultOptions.js +0 -8
  118. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/getDefaultOptions.js.map +0 -1
  119. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/getISODay.js +0 -9
  120. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/getISODay.js.map +0 -1
  121. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/Parser.js +0 -23
  122. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/Parser.js.map +0 -1
  123. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/Setter.js +0 -42
  124. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/Setter.js.map +0 -1
  125. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/constants.js +0 -50
  126. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/constants.js.map +0 -1
  127. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/parsers/AMPMMidnightParser.js +0 -50
  128. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/parsers/AMPMMidnightParser.js.map +0 -1
  129. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/parsers/AMPMParser.js +0 -50
  130. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/parsers/AMPMParser.js.map +0 -1
  131. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/parsers/DateParser.js +0 -62
  132. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/parsers/DateParser.js.map +0 -1
  133. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/parsers/DayOfYearParser.js +0 -52
  134. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/parsers/DayOfYearParser.js.map +0 -1
  135. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/parsers/DayParser.js +0 -50
  136. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/parsers/DayParser.js.map +0 -1
  137. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/parsers/DayPeriodParser.js +0 -50
  138. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/parsers/DayPeriodParser.js.map +0 -1
  139. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/parsers/EraParser.js +0 -34
  140. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/parsers/EraParser.js.map +0 -1
  141. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/parsers/ExtendedYearParser.js +0 -22
  142. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/parsers/ExtendedYearParser.js.map +0 -1
  143. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/parsers/FractionOfSecondParser.js +0 -23
  144. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/parsers/FractionOfSecondParser.js.map +0 -1
  145. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/parsers/Hour0To11Parser.js +0 -33
  146. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/parsers/Hour0To11Parser.js.map +0 -1
  147. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/parsers/Hour0to23Parser.js +0 -33
  148. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/parsers/Hour0to23Parser.js.map +0 -1
  149. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/parsers/Hour1To24Parser.js +0 -34
  150. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/parsers/Hour1To24Parser.js.map +0 -1
  151. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/parsers/Hour1to12Parser.js +0 -34
  152. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/parsers/Hour1to12Parser.js.map +0 -1
  153. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/parsers/ISODayParser.js +0 -106
  154. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/parsers/ISODayParser.js.map +0 -1
  155. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/parsers/ISOTimezoneParser.js +0 -49
  156. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/parsers/ISOTimezoneParser.js.map +0 -1
  157. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/parsers/ISOTimezoneWithZParser.js +0 -49
  158. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/parsers/ISOTimezoneWithZParser.js.map +0 -1
  159. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/parsers/ISOWeekParser.js +0 -50
  160. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/parsers/ISOWeekParser.js.map +0 -1
  161. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/parsers/ISOWeekYearParser.js +0 -41
  162. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/parsers/ISOWeekYearParser.js.map +0 -1
  163. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/parsers/LocalDayParser.js +0 -81
  164. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/parsers/LocalDayParser.js.map +0 -1
  165. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/parsers/LocalWeekParser.js +0 -49
  166. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/parsers/LocalWeekParser.js.map +0 -1
  167. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/parsers/LocalWeekYearParser.js +0 -70
  168. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/parsers/LocalWeekYearParser.js.map +0 -1
  169. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/parsers/MinuteParser.js +0 -33
  170. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/parsers/MinuteParser.js.map +0 -1
  171. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/parsers/MonthParser.js +0 -78
  172. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/parsers/MonthParser.js.map +0 -1
  173. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/parsers/QuarterParser.js +0 -76
  174. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/parsers/QuarterParser.js.map +0 -1
  175. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/parsers/SecondParser.js +0 -33
  176. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/parsers/SecondParser.js.map +0 -1
  177. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/parsers/StandAloneLocalDayParser.js +0 -81
  178. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/parsers/StandAloneLocalDayParser.js.map +0 -1
  179. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/parsers/StandAloneMonthParser.js +0 -78
  180. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/parsers/StandAloneMonthParser.js.map +0 -1
  181. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/parsers/StandAloneQuarterParser.js +0 -76
  182. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/parsers/StandAloneQuarterParser.js.map +0 -1
  183. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/parsers/TimestampMillisecondsParser.js +0 -23
  184. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/parsers/TimestampMillisecondsParser.js.map +0 -1
  185. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/parsers/TimestampSecondsParser.js +0 -23
  186. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/parsers/TimestampSecondsParser.js.map +0 -1
  187. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/parsers/YearParser.js +0 -50
  188. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/parsers/YearParser.js.map +0 -1
  189. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/parsers.js +0 -68
  190. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/parsers.js.map +0 -1
  191. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/utils.js +0 -104
  192. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse/_lib/utils.js.map +0 -1
  193. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse.js +0 -86
  194. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/parse.js.map +0 -1
  195. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/setDay.js +0 -12
  196. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/setDay.js.map +0 -1
  197. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/setISODay.js +0 -11
  198. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/setISODay.js.map +0 -1
  199. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/setISOWeek.js +0 -10
  200. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/setISOWeek.js.map +0 -1
  201. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/setWeek.js +0 -10
  202. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/setWeek.js.map +0 -1
  203. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/transpose.js +0 -18
  204. package/dist/node_modules/.pnpm/date-fns@4.3.0/node_modules/date-fns/transpose.js.map +0 -1
@@ -0,0 +1,25 @@
1
+ import * as m from "react";
2
+ import { mergeProps as o } from "@base-ui/react/merge-props";
3
+ import { useRender as s } from "@base-ui/react/use-render";
4
+ import { cn as p } from "../../../lib/utils.js";
5
+ const f = m.forwardRef(
6
+ ({ className: r, render: e, ...a }, t) => s({
7
+ render: e,
8
+ ref: t,
9
+ defaultTagName: "div",
10
+ props: o(
11
+ {
12
+ className: p(
13
+ "flex w-full items-stretch gap-[var(--ui-gap-16)] [&>*]:flex-1",
14
+ r
15
+ )
16
+ },
17
+ a
18
+ )
19
+ })
20
+ );
21
+ f.displayName = "FilterCards";
22
+ export {
23
+ f as FilterCards
24
+ };
25
+ //# sourceMappingURL=filter-cards.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"filter-cards.js","sources":["../../../../src/components/ui/filter-cards/filter-cards.tsx"],"sourcesContent":["import * as React from 'react';\nimport { mergeProps } from '@base-ui/react/merge-props';\nimport { useRender } from '@base-ui/react/use-render';\n\nimport { cn } from '@/lib/utils';\n\n// Mirrors the Figma \"FilterCards\" component: a horizontal row of `CardFilter`\n// items (Figma's nested \"ListCards\" slot maps to `children`) that fills its\n// container and distributes the available width evenly across however many\n// cards are passed in, matching the \"fill container\" sizing Figma applies to\n// each CardFilter instance inside this composition — it overrides CardFilter's\n// own fixed 224px width. The only styling this container owns is the 16px\n// inter-card gap (`--ui-gap-16`) and `items-stretch`, so every card matches\n// the row's tallest sibling even if one card's label wraps onto a second\n// line; there is no dedicated `--ui-filter-cards-*` token tier.\n//\n// Cards only shrink down to their own content's natural (min-content) width —\n// there is no `min-w-0` override, so the browser's default `min-width: auto`\n// on flex items applies. Once the cards' combined min-content width exceeds\n// the row, the row overflows its container rather than clipping any card's\n// content; the consumer is responsible for giving the row a scrollable\n// container (e.g. `overflow-x-auto`) if that's the desired behavior for a\n// given layout — FilterCards itself never adds scroll or wrap.\nexport interface FilterCardsProps extends React.ComponentPropsWithoutRef<'div'> {\n /**\n * Replace the rendered `<div>` with another element or component\n * (Base UI composition).\n */\n render?: useRender.RenderProp;\n}\n\nconst FilterCards = React.forwardRef<HTMLDivElement, FilterCardsProps>(\n ({ className, render, ...props }, ref) => {\n return useRender({\n render,\n ref,\n defaultTagName: 'div',\n props: mergeProps<'div'>(\n {\n className: cn(\n 'flex w-full items-stretch gap-[var(--ui-gap-16)] [&>*]:flex-1',\n className\n ),\n },\n props\n ),\n });\n }\n);\nFilterCards.displayName = 'FilterCards';\n\nexport { FilterCards };\n"],"names":["FilterCards","React","className","render","props","ref","useRender","mergeProps","cn"],"mappings":";;;;AA+BA,MAAMA,IAAcC,EAAM;AAAA,EACxB,CAAC,EAAE,WAAAC,GAAW,QAAAC,GAAQ,GAAGC,EAAA,GAASC,MACzBC,EAAU;AAAA,IACf,QAAAH;AAAA,IACA,KAAAE;AAAA,IACA,gBAAgB;AAAA,IAChB,OAAOE;AAAA,MACL;AAAA,QACE,WAAWC;AAAA,UACT;AAAA,UACAN;AAAA,QAAA;AAAA,MACF;AAAA,MAEFE;AAAA,IAAA;AAAA,EACF,CACD;AAEL;AACAJ,EAAY,cAAc;"}
@@ -0,0 +1,44 @@
1
+ import { jsx as a } from "react/jsx-runtime";
2
+ import * as s from "react";
3
+ import { mergeProps as m } from "@base-ui/react/merge-props";
4
+ import { useRender as l } from "@base-ui/react/use-render";
5
+ import { cn as o } from "../../../lib/utils.js";
6
+ import { Button as f } from "../button/button.js";
7
+ const n = s.forwardRef(
8
+ ({ className: e, render: r, ariaLabel: t = "Applied filters", ...i }, p) => l({
9
+ render: r,
10
+ ref: p,
11
+ defaultTagName: "div",
12
+ props: m(
13
+ {
14
+ role: "group",
15
+ "aria-label": t,
16
+ className: o("flex items-center gap-[var(--ui-gap-16)]", e)
17
+ },
18
+ i
19
+ )
20
+ })
21
+ );
22
+ n.displayName = "FilterChips";
23
+ const c = s.forwardRef(
24
+ ({ className: e, ...r }, t) => /* @__PURE__ */ a(
25
+ "div",
26
+ {
27
+ ref: t,
28
+ className: o(
29
+ "flex min-w-0 flex-wrap content-center items-center gap-[var(--ui-gap-8)]",
30
+ e
31
+ ),
32
+ ...r
33
+ }
34
+ )
35
+ );
36
+ c.displayName = "FilterChipsList";
37
+ const d = s.forwardRef(({ children: e = "Reset filters", type: r = "button", ...t }, i) => /* @__PURE__ */ a(f, { ref: i, type: r, variant: "ghost", ...t, children: e }));
38
+ d.displayName = "FilterChipsReset";
39
+ export {
40
+ n as FilterChips,
41
+ c as FilterChipsList,
42
+ d as FilterChipsReset
43
+ };
44
+ //# sourceMappingURL=filter-chips.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"filter-chips.js","sources":["../../../../src/components/ui/filter-chips/filter-chips.tsx"],"sourcesContent":["import * as React from 'react';\nimport { mergeProps } from '@base-ui/react/merge-props';\nimport { useRender } from '@base-ui/react/use-render';\n\nimport { cn } from '@/lib/utils';\nimport { Button } from '../button';\n\n// Composable applied-filter row mirroring the Figma \"FilterChips\" component:\n// a wrapping list of removable `Chip`s closed by a ghost \"Reset filters\" action\n// that clears them all at once.\n//\n// There is no `--ui-filter-chips-*` tier, and none is needed — the design\n// references exactly two primitive gap tokens: `--ui-gap-16` between the root's\n// children and `--ui-gap-8` between the items inside the list. Every other token\n// in the node belongs to `Chip` (`--ui-chip-*`) or `Button`\n// (`--ui-button-ghost-*`), which already own them.\n//\n// Figma models the chip area as a single `ListChips` slot, so the chips are the\n// consumer's children rather than a data prop. The \"Reset filters\" button sits\n// *inside* that slot — the design measures 8px, not 16px, between the last chip\n// and the button — so compose `FilterChipsReset` as the last child of\n// `FilterChipsList`. The root's 16px gap is for anything a consumer places\n// beside the list as a whole.\n//\n// Chips are 24px tall and the ghost button is 32px, so the row is 32px tall with\n// the chips centered in it (`items-center`).\n\nexport interface FilterChipsProps extends React.ComponentPropsWithoutRef<'div'> {\n /**\n * Replace the rendered `<div>` with another element or component\n * (Base UI composition). Accepts a React element or a render function.\n */\n render?: useRender.RenderProp;\n /** Accessible name for the applied-filter region. */\n ariaLabel?: string;\n}\n\nconst FilterChips = React.forwardRef<HTMLDivElement, FilterChipsProps>(\n ({ className, render, ariaLabel = 'Applied filters', ...props }, ref) =>\n useRender({\n render,\n ref,\n defaultTagName: 'div',\n props: mergeProps<'div'>(\n {\n role: 'group',\n 'aria-label': ariaLabel,\n className: cn('flex items-center gap-[var(--ui-gap-16)]', className),\n },\n props\n ),\n })\n);\nFilterChips.displayName = 'FilterChips';\n\nexport type FilterChipsListProps = React.ComponentPropsWithoutRef<'div'>;\n\nconst FilterChipsList = React.forwardRef<HTMLDivElement, FilterChipsListProps>(\n ({ className, ...props }, ref) => (\n <div\n ref={ref}\n className={cn(\n 'flex min-w-0 flex-wrap content-center items-center gap-[var(--ui-gap-8)]',\n className\n )}\n {...props}\n />\n )\n);\nFilterChipsList.displayName = 'FilterChipsList';\n\nexport interface FilterChipsResetProps\n extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n /**\n * Replace the rendered `<button>` with another element or component\n * (Base UI composition). Accepts a React element or a render function.\n */\n render?: useRender.RenderProp;\n /** Label for the reset action. */\n children?: React.ReactNode;\n}\n\nconst FilterChipsReset = React.forwardRef<\n HTMLButtonElement,\n FilterChipsResetProps\n>(({ children = 'Reset filters', type = 'button', ...props }, ref) => (\n <Button ref={ref} type={type} variant=\"ghost\" {...props}>\n {children}\n </Button>\n));\nFilterChipsReset.displayName = 'FilterChipsReset';\n\nexport { FilterChips, FilterChipsList, FilterChipsReset };\n"],"names":["FilterChips","React","className","render","ariaLabel","props","ref","useRender","mergeProps","cn","FilterChipsList","jsx","FilterChipsReset","children","type","Button"],"mappings":";;;;;;AAqCA,MAAMA,IAAcC,EAAM;AAAA,EACxB,CAAC,EAAE,WAAAC,GAAW,QAAAC,GAAQ,WAAAC,IAAY,mBAAmB,GAAGC,EAAA,GAASC,MAC/DC,EAAU;AAAA,IACR,QAAAJ;AAAA,IACA,KAAAG;AAAA,IACA,gBAAgB;AAAA,IAChB,OAAOE;AAAA,MACL;AAAA,QACE,MAAM;AAAA,QACN,cAAcJ;AAAA,QACd,WAAWK,EAAG,4CAA4CP,CAAS;AAAA,MAAA;AAAA,MAErEG;AAAA,IAAA;AAAA,EACF,CACD;AACL;AACAL,EAAY,cAAc;AAI1B,MAAMU,IAAkBT,EAAM;AAAA,EAC5B,CAAC,EAAE,WAAAC,GAAW,GAAGG,EAAA,GAASC,MACxB,gBAAAK;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,KAAAL;AAAA,MACA,WAAWG;AAAA,QACT;AAAA,QACAP;AAAA,MAAA;AAAA,MAED,GAAGG;AAAA,IAAA;AAAA,EAAA;AAGV;AACAK,EAAgB,cAAc;AAa9B,MAAME,IAAmBX,EAAM,WAG7B,CAAC,EAAE,UAAAY,IAAW,iBAAiB,MAAAC,IAAO,UAAU,GAAGT,EAAA,GAASC,MAC5D,gBAAAK,EAACI,KAAO,KAAAT,GAAU,MAAAQ,GAAY,SAAQ,SAAS,GAAGT,GAC/C,UAAAQ,GACH,CACD;AACDD,EAAiB,cAAc;"}
@@ -1,165 +1,211 @@
1
- import { jsx as n, jsxs as d } from "react/jsx-runtime";
2
- import * as a from "react";
3
- import { ChevronDownIcon as A } from "@acronis-platform/icons-react/stroke-mono";
1
+ import { jsx as r, jsxs as d } from "react/jsx-runtime";
2
+ import * as i from "react";
3
+ import { ChevronDownIcon as M } from "@acronis-platform/icons-react/stroke-mono";
4
4
  import { cn as u } from "../../../lib/utils.js";
5
- import { deepEqual as P } from "../../../lib/deep-equal.js";
6
- import { Chip as $ } from "../chip/chip.js";
7
- import { Button as p } from "../button/button.js";
8
- import { Popover as E, PopoverTrigger as q, PopoverContent as z } from "../popover/popover.js";
9
- const B = a.forwardRef(
10
- ({ className: t, ...e }, r) => /* @__PURE__ */ n(
5
+ import { deepEqual as T } from "../../../lib/deep-equal.js";
6
+ import { FilterChips as G, FilterChipsList as H, FilterChipsReset as K } from "../filter-chips/filter-chips.js";
7
+ import { Chip as Q } from "../chip/chip.js";
8
+ import { Popover as U, PopoverTrigger as W, PopoverContent as X } from "../popover/popover.js";
9
+ import { Button as h } from "../button/button.js";
10
+ const Y = i.forwardRef(
11
+ ({ className: t, ...e }, n) => /* @__PURE__ */ r(
11
12
  "div",
12
13
  {
13
- ref: r,
14
+ ref: n,
14
15
  className: u("flex items-center gap-4", t),
15
16
  ...e
16
17
  }
17
18
  )
18
19
  );
19
- B.displayName = "FilterSearch";
20
- const I = a.forwardRef(({ className: t, ...e }, r) => /* @__PURE__ */ n(
20
+ Y.displayName = "FilterSearch";
21
+ const Z = i.forwardRef(({ className: t, ...e }, n) => /* @__PURE__ */ r(
21
22
  "div",
22
23
  {
23
- ref: r,
24
- className: u("flex h-8 min-w-px flex-1 items-center justify-end gap-4", t),
24
+ ref: n,
25
+ className: u(
26
+ "flex h-8 min-w-px flex-1 items-center justify-end gap-4",
27
+ t
28
+ ),
25
29
  ...e
26
30
  }
27
31
  ));
28
- I.displayName = "FilterSearchActions";
29
- const C = a.createContext(null);
30
- function X() {
31
- const t = a.useContext(C);
32
+ Z.displayName = "FilterSearchActions";
33
+ const R = i.createContext(null);
34
+ function le() {
35
+ const t = i.useContext(R);
32
36
  if (t === null)
33
37
  throw new Error(
34
38
  "useFilterSearchFilters must be used within a <FilterSearchFilters> popover."
35
39
  );
36
40
  return t;
37
41
  }
38
- const J = a.forwardRef(({ value: t, onValueChange: e, onApply: r, label: s = "Filters", children: b, className: x, ...m }, v) => {
39
- const [o, l] = a.useState(!1), [c, f] = a.useState(t), N = (i) => {
40
- f(t), l(i);
41
- }, F = a.useCallback((i, g) => {
42
- f((h) => {
43
- if (g === void 0) {
44
- if (!(i in h)) return h;
45
- const S = { ...h };
46
- return delete S[i], S;
47
- }
48
- return { ...h, [i]: g };
49
- });
50
- }, []), y = a.useMemo(
51
- () => ({ filters: c, setFilter: F }),
52
- [c, F]
53
- ), w = () => f({}), R = () => {
54
- f(t), l(!1);
55
- }, j = () => {
56
- e(c), r == null || r(c), l(!1);
57
- }, O = Object.keys(c).length === 0, D = P(c, t);
58
- return /* @__PURE__ */ d(E, { open: o, onOpenChange: N, children: [
59
- /* @__PURE__ */ d(
60
- q,
61
- {
62
- ref: v,
63
- render: /* @__PURE__ */ n(
64
- p,
65
- {
66
- variant: "secondary",
67
- className: u(
68
- "group data-[popup-open]:border-[var(--ui-button-secondary-container-border-color-active)] data-[popup-open]:bg-[var(--ui-button-secondary-container-color-active)] data-[popup-open]:text-[var(--ui-button-secondary-label-color-active)]",
69
- x
70
- ),
71
- ...m
72
- }
73
- ),
74
- children: [
75
- s,
76
- /* @__PURE__ */ n(
77
- A,
42
+ const _ = i.forwardRef(
43
+ ({
44
+ value: t,
45
+ onValueChange: e,
46
+ onApply: n,
47
+ label: s = "Filters",
48
+ resetFiltersLabel: b = "Reset filters",
49
+ cancelLabel: F = "Cancel",
50
+ applyLabel: x = "Apply",
51
+ children: v,
52
+ className: l,
53
+ contentClassName: S,
54
+ side: o,
55
+ align: p = "start",
56
+ sideOffset: w,
57
+ portalContainer: j,
58
+ collisionBoundary: O,
59
+ positionMethod: D,
60
+ ...A
61
+ }, P) => {
62
+ const [$, C] = i.useState(!1), [c, m] = i.useState(t), E = (a) => {
63
+ m(t), C(a);
64
+ }, g = i.useCallback((a, N) => {
65
+ m((f) => {
66
+ if (N === void 0) {
67
+ if (!(a in f)) return f;
68
+ const y = { ...f };
69
+ return delete y[a], y;
70
+ }
71
+ return { ...f, [a]: N };
72
+ });
73
+ }, []), L = i.useMemo(
74
+ () => ({ filters: c, setFilter: g }),
75
+ [c, g]
76
+ ), q = () => m({}), z = () => {
77
+ m(t), C(!1);
78
+ }, B = () => {
79
+ e(c), n == null || n(c), C(!1);
80
+ }, I = Object.keys(c).length === 0, J = T(c, t);
81
+ return /* @__PURE__ */ d(U, { open: $, onOpenChange: E, children: [
82
+ /* @__PURE__ */ d(
83
+ W,
84
+ {
85
+ ref: P,
86
+ render: /* @__PURE__ */ r(
87
+ h,
78
88
  {
79
- size: 16,
80
- className: "transition-transform group-data-[popup-open]:rotate-180"
89
+ variant: "secondary",
90
+ className: u(
91
+ "group data-[popup-open]:border-[var(--ui-button-secondary-container-border-color-active)] data-[popup-open]:bg-[var(--ui-button-secondary-container-color-active)] data-[popup-open]:text-[var(--ui-button-secondary-label-color-active)]",
92
+ l
93
+ ),
94
+ ...A
81
95
  }
82
- )
83
- ]
84
- }
85
- ),
86
- /* @__PURE__ */ n(z, { align: "start", className: "w-96 p-0", children: /* @__PURE__ */ d(
87
- "form",
88
- {
89
- onSubmit: (i) => {
90
- i.preventDefault(), j();
91
- },
92
- children: [
93
- /* @__PURE__ */ n("div", { className: "flex max-h-80 flex-col gap-4 overflow-y-auto p-4", children: /* @__PURE__ */ n(C.Provider, { value: y, children: b }) }),
94
- /* @__PURE__ */ d("div", { className: "flex items-center gap-2 border-t border-border p-4", children: [
95
- /* @__PURE__ */ n(
96
- p,
96
+ ),
97
+ children: [
98
+ s,
99
+ /* @__PURE__ */ r(
100
+ M,
97
101
  {
98
- type: "button",
99
- variant: "ghost",
100
- disabled: O,
101
- onClick: w,
102
- children: "Reset filters"
102
+ size: 16,
103
+ className: "transition-transform group-data-[popup-open]:rotate-180"
103
104
  }
104
- ),
105
- /* @__PURE__ */ d("div", { className: "ms-auto flex items-center gap-2", children: [
106
- /* @__PURE__ */ n(p, { type: "button", variant: "secondary", onClick: R, children: "Cancel" }),
107
- /* @__PURE__ */ n(p, { type: "submit", variant: "default", disabled: D, children: "Apply" })
108
- ] })
109
- ] })
110
- ]
111
- }
112
- ) })
113
- ] });
114
- });
115
- J.displayName = "FilterSearchFilters";
116
- function L(t, e) {
117
- const r = Array.isArray(e) ? e.map((s) => String(s)).join(", ") : typeof e == "object" && e !== null ? JSON.stringify(e) : String(e);
118
- return `${t}: ${r}`;
105
+ )
106
+ ]
107
+ }
108
+ ),
109
+ /* @__PURE__ */ r(
110
+ X,
111
+ {
112
+ side: o,
113
+ align: p,
114
+ sideOffset: w,
115
+ portalContainer: j,
116
+ collisionBoundary: O,
117
+ positionMethod: D,
118
+ className: u("w-96 p-0", S),
119
+ children: /* @__PURE__ */ d(
120
+ "form",
121
+ {
122
+ onSubmit: (a) => {
123
+ a.preventDefault(), B();
124
+ },
125
+ children: [
126
+ /* @__PURE__ */ r("div", { className: "flex max-h-80 flex-col gap-4 overflow-y-auto p-4", children: /* @__PURE__ */ r(R.Provider, { value: L, children: v }) }),
127
+ /* @__PURE__ */ d("div", { className: "flex items-center gap-2 border-t border-border p-4", children: [
128
+ /* @__PURE__ */ r(
129
+ h,
130
+ {
131
+ type: "button",
132
+ variant: "ghost",
133
+ disabled: I,
134
+ onClick: q,
135
+ children: b
136
+ }
137
+ ),
138
+ /* @__PURE__ */ d("div", { className: "ms-auto flex items-center gap-2", children: [
139
+ /* @__PURE__ */ r(
140
+ h,
141
+ {
142
+ type: "button",
143
+ variant: "secondary",
144
+ onClick: z,
145
+ children: F
146
+ }
147
+ ),
148
+ /* @__PURE__ */ r(
149
+ h,
150
+ {
151
+ type: "submit",
152
+ variant: "default",
153
+ disabled: J,
154
+ children: x
155
+ }
156
+ )
157
+ ] })
158
+ ] })
159
+ ]
160
+ }
161
+ )
162
+ }
163
+ )
164
+ ] });
165
+ }
166
+ );
167
+ _.displayName = "FilterSearchFilters";
168
+ function k(t, e) {
169
+ const n = Array.isArray(e) ? e.map((s) => String(s)).join(", ") : typeof e == "object" && e !== null ? JSON.stringify(e) : String(e);
170
+ return `${t}: ${n}`;
119
171
  }
120
- const M = a.forwardRef(({ className: t, filters: e, onValueChange: r, getFilterChipLabel: s, ...b }, x) => {
121
- const m = Object.keys(e);
122
- if (m.length === 0) return null;
123
- const v = (o) => {
124
- const l = { ...e };
125
- delete l[o], r(l);
126
- };
127
- return /* @__PURE__ */ d(
128
- "div",
129
- {
130
- ref: x,
131
- className: u("flex flex-wrap items-center gap-3", t),
132
- ...b,
133
- children: [
134
- m.map((o) => /* @__PURE__ */ n(
135
- $,
136
- {
137
- variant: "removable",
138
- onRemove: () => v(o),
139
- removeLabel: `Remove ${o} filter`,
140
- children: s ? s(o, e[o]) : L(o, e[o])
141
- },
142
- o
143
- )),
144
- /* @__PURE__ */ n(
145
- p,
146
- {
147
- type: "button",
148
- variant: "ghost",
149
- onClick: () => r({}),
150
- children: "Reset filters"
151
- }
152
- )
153
- ]
154
- }
155
- );
156
- });
157
- M.displayName = "FilterSearchAppliedFilters";
172
+ const V = i.forwardRef(
173
+ ({
174
+ className: t,
175
+ filters: e,
176
+ onValueChange: n,
177
+ getFilterChipLabel: s,
178
+ getRemoveFilterLabel: b = (l) => `Remove ${l} filter`,
179
+ resetFiltersLabel: F = "Reset filters",
180
+ ...x
181
+ }, v) => {
182
+ const l = Object.keys(e);
183
+ if (l.length === 0) return null;
184
+ const S = (o) => {
185
+ const p = { ...e };
186
+ delete p[o], n(p);
187
+ };
188
+ return /* @__PURE__ */ r(G, { ref: v, className: t, ...x, children: /* @__PURE__ */ d(H, { children: [
189
+ l.map((o) => /* @__PURE__ */ r(
190
+ Q,
191
+ {
192
+ variant: "removable",
193
+ onRemove: () => S(o),
194
+ removeLabel: b(o),
195
+ children: s ? s(o, e[o]) : k(o, e[o])
196
+ },
197
+ o
198
+ )),
199
+ /* @__PURE__ */ r(K, { onClick: () => n({}), children: F })
200
+ ] }) });
201
+ }
202
+ );
203
+ V.displayName = "FilterSearchAppliedFilters";
158
204
  export {
159
- B as FilterSearch,
160
- I as FilterSearchActions,
161
- M as FilterSearchAppliedFilters,
162
- J as FilterSearchFilters,
163
- X as useFilterSearchFilters
205
+ Y as FilterSearch,
206
+ Z as FilterSearchActions,
207
+ V as FilterSearchAppliedFilters,
208
+ _ as FilterSearchFilters,
209
+ le as useFilterSearchFilters
164
210
  };
165
211
  //# sourceMappingURL=filter-search.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"filter-search.js","sources":["../../../../src/components/ui/filter-search/filter-search.tsx"],"sourcesContent":["import * as React from 'react';\nimport { ChevronDownIcon } from '@acronis-platform/icons-react/stroke-mono';\n\nimport { cn } from '@/lib/utils';\nimport { deepEqual } from '@/lib/deep-equal';\nimport { Button } from '../button';\nimport { Chip } from '../chip';\nimport { Popover, PopoverContent, PopoverTrigger } from '../popover';\n\n// A composable toolbar for data tables: arranges a search field, optional\n// filters button, optional tenant/scope switcher, and trailing action buttons\n// in a single horizontal row. Maps to the Figma \"FilterSearch\" component. The\n// root container uses 16px inter-item gap (Figma `gap/gap-16`) and centers\n// children vertically. `FilterSearchActions` is a right-aligned flex area that\n// pushes its content to the trailing edge.\n//\n// No dedicated token tier — spacing is the Figma `gap/gap-16` semantic token\n// (16px), and each child (Search, ButtonMenu, Select) brings its own\n// `--ui-*` tier.\n//\n// `FilterSearchFilters` and `FilterSearchAppliedFilters` are design-pending\n// additions (no Figma node yet, unlike the FilterSearch node itself): the\n// filter popover (trigger + form + Reset/Cancel/Apply) and the applied-filter\n// chip row + top-level \"Reset filters\" affordance. Compose `FilterSearchFilters`\n// as a child of `<FilterSearch>` in place of a plain filter trigger, and render\n// `<FilterSearchAppliedFilters>` as a sibling row below it. Reconcile against\n// the real design with `/figma-component FilterSearchFilters <url> --update`\n// once a mockup lands.\n\nexport type FilterSearchProps = React.ComponentPropsWithoutRef<'div'>;\n\nconst FilterSearch = React.forwardRef<HTMLDivElement, FilterSearchProps>(\n ({ className, ...props }, ref) => (\n <div\n ref={ref}\n className={cn('flex items-center gap-4', className)}\n {...props}\n />\n )\n);\nFilterSearch.displayName = 'FilterSearch';\n\nexport type FilterSearchActionsProps = React.ComponentPropsWithoutRef<'div'>;\n\nconst FilterSearchActions = React.forwardRef<\n HTMLDivElement,\n FilterSearchActionsProps\n>(({ className, ...props }, ref) => (\n <div\n ref={ref}\n className={cn('flex h-8 min-w-px flex-1 items-center justify-end gap-4', className)}\n {...props}\n />\n));\nFilterSearchActions.displayName = 'FilterSearchActions';\n\ninterface FilterSearchFiltersContextValue {\n /** The current draft filters being edited inside the popover. */\n filters: Record<string, unknown>;\n /** Set a single draft filter value by key. */\n setFilter: (key: string, value: unknown) => void;\n}\n\nconst FilterSearchFiltersContext =\n React.createContext<FilterSearchFiltersContextValue | null>(null);\n\n/**\n * Bind a filter field child (rendered inside `FilterSearchFilters`'s popover) to\n * the component's draft filters. Returns the current draft map and a per-key\n * setter. Field children are plain JSX (no render prop) and wire their own\n * `onChange` to `setFilter`; Apply commits the draft, Cancel/dismiss reverts it.\n */\nexport function useFilterSearchFilters(): FilterSearchFiltersContextValue {\n const context = React.useContext(FilterSearchFiltersContext);\n if (context === null) {\n throw new Error(\n 'useFilterSearchFilters must be used within a <FilterSearchFilters> popover.'\n );\n }\n return context;\n}\n\nexport interface FilterSearchFiltersProps\n extends Omit<React.ComponentPropsWithoutRef<'button'>, 'value' | 'onValueChange'> {\n /** The applied filter values, keyed by an arbitrary consumer-chosen id. */\n value: Record<string, unknown>;\n /** Called with the committed filters when Apply is pressed. */\n onValueChange: (next: Record<string, unknown>) => void;\n /** Called with the newly applied filters when Apply is pressed (fires alongside `onValueChange`). */\n onApply?: (filters: Record<string, unknown>) => void;\n /** Label for the filter trigger button. */\n label?: React.ReactNode;\n /**\n * Filter field children rendered inside the popover form. Plain children —\n * wire each field to the draft via `useFilterSearchFilters`. Group fields with\n * a `Separator` as a layout convention if desired.\n */\n children?: React.ReactNode;\n /** Additional classes merged onto the trigger button. */\n className?: string;\n}\n\nconst FilterSearchFilters = React.forwardRef<\n HTMLButtonElement,\n FilterSearchFiltersProps\n>(({ value, onValueChange, onApply, label = 'Filters', children, className, ...rest }, ref) => {\n const [open, setOpen] = React.useState(false);\n const [draft, setDraft] = React.useState<Record<string, unknown>>(value);\n\n const handleOpenChange = (nextOpen: boolean) => {\n // Snapshot the applied filters on open; revert the draft on any dismiss\n // (outside press / Escape) so an un-applied edit never leaks out.\n setDraft(value);\n setOpen(nextOpen);\n };\n\n const setFilter = React.useCallback((key: string, filterValue: unknown) => {\n setDraft((previous) => {\n if (filterValue === undefined) {\n if (!(key in previous)) return previous;\n const next = { ...previous };\n delete next[key];\n return next;\n }\n return { ...previous, [key]: filterValue };\n });\n }, []);\n\n const filterContext = React.useMemo<FilterSearchFiltersContextValue>(\n () => ({ filters: draft, setFilter }),\n [draft, setFilter]\n );\n\n const handleReset = () => setDraft({});\n\n const handleCancel = () => {\n setDraft(value);\n setOpen(false);\n };\n\n const handleApply = () => {\n onValueChange(draft);\n onApply?.(draft);\n setOpen(false);\n };\n\n const resetDisabled = Object.keys(draft).length === 0;\n const applyDisabled = deepEqual(draft, value);\n\n return (\n <Popover open={open} onOpenChange={handleOpenChange}>\n <PopoverTrigger\n ref={ref}\n render={\n <Button\n variant=\"secondary\"\n className={cn(\n 'group data-[popup-open]:border-[var(--ui-button-secondary-container-border-color-active)] data-[popup-open]:bg-[var(--ui-button-secondary-container-color-active)] data-[popup-open]:text-[var(--ui-button-secondary-label-color-active)]',\n className\n )}\n {...rest}\n />\n }\n >\n {label}\n <ChevronDownIcon\n size={16}\n className=\"transition-transform group-data-[popup-open]:rotate-180\"\n />\n </PopoverTrigger>\n <PopoverContent align=\"start\" className=\"w-96 p-0\">\n <form\n onSubmit={(event) => {\n event.preventDefault();\n handleApply();\n }}\n >\n <div className=\"flex max-h-80 flex-col gap-4 overflow-y-auto p-4\">\n <FilterSearchFiltersContext.Provider value={filterContext}>\n {children}\n </FilterSearchFiltersContext.Provider>\n </div>\n <div className=\"flex items-center gap-2 border-t border-border p-4\">\n <Button\n type=\"button\"\n variant=\"ghost\"\n disabled={resetDisabled}\n onClick={handleReset}\n >\n Reset filters\n </Button>\n <div className=\"ms-auto flex items-center gap-2\">\n <Button type=\"button\" variant=\"secondary\" onClick={handleCancel}>\n Cancel\n </Button>\n <Button type=\"submit\" variant=\"default\" disabled={applyDisabled}>\n Apply\n </Button>\n </div>\n </div>\n </form>\n </PopoverContent>\n </Popover>\n );\n});\nFilterSearchFilters.displayName = 'FilterSearchFilters';\n\nfunction defaultFilterChipLabel(key: string, value: unknown): string {\n const text = Array.isArray(value)\n ? value.map((entry) => String(entry)).join(', ')\n : typeof value === 'object' && value !== null\n ? JSON.stringify(value)\n : String(value);\n return `${key}: ${text}`;\n}\n\nexport interface FilterSearchAppliedFiltersProps\n extends Omit<React.ComponentPropsWithoutRef<'div'>, 'children'> {\n /** The currently applied filter values, keyed by an arbitrary consumer-chosen id. */\n filters: Record<string, unknown>;\n /** Called with the remaining filters when a chip is removed or \"Reset filters\" clears all. */\n onValueChange: (next: Record<string, unknown>) => void;\n /** Format an applied-filter chip's label. Defaults to `\"<key>: <value>\"`. */\n getFilterChipLabel?: (key: string, value: unknown) => React.ReactNode;\n}\n\n/**\n * Renders one removable chip per applied filter plus a \"Reset filters\" action\n * that clears all filters immediately (no popover involved). Renders nothing\n * when `filters` is empty.\n */\nconst FilterSearchAppliedFilters = React.forwardRef<\n HTMLDivElement,\n FilterSearchAppliedFiltersProps\n>(({ className, filters, onValueChange, getFilterChipLabel, ...props }, ref) => {\n const keys = Object.keys(filters);\n if (keys.length === 0) return null;\n\n const handleRemove = (key: string) => {\n const next = { ...filters };\n delete next[key];\n onValueChange(next);\n };\n\n return (\n <div\n ref={ref}\n className={cn('flex flex-wrap items-center gap-3', className)}\n {...props}\n >\n {keys.map((key) => (\n <Chip\n key={key}\n variant=\"removable\"\n onRemove={() => handleRemove(key)}\n removeLabel={`Remove ${key} filter`}\n >\n {getFilterChipLabel\n ? getFilterChipLabel(key, filters[key])\n : defaultFilterChipLabel(key, filters[key])}\n </Chip>\n ))}\n <Button\n type=\"button\"\n variant=\"ghost\"\n onClick={() => onValueChange({})}\n >\n Reset filters\n </Button>\n </div>\n );\n});\nFilterSearchAppliedFilters.displayName = 'FilterSearchAppliedFilters';\n\nexport {\n FilterSearch,\n FilterSearchActions,\n FilterSearchFilters,\n FilterSearchAppliedFilters,\n};\n"],"names":["FilterSearch","React","className","props","ref","jsx","cn","FilterSearchActions","FilterSearchFiltersContext","useFilterSearchFilters","context","FilterSearchFilters","value","onValueChange","onApply","label","children","rest","open","setOpen","draft","setDraft","handleOpenChange","nextOpen","setFilter","key","filterValue","previous","next","filterContext","handleReset","handleCancel","handleApply","resetDisabled","applyDisabled","deepEqual","jsxs","Popover","PopoverTrigger","Button","ChevronDownIcon","PopoverContent","event","defaultFilterChipLabel","text","entry","FilterSearchAppliedFilters","filters","getFilterChipLabel","keys","handleRemove","Chip"],"mappings":"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"}
1
+ {"version":3,"file":"filter-search.js","sources":["../../../../src/components/ui/filter-search/filter-search.tsx"],"sourcesContent":["import * as React from 'react';\nimport { ChevronDownIcon } from '@acronis-platform/icons-react/stroke-mono';\n\nimport { cn } from '@/lib/utils';\nimport { deepEqual } from '@/lib/deep-equal';\nimport { Button } from '../button';\nimport { Chip } from '../chip';\nimport {\n FilterChips,\n FilterChipsList,\n FilterChipsReset,\n type FilterChipsProps,\n} from '../filter-chips';\nimport { Popover, PopoverContent, PopoverTrigger } from '../popover';\n\n// A composable toolbar for data tables: arranges a search field, optional\n// filters button, optional tenant/scope switcher, and trailing action buttons\n// in a single horizontal row. Maps to the Figma \"FilterSearch\" component. The\n// root container uses 16px inter-item gap (Figma `gap/gap-16`) and centers\n// children vertically. `FilterSearchActions` is a right-aligned flex area that\n// pushes its content to the trailing edge.\n//\n// No dedicated token tier — spacing is the Figma `gap/gap-16` semantic token\n// (16px), and each child (Search, ButtonMenu, Select) brings its own\n// `--ui-*` tier.\n//\n// `FilterSearchFilters` is still design-pending (no Figma node yet, unlike the\n// FilterSearch node itself): the filter popover — trigger + form +\n// Reset/Cancel/Apply. Compose it as a child of `<FilterSearch>` in place of a\n// plain filter trigger, and reconcile against the real design with\n// `/figma-component FilterSearchFilters <url> --update` once a mockup lands.\n//\n// `FilterSearchAppliedFilters` is no longer design-pending: its chip row landed\n// in Figma as its own \"FilterChips\" component, so it renders through\n// `FilterChips`/`FilterChipsList`/`FilterChipsReset` rather than repeating that\n// layout. It keeps its data-driven API (a `filters` record) as the convenience\n// wrapper over those slot-based parts; render it as a sibling row below\n// `<FilterSearch>`.\n\nexport type FilterSearchProps = React.ComponentPropsWithoutRef<'div'>;\n\nconst FilterSearch = React.forwardRef<HTMLDivElement, FilterSearchProps>(\n ({ className, ...props }, ref) => (\n <div\n ref={ref}\n className={cn('flex items-center gap-4', className)}\n {...props}\n />\n )\n);\nFilterSearch.displayName = 'FilterSearch';\n\nexport type FilterSearchActionsProps = React.ComponentPropsWithoutRef<'div'>;\n\nconst FilterSearchActions = React.forwardRef<\n HTMLDivElement,\n FilterSearchActionsProps\n>(({ className, ...props }, ref) => (\n <div\n ref={ref}\n className={cn(\n 'flex h-8 min-w-px flex-1 items-center justify-end gap-4',\n className\n )}\n {...props}\n />\n));\nFilterSearchActions.displayName = 'FilterSearchActions';\n\ninterface FilterSearchFiltersContextValue {\n /** The current draft filters being edited inside the popover. */\n filters: Record<string, unknown>;\n /** Set a single draft filter value by key. */\n setFilter: (key: string, value: unknown) => void;\n}\n\nconst FilterSearchFiltersContext =\n React.createContext<FilterSearchFiltersContextValue | null>(null);\n\n/**\n * Bind a filter field child (rendered inside `FilterSearchFilters`'s popover) to\n * the component's draft filters. Returns the current draft map and a per-key\n * setter. Field children are plain JSX (no render prop) and wire their own\n * `onChange` to `setFilter`; Apply commits the draft, Cancel/dismiss reverts it.\n */\nexport function useFilterSearchFilters(): FilterSearchFiltersContextValue {\n const context = React.useContext(FilterSearchFiltersContext);\n if (context === null) {\n throw new Error(\n 'useFilterSearchFilters must be used within a <FilterSearchFilters> popover.'\n );\n }\n return context;\n}\n\nexport interface FilterSearchFiltersProps extends Omit<\n React.ComponentPropsWithoutRef<'button'>,\n 'value' | 'onValueChange'\n> {\n /** The applied filter values, keyed by an arbitrary consumer-chosen id. */\n value: Record<string, unknown>;\n /** Called with the committed filters when Apply is pressed. */\n onValueChange: (next: Record<string, unknown>) => void;\n /** Called with the newly applied filters when Apply is pressed (fires alongside `onValueChange`). */\n onApply?: (filters: Record<string, unknown>) => void;\n /** Label for the filter trigger button. */\n label?: React.ReactNode;\n /** Label for the \"Reset filters\" action inside the popover. */\n resetFiltersLabel?: React.ReactNode;\n /** Label for the \"Cancel\" action inside the popover. */\n cancelLabel?: React.ReactNode;\n /** Label for the \"Apply\" action inside the popover. */\n applyLabel?: React.ReactNode;\n /**\n * Filter field children rendered inside the popover form. Plain children —\n * wire each field to the draft via `useFilterSearchFilters`. Group fields with\n * a `Separator` as a layout convention if desired.\n */\n children?: React.ReactNode;\n /** Additional classes merged onto the trigger button. */\n className?: string;\n /** Additional classes merged onto the popover content. */\n contentClassName?: string;\n /** Which side of the trigger to render the popover on. Defaults to `'bottom'`. */\n side?: React.ComponentProps<typeof PopoverContent>['side'];\n /** Alignment of the popover along the chosen side. Defaults to `'start'`. */\n align?: React.ComponentProps<typeof PopoverContent>['align'];\n /** Distance in px between the trigger and the popover. */\n sideOffset?: React.ComponentProps<typeof PopoverContent>['sideOffset'];\n /**\n * Portal container the popover mounts into. Defaults to the nearest\n * `PortalContainerProvider`, or `document.body` if none is set — see\n * `PopoverContent`'s `portalContainer` prop.\n */\n portalContainer?: React.ComponentProps<\n typeof PopoverContent\n >['portalContainer'];\n /**\n * Element/rect the popover is confined to when avoiding collisions. See\n * `PopoverContent`'s `collisionBoundary` prop for the default behavior\n * inside a constrained portal container.\n */\n collisionBoundary?: React.ComponentProps<\n typeof PopoverContent\n >['collisionBoundary'];\n /**\n * Which CSS `position` the popover uses. See `PopoverContent`'s\n * `positionMethod` prop for the default behavior inside a constrained\n * portal container.\n */\n positionMethod?: React.ComponentProps<\n typeof PopoverContent\n >['positionMethod'];\n}\n\nconst FilterSearchFilters = React.forwardRef<\n HTMLButtonElement,\n FilterSearchFiltersProps\n>(\n (\n {\n value,\n onValueChange,\n onApply,\n label = 'Filters',\n resetFiltersLabel = 'Reset filters',\n cancelLabel = 'Cancel',\n applyLabel = 'Apply',\n children,\n className,\n contentClassName,\n side,\n align = 'start',\n sideOffset,\n portalContainer,\n collisionBoundary,\n positionMethod,\n ...rest\n },\n ref\n ) => {\n const [open, setOpen] = React.useState(false);\n const [draft, setDraft] = React.useState<Record<string, unknown>>(value);\n\n const handleOpenChange = (nextOpen: boolean) => {\n // Snapshot the applied filters on open; revert the draft on any dismiss\n // (outside press / Escape) so an un-applied edit never leaks out.\n setDraft(value);\n setOpen(nextOpen);\n };\n\n const setFilter = React.useCallback((key: string, filterValue: unknown) => {\n setDraft((previous) => {\n if (filterValue === undefined) {\n if (!(key in previous)) return previous;\n const next = { ...previous };\n delete next[key];\n return next;\n }\n return { ...previous, [key]: filterValue };\n });\n }, []);\n\n const filterContext = React.useMemo<FilterSearchFiltersContextValue>(\n () => ({ filters: draft, setFilter }),\n [draft, setFilter]\n );\n\n const handleReset = () => setDraft({});\n\n const handleCancel = () => {\n setDraft(value);\n setOpen(false);\n };\n\n const handleApply = () => {\n onValueChange(draft);\n onApply?.(draft);\n setOpen(false);\n };\n\n const resetDisabled = Object.keys(draft).length === 0;\n const applyDisabled = deepEqual(draft, value);\n\n return (\n <Popover open={open} onOpenChange={handleOpenChange}>\n <PopoverTrigger\n ref={ref}\n render={\n <Button\n variant=\"secondary\"\n className={cn(\n 'group data-[popup-open]:border-[var(--ui-button-secondary-container-border-color-active)] data-[popup-open]:bg-[var(--ui-button-secondary-container-color-active)] data-[popup-open]:text-[var(--ui-button-secondary-label-color-active)]',\n className\n )}\n {...rest}\n />\n }\n >\n {label}\n <ChevronDownIcon\n size={16}\n className=\"transition-transform group-data-[popup-open]:rotate-180\"\n />\n </PopoverTrigger>\n <PopoverContent\n side={side}\n align={align}\n sideOffset={sideOffset}\n portalContainer={portalContainer}\n collisionBoundary={collisionBoundary}\n positionMethod={positionMethod}\n className={cn('w-96 p-0', contentClassName)}\n >\n <form\n onSubmit={(event) => {\n event.preventDefault();\n handleApply();\n }}\n >\n <div className=\"flex max-h-80 flex-col gap-4 overflow-y-auto p-4\">\n <FilterSearchFiltersContext.Provider value={filterContext}>\n {children}\n </FilterSearchFiltersContext.Provider>\n </div>\n <div className=\"flex items-center gap-2 border-t border-border p-4\">\n <Button\n type=\"button\"\n variant=\"ghost\"\n disabled={resetDisabled}\n onClick={handleReset}\n >\n {resetFiltersLabel}\n </Button>\n <div className=\"ms-auto flex items-center gap-2\">\n <Button\n type=\"button\"\n variant=\"secondary\"\n onClick={handleCancel}\n >\n {cancelLabel}\n </Button>\n <Button\n type=\"submit\"\n variant=\"default\"\n disabled={applyDisabled}\n >\n {applyLabel}\n </Button>\n </div>\n </div>\n </form>\n </PopoverContent>\n </Popover>\n );\n }\n);\nFilterSearchFilters.displayName = 'FilterSearchFilters';\n\nfunction defaultFilterChipLabel(key: string, value: unknown): string {\n const text = Array.isArray(value)\n ? value.map((entry) => String(entry)).join(', ')\n : typeof value === 'object' && value !== null\n ? JSON.stringify(value)\n : String(value);\n return `${key}: ${text}`;\n}\n\nexport interface FilterSearchAppliedFiltersProps\n extends Omit<FilterChipsProps, 'children'> {\n /** The currently applied filter values, keyed by an arbitrary consumer-chosen id. */\n filters: Record<string, unknown>;\n /** Called with the remaining filters when a chip is removed or \"Reset filters\" clears all. */\n onValueChange: (next: Record<string, unknown>) => void;\n /** Format an applied-filter chip's label. Defaults to `\"<key>: <value>\"`. */\n getFilterChipLabel?: (key: string, value: unknown) => React.ReactNode;\n /** Format a filter chip's remove-button accessible label. Defaults to `\"Remove <key> filter\"`. */\n getRemoveFilterLabel?: (key: string) => string;\n /** Label for the \"Reset filters\" action. */\n resetFiltersLabel?: React.ReactNode;\n}\n\n/**\n * Renders one removable chip per applied filter plus a \"Reset filters\" action\n * that clears all filters immediately (no popover involved). Renders nothing\n * when `filters` is empty.\n */\nconst FilterSearchAppliedFilters = React.forwardRef<\n HTMLDivElement,\n FilterSearchAppliedFiltersProps\n>(\n (\n {\n className,\n filters,\n onValueChange,\n getFilterChipLabel,\n getRemoveFilterLabel = (key) => `Remove ${key} filter`,\n resetFiltersLabel = 'Reset filters',\n ...props\n },\n ref\n ) => {\n const keys = Object.keys(filters);\n if (keys.length === 0) return null;\n\n const handleRemove = (key: string) => {\n const next = { ...filters };\n delete next[key];\n onValueChange(next);\n };\n\n return (\n <FilterChips ref={ref} className={className} {...props}>\n <FilterChipsList>\n {keys.map((key) => (\n <Chip\n key={key}\n variant=\"removable\"\n onRemove={() => handleRemove(key)}\n removeLabel={getRemoveFilterLabel(key)}\n >\n {getFilterChipLabel\n ? getFilterChipLabel(key, filters[key])\n : defaultFilterChipLabel(key, filters[key])}\n </Chip>\n ))}\n <FilterChipsReset onClick={() => onValueChange({})}>\n {resetFiltersLabel}\n </FilterChipsReset>\n </FilterChipsList>\n </FilterChips>\n );\n }\n);\nFilterSearchAppliedFilters.displayName = 'FilterSearchAppliedFilters';\n\nexport {\n FilterSearch,\n FilterSearchActions,\n FilterSearchFilters,\n FilterSearchAppliedFilters,\n};\n"],"names":["FilterSearch","React","className","props","ref","jsx","cn","FilterSearchActions","FilterSearchFiltersContext","useFilterSearchFilters","context","FilterSearchFilters","value","onValueChange","onApply","label","resetFiltersLabel","cancelLabel","applyLabel","children","contentClassName","side","align","sideOffset","portalContainer","collisionBoundary","positionMethod","rest","open","setOpen","draft","setDraft","handleOpenChange","nextOpen","setFilter","key","filterValue","previous","next","filterContext","handleReset","handleCancel","handleApply","resetDisabled","applyDisabled","deepEqual","jsxs","Popover","PopoverTrigger","Button","ChevronDownIcon","PopoverContent","event","defaultFilterChipLabel","text","entry","FilterSearchAppliedFilters","filters","getFilterChipLabel","getRemoveFilterLabel","keys","handleRemove","FilterChips","FilterChipsList","Chip","FilterChipsReset"],"mappings":"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"}