@acronis-platform/ui-react 2.0.0 → 4.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 (243) hide show
  1. package/dist/components/ui/accordion-container/accordion-container.js +144 -0
  2. package/dist/components/ui/accordion-container/accordion-container.js.map +1 -0
  3. package/dist/components/ui/app-shell-chat/app-shell-chat.js.map +1 -1
  4. package/dist/components/ui/area-chart/area-chart.js +141 -139
  5. package/dist/components/ui/area-chart/area-chart.js.map +1 -1
  6. package/dist/components/ui/avatar/avatar.js +33 -22
  7. package/dist/components/ui/avatar/avatar.js.map +1 -1
  8. package/dist/components/ui/bar-chart/bar-chart.js +295 -293
  9. package/dist/components/ui/bar-chart/bar-chart.js.map +1 -1
  10. package/dist/components/ui/card/card.js +150 -74
  11. package/dist/components/ui/card/card.js.map +1 -1
  12. package/dist/components/ui/card-section/card-section.js +111 -0
  13. package/dist/components/ui/card-section/card-section.js.map +1 -0
  14. package/dist/components/ui/category-bar/category-bar.js +109 -93
  15. package/dist/components/ui/category-bar/category-bar.js.map +1 -1
  16. package/dist/components/ui/chart/chart-palette.js +113 -0
  17. package/dist/components/ui/chart/chart-palette.js.map +1 -0
  18. package/dist/components/ui/chart/chart.js +176 -129
  19. package/dist/components/ui/chart/chart.js.map +1 -1
  20. package/dist/components/ui/chart-state/chart-state-illustrations.js +310 -0
  21. package/dist/components/ui/chart-state/chart-state-illustrations.js.map +1 -0
  22. package/dist/components/ui/chart-state/chart-state.js +48 -34
  23. package/dist/components/ui/chart-state/chart-state.js.map +1 -1
  24. package/dist/components/ui/chart-widget/chart-widget.js +87 -0
  25. package/dist/components/ui/chart-widget/chart-widget.js.map +1 -0
  26. package/dist/components/ui/composed-chart/composed-chart.js +117 -115
  27. package/dist/components/ui/composed-chart/composed-chart.js.map +1 -1
  28. package/dist/components/ui/confidence-cone/confidence-cone.js +166 -158
  29. package/dist/components/ui/confidence-cone/confidence-cone.js.map +1 -1
  30. package/dist/components/ui/data-table/data-table.js +4 -2
  31. package/dist/components/ui/data-table/data-table.js.map +1 -1
  32. package/dist/components/ui/empty-overlay/empty-overlay.js +49 -0
  33. package/dist/components/ui/empty-overlay/empty-overlay.js.map +1 -0
  34. package/dist/components/ui/funnel-chart/funnel-chart.js +162 -161
  35. package/dist/components/ui/funnel-chart/funnel-chart.js.map +1 -1
  36. package/dist/components/ui/histogram/histogram.js +94 -92
  37. package/dist/components/ui/histogram/histogram.js.map +1 -1
  38. package/dist/components/ui/input/input.js.map +1 -1
  39. package/dist/components/ui/label/label.js +2 -9
  40. package/dist/components/ui/label/label.js.map +1 -1
  41. package/dist/components/ui/line-chart/line-chart.js +143 -141
  42. package/dist/components/ui/line-chart/line-chart.js.map +1 -1
  43. package/dist/components/ui/metric/metric.js +74 -185
  44. package/dist/components/ui/metric/metric.js.map +1 -1
  45. package/dist/components/ui/page-content/page-content.js.map +1 -1
  46. package/dist/components/ui/pie-chart/pie-chart.js +201 -195
  47. package/dist/components/ui/pie-chart/pie-chart.js.map +1 -1
  48. package/dist/components/ui/radar-chart/radar-chart.js +133 -131
  49. package/dist/components/ui/radar-chart/radar-chart.js.map +1 -1
  50. package/dist/components/ui/radial-bar-chart/radial-bar-chart.js +297 -265
  51. package/dist/components/ui/radial-bar-chart/radial-bar-chart.js.map +1 -1
  52. package/dist/components/ui/sankey-chart/sankey-chart.js +123 -101
  53. package/dist/components/ui/sankey-chart/sankey-chart.js.map +1 -1
  54. package/dist/components/ui/scatter-chart/scatter-chart.js +76 -74
  55. package/dist/components/ui/scatter-chart/scatter-chart.js.map +1 -1
  56. package/dist/components/ui/section/section.js +157 -31
  57. package/dist/components/ui/section/section.js.map +1 -1
  58. package/dist/components/ui/stepper/stepper.js +24 -24
  59. package/dist/components/ui/stepper/stepper.js.map +1 -1
  60. package/dist/components/ui/stepper-item/stepper-item.js +43 -24
  61. package/dist/components/ui/stepper-item/stepper-item.js.map +1 -1
  62. package/dist/components/ui/table/table.js +27 -27
  63. package/dist/components/ui/table/table.js.map +1 -1
  64. package/dist/components/ui/treemap/treemap.js +133 -124
  65. package/dist/components/ui/treemap/treemap.js.map +1 -1
  66. package/dist/components/ui/trend-indicator/trend-indicator.js +34 -69
  67. package/dist/components/ui/trend-indicator/trend-indicator.js.map +1 -1
  68. package/dist/components/ui/wizard/wizard.js +59 -0
  69. package/dist/components/ui/wizard/wizard.js.map +1 -0
  70. package/dist/hooks/use-wizard.js +75 -0
  71. package/dist/hooks/use-wizard.js.map +1 -0
  72. package/dist/index.js +540 -525
  73. package/dist/index.js.map +1 -1
  74. package/dist/llms/accordion-container.md +181 -0
  75. package/dist/llms/accordion.md +124 -0
  76. package/dist/llms/alert.md +225 -0
  77. package/dist/llms/app-shell-chat.md +415 -0
  78. package/dist/llms/area-chart.md +355 -0
  79. package/dist/llms/avatar.md +208 -0
  80. package/dist/llms/bar-chart.md +406 -0
  81. package/dist/llms/breadcrumb.md +326 -0
  82. package/dist/llms/button-group.md +298 -0
  83. package/dist/llms/button-icon-input.md +142 -0
  84. package/dist/llms/button-icon-menu.md +209 -0
  85. package/dist/llms/button-icon.md +128 -0
  86. package/dist/llms/button-menu.md +172 -0
  87. package/dist/llms/button.md +185 -0
  88. package/dist/llms/calendar-panel.md +733 -0
  89. package/dist/llms/calendar.md +188 -0
  90. package/dist/llms/card-filter.md +214 -0
  91. package/dist/llms/card-section.md +293 -0
  92. package/dist/llms/card.md +447 -0
  93. package/dist/llms/carousel-dialog.md +156 -0
  94. package/dist/llms/category-bar.md +193 -0
  95. package/dist/llms/chart-state.md +190 -0
  96. package/dist/llms/chart-widget.md +209 -0
  97. package/dist/llms/chart.md +182 -0
  98. package/dist/llms/checkbox.md +257 -0
  99. package/dist/llms/chip.md +195 -0
  100. package/dist/llms/combobox.md +164 -0
  101. package/dist/llms/composed-chart.md +508 -0
  102. package/dist/llms/confidence-cone.md +277 -0
  103. package/dist/llms/data-table.md +474 -0
  104. package/dist/llms/date-range-picker.md +272 -0
  105. package/dist/llms/description-list.md +131 -0
  106. package/dist/llms/dialog-footer-carousel.md +147 -0
  107. package/dist/llms/dialog-footer-default.md +142 -0
  108. package/dist/llms/dialog-root.md +246 -0
  109. package/dist/llms/dialog-welcome.md +223 -0
  110. package/dist/llms/dialog.md +403 -0
  111. package/dist/llms/dropdown-menu.md +193 -0
  112. package/dist/llms/empty-overlay.md +146 -0
  113. package/dist/llms/empty.md +156 -0
  114. package/dist/llms/field.md +185 -0
  115. package/dist/llms/filter-cards.md +157 -0
  116. package/dist/llms/filter-chips.md +323 -0
  117. package/dist/llms/filter-search.md +512 -0
  118. package/dist/llms/form.md +154 -0
  119. package/dist/llms/funnel-chart.md +333 -0
  120. package/dist/llms/grid.md +80 -0
  121. package/dist/llms/histogram.md +190 -0
  122. package/dist/llms/input-date-picker.md +203 -0
  123. package/dist/llms/input-otp.md +173 -0
  124. package/dist/llms/input-password.md +197 -0
  125. package/dist/llms/input-search.md +170 -0
  126. package/dist/llms/input-select.md +278 -0
  127. package/dist/llms/input-text-area.md +271 -0
  128. package/dist/llms/input-text.md +192 -0
  129. package/dist/llms/line-chart.md +369 -0
  130. package/dist/llms/link.md +209 -0
  131. package/dist/llms/loading.md +130 -0
  132. package/dist/llms/meter.md +177 -0
  133. package/dist/llms/metric.md +204 -0
  134. package/dist/llms/number-field.md +122 -0
  135. package/dist/llms/page-content.md +69 -0
  136. package/dist/llms/page-header.md +182 -0
  137. package/dist/llms/pagination.md +133 -0
  138. package/dist/llms/pie-chart.md +307 -0
  139. package/dist/llms/popover.md +252 -0
  140. package/dist/llms/progress-circle.md +126 -0
  141. package/dist/llms/progress.md +111 -0
  142. package/dist/llms/radar-chart.md +316 -0
  143. package/dist/llms/radial-bar-chart.md +319 -0
  144. package/dist/llms/radio.md +255 -0
  145. package/dist/llms/resizable.md +195 -0
  146. package/dist/llms/sankey-chart.md +208 -0
  147. package/dist/llms/scatter-chart.md +239 -0
  148. package/dist/llms/scroll-area.md +183 -0
  149. package/dist/llms/section.md +401 -0
  150. package/dist/llms/select.md +210 -0
  151. package/dist/llms/separator.md +87 -0
  152. package/dist/llms/sheet.md +202 -0
  153. package/dist/llms/sidebar-primary.md +360 -0
  154. package/dist/llms/sidebar-secondary.md +417 -0
  155. package/dist/llms/skeleton.md +81 -0
  156. package/dist/llms/slider.md +97 -0
  157. package/dist/llms/spinner.md +100 -0
  158. package/dist/llms/stack.md +80 -0
  159. package/dist/llms/stepper-item.md +309 -0
  160. package/dist/llms/stepper.md +251 -0
  161. package/dist/llms/switch.md +140 -0
  162. package/dist/llms/table.md +436 -0
  163. package/dist/llms/tabs.md +197 -0
  164. package/dist/llms/tag.md +139 -0
  165. package/dist/llms/timeline.md +361 -0
  166. package/dist/llms/timer.md +259 -0
  167. package/dist/llms/toast.md +241 -0
  168. package/dist/llms/toggle-group.md +121 -0
  169. package/dist/llms/toolbar.md +453 -0
  170. package/dist/llms/tooltip.md +164 -0
  171. package/dist/llms/treemap.md +254 -0
  172. package/dist/llms/trend-indicator.md +132 -0
  173. package/dist/llms/widget-placeholder.md +169 -0
  174. package/dist/llms/wizard.md +412 -0
  175. package/dist/llms.txt +142 -0
  176. package/dist/react.js +540 -525
  177. package/dist/react.js.map +1 -1
  178. package/dist/src/components/ui/accordion-container/accordion-container.d.ts +44 -0
  179. package/dist/src/components/ui/accordion-container/index.d.ts +1 -0
  180. package/dist/src/components/ui/area-chart/area-chart.d.ts +9 -4
  181. package/dist/src/components/ui/avatar/avatar.d.ts +27 -8
  182. package/dist/src/components/ui/bar-chart/bar-chart.d.ts +9 -4
  183. package/dist/src/components/ui/button/button.d.ts +1 -1
  184. package/dist/src/components/ui/card/card.d.ts +69 -8
  185. package/dist/src/components/ui/card/index.d.ts +1 -1
  186. package/dist/src/components/ui/card-section/card-section.d.ts +50 -0
  187. package/dist/src/components/ui/card-section/index.d.ts +1 -0
  188. package/dist/src/components/ui/category-bar/category-bar.d.ts +10 -4
  189. package/dist/src/components/ui/chart/__stories__/palette-control.d.ts +48 -0
  190. package/dist/src/components/ui/chart/__tests__/chart-palette.test.d.ts +1 -0
  191. package/dist/src/components/ui/chart/chart-palette.d.ts +128 -0
  192. package/dist/src/components/ui/chart/chart.d.ts +66 -15
  193. package/dist/src/components/ui/chart/index.d.ts +4 -2
  194. package/dist/src/components/ui/chart-state/chart-state-illustrations.d.ts +6 -0
  195. package/dist/src/components/ui/chart-state/chart-state.d.ts +13 -2
  196. package/dist/src/components/ui/chart-state/index.d.ts +1 -0
  197. package/dist/src/components/ui/chart-widget/chart-widget.d.ts +64 -0
  198. package/dist/src/components/ui/chart-widget/index.d.ts +1 -0
  199. package/dist/src/components/ui/composed-chart/composed-chart.d.ts +12 -7
  200. package/dist/src/components/ui/confidence-cone/confidence-cone.d.ts +10 -5
  201. package/dist/src/components/ui/dialog/dialog.d.ts +1 -1
  202. package/dist/src/components/ui/empty-overlay/empty-overlay.d.ts +20 -0
  203. package/dist/src/components/ui/empty-overlay/index.d.ts +2 -0
  204. package/dist/src/components/ui/funnel-chart/funnel-chart.d.ts +11 -5
  205. package/dist/src/components/ui/grid/grid.d.ts +1 -1
  206. package/dist/src/components/ui/histogram/histogram.d.ts +10 -4
  207. package/dist/src/components/ui/label/index.d.ts +1 -1
  208. package/dist/src/components/ui/label/label.d.ts +1 -5
  209. package/dist/src/components/ui/line-chart/line-chart.d.ts +9 -4
  210. package/dist/src/components/ui/metric/metric.d.ts +13 -14
  211. package/dist/src/components/ui/pie-chart/pie-chart.d.ts +17 -8
  212. package/dist/src/components/ui/radar-chart/radar-chart.d.ts +10 -5
  213. package/dist/src/components/ui/radial-bar-chart/radial-bar-chart.d.ts +17 -6
  214. package/dist/src/components/ui/sankey-chart/sankey-chart.d.ts +10 -5
  215. package/dist/src/components/ui/scatter-chart/scatter-chart.d.ts +10 -5
  216. package/dist/src/components/ui/section/index.d.ts +1 -1
  217. package/dist/src/components/ui/section/section.d.ts +75 -6
  218. package/dist/src/components/ui/sheet/sheet.d.ts +1 -1
  219. package/dist/src/components/ui/stack/stack.d.ts +1 -1
  220. package/dist/src/components/ui/stepper-item/stepper-item.d.ts +6 -5
  221. package/dist/src/components/ui/tag/tag.d.ts +1 -1
  222. package/dist/src/components/ui/treemap/treemap.d.ts +11 -5
  223. package/dist/src/components/ui/trend-indicator/trend-indicator.d.ts +3 -7
  224. package/dist/src/components/ui/wizard/index.d.ts +1 -0
  225. package/dist/src/components/ui/wizard/wizard.d.ts +6 -0
  226. package/dist/src/hooks/index.d.ts +1 -0
  227. package/dist/src/hooks/use-wizard.d.ts +80 -0
  228. package/dist/src/index.d.ts +5 -3
  229. package/dist/ui-react.css +1 -1
  230. package/package.json +12 -6
  231. package/dist/components/ui/app-shell/app-shell.js +0 -75
  232. package/dist/components/ui/app-shell/app-shell.js.map +0 -1
  233. package/dist/components/ui/auth-layout/auth-layout.js +0 -56
  234. package/dist/components/ui/auth-layout/auth-layout.js.map +0 -1
  235. package/dist/components/ui/collapsible/collapsible.js +0 -22
  236. package/dist/components/ui/collapsible/collapsible.js.map +0 -1
  237. package/dist/src/components/ui/app-shell/app-shell.d.ts +0 -8
  238. package/dist/src/components/ui/app-shell/index.d.ts +0 -1
  239. package/dist/src/components/ui/auth-layout/auth-layout.d.ts +0 -6
  240. package/dist/src/components/ui/auth-layout/index.d.ts +0 -1
  241. package/dist/src/components/ui/collapsible/collapsible.d.ts +0 -5
  242. package/dist/src/components/ui/collapsible/index.d.ts +0 -1
  243. package/dist/src/components/ui/label/label.docs.d.ts +0 -10
@@ -0,0 +1,188 @@
1
+ # Calendar
2
+
3
+ > A day-grid built on react-day-picker: single / range / multiple date selection across one or more months side by side, with prev/next navigation at the outer edges of the month row. Design-pending v1 ported from ui-legacy — themed off the shared semantic tokens (no `--ui-calendar-*` tier yet).
4
+
5
+ **Status:** draft · **Category:** forms · **Since:** v0.56.0
6
+
7
+ ## Import
8
+
9
+ ```tsx
10
+ import { Calendar } from '@acronis-platform/ui-react'
11
+ ```
12
+
13
+ ## Quick example
14
+
15
+ ```tsx
16
+ const [selected, setSelected] = React.useState<Date>();
17
+
18
+ <Calendar mode="single" selected={selected} onSelect={setSelected} />
19
+
20
+ {/* Two-month range */}
21
+ <Calendar
22
+ mode="range"
23
+ numberOfMonths={2}
24
+ selected={range}
25
+ onSelect={setRange}
26
+ />
27
+ ```
28
+
29
+ A day-grid for picking dates, built on
30
+ [`react-day-picker`](https://daypicker.dev/) and re-themed to the Acronis UI Kit's
31
+ semantic tokens.
32
+
33
+ > **Design-pending v1.** Ported from `@acronis-platform/shadcn-uikit` before a
34
+ > "ready for dev" Figma node exists. It is themed off the shared semantic
35
+ > vocabulary (no `--ui-calendar-*` token tier yet); reconcile against the real
36
+ > design with `/figma-component Calendar <url> --update` once mockups land.
37
+
38
+ ## When to use
39
+
40
+ - Selecting a single date, a set of dates, or a start–end range in place.
41
+ - As the grid inside a date-field popover (see `DateRangePicker`, `InputDatePicker`).
42
+
43
+ ## When not to use
44
+
45
+ - For a compact date **field** with a popover trigger, compose `InputDatePicker`
46
+ (single) or `DateRangePicker` (range) instead of embedding the bare grid.
47
+
48
+ ## Examples
49
+
50
+ ```tsx
51
+ import { Calendar } from '@acronis-platform/ui-react';
52
+
53
+ // Single date
54
+ const [date, setDate] = React.useState<Date>();
55
+ <Calendar mode="single" selected={date} onSelect={setDate} />;
56
+
57
+ // Two-month range
58
+ <Calendar
59
+ mode="range"
60
+ numberOfMonths={2}
61
+ selected={range}
62
+ onSelect={setRange}
63
+ />;
64
+
65
+ // Disabled weekends + specific dates
66
+ <Calendar
67
+ mode="single"
68
+ disabled={[{ dayOfWeek: [0, 6] }, new Date(2026, 6, 4)]}
69
+ />;
70
+ ```
71
+
72
+ ## Parts
73
+
74
+ | Part | Element | Notes |
75
+ | --------- | ------------------- | ---------------------------------------------- |
76
+ | `nav` | `<button>` pair | Previous / next, at the outer edges of the row |
77
+ | `caption` | `<div>` | "Month Year" label per month |
78
+ | `weekday` | `<div>` | Weekday column header |
79
+ | `grid` | `<table role=grid>` | One per month |
80
+ | `day` | `<button>` | Selectable day |
81
+ | `outside` | `<button>` | Adjacent-month filler day (optional) |
82
+
83
+ Selection mode, month count, and every other `react-day-picker` prop pass through.
84
+
85
+ ## Props
86
+
87
+ | Prop | Type | Default | Required | Description |
88
+ |------|------|---------|----------|-------------|
89
+ | `mode` | `'single' | 'multiple' | 'range'` | `single` | no | Selection mode — a single date, a set of dates, or a start–end range. |
90
+ | `selected` | `Date | Date[] | DateRange` | — | no | The current selection (controlled). Shape depends on `mode`: a `Date` for single, `Date[]` for multiple, `{ from, to }` for range. |
91
+ | `number-of-months` | `number` | `1` | no | How many months to render side by side. |
92
+ | `show-outside-days` | `boolean` | `true` | no | Show days from the previous/next month to fill the first/last week. |
93
+ | `caption-layout` | `'label' | 'dropdown' | 'dropdown-months' | 'dropdown-years'` | `label` | no | How the month/year caption is rendered (plain label or dropdowns). |
94
+ | `disabled` | `Matcher | Matcher[]` | — | no | Day(s) that cannot be selected. Accepts a date, a range, a predicate, a day-of-week matcher, or `true` to disable all days. |
95
+ | `default-month` | `Date` | — | no | The month rendered first (uncontrolled navigation). |
96
+
97
+ ## Events
98
+
99
+ | Event | Payload | Description |
100
+ |-------|---------|-------------|
101
+ | `select` | `selected` | Fired when the selection changes (React: `onSelect`). The payload matches the `selected` shape for the current `mode`. |
102
+
103
+ ## Behavior
104
+
105
+ Design-pending v1 ported from `@acronis-platform/shadcn-uikit`'s `calendar`.
106
+ Behavior is provided by `react-day-picker`'s `DayPicker`; this component only
107
+ re-themes the grid.
108
+
109
+ ### Single selection
110
+
111
+ - **Given** `mode="single"`, **when** the user clicks a day, **then** `onSelect`
112
+ fires with that `Date` and the day paints the brand fill
113
+ (`--ui-background-brand-primary` / `--ui-glyph-on-brand-primary`).
114
+ - **Given** a selected day, **when** the user clicks it again, **then** the
115
+ selection clears (`onSelect` fires with `undefined`).
116
+
117
+ ### Range selection
118
+
119
+ - **Given** `mode="range"`, **when** the user clicks a first day, **then**
120
+ `onSelect` fires with `{ from }` and that day becomes the range start.
121
+ - **When** the user clicks a second day, **then** `onSelect` fires with
122
+ `{ from, to }`; the start and end days paint the brand fill and the days between
123
+ them get the range-middle band (`--ui-background-surface-hover`).
124
+
125
+ ### Multiple months
126
+
127
+ - **Given** `numberOfMonths={2}`, **then** two month grids render side by side and
128
+ a single previous / next button pair sits at the outer edges of the row (not one
129
+ pair per month). Clicking next advances **both** months.
130
+
131
+ ### Navigation
132
+
133
+ - **When** the user clicks the previous / next button, **then** the displayed
134
+ month(s) shift by one. A nav button at the edge of the allowed range is disabled
135
+ and paints `--ui-text-on-surface-disabled`.
136
+
137
+ ### Disabled days
138
+
139
+ - **Given** a `disabled` matcher, **then** matched days are non-interactive
140
+ (`disabled` attribute) and paint `--ui-text-on-surface-disabled`; clicking them
141
+ does not fire `onSelect`.
142
+
143
+ ### Today & outside days
144
+
145
+ - The current day is decorated with a bold, underlined label (no color
146
+ dependency); the underline is dropped when the day is also selected.
147
+ - With `showOutsideDays` (default), leading/trailing days from the adjacent months
148
+ fill the grid and render in `--ui-text-on-surface-secondary`.
149
+
150
+ ## Accessibility
151
+
152
+ Accessibility is provided by `react-day-picker`, which follows the ARIA
153
+ [grid pattern](https://www.w3.org/WAI/ARIA/apg/patterns/grid/) for the day grid.
154
+
155
+ ## Roles & structure
156
+
157
+ - The root is a calendar application region; each month renders as a
158
+ `<table role="grid">` with column headers for the weekdays.
159
+ - Each day is a `<button>` inside a grid cell. Selected days expose
160
+ `aria-selected`; disabled days set the `disabled` attribute.
161
+ - The previous / next controls are labelled buttons; a control that would move
162
+ past the allowed range is `aria-disabled`.
163
+
164
+ ## Keyboard
165
+
166
+ | Key | Action |
167
+ | --------------------- | ----------------------------------------------- |
168
+ | `Arrow Left/Right` | Move focus to the previous / next day |
169
+ | `Arrow Up/Down` | Move focus to the same weekday of the adj. week |
170
+ | `Home` / `End` | First / last day of the week |
171
+ | `PageUp` / `PageDown` | Previous / next month |
172
+ | `Shift+PageUp/Down` | Previous / next year |
173
+ | `Enter` / `Space` | Select the focused day |
174
+
175
+ Roving focus: only the active day is in the tab order; arrow keys move focus and
176
+ auto-advance the visible month when crossing a boundary.
177
+
178
+ ## Focus
179
+
180
+ - The focused day shows a 3px `--ui-focus-primary` ring, raised above its
181
+ neighbours (`z-10`) so the ring is never clipped by an adjacent selected fill.
182
+
183
+ ## Contrast
184
+
185
+ - Selected days pair `--ui-background-brand-primary` with
186
+ `--ui-glyph-on-brand-primary`; idle days use `text-foreground` on the calendar
187
+ surface. Outside/disabled days use the secondary/disabled text tokens, which are
188
+ intentionally lower-emphasis but remain within the palette's contrast budget.
@@ -0,0 +1,214 @@
1
+ # CardFilter
2
+
3
+ > A compact stat/filter card: a caption label above a prominent value, with an optional leading icon. Three variants — `static` (presentational), `static-empty` (presentational placeholder with an em-dash), and `clickable` (an interactive filter that renders a button with hover / active / focus states).
4
+
5
+ **Status:** ready · **Category:** data-display · **Since:** v0.26.0
6
+
7
+ ## Import
8
+
9
+ ```tsx
10
+ import { CardFilter } from '@acronis-platform/ui-react'
11
+ ```
12
+
13
+ ## Quick example
14
+
15
+ ```tsx
16
+ <CardFilter variant="static" label="Total assets" value="125" icon={<CircleInfoIcon />} />
17
+
18
+ {/* Clickable filter, selected is controlled */}
19
+ <CardFilter
20
+ variant="clickable"
21
+ label="Active filters"
22
+ value="3"
23
+ selected={selected}
24
+ onClick={() => setSelected((prev) => !prev)}
25
+ />
26
+
27
+ {/* Polymorphic: render as a link */}
28
+ <CardFilter variant="clickable" label="Alerts" value="12" render={<a href="/alerts" />} />
29
+ ```
30
+
31
+ A compact stat/filter card: a caption label above a prominent value, with an
32
+ optional leading icon. Use it for dashboard metrics and for clickable filter
33
+ chips that summarize a count.
34
+
35
+ ## When to use
36
+
37
+ - Surfacing a single metric or count with a short label (e.g. "Active filters 3").
38
+ - A clickable summary that applies or navigates to a filtered view
39
+ (`variant="clickable"`).
40
+ - An empty/placeholder metric slot (`variant="static-empty"`).
41
+
42
+ ## When not to use
43
+
44
+ - For rich, multi-field content — use a general Card/Panel instead.
45
+ - For a primary call to action — use `Button` / `ButtonMenu`.
46
+
47
+ ## Variants
48
+
49
+ | variant | Interactive | Value color | Notes |
50
+ | -------------- | ----------- | ------------------------------------------ | ------------------------------ |
51
+ | `static` | no | `--ui-card-filter-static-value-color-idle` | Default presentational card. |
52
+ | `static-empty` | no | `…-static-value-color-disabled` | No icon; shows an em-dash `–`. |
53
+ | `clickable` | yes | `--ui-card-filter-clickable-value-color` | Renders a `<button>`. |
54
+
55
+ ## Examples
56
+
57
+ ```tsx
58
+ import { CardFilter } from '@acronis-platform/ui-react';
59
+ import { CircleInfoIcon } from '@acronis-platform/icons-react/stroke-mono';
60
+
61
+ // Static metric
62
+ <CardFilter label="Total assets" value="125" icon={<CircleInfoIcon />} />;
63
+
64
+ // Empty placeholder
65
+ <CardFilter variant="static-empty" label="Pending" />;
66
+
67
+ // Clickable filter
68
+ <CardFilter
69
+ variant="clickable"
70
+ label="Active filters"
71
+ value="3"
72
+ icon={<CircleInfoIcon />}
73
+ onClick={applyFilter}
74
+ />;
75
+
76
+ // Polymorphic: render as a link
77
+ <CardFilter
78
+ variant="clickable"
79
+ label="Alerts"
80
+ value="12"
81
+ render={<a href="/alerts" />}
82
+ />;
83
+ ```
84
+
85
+ ## Parts
86
+
87
+ | Part | Element | Description |
88
+ | ------- | -------------------- | ------------------------------------------------ |
89
+ | `root` | `<button>` / `<div>` | Card surface; interactive only for `clickable`. |
90
+ | `label` | `<span>` | Caption above the value (12px). |
91
+ | `icon` | `<svg>` | Optional 16px leading glyph (hidden when empty). |
92
+ | `value` | `<span>` | Prominent value (24px); colored per variant. |
93
+
94
+ ## Props
95
+
96
+ | Prop | Type | Default | Required | Description |
97
+ |------|------|---------|----------|-------------|
98
+ | `variant` | `'static' | 'static-empty' | 'clickable'` | `'static'` | no | Visual style and interactivity. `static` is presentational with a default value color; `static-empty` is a presentational placeholder (no icon, a muted em-dash); `clickable` renders an interactive `<button>` with a link-colored value and hover / active / focus states. Per the design, only `clickable` has states beyond idle. |
99
+ | `selected` | `boolean` | — | no | `clickable` only. Controlled — applies the selected (active) styling and exposes the card as a pressed toggle (`aria-pressed`/`data-selected`). The consumer owns the state and flips it in the `click` handler; there is no internal state and no uncontrolled default. |
100
+
101
+ ## Events
102
+
103
+ | Event | Payload | Description |
104
+ |-------|---------|-------------|
105
+ | `click` | `MouseEvent` | Fired on activation (pointer or keyboard) of the `clickable` variant. Typically applies the filter the card represents. |
106
+
107
+ ## Content slots
108
+
109
+ | Slot | Description |
110
+ |------|-------------|
111
+ | `label` | The caption shown above the value. Plain text or inline nodes. |
112
+ | `value` | The prominent value. Ignored for `static-empty` (which shows an em-dash placeholder). |
113
+ | `icon` | Optional leading glyph (16px) rendered before the value. Hidden for `static-empty`. |
114
+
115
+ ## Behavior
116
+
117
+ ### Rendering
118
+
119
+ **Given** a CardFilter with `label` and `value`
120
+ **When** it renders with the default `variant="static"`
121
+ **Then** the label appears above the value, the value uses the static idle color,
122
+ and the card is a presentational `<div>` (no interaction states).
123
+
124
+ **Given** `variant="static-empty"`
125
+ **When** it renders
126
+ **Then** no icon is shown and the value is a muted em-dash (`–`) regardless of the
127
+ `value` prop — the empty-state placeholder.
128
+
129
+ **Given** an `icon`
130
+ **When** the variant is `static` or `clickable`
131
+ **Then** the icon (16px) is rendered before the value with an 8px gap. The icon is
132
+ ignored for `static-empty`.
133
+
134
+ ### Interaction (clickable only)
135
+
136
+ **Given** `variant="clickable"`
137
+ **When** it renders
138
+ **Then** the card is a native `<button>`, the value uses the link color, and the
139
+ card exposes hover, active, and focus-visible treatments.
140
+
141
+ **Given** a clickable CardFilter
142
+ **When** the pointer hovers / presses it
143
+ **Then** the container fill and border shift to their `*-hover` / `*-active` tokens.
144
+
145
+ **Given** a clickable CardFilter
146
+ **When** it receives keyboard focus
147
+ **Then** a 3px `--ui-focus-primary` ring is painted flush to the edge and the
148
+ border takes its focused token; the ring is suppressed for pointer focus.
149
+
150
+ **Given** a clickable CardFilter
151
+ **When** it is activated (click, Enter, or Space)
152
+ **Then** a `click` event fires.
153
+
154
+ **Constraint:** `static` and `static-empty` are non-interactive — they have no
155
+ state other than idle (mirrors the Figma constraint).
156
+
157
+ ### Selection (clickable only)
158
+
159
+ **Given** a clickable CardFilter with `selected={false}`
160
+ **When** it renders
161
+ **Then** `aria-pressed="false"` and no `data-selected` attribute is present; the
162
+ card shows its idle/hover/active treatments only.
163
+
164
+ **Given** a clickable CardFilter with `selected={true}`
165
+ **When** it renders
166
+ **Then** `aria-pressed="true"` and `data-selected="true"` are set, and the
167
+ container fill/border switch to the active tokens even without pointer hover or
168
+ press. The `hover:` and `data-[selected=true]:` utilities are equal-specificity
169
+ Tailwind selectors; the selected styling wins on hover only because
170
+ `data-[selected=true]:*` is declared after `hover:*` in the `clickable` variant
171
+ string, not because of any inherent precedence — reordering that string would
172
+ flip the result. No story or test currently exercises the selected+hover
173
+ combination; treat this as source-order-dependent until one does.
174
+
175
+ **Constraint:** `aria-pressed` (and `type="button"`) apply only to the default
176
+ `<button>` root. When composed via `render` onto a non-button element (e.g.
177
+ `render={<a href="/alerts" />}`), they are omitted — that ARIA/HTML pairing
178
+ would be invalid on a link or other element. `data-selected` is a pure styling
179
+ hook and is still set regardless of the rendered element.
180
+
181
+ **Given** a clickable CardFilter
182
+ **When** the user activates it
183
+ **Then** the card only fires `click` — `selected` does not change on its own. The
184
+ consumer flips `selected` in its `onClick` handler (the component is controlled
185
+ only; there is no internal selected state).
186
+
187
+ ### Composition
188
+
189
+ **Given** a `render` prop (e.g. `<a href>`)
190
+ **When** the CardFilter renders
191
+ **Then** it renders as that element with the card's classes and props merged on —
192
+ e.g. a clickable filter that navigates as a link.
193
+
194
+ ## Accessibility
195
+
196
+ - **Role:** `clickable` renders a native `<button>` (implicit `role="button"`);
197
+ `static` / `static-empty` render a presentational `<div>`. The `render` prop can
198
+ swap the element (e.g. a native `<a>` for a link filter).
199
+ - **Accessible name:** for the `clickable` variant the name comes from the card's
200
+ text content (label + value). If that is not descriptive enough, pass an explicit
201
+ `aria-label`.
202
+ - **Keyboard (clickable):** Enter and Space activate (native button). Tab focuses;
203
+ the static variants are not focusable.
204
+ - **Focus visible:** keyboard focus shows a 3px ring in `--ui-focus-primary` flush
205
+ to the card edge (no offset), via `:focus-visible`; suppressed for pointer focus.
206
+ - **Pressed state (clickable):** `aria-pressed` reflects the controlled `selected`
207
+ prop (`"true"`/`"false"`), exposing the card as a toggle button; `data-selected`
208
+ mirrors it for styling.
209
+ - **Static content:** `static` / `static-empty` are presentational; they convey a
210
+ value but are not interactive and are not in the tab order.
211
+ - **Contrast:** label / value / surface pairs come from the design tokens, authored
212
+ to meet WCAG contrast. The `static-empty` placeholder uses a muted token.
213
+ - **WCAG:** 2.1.1 (keyboard), 2.4.7 (focus visible), 1.4.3 / 1.4.11 (contrast),
214
+ 4.1.2 (name/role/value).