@godxjp/ui 19.6.0 → 20.1.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 (326) hide show
  1. package/README.md +8 -2
  2. package/dist/app/theme-axes.d.ts +2 -0
  3. package/dist/app/theme-axes.js +45 -0
  4. package/dist/components/charts/chart-cartesian.d.ts +2 -1
  5. package/dist/components/charts/chart-cartesian.js +52 -3
  6. package/dist/components/charts/chart-category-axis.d.ts +55 -0
  7. package/dist/components/charts/chart-category-axis.js +93 -0
  8. package/dist/components/charts/chart-frame.d.ts +10 -1
  9. package/dist/components/charts/chart-frame.js +19 -3
  10. package/dist/components/charts/compact-bar-trend.d.ts +1 -1
  11. package/dist/components/charts/compact-bar-trend.js +2 -0
  12. package/dist/components/charts/pie-chart.d.ts +1 -1
  13. package/dist/components/charts/pie-chart.js +12 -1
  14. package/dist/components/charts/recharts-peer.d.ts +49 -0
  15. package/dist/components/charts/recharts-peer.js +45 -0
  16. package/dist/components/data-display/card.d.ts +14 -3
  17. package/dist/components/data-display/card.js +22 -4
  18. package/dist/components/data-display/code-block.js +6 -2
  19. package/dist/components/data-display/collapsible.d.ts +23 -4
  20. package/dist/components/data-display/collapsible.js +119 -4
  21. package/dist/components/data-display/data-table.d.ts +39 -4
  22. package/dist/components/data-display/data-table.js +802 -270
  23. package/dist/components/data-display/descriptions.d.ts +27 -6
  24. package/dist/components/data-display/descriptions.js +58 -17
  25. package/dist/components/data-display/index.d.ts +5 -1
  26. package/dist/components/data-display/index.js +4 -0
  27. package/dist/components/data-display/legend.d.ts +15 -0
  28. package/dist/components/data-display/legend.js +11 -0
  29. package/dist/components/data-display/list-row.d.ts +10 -1
  30. package/dist/components/data-display/list-row.js +8 -2
  31. package/dist/components/data-display/popover.d.ts +60 -7
  32. package/dist/components/data-display/popover.js +268 -39
  33. package/dist/components/data-display/progress.d.ts +50 -2
  34. package/dist/components/data-display/progress.js +57 -9
  35. package/dist/components/data-display/range-timeline.d.ts +38 -0
  36. package/dist/components/data-display/range-timeline.js +161 -0
  37. package/dist/components/data-display/scroll-area.js +13 -2
  38. package/dist/components/data-display/service-launcher-card.js +10 -10
  39. package/dist/components/data-display/table.d.ts +11 -3
  40. package/dist/components/data-display/table.js +48 -18
  41. package/dist/components/data-display/tree-list.js +4 -9
  42. package/dist/components/data-entry/calendar.d.ts +2 -2
  43. package/dist/components/data-entry/calendar.js +79 -33
  44. package/dist/components/data-entry/cascader.d.ts +1 -1
  45. package/dist/components/data-entry/cascader.js +188 -24
  46. package/dist/components/data-entry/checkbox.d.ts +19 -6
  47. package/dist/components/data-entry/checkbox.js +55 -16
  48. package/dist/components/data-entry/choice-option.d.ts +1 -1
  49. package/dist/components/data-entry/color-picker.d.ts +1 -1
  50. package/dist/components/data-entry/color-picker.js +17 -5
  51. package/dist/components/data-entry/control-appearance.d.ts +64 -0
  52. package/dist/components/data-entry/control-appearance.js +39 -0
  53. package/dist/components/data-entry/control-surface.d.ts +61 -0
  54. package/dist/components/data-entry/control-surface.js +39 -0
  55. package/dist/components/data-entry/date-picker.d.ts +1 -1
  56. package/dist/components/data-entry/date-picker.js +344 -113
  57. package/dist/components/data-entry/date-range-picker.d.ts +2 -2
  58. package/dist/components/data-entry/date-range-picker.js +278 -140
  59. package/dist/components/data-entry/field.js +0 -1
  60. package/dist/components/data-entry/form-field.d.ts +1 -1
  61. package/dist/components/data-entry/form-field.js +39 -4
  62. package/dist/components/data-entry/form.d.ts +4 -0
  63. package/dist/components/data-entry/form.js +5 -3
  64. package/dist/components/data-entry/index.d.ts +7 -3
  65. package/dist/components/data-entry/index.js +10 -1
  66. package/dist/components/data-entry/input-otp.d.ts +1 -1
  67. package/dist/components/data-entry/input.d.ts +12 -34
  68. package/dist/components/data-entry/input.js +92 -24
  69. package/dist/components/data-entry/label.d.ts +3 -2
  70. package/dist/components/data-entry/label.js +23 -10
  71. package/dist/components/data-entry/month-picker.d.ts +2 -2
  72. package/dist/components/data-entry/month-picker.js +47 -10
  73. package/dist/components/data-entry/month-range-picker.d.ts +2 -2
  74. package/dist/components/data-entry/month-range-picker.js +51 -11
  75. package/dist/components/data-entry/number-input.d.ts +7 -0
  76. package/dist/components/data-entry/number-input.js +147 -98
  77. package/dist/components/data-entry/password-input.d.ts +1 -1
  78. package/dist/components/data-entry/radio.d.ts +1 -1
  79. package/dist/components/data-entry/radio.js +61 -13
  80. package/dist/components/data-entry/search-input.d.ts +1 -1
  81. package/dist/components/data-entry/search-input.js +16 -2
  82. package/dist/components/data-entry/search-select.d.ts +2 -2
  83. package/dist/components/data-entry/search-select.js +209 -78
  84. package/dist/components/data-entry/select.d.ts +22 -4
  85. package/dist/components/data-entry/select.js +215 -163
  86. package/dist/components/data-entry/slider.d.ts +9 -1
  87. package/dist/components/data-entry/slider.js +87 -9
  88. package/dist/components/data-entry/switch.d.ts +3 -0
  89. package/dist/components/data-entry/switch.js +29 -3
  90. package/dist/components/data-entry/textarea.d.ts +14 -56
  91. package/dist/components/data-entry/textarea.js +80 -33
  92. package/dist/components/data-entry/time-picker.d.ts +2 -2
  93. package/dist/components/data-entry/time-picker.js +333 -109
  94. package/dist/components/data-entry/time-range-picker.d.ts +5 -0
  95. package/dist/components/data-entry/time-range-picker.js +89 -0
  96. package/dist/components/data-entry/transfer.d.ts +1 -1
  97. package/dist/components/data-entry/transfer.js +99 -31
  98. package/dist/components/data-entry/tree-select-strategy.d.ts +1 -1
  99. package/dist/components/data-entry/tree-select.d.ts +1 -1
  100. package/dist/components/data-entry/tree-select.js +197 -92
  101. package/dist/components/data-entry/tree-utils.d.ts +1 -1
  102. package/dist/components/data-entry/tree-utils.js +7 -14
  103. package/dist/components/data-entry/upload-files.d.ts +2 -0
  104. package/dist/components/data-entry/upload-files.js +31 -0
  105. package/dist/components/data-entry/upload-request.d.ts +4 -0
  106. package/dist/components/data-entry/upload-request.js +53 -0
  107. package/dist/components/data-entry/upload-types.d.ts +28 -0
  108. package/dist/components/data-entry/upload-types.js +2 -0
  109. package/dist/components/data-entry/upload.d.ts +2 -2
  110. package/dist/components/data-entry/upload.js +482 -117
  111. package/dist/components/feedback/dialog.d.ts +105 -38
  112. package/dist/components/feedback/dialog.js +268 -193
  113. package/dist/components/feedback/overlay-close-focus.d.ts +31 -0
  114. package/dist/components/feedback/overlay-close-focus.js +31 -0
  115. package/dist/components/feedback/overlay-header-tone.d.ts +1 -1
  116. package/dist/components/feedback/sheet.d.ts +53 -11
  117. package/dist/components/feedback/sheet.js +150 -81
  118. package/dist/components/feedback/tooltip.d.ts +51 -7
  119. package/dist/components/feedback/tooltip.js +107 -25
  120. package/dist/components/general/button.d.ts +1 -1
  121. package/dist/components/general/button.js +7 -3
  122. package/dist/components/general/index.d.ts +1 -0
  123. package/dist/components/general/index.js +2 -0
  124. package/dist/components/general/logo.d.ts +17 -0
  125. package/dist/components/general/logo.js +22 -16
  126. package/dist/components/general/typography.d.ts +3 -0
  127. package/dist/components/general/typography.js +15 -1
  128. package/dist/components/general/visually-hidden.d.ts +3 -0
  129. package/dist/components/general/visually-hidden.js +9 -0
  130. package/dist/components/layout/app-launcher.d.ts +34 -0
  131. package/dist/components/layout/app-launcher.js +228 -0
  132. package/dist/components/layout/app-shell.d.ts +3 -1
  133. package/dist/components/layout/app-shell.js +69 -12
  134. package/dist/components/layout/aspect-ratio.js +0 -1
  135. package/dist/components/layout/auth-divider.js +0 -1
  136. package/dist/components/layout/breadcrumb.d.ts +14 -2
  137. package/dist/components/layout/breadcrumb.js +46 -4
  138. package/dist/components/layout/flex.d.ts +1 -1
  139. package/dist/components/layout/flex.js +41 -3
  140. package/dist/components/layout/index.d.ts +3 -0
  141. package/dist/components/layout/index.js +5 -1
  142. package/dist/components/layout/nav-surface.d.ts +26 -0
  143. package/dist/components/layout/nav-surface.js +17 -0
  144. package/dist/components/layout/org-switcher.d.ts +5 -1
  145. package/dist/components/layout/org-switcher.js +25 -4
  146. package/dist/components/layout/page-container.d.ts +1 -1
  147. package/dist/components/layout/page-container.js +5 -3
  148. package/dist/components/layout/responsive-grid.d.ts +16 -2
  149. package/dist/components/layout/responsive-grid.js +29 -2
  150. package/dist/components/layout/separator.js +0 -1
  151. package/dist/components/layout/sidebar.js +4 -1
  152. package/dist/components/layout/split-pane.d.ts +14 -1
  153. package/dist/components/layout/split-pane.js +26 -13
  154. package/dist/components/layout/topbar-item.d.ts +3 -0
  155. package/dist/components/layout/topbar-item.js +19 -5
  156. package/dist/components/layout/topbar.d.ts +1 -1
  157. package/dist/components/layout/topbar.js +27 -6
  158. package/dist/components/navigation/app-setting-picker.js +21 -2
  159. package/dist/components/navigation/app-setting-toggle.d.ts +16 -0
  160. package/dist/components/navigation/app-setting-toggle.js +96 -0
  161. package/dist/components/navigation/dropdown-menu.d.ts +227 -18
  162. package/dist/components/navigation/dropdown-menu.js +402 -118
  163. package/dist/components/navigation/index.d.ts +2 -0
  164. package/dist/components/navigation/index.js +2 -0
  165. package/dist/components/navigation/pagination-utils.d.ts +2 -1
  166. package/dist/components/navigation/pagination.d.ts +2 -2
  167. package/dist/components/navigation/pagination.js +155 -83
  168. package/dist/components/navigation/steps.d.ts +2 -2
  169. package/dist/components/navigation/steps.js +29 -4
  170. package/dist/components/navigation/tabs.d.ts +29 -16
  171. package/dist/components/navigation/tabs.js +374 -144
  172. package/dist/components/ui/accordion.d.ts +50 -5
  173. package/dist/components/ui/accordion.js +239 -33
  174. package/dist/components/ui/aspect-ratio.d.ts +23 -2
  175. package/dist/components/ui/aspect-ratio.js +15 -13
  176. package/dist/components/ui/avatar.d.ts +29 -4
  177. package/dist/components/ui/avatar.js +111 -25
  178. package/dist/components/ui/hover-card.d.ts +42 -4
  179. package/dist/components/ui/hover-card.js +183 -27
  180. package/dist/components/ui/input-otp.d.ts +26 -28
  181. package/dist/components/ui/input-otp.js +50 -7
  182. package/dist/components/ui/label.js +0 -1
  183. package/dist/components/ui/password-input.d.ts +36 -2
  184. package/dist/components/ui/password-input.js +27 -7
  185. package/dist/components/ui/rating.d.ts +25 -0
  186. package/dist/components/ui/rating.js +67 -27
  187. package/dist/components/ui/segmented.d.ts +12 -3
  188. package/dist/components/ui/segmented.js +17 -2
  189. package/dist/components/ui/separator.d.ts +12 -2
  190. package/dist/components/ui/separator.js +30 -9
  191. package/dist/components/ui/tag-input.d.ts +45 -0
  192. package/dist/components/ui/tag-input.js +109 -27
  193. package/dist/components/ui/toggle-group.d.ts +50 -5
  194. package/dist/components/ui/toggle-group.js +79 -20
  195. package/dist/components/ui/toggle.d.ts +31 -5
  196. package/dist/components/ui/toggle.js +42 -3
  197. package/dist/form/form-context.d.ts +29 -0
  198. package/dist/form/form-context.js +44 -4
  199. package/dist/form/form-field-array.d.ts +22 -0
  200. package/dist/form/form-field-array.js +50 -0
  201. package/dist/form/form-field-control.d.ts +2 -1
  202. package/dist/form/form-field-control.js +116 -40
  203. package/dist/form/form-root.d.ts +2 -1
  204. package/dist/form/form-root.js +142 -23
  205. package/dist/form/index.d.ts +3 -1
  206. package/dist/form/index.js +12 -1
  207. package/dist/i18n/messages/en.json +64 -5
  208. package/dist/i18n/messages/ja.json +64 -5
  209. package/dist/i18n/messages/vi.json +64 -5
  210. package/dist/inertia/index.d.ts +20 -0
  211. package/dist/inertia/index.js +60 -1
  212. package/dist/lib/control-styles.d.ts +25 -3
  213. package/dist/lib/control-styles.js +9 -3
  214. package/dist/lib/datetime/picker-format.d.ts +8 -0
  215. package/dist/lib/datetime/picker-format.js +54 -0
  216. package/dist/lib/slot.d.ts +32 -0
  217. package/dist/lib/slot.js +22 -0
  218. package/dist/lib/variants.d.ts +22 -3
  219. package/dist/lib/variants.js +56 -1
  220. package/dist/props/components/app.prop.d.ts +25 -1
  221. package/dist/props/components/charts.prop.d.ts +21 -0
  222. package/dist/props/components/data-display.prop.d.ts +72 -4
  223. package/dist/props/components/data-entry.prop.d.ts +718 -46
  224. package/dist/props/components/form.prop.d.ts +142 -4
  225. package/dist/props/components/general.prop.d.ts +17 -1
  226. package/dist/props/components/index.d.ts +3 -3
  227. package/dist/props/components/layout.prop.d.ts +281 -11
  228. package/dist/props/components/navigation.prop.d.ts +114 -4
  229. package/dist/props/registry.d.ts +397 -11
  230. package/dist/props/registry.js +526 -11
  231. package/dist/props/vocabulary/content.prop.d.ts +1 -1
  232. package/dist/props/vocabulary/data.prop.d.ts +179 -1
  233. package/dist/props/vocabulary/index.d.ts +5 -5
  234. package/dist/props/vocabulary/interaction.prop.d.ts +68 -3
  235. package/dist/props/vocabulary/layout.prop.d.ts +57 -1
  236. package/dist/props/vocabulary/navigation.prop.d.ts +40 -0
  237. package/dist/props/vocabulary/shared.prop.d.ts +33 -0
  238. package/dist/styles/badge-layout.css +2 -1
  239. package/dist/styles/card-layout.css +26 -4
  240. package/dist/styles/chart-layout.css +15 -0
  241. package/dist/styles/control.css +657 -15
  242. package/dist/styles/core.css +5 -2
  243. package/dist/styles/data-display-layout.css +313 -6
  244. package/dist/styles/data-entry-layout.css +13 -0
  245. package/dist/styles/focus-ring.css +4 -0
  246. package/dist/styles/index.css +5 -2
  247. package/dist/styles/layout.css +327 -4
  248. package/dist/styles/navigation-layout.css +227 -0
  249. package/dist/styles/shell-layout.css +369 -13
  250. package/dist/styles/table-layout.css +95 -6
  251. package/dist/styles/text-layout.css +10 -4
  252. package/dist/tokens/base.css +2 -1
  253. package/dist/tokens/components/badge.css +1 -0
  254. package/dist/tokens/components/chart.css +6 -0
  255. package/dist/tokens/components/control.css +79 -2
  256. package/dist/tokens/components/data-display.css +20 -0
  257. package/dist/tokens/components/descriptions.css +11 -0
  258. package/dist/tokens/components/flex.css +8 -0
  259. package/dist/tokens/components/navigation.css +55 -0
  260. package/dist/tokens/components/shell.css +53 -3
  261. package/dist/tokens/components/table.css +14 -0
  262. package/dist/tokens/foundation.css +2 -0
  263. package/dist/tokens/semantic/layout.css +9 -0
  264. package/docs/COMPONENTS.md +9 -3
  265. package/docs/CONSUMER-RULES.md +13 -0
  266. package/docs/DESIGN-AUTHORITY.md +145 -83
  267. package/docs/DEVELOPMENT.md +4 -3
  268. package/docs/FORMS.md +151 -6
  269. package/docs/FRAME-COVERAGE-REPORT.md +32 -17
  270. package/docs/README.md +15 -15
  271. package/docs/STANDARDS-vocabulary-tokens.md +1 -1
  272. package/docs/TESTING.md +15 -6
  273. package/docs/WHAT-BELONGS-HERE.md +179 -0
  274. package/docs/charts/cjk-category-axis.tsx +81 -0
  275. package/docs/data-display/card/index.tsx +22 -0
  276. package/docs/data-display/data-table/examples/antd-parity.tsx +257 -0
  277. package/docs/data-display/data-table/index.tsx +23 -0
  278. package/docs/data-display/descriptions.tsx +41 -0
  279. package/docs/data-display/legend.tsx +145 -0
  280. package/docs/data-display/progress.tsx +32 -0
  281. package/docs/data-display/scroll-area.tsx +31 -25
  282. package/docs/data-display/table.tsx +104 -45
  283. package/docs/data-display/timeline.tsx +41 -0
  284. package/docs/data-entry/date-picker.tsx +85 -0
  285. package/docs/data-entry/date-range-picker.tsx +26 -0
  286. package/docs/data-entry/form-dynamic-fields.tsx +199 -0
  287. package/docs/data-entry/form.tsx +74 -4
  288. package/docs/data-entry/input-otp.tsx +24 -0
  289. package/docs/data-entry/input.tsx +46 -1
  290. package/docs/data-entry/month-range-picker.tsx +1 -1
  291. package/docs/data-entry/segmented.tsx +1 -1
  292. package/docs/data-entry/select.tsx +29 -2
  293. package/docs/data-entry/switch.tsx +41 -0
  294. package/docs/data-entry/textarea.tsx +38 -0
  295. package/docs/data-entry/time-picker.tsx +85 -1
  296. package/docs/data-entry/time-range-picker.tsx +55 -0
  297. package/docs/data-entry/transfer.tsx +17 -0
  298. package/docs/data-entry/upload.tsx +56 -12
  299. package/docs/feedback/sheet.tsx +1 -1
  300. package/docs/feedback/tooltip.tsx +1 -1
  301. package/docs/general/activity.tsx +2 -2
  302. package/docs/general/button/index.tsx +14 -1
  303. package/docs/general/typography.tsx +14 -1
  304. package/docs/layout/app-launcher.tsx +151 -0
  305. package/docs/layout/app-shell-arrangements.tsx +225 -0
  306. package/docs/layout/app-shell.tsx +11 -0
  307. package/docs/layout/aspect-ratio.tsx +1 -1
  308. package/docs/layout/flex.tsx +50 -0
  309. package/docs/layout/responsive-grid.tsx +21 -1
  310. package/docs/layout/topbar.tsx +5 -9
  311. package/docs/navigation/app-setting-picker.tsx +37 -1
  312. package/docs/navigation/app-setting-toggle.tsx +111 -0
  313. package/docs/navigation/breadcrumb.tsx +48 -0
  314. package/docs/navigation/dropdown-menu.tsx +21 -0
  315. package/docs/navigation/pagination.tsx +52 -0
  316. package/docs/navigation/steps.tsx +37 -0
  317. package/docs/navigation/tabs.tsx +97 -1
  318. package/docs/query/button-refetch.tsx +1 -0
  319. package/package.json +28 -8
  320. package/scripts/_agent-setup.mjs +182 -3
  321. package/scripts/consumer-rule.md +98 -0
  322. package/scripts/guinea-pig-skill.md +322 -0
  323. package/scripts/init-guinea-pig.mjs +84 -0
  324. package/scripts/postinstall.mjs +13 -2
  325. package/scripts/ui-audit.mjs +351 -37
  326. /package/dist/tokens/{antd.generated.css → derived.css} +0 -0
@@ -1,45 +1,251 @@
1
1
  "use client";
2
2
  import { jsx, jsxs } from "react/jsx-runtime";
3
3
  import * as React from "react";
4
- import * as AccordionPrimitive from "@radix-ui/react-accordion";
4
+ import { chain, mergeRefs } from "@react-aria/utils";
5
+ import {
6
+ ButtonContext,
7
+ Disclosure,
8
+ DisclosureGroup,
9
+ DisclosureGroupStateContext,
10
+ DisclosurePanel,
11
+ DisclosureStateContext,
12
+ useSlottedContext
13
+ } from "react-aria-components";
5
14
  import { ChevronDown } from "lucide-react";
6
15
  import { cn } from "../../lib/utils.js";
7
- const Accordion = AccordionPrimitive.Root;
8
- const AccordionItem = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
9
- AccordionPrimitive.Item,
10
- {
11
- ref,
12
- "data-slot": "accordion-item",
13
- className: cn("ui-accordion-item", className),
14
- ...props
16
+ import { Slot } from "../../lib/slot.js";
17
+ const AccordionGroupContext = React.createContext({
18
+ orientation: "vertical"
19
+ });
20
+ const AccordionItemContext = React.createContext(null);
21
+ function useAccordionItem(component) {
22
+ const item = React.useContext(AccordionItemContext);
23
+ const state = React.useContext(DisclosureStateContext);
24
+ if (!item || !state) {
25
+ throw new Error(`\`${component}\` ph\u1EA3i n\u1EB1m trong \`AccordionItem\`.`);
15
26
  }
16
- ));
17
- AccordionItem.displayName = "AccordionItem";
18
- const AccordionTrigger = React.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsx(AccordionPrimitive.Header, { className: "ui-accordion-header", children: /* @__PURE__ */ jsxs(
19
- AccordionPrimitive.Trigger,
20
- {
21
- ref,
22
- "data-slot": "accordion-trigger",
23
- className: cn("ui-accordion-trigger", className),
24
- ...props,
25
- children: [
26
- children,
27
- /* @__PURE__ */ jsx(ChevronDown, { className: "ui-accordion-chevron", "aria-hidden": "true" })
28
- ]
27
+ return { item, state };
28
+ }
29
+ const TRIGGER_SELECTOR = '[data-slot="accordion-trigger"]:not([disabled])';
30
+ function toArray(value) {
31
+ if (value === void 0) {
32
+ return [];
29
33
  }
30
- ) }));
31
- AccordionTrigger.displayName = "AccordionTrigger";
32
- const AccordionContent = React.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsx(
33
- AccordionPrimitive.Content,
34
- {
34
+ return Array.isArray(value) ? value : [value];
35
+ }
36
+ function Accordion(accordionProps) {
37
+ const {
38
+ type,
39
+ value,
40
+ defaultValue,
41
+ onValueChange,
42
+ collapsible,
43
+ orientation = "vertical",
44
+ dir,
45
+ disabled,
46
+ onKeyDown,
47
+ children,
35
48
  ref,
36
- "data-slot": "accordion-content",
37
- className: cn("ui-accordion-content", className),
38
- ...props,
39
- children: /* @__PURE__ */ jsx("div", { className: "ui-accordion-content-inner", children })
49
+ ...props
50
+ } = accordionProps;
51
+ const [uncontrolled, setUncontrolled] = React.useState(() => toArray(defaultValue));
52
+ const isControlled = value !== void 0;
53
+ const expandedKeys = new Set(isControlled ? toArray(value) : uncontrolled);
54
+ function handleExpandedChange(keys) {
55
+ const next = [...keys].map(String);
56
+ if (type === "single" && !collapsible && next.length === 0) {
57
+ return;
58
+ }
59
+ if (!isControlled) {
60
+ setUncontrolled(next);
61
+ }
62
+ onValueChange?.(type === "multiple" ? next : next[0] ?? "");
63
+ }
64
+ function moveFocus(event) {
65
+ const from = event.target.closest?.(TRIGGER_SELECTOR);
66
+ if (!from) {
67
+ return;
68
+ }
69
+ const horizontal = orientation === "horizontal";
70
+ const forward = horizontal ? dir === "rtl" ? "ArrowLeft" : "ArrowRight" : "ArrowDown";
71
+ const backward = horizontal ? dir === "rtl" ? "ArrowRight" : "ArrowLeft" : "ArrowUp";
72
+ const triggers = [...event.currentTarget.querySelectorAll(TRIGGER_SELECTOR)];
73
+ const at = triggers.indexOf(from);
74
+ if (at < 0) {
75
+ return;
76
+ }
77
+ let to;
78
+ if (event.key === forward) {
79
+ to = (at + 1) % triggers.length;
80
+ } else if (event.key === backward) {
81
+ to = (at - 1 + triggers.length) % triggers.length;
82
+ } else if (event.key === "Home") {
83
+ to = 0;
84
+ } else if (event.key === "End") {
85
+ to = triggers.length - 1;
86
+ } else {
87
+ return;
88
+ }
89
+ event.preventDefault();
90
+ triggers[to].focus();
40
91
  }
41
- ));
42
- AccordionContent.displayName = "AccordionContent";
92
+ return /* @__PURE__ */ jsx(
93
+ DisclosureGroup,
94
+ {
95
+ allowsMultipleExpanded: type === "multiple",
96
+ expandedKeys,
97
+ onExpandedChange: handleExpandedChange,
98
+ isDisabled: disabled,
99
+ render: (racProps) => {
100
+ const {
101
+ className: _racClass,
102
+ "data-rac": _rac,
103
+ ref: racRef,
104
+ ...rest
105
+ } = racProps;
106
+ return /* @__PURE__ */ jsx(
107
+ "div",
108
+ {
109
+ ...props,
110
+ ...rest,
111
+ ref: mergeRefs(ref, racRef),
112
+ dir,
113
+ "data-orientation": orientation,
114
+ onKeyDown: chain(onKeyDown, moveFocus)
115
+ }
116
+ );
117
+ },
118
+ children: /* @__PURE__ */ jsx(AccordionGroupContext.Provider, { value: { orientation }, children })
119
+ }
120
+ );
121
+ }
122
+ function AccordionItem({
123
+ className,
124
+ disabled,
125
+ value,
126
+ children,
127
+ ref,
128
+ ...props
129
+ }) {
130
+ const { orientation } = React.useContext(AccordionGroupContext);
131
+ const groupState = React.useContext(DisclosureGroupStateContext);
132
+ const isDisabled = Boolean(disabled || groupState?.isDisabled);
133
+ return /* @__PURE__ */ jsx(
134
+ Disclosure,
135
+ {
136
+ id: value,
137
+ isDisabled,
138
+ render: (racProps, { isExpanded }) => {
139
+ const {
140
+ className: _racClass,
141
+ "data-rac": _rac,
142
+ ref: racRef,
143
+ ...rest
144
+ } = racProps;
145
+ return /* @__PURE__ */ jsx(
146
+ "div",
147
+ {
148
+ "data-slot": "accordion-item",
149
+ className: cn("ui-accordion-item", className),
150
+ ...props,
151
+ ...rest,
152
+ ref: mergeRefs(ref, racRef),
153
+ "data-state": isExpanded ? "open" : "closed",
154
+ "data-disabled": isDisabled ? "" : void 0,
155
+ "data-orientation": orientation,
156
+ children: /* @__PURE__ */ jsx(AccordionItemContext.Provider, { value: { orientation, isDisabled }, children })
157
+ }
158
+ );
159
+ }
160
+ }
161
+ );
162
+ }
163
+ function AccordionTrigger({
164
+ asChild,
165
+ className,
166
+ children,
167
+ onClick,
168
+ ...props
169
+ }) {
170
+ const { item, state } = useAccordionItem("AccordionTrigger");
171
+ const trigger = useSlottedContext(ButtonContext, "trigger");
172
+ const Comp = asChild ? Slot : "button";
173
+ const dataState = state.isExpanded ? "open" : "closed";
174
+ const dataDisabled = item.isDisabled ? "" : void 0;
175
+ return /* @__PURE__ */ jsx(
176
+ "h3",
177
+ {
178
+ className: "ui-accordion-header",
179
+ "data-orientation": item.orientation,
180
+ "data-state": dataState,
181
+ "data-disabled": dataDisabled,
182
+ children: /* @__PURE__ */ jsxs(
183
+ Comp,
184
+ {
185
+ type: "button",
186
+ id: trigger?.id,
187
+ "aria-controls": state.isExpanded ? trigger?.["aria-controls"] : void 0,
188
+ "aria-expanded": state.isExpanded,
189
+ "data-slot": "accordion-trigger",
190
+ "data-state": dataState,
191
+ "data-disabled": dataDisabled,
192
+ "data-orientation": item.orientation,
193
+ disabled: item.isDisabled,
194
+ className: cn("ui-accordion-trigger", className),
195
+ ...props,
196
+ onClick: chain(onClick, () => {
197
+ if (!item.isDisabled) {
198
+ state.toggle();
199
+ }
200
+ }),
201
+ children: [
202
+ children,
203
+ /* @__PURE__ */ jsx(ChevronDown, { className: "ui-accordion-chevron", "aria-hidden": "true" })
204
+ ]
205
+ }
206
+ )
207
+ }
208
+ );
209
+ }
210
+ function AccordionContent({
211
+ className,
212
+ forceMount,
213
+ children,
214
+ ref,
215
+ ...props
216
+ }) {
217
+ const { item, state } = useAccordionItem("AccordionContent");
218
+ return /* @__PURE__ */ jsx(
219
+ DisclosurePanel,
220
+ {
221
+ role: "region",
222
+ render: (racProps) => {
223
+ const {
224
+ className: _racClass,
225
+ "data-rac": _rac,
226
+ children: _racChildren,
227
+ ref: racRef,
228
+ ...rest
229
+ } = racProps;
230
+ return /* @__PURE__ */ jsx(
231
+ "div",
232
+ {
233
+ "data-slot": "accordion-content",
234
+ className: cn("ui-accordion-content", className),
235
+ ...props,
236
+ ...rest,
237
+ ref: mergeRefs(ref, racRef),
238
+ "data-state": state.isExpanded ? "open" : "closed",
239
+ "data-disabled": item.isDisabled ? "" : void 0,
240
+ "data-orientation": item.orientation,
241
+ children: state.isExpanded || forceMount ? /* @__PURE__ */ jsx("div", { className: "ui-accordion-content-inner", children }) : null
242
+ }
243
+ );
244
+ },
245
+ children: null
246
+ }
247
+ );
248
+ }
43
249
  export {
44
250
  Accordion,
45
251
  AccordionContent,
@@ -1,3 +1,24 @@
1
1
  import * as React from "react";
2
- import * as AspectRatioPrimitive from "@radix-ui/react-aspect-ratio";
3
- export declare const AspectRatio: React.ForwardRefExoticComponent<Omit<AspectRatioPrimitive.AspectRatioProps & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
2
+ /**
3
+ * AspectRatio hộp giữ tỉ lệ, dựng bằng thuộc tính CSS `aspect-ratio`.
4
+ *
5
+ * Radix dựng cái này bằng mẹo `padding-bottom` thời chưa có `aspect-ratio`: một
6
+ * div bọc `position: relative; width: 100%; padding-bottom: (100/ratio)%`, rồi
7
+ * div THẬT nằm trong nó ở `position: absolute; inset: 0`. Hai node, hai lớp
8
+ * định vị, chỉ để nói một câu mà CSS ngày nay nói được bằng một khai báo.
9
+ *
10
+ * Nên node bọc biến mất và `.ui-aspect-ratio` giờ LÀ hộp tỉ lệ. Kiểm trước khi
11
+ * đổi: không luật nào trong `src/styles/` bám vào `[data-radix-aspect-ratio-wrapper]`
12
+ * hay vào việc `.ui-aspect-ratio` phải là con của một node khác — luật duy nhất
13
+ * chạm tới nó là `.ui-aspect-ratio { overflow: clip; overflow-clip-margin }`
14
+ * trong `layout.css`, và nó bám vào CHÍNH node này, node vẫn còn.
15
+ *
16
+ * `position: relative` được giữ lại dù không còn cần cho mẹo padding: node bọc
17
+ * trước đây là containing block của mọi con `position: absolute` mà consumer
18
+ * đặt vào (một overlay, một badge góc). Bỏ nó đi thì những con ấy lặng lẽ nhảy
19
+ * ra neo vào tổ tiên định vị gần nhất ở ngoài.
20
+ */
21
+ export declare const AspectRatio: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & {
22
+ asChild?: boolean;
23
+ ratio?: number;
24
+ } & React.RefAttributes<HTMLDivElement>>;
@@ -1,19 +1,21 @@
1
- "use client";
2
1
  import { jsx } from "react/jsx-runtime";
3
2
  import * as React from "react";
4
- import * as AspectRatioPrimitive from "@radix-ui/react-aspect-ratio";
3
+ import { Slot } from "../../lib/slot.js";
5
4
  import { cn } from "../../lib/utils.js";
6
- const AspectRatio = React.forwardRef(({ className, ratio = 16 / 9, ...props }, ref) => /* @__PURE__ */ jsx(
7
- AspectRatioPrimitive.Root,
8
- {
9
- ref,
10
- "data-slot": "aspect-ratio",
11
- ratio,
12
- className: cn("ui-aspect-ratio", className),
13
- ...props
14
- }
15
- ));
16
- AspectRatio.displayName = AspectRatioPrimitive.Root.displayName;
5
+ const AspectRatio = React.forwardRef(({ className, ratio = 16 / 9, style, asChild = false, ...props }, ref) => {
6
+ const Comp = asChild ? Slot : "div";
7
+ return /* @__PURE__ */ jsx(
8
+ Comp,
9
+ {
10
+ ref,
11
+ "data-slot": "aspect-ratio",
12
+ className: cn("ui-aspect-ratio", className),
13
+ style: { ...style, position: "relative", width: "100%", aspectRatio: `${ratio}` },
14
+ ...props
15
+ }
16
+ );
17
+ });
18
+ AspectRatio.displayName = "AspectRatio";
17
19
  export {
18
20
  AspectRatio
19
21
  };
@@ -1,6 +1,31 @@
1
1
  import * as React from "react";
2
- import * as AvatarPrimitive from "@radix-ui/react-avatar";
3
2
  import type { AvatarProp } from "../../props/components/data-display.prop.js";
4
- export declare const Avatar: React.ForwardRefExoticComponent<Omit<AvatarPrimitive.AvatarProps & React.RefAttributes<HTMLSpanElement>, "ref"> & Pick<AvatarProp, "appearance" | "presence" | "presenceLabel" | "shape"> & React.RefAttributes<HTMLSpanElement>>;
5
- export declare const AvatarImage: React.ForwardRefExoticComponent<Omit<AvatarPrimitive.AvatarImageProps & React.RefAttributes<HTMLImageElement>, "ref"> & React.RefAttributes<HTMLImageElement>>;
6
- export declare const AvatarFallback: React.ForwardRefExoticComponent<Omit<AvatarPrimitive.AvatarFallbackProps & React.RefAttributes<HTMLSpanElement>, "ref"> & React.RefAttributes<HTMLSpanElement>>;
3
+ /**
4
+ * Trạng thái tải của ảnh trong avatar — chia sẻ giữa `AvatarImage` và
5
+ * `AvatarFallback` qua context, đúng như Radix làm.
6
+ *
7
+ * React Aria KHÔNG có avatar, nên đây là việc TỰ DỰNG. Nhưng phần cần dựng lại
8
+ * không phải cái vỏ `<span>` — mà là logic thật mà `@radix-ui/react-avatar` cầm:
9
+ * ảnh chỉ được vẽ khi đã tải XONG, fallback chỉ được vẽ khi ảnh CHƯA xong hoặc
10
+ * HỎNG, và `delayMs` giữ fallback im lặng đủ lâu để mạng nhanh không kịp nháy
11
+ * một khung initials trước khi ảnh về.
12
+ *
13
+ * Phép dò là một `new Image()` RỜI, không phải `onLoad`/`onError` trên chính
14
+ * thẻ được vẽ: thẻ chỉ tồn tại khi đã `loaded`, nên handler trên nó không bao
15
+ * giờ có cơ hội báo "đang tải" hay "hỏng". Đây cũng là lý do một `<img>` hỏng
16
+ * không bao giờ nằm trong DOM để trình duyệt vẽ biểu tượng ảnh vỡ lên trên
17
+ * fallback.
18
+ */
19
+ type ImageLoadingStatus = "idle" | "loading" | "loaded" | "error";
20
+ export declare const Avatar: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>, "ref"> & {
21
+ asChild?: boolean;
22
+ } & Pick<AvatarProp, "appearance" | "presence" | "presenceLabel" | "shape"> & React.RefAttributes<HTMLSpanElement>>;
23
+ export declare const AvatarImage: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.ImgHTMLAttributes<HTMLImageElement>, HTMLImageElement>, "ref"> & {
24
+ asChild?: boolean;
25
+ onLoadingStatusChange?: (status: ImageLoadingStatus) => void;
26
+ } & React.RefAttributes<HTMLImageElement>>;
27
+ export declare const AvatarFallback: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>, "ref"> & {
28
+ asChild?: boolean;
29
+ delayMs?: number;
30
+ } & React.RefAttributes<HTMLSpanElement>>;
31
+ export {};
@@ -1,9 +1,54 @@
1
1
  "use client";
2
2
  import { jsx, jsxs } from "react/jsx-runtime";
3
+ import { useEffectEvent, useLayoutEffect } from "@react-aria/utils";
3
4
  import * as React from "react";
4
- import * as AvatarPrimitive from "@radix-ui/react-avatar";
5
5
  import { useTranslation } from "../../i18n/use-translation.js";
6
+ import { Slot } from "../../lib/slot.js";
6
7
  import { cn } from "../../lib/utils.js";
8
+ const AvatarContext = React.createContext(null);
9
+ function useAvatarContext(part) {
10
+ const context = React.useContext(AvatarContext);
11
+ if (context === null) {
12
+ throw new Error(`\`${part}\` must be used within \`Avatar\``);
13
+ }
14
+ return context;
15
+ }
16
+ function getImageLoadingStatus(image) {
17
+ if (!image.complete) {
18
+ return "loading";
19
+ }
20
+ return image.naturalWidth > 0 ? "loaded" : "error";
21
+ }
22
+ function useImageLoadingStatus(src, {
23
+ loadingStatus,
24
+ setLoadingStatus,
25
+ referrerPolicy,
26
+ crossOrigin
27
+ }) {
28
+ useLayoutEffect(() => {
29
+ if (!src) {
30
+ setLoadingStatus("error");
31
+ return;
32
+ }
33
+ const image = new window.Image();
34
+ const handleLoad = (event) => setLoadingStatus(getImageLoadingStatus(event.currentTarget));
35
+ const handleError = () => setLoadingStatus("error");
36
+ image.addEventListener("load", handleLoad);
37
+ image.addEventListener("error", handleError);
38
+ if (referrerPolicy) {
39
+ image.referrerPolicy = referrerPolicy;
40
+ }
41
+ image.crossOrigin = crossOrigin ?? null;
42
+ image.src = src;
43
+ setLoadingStatus(getImageLoadingStatus(image));
44
+ return () => {
45
+ image.removeEventListener("load", handleLoad);
46
+ image.removeEventListener("error", handleError);
47
+ setLoadingStatus("idle");
48
+ };
49
+ }, [src, crossOrigin, referrerPolicy, setLoadingStatus]);
50
+ return loadingStatus;
51
+ }
7
52
  const Avatar = React.forwardRef(
8
53
  ({
9
54
  className,
@@ -11,12 +56,19 @@ const Avatar = React.forwardRef(
11
56
  appearance = "default",
12
57
  presence,
13
58
  presenceLabel,
59
+ asChild = false,
14
60
  children,
15
61
  ...props
16
62
  }, ref) => {
17
63
  const { t } = useTranslation();
18
- return /* @__PURE__ */ jsxs(
19
- AvatarPrimitive.Root,
64
+ const [imageLoadingStatus, setImageLoadingStatus] = React.useState("idle");
65
+ const context = React.useMemo(
66
+ () => ({ imageLoadingStatus, setImageLoadingStatus }),
67
+ [imageLoadingStatus]
68
+ );
69
+ const Comp = asChild ? Slot : "span";
70
+ return /* @__PURE__ */ jsx(AvatarContext.Provider, { value: context, children: /* @__PURE__ */ jsxs(
71
+ Comp,
20
72
  {
21
73
  ref,
22
74
  "data-slot": "avatar",
@@ -30,30 +82,64 @@ const Avatar = React.forwardRef(
30
82
  presence !== void 0 ? /* @__PURE__ */ jsx("span", { "data-slot": "avatar-presence", "data-presence": presence, children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: presenceLabel ?? t(`dataDisplay.avatar.presence.${presence}`) }) }) : null
31
83
  ]
32
84
  }
33
- );
85
+ ) });
34
86
  }
35
87
  );
36
- Avatar.displayName = AvatarPrimitive.Root.displayName;
37
- const AvatarImage = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
38
- AvatarPrimitive.Image,
39
- {
40
- ref,
41
- "data-slot": "avatar-image",
42
- className: cn("ui-avatar-image", className),
43
- ...props
44
- }
45
- ));
46
- AvatarImage.displayName = AvatarPrimitive.Image.displayName;
47
- const AvatarFallback = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
48
- AvatarPrimitive.Fallback,
49
- {
50
- ref,
51
- "data-slot": "avatar-fallback",
52
- className: cn("ui-avatar-fallback", className),
53
- ...props
54
- }
55
- ));
56
- AvatarFallback.displayName = AvatarPrimitive.Fallback.displayName;
88
+ Avatar.displayName = "Avatar";
89
+ const AvatarImage = React.forwardRef(({ className, src, onLoadingStatusChange, asChild = false, ...props }, ref) => {
90
+ const { imageLoadingStatus, setImageLoadingStatus } = useAvatarContext("AvatarImage");
91
+ const status = useImageLoadingStatus(src, {
92
+ referrerPolicy: props.referrerPolicy,
93
+ crossOrigin: props.crossOrigin,
94
+ loadingStatus: imageLoadingStatus,
95
+ setLoadingStatus: setImageLoadingStatus
96
+ });
97
+ const handleLoadingStatusChange = useEffectEvent((next) => {
98
+ onLoadingStatusChange?.(next);
99
+ });
100
+ const previousStatus = React.useRef(status);
101
+ useLayoutEffect(() => {
102
+ const previous = previousStatus.current;
103
+ previousStatus.current = status;
104
+ if (status !== previous) {
105
+ handleLoadingStatusChange(status);
106
+ }
107
+ }, [status]);
108
+ const Comp = asChild ? Slot : "img";
109
+ return status === "loaded" ? /* @__PURE__ */ jsx(
110
+ Comp,
111
+ {
112
+ ref,
113
+ "data-slot": "avatar-image",
114
+ className: cn("ui-avatar-image", className),
115
+ ...props,
116
+ src
117
+ }
118
+ ) : null;
119
+ });
120
+ AvatarImage.displayName = "AvatarImage";
121
+ const AvatarFallback = React.forwardRef(({ className, delayMs, asChild = false, ...props }, ref) => {
122
+ const { imageLoadingStatus } = useAvatarContext("AvatarFallback");
123
+ const [canRender, setCanRender] = React.useState(delayMs === void 0);
124
+ React.useEffect(() => {
125
+ if (delayMs === void 0) {
126
+ return;
127
+ }
128
+ const timerId = window.setTimeout(() => setCanRender(true), delayMs);
129
+ return () => window.clearTimeout(timerId);
130
+ }, [delayMs]);
131
+ const Comp = asChild ? Slot : "span";
132
+ return canRender && imageLoadingStatus !== "loaded" ? /* @__PURE__ */ jsx(
133
+ Comp,
134
+ {
135
+ ref,
136
+ "data-slot": "avatar-fallback",
137
+ className: cn("ui-avatar-fallback", className),
138
+ ...props
139
+ }
140
+ ) : null;
141
+ });
142
+ AvatarFallback.displayName = "AvatarFallback";
57
143
  export {
58
144
  Avatar,
59
145
  AvatarFallback,
@@ -1,9 +1,47 @@
1
1
  import * as React from "react";
2
- import * as HoverCardPrimitive from "@radix-ui/react-hover-card";
2
+ type Side = "top" | "right" | "bottom" | "left";
3
+ type Align = "start" | "center" | "end";
4
+ interface HoverCardProps {
5
+ /** Trạng thái mở, có kiểm soát. */
6
+ open?: boolean;
7
+ /** Trạng thái mở ban đầu khi không kiểm soát. */
8
+ defaultOpen?: boolean;
9
+ /** Gọi khi trạng thái mở/đóng đổi. */
10
+ onOpenChange?: (open: boolean) => void;
11
+ /** Thời gian rê chuột trước khi mở, tính bằng ms. */
12
+ openDelay?: number;
13
+ /** Thời gian sau khi con trỏ rời đi trước khi đóng, tính bằng ms. */
14
+ closeDelay?: number;
15
+ }
3
16
  /**
4
17
  * HoverCard root. Defaults to a SNAPPY 200ms open / 100ms close (Radix's raw 700/300 default felt
5
18
  * laggy); consumers can still pass `openDelay`/`closeDelay`.
6
19
  */
7
- export declare function HoverCard({ openDelay, closeDelay, ...props }: React.ComponentProps<typeof HoverCardPrimitive.Root>): React.JSX.Element;
8
- export declare const HoverCardTrigger: React.ForwardRefExoticComponent<HoverCardPrimitive.HoverCardTriggerProps & React.RefAttributes<HTMLAnchorElement>>;
9
- export declare const HoverCardContent: React.ForwardRefExoticComponent<Omit<HoverCardPrimitive.HoverCardContentProps & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
20
+ export declare function HoverCard({ open, defaultOpen, onOpenChange, openDelay, closeDelay, children, }: React.PropsWithChildren<HoverCardProps>): React.JSX.Element;
21
+ interface HoverCardTriggerProps extends React.ComponentPropsWithRef<"a"> {
22
+ /** Mượn thẻ của con thay dựng `<a>` riêng. */
23
+ asChild?: boolean;
24
+ }
25
+ export declare function HoverCardTrigger({ asChild, onPointerEnter, onPointerLeave, onFocus, onBlur, ref, ...props }: HoverCardTriggerProps): React.JSX.Element;
26
+ interface HoverCardContentProps extends React.ComponentPropsWithRef<"div"> {
27
+ /** Cạnh của trigger mà tấm thẻ bám vào. */
28
+ side?: Side;
29
+ /** Canh tấm thẻ theo cạnh của trigger. */
30
+ align?: Align;
31
+ /** Khoảng cách theo trục chính, tính bằng px. */
32
+ sideOffset?: number;
33
+ /** Khoảng cách theo trục phụ, tính bằng px. */
34
+ alignOffset?: number;
35
+ /** Lật tấm thẻ sang cạnh đối diện khi hết chỗ. */
36
+ avoidCollisions?: boolean;
37
+ /** Khoảng chừa với mép khung nhìn. RAC chỉ nhận một số; object lấy cạnh lớn nhất. */
38
+ collisionPadding?: number | Partial<Record<Side, number>>;
39
+ /** Không còn tác dụng trên nền RAC — giữ trong kiểu vì là API công khai. */
40
+ sticky?: "partial" | "always";
41
+ /** Không còn tác dụng trên nền RAC — giữ trong kiểu vì là API công khai. */
42
+ hideWhenDetached?: boolean;
43
+ /** Không còn tác dụng trên nền RAC — giữ trong kiểu vì là API công khai. */
44
+ forceMount?: true;
45
+ }
46
+ export declare function HoverCardContent({ className, style, children, ref, side, align, sideOffset, alignOffset, avoidCollisions, collisionPadding, sticky: _sticky, hideWhenDetached: _hideWhenDetached, forceMount: _forceMount, onPointerEnter, onPointerLeave, ...props }: HoverCardContentProps): React.JSX.Element;
47
+ export {};