@acronis-platform/ui-react 3.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 (219) hide show
  1. package/dist/components/ui/accordion-container/accordion-container.js +14 -14
  2. package/dist/components/ui/accordion-container/accordion-container.js.map +1 -1
  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/bar-chart/bar-chart.js +295 -293
  7. package/dist/components/ui/bar-chart/bar-chart.js.map +1 -1
  8. package/dist/components/ui/category-bar/category-bar.js +109 -93
  9. package/dist/components/ui/category-bar/category-bar.js.map +1 -1
  10. package/dist/components/ui/chart/chart-palette.js +113 -0
  11. package/dist/components/ui/chart/chart-palette.js.map +1 -0
  12. package/dist/components/ui/chart/chart.js +176 -129
  13. package/dist/components/ui/chart/chart.js.map +1 -1
  14. package/dist/components/ui/chart-state/chart-state-illustrations.js +310 -0
  15. package/dist/components/ui/chart-state/chart-state-illustrations.js.map +1 -0
  16. package/dist/components/ui/chart-state/chart-state.js +48 -34
  17. package/dist/components/ui/chart-state/chart-state.js.map +1 -1
  18. package/dist/components/ui/chart-widget/chart-widget.js +87 -0
  19. package/dist/components/ui/chart-widget/chart-widget.js.map +1 -0
  20. package/dist/components/ui/composed-chart/composed-chart.js +117 -115
  21. package/dist/components/ui/composed-chart/composed-chart.js.map +1 -1
  22. package/dist/components/ui/confidence-cone/confidence-cone.js +166 -158
  23. package/dist/components/ui/confidence-cone/confidence-cone.js.map +1 -1
  24. package/dist/components/ui/funnel-chart/funnel-chart.js +162 -161
  25. package/dist/components/ui/funnel-chart/funnel-chart.js.map +1 -1
  26. package/dist/components/ui/histogram/histogram.js +94 -92
  27. package/dist/components/ui/histogram/histogram.js.map +1 -1
  28. package/dist/components/ui/input/input.js.map +1 -1
  29. package/dist/components/ui/label/label.js +2 -9
  30. package/dist/components/ui/label/label.js.map +1 -1
  31. package/dist/components/ui/line-chart/line-chart.js +143 -141
  32. package/dist/components/ui/line-chart/line-chart.js.map +1 -1
  33. package/dist/components/ui/metric/metric.js +74 -185
  34. package/dist/components/ui/metric/metric.js.map +1 -1
  35. package/dist/components/ui/page-content/page-content.js.map +1 -1
  36. package/dist/components/ui/pie-chart/pie-chart.js +201 -195
  37. package/dist/components/ui/pie-chart/pie-chart.js.map +1 -1
  38. package/dist/components/ui/radar-chart/radar-chart.js +133 -131
  39. package/dist/components/ui/radar-chart/radar-chart.js.map +1 -1
  40. package/dist/components/ui/radial-bar-chart/radial-bar-chart.js +297 -265
  41. package/dist/components/ui/radial-bar-chart/radial-bar-chart.js.map +1 -1
  42. package/dist/components/ui/sankey-chart/sankey-chart.js +123 -101
  43. package/dist/components/ui/sankey-chart/sankey-chart.js.map +1 -1
  44. package/dist/components/ui/scatter-chart/scatter-chart.js +76 -74
  45. package/dist/components/ui/scatter-chart/scatter-chart.js.map +1 -1
  46. package/dist/components/ui/section/section.js +157 -31
  47. package/dist/components/ui/section/section.js.map +1 -1
  48. package/dist/components/ui/stepper/stepper.js +24 -24
  49. package/dist/components/ui/stepper/stepper.js.map +1 -1
  50. package/dist/components/ui/stepper-item/stepper-item.js +43 -24
  51. package/dist/components/ui/stepper-item/stepper-item.js.map +1 -1
  52. package/dist/components/ui/treemap/treemap.js +133 -124
  53. package/dist/components/ui/treemap/treemap.js.map +1 -1
  54. package/dist/components/ui/trend-indicator/trend-indicator.js +34 -69
  55. package/dist/components/ui/trend-indicator/trend-indicator.js.map +1 -1
  56. package/dist/components/ui/wizard/wizard.js +59 -0
  57. package/dist/components/ui/wizard/wizard.js.map +1 -0
  58. package/dist/hooks/use-wizard.js +75 -0
  59. package/dist/hooks/use-wizard.js.map +1 -0
  60. package/dist/index.js +502 -497
  61. package/dist/index.js.map +1 -1
  62. package/dist/llms/accordion-container.md +181 -0
  63. package/dist/llms/accordion.md +124 -0
  64. package/dist/llms/alert.md +225 -0
  65. package/dist/llms/app-shell-chat.md +415 -0
  66. package/dist/llms/area-chart.md +355 -0
  67. package/dist/llms/avatar.md +208 -0
  68. package/dist/llms/bar-chart.md +406 -0
  69. package/dist/llms/breadcrumb.md +326 -0
  70. package/dist/llms/button-group.md +298 -0
  71. package/dist/llms/button-icon-input.md +142 -0
  72. package/dist/llms/button-icon-menu.md +209 -0
  73. package/dist/llms/button-icon.md +128 -0
  74. package/dist/llms/button-menu.md +172 -0
  75. package/dist/llms/button.md +185 -0
  76. package/dist/llms/calendar-panel.md +733 -0
  77. package/dist/llms/calendar.md +188 -0
  78. package/dist/llms/card-filter.md +214 -0
  79. package/dist/llms/card-section.md +293 -0
  80. package/dist/llms/card.md +447 -0
  81. package/dist/llms/carousel-dialog.md +156 -0
  82. package/dist/llms/category-bar.md +193 -0
  83. package/dist/llms/chart-state.md +190 -0
  84. package/dist/llms/chart-widget.md +209 -0
  85. package/dist/llms/chart.md +182 -0
  86. package/dist/llms/checkbox.md +257 -0
  87. package/dist/llms/chip.md +195 -0
  88. package/dist/llms/combobox.md +164 -0
  89. package/dist/llms/composed-chart.md +508 -0
  90. package/dist/llms/confidence-cone.md +277 -0
  91. package/dist/llms/data-table.md +474 -0
  92. package/dist/llms/date-range-picker.md +272 -0
  93. package/dist/llms/description-list.md +131 -0
  94. package/dist/llms/dialog-footer-carousel.md +147 -0
  95. package/dist/llms/dialog-footer-default.md +142 -0
  96. package/dist/llms/dialog-root.md +246 -0
  97. package/dist/llms/dialog-welcome.md +223 -0
  98. package/dist/llms/dialog.md +403 -0
  99. package/dist/llms/dropdown-menu.md +193 -0
  100. package/dist/llms/empty-overlay.md +146 -0
  101. package/dist/llms/empty.md +156 -0
  102. package/dist/llms/field.md +185 -0
  103. package/dist/llms/filter-cards.md +157 -0
  104. package/dist/llms/filter-chips.md +323 -0
  105. package/dist/llms/filter-search.md +512 -0
  106. package/dist/llms/form.md +154 -0
  107. package/dist/llms/funnel-chart.md +333 -0
  108. package/dist/llms/grid.md +80 -0
  109. package/dist/llms/histogram.md +190 -0
  110. package/dist/llms/input-date-picker.md +203 -0
  111. package/dist/llms/input-otp.md +173 -0
  112. package/dist/llms/input-password.md +197 -0
  113. package/dist/llms/input-search.md +170 -0
  114. package/dist/llms/input-select.md +278 -0
  115. package/dist/llms/input-text-area.md +271 -0
  116. package/dist/llms/input-text.md +192 -0
  117. package/dist/llms/line-chart.md +369 -0
  118. package/dist/llms/link.md +209 -0
  119. package/dist/llms/loading.md +130 -0
  120. package/dist/llms/meter.md +177 -0
  121. package/dist/llms/metric.md +204 -0
  122. package/dist/llms/number-field.md +122 -0
  123. package/dist/llms/page-content.md +69 -0
  124. package/dist/llms/page-header.md +182 -0
  125. package/dist/llms/pagination.md +133 -0
  126. package/dist/llms/pie-chart.md +307 -0
  127. package/dist/llms/popover.md +252 -0
  128. package/dist/llms/progress-circle.md +126 -0
  129. package/dist/llms/progress.md +111 -0
  130. package/dist/llms/radar-chart.md +316 -0
  131. package/dist/llms/radial-bar-chart.md +319 -0
  132. package/dist/llms/radio.md +255 -0
  133. package/dist/llms/resizable.md +195 -0
  134. package/dist/llms/sankey-chart.md +208 -0
  135. package/dist/llms/scatter-chart.md +239 -0
  136. package/dist/llms/scroll-area.md +183 -0
  137. package/dist/llms/section.md +401 -0
  138. package/dist/llms/select.md +210 -0
  139. package/dist/llms/separator.md +87 -0
  140. package/dist/llms/sheet.md +202 -0
  141. package/dist/llms/sidebar-primary.md +360 -0
  142. package/dist/llms/sidebar-secondary.md +417 -0
  143. package/dist/llms/skeleton.md +81 -0
  144. package/dist/llms/slider.md +97 -0
  145. package/dist/llms/spinner.md +100 -0
  146. package/dist/llms/stack.md +80 -0
  147. package/dist/llms/stepper-item.md +309 -0
  148. package/dist/llms/stepper.md +251 -0
  149. package/dist/llms/switch.md +140 -0
  150. package/dist/llms/table.md +436 -0
  151. package/dist/llms/tabs.md +197 -0
  152. package/dist/llms/tag.md +139 -0
  153. package/dist/llms/timeline.md +361 -0
  154. package/dist/llms/timer.md +259 -0
  155. package/dist/llms/toast.md +241 -0
  156. package/dist/llms/toggle-group.md +121 -0
  157. package/dist/llms/toolbar.md +453 -0
  158. package/dist/llms/tooltip.md +164 -0
  159. package/dist/llms/treemap.md +254 -0
  160. package/dist/llms/trend-indicator.md +132 -0
  161. package/dist/llms/widget-placeholder.md +169 -0
  162. package/dist/llms/wizard.md +412 -0
  163. package/dist/llms.txt +142 -0
  164. package/dist/react.js +502 -497
  165. package/dist/react.js.map +1 -1
  166. package/dist/src/components/ui/area-chart/area-chart.d.ts +9 -4
  167. package/dist/src/components/ui/avatar/avatar.d.ts +1 -1
  168. package/dist/src/components/ui/bar-chart/bar-chart.d.ts +9 -4
  169. package/dist/src/components/ui/category-bar/category-bar.d.ts +10 -4
  170. package/dist/src/components/ui/chart/__stories__/palette-control.d.ts +48 -0
  171. package/dist/src/components/ui/chart/__tests__/chart-palette.test.d.ts +1 -0
  172. package/dist/src/components/ui/chart/chart-palette.d.ts +128 -0
  173. package/dist/src/components/ui/chart/chart.d.ts +66 -15
  174. package/dist/src/components/ui/chart/index.d.ts +4 -2
  175. package/dist/src/components/ui/chart-state/chart-state-illustrations.d.ts +6 -0
  176. package/dist/src/components/ui/chart-state/chart-state.d.ts +13 -2
  177. package/dist/src/components/ui/chart-state/index.d.ts +1 -0
  178. package/dist/src/components/ui/chart-widget/chart-widget.d.ts +64 -0
  179. package/dist/src/components/ui/chart-widget/index.d.ts +1 -0
  180. package/dist/src/components/ui/composed-chart/composed-chart.d.ts +12 -7
  181. package/dist/src/components/ui/confidence-cone/confidence-cone.d.ts +10 -5
  182. package/dist/src/components/ui/empty-overlay/empty-overlay.d.ts +1 -1
  183. package/dist/src/components/ui/funnel-chart/funnel-chart.d.ts +11 -5
  184. package/dist/src/components/ui/histogram/histogram.d.ts +10 -4
  185. package/dist/src/components/ui/label/index.d.ts +1 -1
  186. package/dist/src/components/ui/label/label.d.ts +1 -5
  187. package/dist/src/components/ui/line-chart/line-chart.d.ts +9 -4
  188. package/dist/src/components/ui/metric/metric.d.ts +13 -14
  189. package/dist/src/components/ui/pie-chart/pie-chart.d.ts +17 -8
  190. package/dist/src/components/ui/radar-chart/radar-chart.d.ts +10 -5
  191. package/dist/src/components/ui/radial-bar-chart/radial-bar-chart.d.ts +17 -6
  192. package/dist/src/components/ui/sankey-chart/sankey-chart.d.ts +10 -5
  193. package/dist/src/components/ui/scatter-chart/scatter-chart.d.ts +10 -5
  194. package/dist/src/components/ui/section/index.d.ts +1 -1
  195. package/dist/src/components/ui/section/section.d.ts +75 -6
  196. package/dist/src/components/ui/stepper-item/stepper-item.d.ts +6 -5
  197. package/dist/src/components/ui/tag/tag.d.ts +1 -1
  198. package/dist/src/components/ui/treemap/treemap.d.ts +11 -5
  199. package/dist/src/components/ui/trend-indicator/trend-indicator.d.ts +3 -7
  200. package/dist/src/components/ui/wizard/index.d.ts +1 -0
  201. package/dist/src/components/ui/wizard/wizard.d.ts +6 -0
  202. package/dist/src/hooks/index.d.ts +1 -0
  203. package/dist/src/hooks/use-wizard.d.ts +80 -0
  204. package/dist/src/index.d.ts +2 -3
  205. package/dist/ui-react.css +1 -1
  206. package/package.json +9 -3
  207. package/dist/components/ui/app-shell/app-shell.js +0 -75
  208. package/dist/components/ui/app-shell/app-shell.js.map +0 -1
  209. package/dist/components/ui/auth-layout/auth-layout.js +0 -56
  210. package/dist/components/ui/auth-layout/auth-layout.js.map +0 -1
  211. package/dist/components/ui/collapsible/collapsible.js +0 -22
  212. package/dist/components/ui/collapsible/collapsible.js.map +0 -1
  213. package/dist/src/components/ui/app-shell/app-shell.d.ts +0 -8
  214. package/dist/src/components/ui/app-shell/index.d.ts +0 -1
  215. package/dist/src/components/ui/auth-layout/auth-layout.d.ts +0 -6
  216. package/dist/src/components/ui/auth-layout/index.d.ts +0 -1
  217. package/dist/src/components/ui/collapsible/collapsible.d.ts +0 -5
  218. package/dist/src/components/ui/collapsible/index.d.ts +0 -1
  219. package/dist/src/components/ui/label/label.docs.d.ts +0 -10
@@ -0,0 +1,142 @@
1
+ # DialogFooterDefault
2
+
3
+ > A bottom action bar (panel/dialog/sheet footer) — end-aligned actions plus an optional start slot: a truncated description, or a link. The Figma `variant` (default / withDescription / withLink) is structural, following from which slot is passed, not a separate prop.
4
+
5
+ **Status:** ready · **Category:** layout · **Since:** v0.58.0
6
+
7
+ ## Import
8
+
9
+ ```tsx
10
+ import { DialogFooterDefault } from '@acronis-platform/ui-react'
11
+ ```
12
+
13
+ ## Quick example
14
+
15
+ ```tsx
16
+ <DialogFooterDefault>
17
+ <Button variant="secondary">Cancel</Button>
18
+ <Button>Save</Button>
19
+ </DialogFooterDefault>
20
+
21
+ <DialogFooterDefault description="Changes are saved automatically as you type.">
22
+ <Button variant="secondary">Cancel</Button>
23
+ <Button>Save</Button>
24
+ </DialogFooterDefault>
25
+
26
+ <DialogFooterDefault link={<Link href="/docs">Learn more</Link>}>
27
+ <Button variant="secondary">Cancel</Button>
28
+ <Button>Save</Button>
29
+ </DialogFooterDefault>
30
+ ```
31
+
32
+ A bottom action bar for panels, dialogs, and sheets — end-aligned actions
33
+ plus an optional start slot: a truncated description, or a link.
34
+
35
+ ## When to use
36
+
37
+ - The bottom action row of a panel/dialog/sheet — e.g. Cancel + Save.
38
+ - When the actions need brief accompanying context (a description) or a
39
+ related link (e.g. "Learn more").
40
+
41
+ ## When not to use
42
+
43
+ - For a bulk-action/selection bar above a list or table — use `Toolbar`.
44
+ - For a full app-level bottom bar — compose the layout directly.
45
+
46
+ ## Parts
47
+
48
+ | Part | Description |
49
+ | ----------- | ---------------------------------------------------------------------- |
50
+ | description | Optional truncated text next to the actions. |
51
+ | link | Optional `Link` (or similar) element next to the actions. |
52
+ | actions | End-aligned action content — typically a secondary + primary `Button`. |
53
+
54
+ `description` and `link` are mutually exclusive — pass at most one.
55
+
56
+ ## Example
57
+
58
+ ```tsx
59
+ import { Button, DialogFooterDefault, Link } from '@acronis-platform/ui-react';
60
+
61
+ <DialogFooterDefault>
62
+ <Button variant="secondary">Cancel</Button>
63
+ <Button>Save</Button>
64
+ </DialogFooterDefault>
65
+
66
+ <DialogFooterDefault description="Changes are saved automatically as you type.">
67
+ <Button variant="secondary">Cancel</Button>
68
+ <Button>Save</Button>
69
+ </DialogFooterDefault>
70
+
71
+ <DialogFooterDefault link={<Link href="/docs">Learn more</Link>}>
72
+ <Button variant="secondary">Cancel</Button>
73
+ <Button>Save</Button>
74
+ </DialogFooterDefault>
75
+ ```
76
+
77
+ ## Props
78
+
79
+ | Prop | Type | Default | Required | Description |
80
+ |------|------|---------|----------|-------------|
81
+ | `description` | `string` | — | no | Truncated description text next to the actions. Mutually exclusive with `link` — set at most one. |
82
+ | `link` | `ReactNode` | — | no | A `Link` (or similar) element next to the actions. Mutually exclusive with `description` — set at most one. |
83
+
84
+ ## Content slots
85
+
86
+ | Slot | Description |
87
+ |------|-------------|
88
+ | `default` | End-aligned actions — typically a secondary and a primary `Button`. DialogFooterDefault imposes no button count or order. |
89
+
90
+ ## Behavior
91
+
92
+ DialogFooterDefault is a pure function of its props — no internal state, no
93
+ interaction of its own (interactivity lives on the composed `Button`/`Link`
94
+ children).
95
+
96
+ ```gherkin
97
+ Scenario: Actions only
98
+ Given a DialogFooterDefault with no `description` or `link`
99
+ Then its children render end-aligned (root falls back to justify-end)
100
+ ```
101
+
102
+ ```gherkin
103
+ Scenario: With a description
104
+ Given a DialogFooterDefault with description="Changes are saved automatically as you type."
105
+ Then the description renders truncated (single line, ellipsis) next to the actions
106
+ And the actions no longer need the justify-end fallback (the description's
107
+ flex-1 pushes them to the end)
108
+ ```
109
+
110
+ ```gherkin
111
+ Scenario: With a link
112
+ Given a DialogFooterDefault with link={<Link href="/docs">Learn more</Link>}
113
+ Then the link renders in a 32px-tall row next to the actions, untruncated
114
+ ```
115
+
116
+ ```gherkin
117
+ Scenario: description and link are mutually exclusive
118
+ Given a DialogFooterDefault with both `description` and `link` set
119
+ Then both slots render (the component does not validate mutual exclusivity) —
120
+ callers should pass at most one, matching the single Figma `variant`
121
+ ```
122
+
123
+ ## Accessibility
124
+
125
+ - DialogFooterDefault is a plain layout container — no landmark role of its
126
+ own. If a DialogFooterDefault's actions form the primary controls for an
127
+ enclosing dialog/sheet, that ancestor (e.g. `Dialog`, `Sheet`) owns the
128
+ relevant ARIA (e.g. `role="dialog"`, focus trapping); DialogFooterDefault
129
+ does not duplicate it.
130
+ - All interactive semantics (focus order, keyboard activation, accessible
131
+ names) come from the composed `Button`/`Link` children — DialogFooterDefault
132
+ does not wrap or override them.
133
+ - The `description` text is plain, truncated text — `title`/`aria-label` is
134
+ the caller's responsibility if the full (untruncated) text should also be
135
+ available to assistive tech or as a hover tooltip.
136
+
137
+ ## Contrast
138
+
139
+ `description` uses the shared `text-foreground` token
140
+ (`--ui-text-on-surface-primary`), guaranteed to meet contrast against
141
+ DialogFooterDefault's own `--ui-footer-default-color` background in both
142
+ light and dark (both come from the same semantic surface/text pairing).
@@ -0,0 +1,246 @@
1
+ # DialogRoot
2
+
3
+ > A modal overlay that interrupts the user to show focused content or request a decision. A set of composable parts (trigger, overlay, content, header, title, close, body, description, footer) built on the Base UI Dialog primitive. Initial version ported from the legacy shadcn-uikit `Dialog`; design reconciliation against Figma is pending. Internal-only as of the Dialog (recipe) merge — not exported from the package root. `Dialog` (sourceDir: dialog, see the `dialog` spec) is the sole public entry point; it composes these parts internally.
4
+
5
+ **Status:** draft · **Category:** overlays · **Since:** v0.9.0
6
+
7
+ ## Import
8
+
9
+ ```tsx
10
+ Internal-only — NOT exported from '@acronis-platform/ui-react'. `Dialog` (the recipe) is the sole public entry point; these parts are an implementation detail it composes internally (src/components/ui/dialog/dialog.tsx).
11
+ ```
12
+
13
+ ## Quick example
14
+
15
+ ```tsx
16
+ // Internal usage only (e.g. inside Dialog or its tests):
17
+ <DialogRoot>
18
+ <DialogTrigger render={<Button variant="secondary">Open</Button>} />
19
+ <DialogContent>
20
+ <DialogHeaderRoot>
21
+ <DialogTitle>Are you absolutely sure?</DialogTitle>
22
+ <DialogCloseButton />
23
+ </DialogHeaderRoot>
24
+ <DialogBodyRoot>
25
+ <DialogDescription>This action cannot be undone.</DialogDescription>
26
+ </DialogBodyRoot>
27
+ <DialogFooterRoot>
28
+ <DialogClose render={<Button variant="ghost">Cancel</Button>} />
29
+ <Button variant="destructive">Delete</Button>
30
+ </DialogFooterRoot>
31
+ </DialogContent>
32
+ </DialogRoot>
33
+ ```
34
+
35
+ > **Internal-only.** Not exported from `@acronis-platform/ui-react`. This is
36
+ > the composable primitive `Dialog` (the recipe) is built on — use
37
+ > [`Dialog`](../dialog/README.md) instead. Documented here because its source
38
+ > lives alongside `Dialog`'s (`packages/ui-react/src/components/ui/dialog/`)
39
+ > and other internal code (tests, Storybook VR coverage) still references it
40
+ > directly.
41
+
42
+ A modal overlay that interrupts the user to show focused content or request a
43
+ decision. Composable from parts; built on the Base UI Dialog primitive.
44
+
45
+ > **Status: draft (design-pending v1).** Ported from the legacy
46
+ > `@acronis-platform/shadcn-uikit` `Dialog`. There is no `--ui-dialog-*` token
47
+ > tier yet, so colors resolve to the shared semantic tokens. Enter/exit
48
+ > animations use `tw-animate-css` (overlay fade, popup fade + zoom), keyed to
49
+ > Base UI's open/closed state. Reconcile against Figma with
50
+ > `/figma-component Dialog <url> --update` once a mockup lands.
51
+
52
+ ## When to use
53
+
54
+ - Never directly — it has no public export. Use `Dialog`; if none of its
55
+ seven canned use-cases (or the `wide` escape hatch) fit, that's a gap to
56
+ raise with the design system team (a new variant), not a reason to reach
57
+ for this primitive.
58
+
59
+ ## Parts
60
+
61
+ | Part | Element (default) | Purpose |
62
+ | -------------------------------- | ------------------ | ------------------------------------------------- |
63
+ | `DialogRoot` | — | Root; owns the open state (Base UI `Root`). |
64
+ | `DialogTrigger` | `button` | Opens the dialog. |
65
+ | `DialogContent` | `div[role=dialog]` | The portaled, centered popup (+ overlay). |
66
+ | `DialogHeaderRoot` | `div` | Top bar; holds the title and close button. |
67
+ | `DialogTitle` | `h2` | Accessible dialog name (`aria-labelledby`). |
68
+ | `DialogCloseButton` | `button` | Icon button that dismisses the dialog. |
69
+ | `DialogBodyRoot` | `div` | Scrollable content region. |
70
+ | `DialogDescription` | `p` | Supporting copy (`aria-describedby`). |
71
+ | `DialogFooterRoot` | `div` | Right-aligned action bar. |
72
+ | `DialogClose` | `button` | Closes the dialog; wrap a Button via `render`. |
73
+ | `DialogOverlay` / `DialogPortal` | — | Lower-level parts (`DialogContent` renders them). |
74
+
75
+ ## Sizes
76
+
77
+ `DialogContent` takes a `size` prop controlling the popup max-width. `sm`
78
+ (512px, default) has a Figma-defined token (`--ui-dialog-container-size-sm`);
79
+ `large` (832px) is a legacy backward-compatibility size with no design token,
80
+ kept for existing call sites (see the public `Dialog` recipe's `wide` variant).
81
+
82
+ ## Example (internal usage only)
83
+
84
+ ```tsx
85
+ // NOT a public import — './dialog' is an internal module path, shown here
86
+ // only to document what Dialog (the recipe) composes internally.
87
+ import {
88
+ DialogRoot,
89
+ DialogTrigger,
90
+ DialogContent,
91
+ DialogHeaderRoot,
92
+ DialogTitle,
93
+ DialogCloseButton,
94
+ DialogBodyRoot,
95
+ DialogDescription,
96
+ DialogFooterRoot,
97
+ DialogClose,
98
+ } from './dialog';
99
+ import { Button } from '../button';
100
+
101
+ <DialogRoot>
102
+ <DialogTrigger render={<Button variant="secondary">Open dialog</Button>} />
103
+ <DialogContent>
104
+ <DialogHeaderRoot>
105
+ <DialogTitle>Are you absolutely sure?</DialogTitle>
106
+ <DialogCloseButton />
107
+ </DialogHeaderRoot>
108
+ <DialogBodyRoot>
109
+ <DialogDescription>This action cannot be undone.</DialogDescription>
110
+ </DialogBodyRoot>
111
+ <DialogFooterRoot>
112
+ <DialogClose render={<Button variant="ghost">Cancel</Button>} />
113
+ <Button variant="destructive">Delete account</Button>
114
+ </DialogFooterRoot>
115
+ </DialogContent>
116
+ </DialogRoot>;
117
+ ```
118
+
119
+ ## Props
120
+
121
+ | Prop | Type | Default | Required | Description |
122
+ |------|------|---------|----------|-------------|
123
+ | `open` | `boolean` | — | no | Controlled open state. Pair with the change event. |
124
+ | `default-open` | `boolean` | `false` | no | Initial open state when uncontrolled. |
125
+ | `modal` | `boolean | 'trap-focus'` | `true` | no | Modal behavior — traps focus and locks background scroll while open. `'trap-focus'` keeps the focus trap but allows background interaction. |
126
+ | `size` | `'sm' | 'large'` | `'sm'` | no | Popup max-width (on the content part). `sm` (512px) has a Figma-defined token (`--ui-dialog-container-size-sm`); `large` (832px) is a legacy backward-compatibility size with no design token, kept for existing call sites (see the public `Dialog` recipe's `wide` variant). |
127
+ | `portal` | `boolean` | `true` | no | Render the content inside a portal (the content part). Required by the underlying primitive for correct stacking; disable only when supplying your own portal ancestor. |
128
+ | `render` | `RenderProp` | `undefined` | no | Composition prop available on the trigger, close, title, description, and other primitive parts — replaces the rendered element with another component (e.g. render the trigger as a Button) while merging props. React-only; other frameworks use their own polymorphism. |
129
+
130
+ ## Events
131
+
132
+ | Event | Payload | Description |
133
+ |-------|---------|-------------|
134
+ | `open-change` | `boolean` | Fired when the dialog opens or closes (React: `onOpenChange`). Payload is the new open value. |
135
+
136
+ ## Content slots
137
+
138
+ | Slot | Description |
139
+ |------|-------------|
140
+ | `default` | The composed dialog. Author it from the parts: an optional trigger, plus the content (popup) wrapping an optional header (title + close), a body (with a description), and an optional footer for actions. |
141
+
142
+ ## Behavior
143
+
144
+ DialogRoot is a modal overlay assembled from composable parts. It owns one
145
+ piece of state — `open` — and the focus/scroll management that comes with
146
+ being modal.
147
+
148
+ ### Opening & closing
149
+
150
+ ```gherkin
151
+ Scenario: Opening from the trigger
152
+ Given a closed DialogRoot with a DialogTrigger
153
+ When the user activates the trigger
154
+ Then the overlay and popup appear
155
+ And focus moves into the dialog
156
+ And open-change(true) fires
157
+ ```
158
+
159
+ ```gherkin
160
+ Scenario: Closing via the close button
161
+ Given an open DialogRoot with a DialogCloseButton
162
+ When the user activates the close button
163
+ Then the dialog closes
164
+ And open-change(false) fires
165
+ And focus returns to the trigger
166
+ ```
167
+
168
+ ```gherkin
169
+ Scenario: Dismissing with the keyboard
170
+ Given an open modal DialogRoot
171
+ When the user presses Escape
172
+ Then the dialog closes and open-change(false) fires
173
+ ```
174
+
175
+ ```gherkin
176
+ Scenario: Dismissing by clicking outside
177
+ Given an open DialogRoot
178
+ When the user presses on the overlay outside the popup
179
+ Then the dialog closes and open-change(false) fires
180
+ ```
181
+
182
+ ### Controlled vs uncontrolled
183
+
184
+ ```gherkin
185
+ Scenario: Uncontrolled with default-open
186
+ Given a DialogRoot with default-open = true and no open prop
187
+ When it mounts
188
+ Then it renders open, and the user can dismiss it without consumer code
189
+ ```
190
+
191
+ ```gherkin
192
+ Scenario: Controlled
193
+ Given a DialogRoot with a fixed open prop
194
+ When the user attempts to dismiss it
195
+ Then internal state does NOT change on its own
196
+ And open-change fires so the consumer can update the open prop
197
+ ```
198
+
199
+ ### Modality
200
+
201
+ ```gherkin
202
+ Scenario: Modal locks the background (default)
203
+ Given an open DialogRoot with modal = true
204
+ Then background content is inert, scroll is locked, and focus is trapped
205
+ inside the dialog until it closes
206
+ ```
207
+
208
+ ## Accessibility
209
+
210
+ DialogRoot leans on the Base UI Dialog primitive for its modal semantics,
211
+ focus management, and keyboard handling. The author's job is to provide an
212
+ accessible name and description and to use the parts as intended.
213
+
214
+ ## Roles & semantics
215
+
216
+ - The popup (`root`) has `role="dialog"` and `aria-modal="true"` when modal.
217
+ - **Name the dialog.** Render a `DialogTitle` — it is wired to the popup via
218
+ `aria-labelledby`. Without a title the dialog has no accessible name.
219
+ - **Describe it when useful.** A `DialogDescription` is wired via
220
+ `aria-describedby`, so supporting copy is announced after the name.
221
+ - The close button exposes an accessible name ("Close") via an `sr-only` label
222
+ alongside the icon.
223
+
224
+ ## Keyboard
225
+
226
+ - **Tab / Shift+Tab** — focus cycles **within** the dialog only; the focus trap
227
+ prevents reaching background content while modal.
228
+ - **Escape** — closes the dialog (fires the change event).
229
+ - On open, focus moves into the dialog (the first focusable element, or the
230
+ popup); on close, focus returns to the element that opened it (the trigger).
231
+
232
+ ## Screen reader
233
+
234
+ - Entering the dialog announces its role, name (title), and description.
235
+ - While modal, background content is marked inert, so assistive tech stays
236
+ within the dialog.
237
+
238
+ ## Contrast
239
+
240
+ - Title/body text use `--ui-text-on-surface-primary`; the description and idle
241
+ close icon use `--ui-text-on-surface-secondary`; both meet WCAG AA against the
242
+ `--ui-background-surface-secondary` popup and `--ui-background-surface-primary`
243
+ header/footer in light and dark themes. The close button shows a 2px
244
+ `--ui-focus-primary` ring on keyboard focus.
245
+ - This is a design-pending v1 on semantic tokens — re-verify contrast against the
246
+ final palette once a `--ui-dialog-*` tier and Figma reference exist.
@@ -0,0 +1,223 @@
1
+ # DialogWelcome
2
+
3
+ > An onboarding dialog with two layouts: `carousel` (a multi-slide feature tour driven by a real Embla carousel engine, with a `DialogFooterCarousel` footer) and `single` (one image/title/description body with a primary action and a `Close` link). Built from scratch — does not reuse any existing carousel implementation in this repo.
4
+
5
+ **Status:** draft · **Category:** overlay · **Since:** v0.58.0
6
+
7
+ ## Import
8
+
9
+ ```tsx
10
+ import { DialogWelcome } from '@acronis-platform/ui-react'
11
+ ```
12
+
13
+ ## Quick example
14
+
15
+ ```tsx
16
+ <DialogWelcome
17
+ variant="carousel"
18
+ slides={[
19
+ { title: 'Automated backups', description: 'Your data is backed up on a schedule you control.' },
20
+ { title: 'Instant recovery', description: 'Restore a full workload in minutes, not hours.' },
21
+ ]}
22
+ open={open}
23
+ onOpenChange={setOpen}
24
+ onPrimaryAction={() => setOpen(false)}
25
+ />
26
+
27
+ <DialogWelcome
28
+ variant="single"
29
+ title="You're all set"
30
+ description="Your workspace is ready to go."
31
+ primaryLabel="Get started"
32
+ open={open}
33
+ onOpenChange={setOpen}
34
+ />
35
+ ```
36
+
37
+ An onboarding dialog with two layouts: `carousel` (a multi-slide feature tour
38
+ driven by a real Embla carousel engine, with a `DialogFooterCarousel` footer)
39
+ and `single` (one image/title/description body with a primary action and a
40
+ `Close` link). Built from scratch; does not reuse any existing carousel
41
+ implementation in this repo.
42
+
43
+ ## When to use
44
+
45
+ - A first-run or feature-announcement dialog that walks through several
46
+ screenshots/highlights one at a time — use `variant="carousel"`.
47
+ - A single-screen announcement or confirmation with one image and one
48
+ call-to-action — use `variant="single"`.
49
+
50
+ ## When not to use
51
+
52
+ - An ordinary confirmation/action dialog — use `Dialog`.
53
+ - A content carousel with no dialog chrome — compose `DialogFooterCarousel`
54
+ (or a plain Embla instance) directly into your own layout.
55
+
56
+ ## Parts
57
+
58
+ | Part | Description |
59
+ | ------------- | ------------------------------------------------------------------------- |
60
+ | container | The popup card — reuses `Dialog`'s own chrome. |
61
+ | image | Illustration/media for the active slide (or the single body). |
62
+ | title | The active slide's title; also the dialog's accessible name. |
63
+ | description | The active slide's description; also the dialog's accessible description. |
64
+ | footer | `DialogFooterCarousel` (`variant="carousel"` only). |
65
+ | primaryAction | Call-to-action `Button` (`variant="single"` only). |
66
+ | close | Ghost `Button` that dismisses the dialog (`variant="single"` only). |
67
+
68
+ ## Example
69
+
70
+ ```tsx
71
+ import { DialogWelcome } from '@acronis-platform/ui-react';
72
+
73
+ <DialogWelcome
74
+ variant="carousel"
75
+ slides={[
76
+ { title: 'Automated backups', description: 'Your data is backed up on a schedule you control.' },
77
+ { title: 'Instant recovery', description: 'Restore a full workload in minutes, not hours.' },
78
+ ]}
79
+ open={open}
80
+ onOpenChange={setOpen}
81
+ onPrimaryAction={() => setOpen(false)}
82
+ />
83
+
84
+ <DialogWelcome
85
+ variant="single"
86
+ title="You're all set"
87
+ description="Your workspace is ready to go."
88
+ primaryLabel="Get started"
89
+ open={open}
90
+ onOpenChange={setOpen}
91
+ />
92
+ ```
93
+
94
+ ## Props
95
+
96
+ | Prop | Type | Default | Required | Description |
97
+ |------|------|---------|----------|-------------|
98
+ | `variant` | `'carousel' | 'single'` | `'carousel'` | no | Selects the Figma-defined layout. |
99
+ | `slides` | `Array<{ image?: ReactNode; title: string; description: string }>` | `3-item placeholder ('Title' / 'Feature description.')` | no | Slides shown one at a time (`variant="carousel"`). |
100
+ | `selected-index` | `number` | — | no | Controls the active slide (`variant="carousel"`). Uncontrolled (starting at `0`) when omitted. |
101
+ | `back-label` | `string` | `'Back'` | no | `Back` button label (`variant="carousel"`). |
102
+ | `next-label` | `string` | `'Next'` | no | `Next` button label (`variant="carousel"`). |
103
+ | `go-to-slide-label` | `(index: number, count: number) => string` | — | no | Builds each carousel dot's accessible name (`variant="carousel"`). |
104
+ | `image` | `ReactNode` | — | no | Illustration/media (`variant="single"`). |
105
+ | `title` | `string` | `'Title'` | no | `variant="single"` title. |
106
+ | `description` | `string` | `'Feature description.'` | no | `variant="single"` description. |
107
+ | `close-label` | `string` | `'Close'` | no | `Close` link label (`variant="single"`). |
108
+ | `primary-label` | `string` | `'Call to action'` | no | Call-to-action button label. |
109
+ | `open` | `boolean` | — | no | Controlled open state. Pair with the change event. |
110
+ | `default-open` | `boolean` | `false` | no | Initial open state when uncontrolled (React `defaultOpen`). |
111
+ | `modal` | `boolean | 'trap-focus'` | `true` | no | Modal behavior — traps focus and locks background scroll while open. |
112
+ | `portal` | `boolean` | `true` | no | Render the popup inside a portal (forwarded to `DialogContent`). |
113
+ | `keep-mounted` | `boolean` | — | no | Keep the popup mounted while closed (forwarded to `DialogContent`). |
114
+
115
+ ## Events
116
+
117
+ | Event | Payload | Description |
118
+ |-------|---------|-------------|
119
+ | `open-change` | `boolean` | Fired when the dialog opens or closes (React `onOpenChange`). |
120
+ | `selected-index-change` | `number` | Fired whenever the active slide changes (React `onSelectedIndexChange`, `variant="carousel"`). |
121
+ | `close-action` | `undefined` | Fired when `Close` is activated, before the dialog closes (React `onCloseAction`, `variant="single"`). |
122
+ | `primary-action` | `undefined` | Fired when the call-to-action button is activated (React `onPrimaryAction`). |
123
+
124
+ ## Behavior
125
+
126
+ ```gherkin
127
+ Scenario: Opening the carousel variant
128
+ Given a DialogWelcome with variant="carousel" and 3 slides
129
+ When it opens
130
+ Then the first slide's image/title/description render
131
+ And the footer renders with variant="start" (no Back, Next visible)
132
+ And the dot indicator marks the first dot active
133
+ ```
134
+
135
+ ```gherkin
136
+ Scenario: Advancing through the carousel
137
+ Given an open DialogWelcome carousel on a middle slide
138
+ When Next is activated
139
+ Then the carousel scrolls to the next slide
140
+ And onSelectedIndexChange fires with the new index
141
+ And the footer's variant updates (start/middle/end) to match the new position
142
+ ```
143
+
144
+ ```gherkin
145
+ Scenario: Reaching the last slide
146
+ Given an open DialogWelcome carousel on the last slide
147
+ Then the footer renders with variant="end"
148
+ And its call-to-action button (default "Call to action") replaces Next
149
+ When the call-to-action button is activated
150
+ Then onPrimaryAction fires — the dialog does not close automatically
151
+ ```
152
+
153
+ ```gherkin
154
+ Scenario: Jumping directly to a slide
155
+ Given an open DialogWelcome carousel
156
+ When a dot other than the active one is activated
157
+ Then the carousel scrolls directly to that slide
158
+ And onSelectedIndexChange fires with its index
159
+ ```
160
+
161
+ ```gherkin
162
+ Scenario: Controlled without a change handler
163
+ Given an open DialogWelcome carousel with a controlled `selectedIndex`
164
+ and no `onSelectedIndexChange` wired
165
+ When Back, Next, or a dot is activated
166
+ Then nothing happens — these controls only ever call
167
+ `onSelectedIndexChange`, which is absent, so the carousel cannot move
168
+ When a drag gesture moves the carousel's physical position directly
169
+ Then it snaps back to the controlled `selectedIndex` instead of leaving
170
+ the visible slide out of sync with the slide carrying the dialog's
171
+ accessible name
172
+ ```
173
+
174
+ ```gherkin
175
+ Scenario: Non-active slides are inert
176
+ Given an open DialogWelcome carousel with more than one slide
177
+ Then every slide except the active one is `aria-hidden` and `inert` —
178
+ unreachable by keyboard/screen reader until it becomes active
179
+ ```
180
+
181
+ ```gherkin
182
+ Scenario: Opening the single variant
183
+ Given a DialogWelcome with variant="single"
184
+ When it opens
185
+ Then the image/title/description render once, with no footer
186
+ And a primary call-to-action button and a "Close" link render below it
187
+ ```
188
+
189
+ ```gherkin
190
+ Scenario: Closing from the single variant
191
+ Given an open DialogWelcome with variant="single"
192
+ When Close is activated
193
+ Then onCloseAction fires
194
+ And the dialog closes (Dialog.Close's default behavior)
195
+ ```
196
+
197
+ ## Accessibility
198
+
199
+ - Reuses Base UI `Dialog.Root`/`Dialog.Popup` (via `DialogContent`) for focus
200
+ trapping, scroll locking, `role="dialog"`/`aria-modal`, and Escape/
201
+ outside-press dismissal — the same primitive `Dialog` builds on.
202
+ - Exactly one `Dialog.Title`/`Dialog.Description` pair is mounted at a time —
203
+ the active slide's (`variant="carousel"`) or the single body's
204
+ (`variant="single"`). This keeps `aria-labelledby`/`aria-describedby`
205
+ pointed at real, visible content instead of an off-screen duplicate.
206
+ - **Non-active carousel slides are hidden from assistive tech and the
207
+ keyboard** (`aria-hidden` + `inert`) — a screen reader or Tab press cannot
208
+ land on a slide that isn't currently shown, which a naive "just clip it
209
+ visually" carousel would get wrong.
210
+ - The footer's `Back`/`Next`/call-to-action controls and dot indicators
211
+ inherit `DialogFooterCarousel`'s accessibility contract (see its own
212
+ `accessibility.md`) — real `<button>`s, explicit dot labels, `aria-current`
213
+ on the active dot.
214
+ - `variant="single"`'s primary action and `Close` are both real `Button`s;
215
+ `Close` is wrapped in `Dialog.Close` so Escape and the button both dismiss
216
+ the same way.
217
+
218
+ ## Contrast
219
+
220
+ `image`'s placeholder surface (`--ui-background-surface-active`) and
221
+ `title`/`description`'s text (`--ui-text-on-surface-primary`, bridged via
222
+ `text-foreground`) are the same semantic surface/text pairing used across the
223
+ kit — contrast-checked in both light and dark by construction.