@central-ui/react 0.1.1 → 0.2.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 (281) hide show
  1. package/LICENSE +49 -0
  2. package/README.md +1 -1
  3. package/dist/components/accordion/index.d.ts +7 -6
  4. package/dist/components/accordion/index.js +13 -10
  5. package/dist/components/autocomplete/index.d.ts +22 -33
  6. package/dist/components/autocomplete/index.js +90 -73
  7. package/dist/components/avatar/index.d.ts +1 -2
  8. package/dist/components/avatar/index.js +6 -6
  9. package/dist/components/badge/index.d.ts +0 -1
  10. package/dist/components/badge/index.js +2 -2
  11. package/dist/components/banner/index.d.ts +1 -1
  12. package/dist/components/banner/index.js +24 -26
  13. package/dist/components/barchart/index.d.ts +106 -0
  14. package/dist/components/barchart/index.js +122 -0
  15. package/dist/components/breadcrumb/index.d.ts +0 -1
  16. package/dist/components/breadcrumb/index.js +6 -7
  17. package/dist/components/button/index.d.ts +3 -4
  18. package/dist/components/button/index.js +11 -12
  19. package/dist/components/card/index.d.ts +0 -1
  20. package/dist/components/card/index.js +0 -1
  21. package/dist/components/checkbox/index.d.ts +13 -11
  22. package/dist/components/checkbox/index.js +59 -39
  23. package/dist/components/chip/index.d.ts +1 -1
  24. package/dist/components/chip/index.js +2 -3
  25. package/dist/components/combobox/index.d.ts +32 -44
  26. package/dist/components/combobox/index.js +112 -88
  27. package/dist/components/datepicker/index.d.ts +54 -55
  28. package/dist/components/datepicker/index.js +105 -100
  29. package/dist/components/dialog/index.d.ts +17 -30
  30. package/dist/components/dialog/index.js +25 -26
  31. package/dist/components/divider/index.d.ts +0 -1
  32. package/dist/components/divider/index.js +0 -1
  33. package/dist/components/donutchart/index.d.ts +100 -0
  34. package/dist/components/donutchart/index.js +178 -0
  35. package/dist/components/drawer/index.d.ts +15 -24
  36. package/dist/components/drawer/index.js +45 -47
  37. package/dist/components/empty/index.d.ts +1 -2
  38. package/dist/components/empty/index.js +2 -4
  39. package/dist/components/fileupload/index.d.ts +4 -9
  40. package/dist/components/fileupload/index.js +27 -39
  41. package/dist/components/form/index.d.ts +0 -1
  42. package/dist/components/form/index.js +0 -1
  43. package/dist/components/horizontalbarchart/index.d.ts +120 -0
  44. package/dist/components/horizontalbarchart/index.js +193 -0
  45. package/dist/components/input/index.d.ts +23 -23
  46. package/dist/components/input/index.js +86 -115
  47. package/dist/components/linechart/index.d.ts +114 -0
  48. package/dist/components/linechart/index.js +139 -0
  49. package/dist/components/menu/index.d.ts +14 -16
  50. package/dist/components/menu/index.js +56 -53
  51. package/dist/components/metric/index.d.ts +0 -1
  52. package/dist/components/metric/index.js +0 -1
  53. package/dist/components/numberinput/index.d.ts +16 -23
  54. package/dist/components/numberinput/index.js +55 -68
  55. package/dist/components/otpinput/index.d.ts +14 -9
  56. package/dist/components/otpinput/index.js +32 -25
  57. package/dist/components/page/index.d.ts +0 -1
  58. package/dist/components/page/index.js +2 -4
  59. package/dist/components/passwordinput/index.d.ts +16 -13
  60. package/dist/components/passwordinput/index.js +47 -56
  61. package/dist/components/popover/index.d.ts +21 -19
  62. package/dist/components/popover/index.js +40 -21
  63. package/dist/components/radio/index.d.ts +13 -9
  64. package/dist/components/radio/index.js +80 -71
  65. package/dist/components/ratinginput/index.d.ts +15 -10
  66. package/dist/components/ratinginput/index.js +38 -18
  67. package/dist/components/select/index.d.ts +29 -32
  68. package/dist/components/select/index.js +79 -50
  69. package/dist/components/skeleton/index.d.ts +0 -1
  70. package/dist/components/skeleton/index.js +0 -1
  71. package/dist/components/slider/index.d.ts +14 -9
  72. package/dist/components/slider/index.js +75 -74
  73. package/dist/components/spinner/index.d.ts +2 -3
  74. package/dist/components/spinner/index.js +2 -3
  75. package/dist/components/splitter/index.d.ts +1 -2
  76. package/dist/components/splitter/index.js +6 -7
  77. package/dist/components/stepper/index.d.ts +8 -20
  78. package/dist/components/stepper/index.js +15 -16
  79. package/dist/components/switch/index.d.ts +12 -10
  80. package/dist/components/switch/index.js +52 -36
  81. package/dist/components/table/index.d.ts +3 -3
  82. package/dist/components/table/index.js +17 -16
  83. package/dist/components/tabs/index.d.ts +3 -4
  84. package/dist/components/tabs/index.js +6 -7
  85. package/dist/components/textarea/index.d.ts +16 -13
  86. package/dist/components/textarea/index.js +46 -55
  87. package/dist/components/textlink/index.d.ts +3 -1
  88. package/dist/components/textlink/index.js +4 -1
  89. package/dist/components/toast/index.d.ts +8 -14
  90. package/dist/components/toast/index.js +54 -54
  91. package/dist/components/toggle/index.d.ts +5 -6
  92. package/dist/components/toggle/index.js +19 -26
  93. package/dist/components/tooltip/index.d.ts +11 -13
  94. package/dist/components/tooltip/index.js +14 -11
  95. package/dist/components/tour/index.d.ts +154 -0
  96. package/dist/components/tour/index.js +280 -0
  97. package/dist/index.d.ts +5 -2
  98. package/dist/index.js +5 -1
  99. package/dist/types/Icon.d.ts +10 -0
  100. package/dist/types/Icon.js +1 -0
  101. package/dist/types/Style.d.ts +0 -1
  102. package/dist/types/Style.js +0 -1
  103. package/dist/types/Tone.d.ts +0 -1
  104. package/dist/types/Tone.js +0 -1
  105. package/dist/types/Validation.d.ts +12 -0
  106. package/dist/types/Validation.js +1 -0
  107. package/dist/utils/ArkStateToDataAttributes.d.ts +0 -1
  108. package/dist/utils/ArkStateToDataAttributes.js +3 -2
  109. package/dist/utils/Tone.d.ts +0 -1
  110. package/dist/utils/Tone.js +1 -2
  111. package/dist/utils/Validation.d.ts +14 -0
  112. package/dist/utils/Validation.js +23 -0
  113. package/dist/utils/asChild.d.ts +41 -0
  114. package/dist/utils/asChild.js +15 -0
  115. package/dist/utils/icons.d.ts +24 -0
  116. package/dist/utils/icons.js +160 -0
  117. package/dist/utils/useForwardClickToInput.d.ts +0 -1
  118. package/dist/utils/useForwardClickToInput.js +4 -3
  119. package/dist/utils/virtualization/useVirtualizedAutocomplete.d.ts +0 -1
  120. package/dist/utils/virtualization/useVirtualizedAutocomplete.js +0 -1
  121. package/dist/utils/virtualization/useVirtualizedCombobox.d.ts +0 -1
  122. package/dist/utils/virtualization/useVirtualizedCombobox.js +0 -1
  123. package/dist/utils/virtualization/useVirtualizedTable.d.ts +0 -1
  124. package/dist/utils/virtualization/useVirtualizedTable.js +0 -1
  125. package/package.json +12 -11
  126. package/src/presets/shopify-polaris/shopify-polaris-autocomplete.css +15 -6
  127. package/src/presets/shopify-polaris/shopify-polaris-badge.css +1 -1
  128. package/src/presets/shopify-polaris/shopify-polaris-barchart.css +64 -0
  129. package/src/presets/shopify-polaris/shopify-polaris-checkbox.css +2 -2
  130. package/src/presets/shopify-polaris/shopify-polaris-chip.css +3 -3
  131. package/src/presets/shopify-polaris/shopify-polaris-combobox.css +19 -10
  132. package/src/presets/shopify-polaris/shopify-polaris-datepicker.css +20 -11
  133. package/src/presets/shopify-polaris/shopify-polaris-dialog.css +16 -0
  134. package/src/presets/shopify-polaris/shopify-polaris-donutchart.css +172 -0
  135. package/src/presets/shopify-polaris/shopify-polaris-drawer.css +16 -0
  136. package/src/presets/shopify-polaris/shopify-polaris-fileupload.css +1 -1
  137. package/src/presets/shopify-polaris/shopify-polaris-horizontalbarchart.css +60 -0
  138. package/src/presets/shopify-polaris/shopify-polaris-input.css +14 -5
  139. package/src/presets/shopify-polaris/shopify-polaris-linechart.css +68 -0
  140. package/src/presets/shopify-polaris/shopify-polaris-menu.css +47 -6
  141. package/src/presets/shopify-polaris/shopify-polaris-numberinput.css +16 -7
  142. package/src/presets/shopify-polaris/shopify-polaris-otpinput.css +3 -3
  143. package/src/presets/shopify-polaris/shopify-polaris-passwordinput.css +14 -5
  144. package/src/presets/shopify-polaris/shopify-polaris-popover.css +29 -0
  145. package/src/presets/shopify-polaris/shopify-polaris-radio.css +2 -2
  146. package/src/presets/shopify-polaris/shopify-polaris-ratinginput.css +2 -2
  147. package/src/presets/shopify-polaris/shopify-polaris-select.css +15 -6
  148. package/src/presets/shopify-polaris/shopify-polaris-slider.css +2 -2
  149. package/src/presets/shopify-polaris/shopify-polaris-stepper.css +16 -0
  150. package/src/presets/shopify-polaris/shopify-polaris-switch.css +2 -2
  151. package/src/presets/shopify-polaris/shopify-polaris-textarea.css +13 -4
  152. package/src/presets/shopify-polaris/shopify-polaris-toast.css +43 -0
  153. package/src/presets/shopify-polaris/shopify-polaris-tooltip.css +16 -0
  154. package/src/presets/shopify-polaris/shopify-polaris.css +5 -0
  155. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-autocomplete.css +2 -2
  156. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-barchart.css +64 -0
  157. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-checkbox.css +2 -2
  158. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-combobox.css +2 -2
  159. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-datepicker.css +2 -2
  160. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-dialog.css +9 -0
  161. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-donutchart.css +172 -0
  162. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-drawer.css +9 -0
  163. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-fileupload.css +1 -1
  164. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-horizontalbarchart.css +60 -0
  165. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-input.css +2 -2
  166. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-linechart.css +68 -0
  167. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-menu.css +9 -0
  168. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-numberinput.css +2 -2
  169. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-otpinput.css +2 -2
  170. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-passwordinput.css +2 -2
  171. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-popover.css +22 -0
  172. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-radio.css +2 -2
  173. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-ratinginput.css +2 -2
  174. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-slider.css +2 -2
  175. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-stepper.css +9 -0
  176. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-switch.css +2 -2
  177. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-textarea.css +2 -2
  178. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-tooltip.css +9 -0
  179. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy.css +4 -0
  180. package/dist/components/accordion/index.d.ts.map +0 -1
  181. package/dist/components/accordion/index.js.map +0 -1
  182. package/dist/components/autocomplete/index.d.ts.map +0 -1
  183. package/dist/components/autocomplete/index.js.map +0 -1
  184. package/dist/components/avatar/index.d.ts.map +0 -1
  185. package/dist/components/avatar/index.js.map +0 -1
  186. package/dist/components/badge/index.d.ts.map +0 -1
  187. package/dist/components/badge/index.js.map +0 -1
  188. package/dist/components/banner/index.d.ts.map +0 -1
  189. package/dist/components/banner/index.js.map +0 -1
  190. package/dist/components/breadcrumb/index.d.ts.map +0 -1
  191. package/dist/components/breadcrumb/index.js.map +0 -1
  192. package/dist/components/button/index.d.ts.map +0 -1
  193. package/dist/components/button/index.js.map +0 -1
  194. package/dist/components/card/index.d.ts.map +0 -1
  195. package/dist/components/card/index.js.map +0 -1
  196. package/dist/components/checkbox/index.d.ts.map +0 -1
  197. package/dist/components/checkbox/index.js.map +0 -1
  198. package/dist/components/chip/index.d.ts.map +0 -1
  199. package/dist/components/chip/index.js.map +0 -1
  200. package/dist/components/combobox/index.d.ts.map +0 -1
  201. package/dist/components/combobox/index.js.map +0 -1
  202. package/dist/components/datepicker/index.d.ts.map +0 -1
  203. package/dist/components/datepicker/index.js.map +0 -1
  204. package/dist/components/dialog/index.d.ts.map +0 -1
  205. package/dist/components/dialog/index.js.map +0 -1
  206. package/dist/components/divider/index.d.ts.map +0 -1
  207. package/dist/components/divider/index.js.map +0 -1
  208. package/dist/components/drawer/index.d.ts.map +0 -1
  209. package/dist/components/drawer/index.js.map +0 -1
  210. package/dist/components/empty/index.d.ts.map +0 -1
  211. package/dist/components/empty/index.js.map +0 -1
  212. package/dist/components/fileupload/index.d.ts.map +0 -1
  213. package/dist/components/fileupload/index.js.map +0 -1
  214. package/dist/components/form/index.d.ts.map +0 -1
  215. package/dist/components/form/index.js.map +0 -1
  216. package/dist/components/input/index.d.ts.map +0 -1
  217. package/dist/components/input/index.js.map +0 -1
  218. package/dist/components/menu/index.d.ts.map +0 -1
  219. package/dist/components/menu/index.js.map +0 -1
  220. package/dist/components/metric/index.d.ts.map +0 -1
  221. package/dist/components/metric/index.js.map +0 -1
  222. package/dist/components/numberinput/index.d.ts.map +0 -1
  223. package/dist/components/numberinput/index.js.map +0 -1
  224. package/dist/components/otpinput/index.d.ts.map +0 -1
  225. package/dist/components/otpinput/index.js.map +0 -1
  226. package/dist/components/page/index.d.ts.map +0 -1
  227. package/dist/components/page/index.js.map +0 -1
  228. package/dist/components/passwordinput/index.d.ts.map +0 -1
  229. package/dist/components/passwordinput/index.js.map +0 -1
  230. package/dist/components/popover/index.d.ts.map +0 -1
  231. package/dist/components/popover/index.js.map +0 -1
  232. package/dist/components/radio/index.d.ts.map +0 -1
  233. package/dist/components/radio/index.js.map +0 -1
  234. package/dist/components/ratinginput/index.d.ts.map +0 -1
  235. package/dist/components/ratinginput/index.js.map +0 -1
  236. package/dist/components/select/index.d.ts.map +0 -1
  237. package/dist/components/select/index.js.map +0 -1
  238. package/dist/components/skeleton/index.d.ts.map +0 -1
  239. package/dist/components/skeleton/index.js.map +0 -1
  240. package/dist/components/slider/index.d.ts.map +0 -1
  241. package/dist/components/slider/index.js.map +0 -1
  242. package/dist/components/spinner/index.d.ts.map +0 -1
  243. package/dist/components/spinner/index.js.map +0 -1
  244. package/dist/components/splitter/index.d.ts.map +0 -1
  245. package/dist/components/splitter/index.js.map +0 -1
  246. package/dist/components/stepper/index.d.ts.map +0 -1
  247. package/dist/components/stepper/index.js.map +0 -1
  248. package/dist/components/switch/index.d.ts.map +0 -1
  249. package/dist/components/switch/index.js.map +0 -1
  250. package/dist/components/table/index.d.ts.map +0 -1
  251. package/dist/components/table/index.js.map +0 -1
  252. package/dist/components/tabs/index.d.ts.map +0 -1
  253. package/dist/components/tabs/index.js.map +0 -1
  254. package/dist/components/textarea/index.d.ts.map +0 -1
  255. package/dist/components/textarea/index.js.map +0 -1
  256. package/dist/components/textlink/index.d.ts.map +0 -1
  257. package/dist/components/textlink/index.js.map +0 -1
  258. package/dist/components/toast/index.d.ts.map +0 -1
  259. package/dist/components/toast/index.js.map +0 -1
  260. package/dist/components/toggle/index.d.ts.map +0 -1
  261. package/dist/components/toggle/index.js.map +0 -1
  262. package/dist/components/tooltip/index.d.ts.map +0 -1
  263. package/dist/components/tooltip/index.js.map +0 -1
  264. package/dist/index.d.ts.map +0 -1
  265. package/dist/index.js.map +0 -1
  266. package/dist/types/Style.d.ts.map +0 -1
  267. package/dist/types/Style.js.map +0 -1
  268. package/dist/types/Tone.d.ts.map +0 -1
  269. package/dist/types/Tone.js.map +0 -1
  270. package/dist/utils/ArkStateToDataAttributes.d.ts.map +0 -1
  271. package/dist/utils/ArkStateToDataAttributes.js.map +0 -1
  272. package/dist/utils/Tone.d.ts.map +0 -1
  273. package/dist/utils/Tone.js.map +0 -1
  274. package/dist/utils/useForwardClickToInput.d.ts.map +0 -1
  275. package/dist/utils/useForwardClickToInput.js.map +0 -1
  276. package/dist/utils/virtualization/useVirtualizedAutocomplete.d.ts.map +0 -1
  277. package/dist/utils/virtualization/useVirtualizedAutocomplete.js.map +0 -1
  278. package/dist/utils/virtualization/useVirtualizedCombobox.d.ts.map +0 -1
  279. package/dist/utils/virtualization/useVirtualizedCombobox.js.map +0 -1
  280. package/dist/utils/virtualization/useVirtualizedTable.d.ts.map +0 -1
  281. package/dist/utils/virtualization/useVirtualizedTable.js.map +0 -1
@@ -1,8 +1,9 @@
1
1
  import type { StyleProps } from '../../types/Style.ts';
2
+ import type { AsChildProps } from '../../utils/asChild.ts';
2
3
  import { Tooltip as BaseTooltip } from '@base-ui/react/tooltip';
3
- import type { ComponentPropsWithRef, ReactElement } from 'react';
4
+ import type { ComponentPropsWithRef } from 'react';
4
5
  /**
5
- * Wrap the target element with OpenHandler and keep Popup in the same Root. Popup already includes its portal and positioner. PopupText supplies the help text; Arrow is optional.
6
+ * OpenButton renders its own trigger button; pass asChild to make your own target element the trigger instead. Keep Popup in the same Root. Popup already includes its portal and positioner. PopupText supplies the help text; Arrow is optional.
6
7
  *
7
8
  * @example Complete composition
8
9
  * import { Button, Tooltip } from '@central-ui/react'
@@ -10,9 +11,9 @@ import type { ComponentPropsWithRef, ReactElement } from 'react';
10
11
  * function Example() {
11
12
  * return (
12
13
  * <Tooltip.Root>
13
- * <Tooltip.OpenHandler>
14
+ * <Tooltip.OpenButton asChild>
14
15
  * <Button.default variant="secondary">Delivery information</Button.default>
15
- * </Tooltip.OpenHandler>
16
+ * </Tooltip.OpenButton>
16
17
  * <Tooltip.Popup>
17
18
  * <Tooltip.PopupText>Usually arrives within three days.</Tooltip.PopupText>
18
19
  * <Tooltip.Arrow />
@@ -22,23 +23,20 @@ import type { ComponentPropsWithRef, ReactElement } from 'react';
22
23
  * }
23
24
  *
24
25
  * @example Place help below its target
25
- * // Keep the same OpenHandler and Root.
26
+ * // Keep the same OpenButton and Root.
26
27
  * ;<Tooltip.Popup side="bottom">
27
28
  * <Tooltip.PopupText>Delivery details</Tooltip.PopupText>
28
29
  * </Tooltip.Popup>
29
30
  */
30
- export declare const Root: <Payload>(props: BaseTooltip.Root.Props<Payload>) => React.JSX.Element;
31
- /** Behavior only: give your child control this action. Style the child itself; this wrapper has no preset appearance or disableStyle prop. */
32
- export declare const OpenHandler: import("react").ForwardRefExoticComponent<Omit<Omit<BaseTooltip.Trigger.Props<unknown>, "children" | "className" | "render"> & {
31
+ export declare function Root<Payload = unknown>(props: BaseTooltip.Root.Props<Payload>): import("react").JSX.Element;
32
+ /** Opens the tooltip on hover or focus. Pass asChild to give this behavior to your own element, like your app's Button. */
33
+ export declare const OpenButton: import("react").ForwardRefExoticComponent<Omit<Omit<BaseTooltip.Trigger.Props<unknown>, "className" | "render"> & {
33
34
  className?: string;
34
- /** Supply your own accessible control. It receives the behavior; its own className owns the appearance. */
35
- children: ReactElement;
36
- }, "ref"> & import("react").RefAttributes<HTMLButtonElement>>;
35
+ } & AsChildProps & StyleProps, "ref"> & import("react").RefAttributes<HTMLButtonElement>>;
37
36
  export type PopupProps = Omit<ComponentPropsWithRef<typeof BaseTooltip.Popup>, 'className'> & {
38
37
  className?: string;
39
38
  } & Pick<BaseTooltip.Portal.Props, 'container' | 'keepMounted'> & Pick<BaseTooltip.Positioner.Props, 'anchor' | 'positionMethod' | 'side' | 'sideOffset' | 'align' | 'alignOffset' | 'collisionBoundary' | 'collisionPadding' | 'sticky' | 'arrowPadding' | 'disableAnchorTracking' | 'collisionAvoidance'> & StyleProps;
40
39
  /** Already includes the portal and positioner. Keep it in the matching Root and let the native open state control visibility. */
41
- export declare function Popup({ disableStyle, container, keepMounted, anchor, positionMethod, side, sideOffset, align, alignOffset, collisionBoundary, collisionPadding, sticky, arrowPadding, disableAnchorTracking, collisionAvoidance, className, style, ...props }: PopupProps & StyleProps): import("react").JSX.Element;
40
+ export declare function Popup({ disableStyle, container, keepMounted, anchor, positionMethod, side, sideOffset, align, alignOffset, collisionBoundary, collisionPadding, sticky, arrowPadding, disableAnchorTracking, collisionAvoidance, className, style, ...props }: PopupProps): import("react").JSX.Element;
42
41
  export declare const PopupText: import("react").ForwardRefExoticComponent<Omit<import("react").ClassAttributes<HTMLSpanElement> & import("react").HTMLAttributes<HTMLSpanElement> & StyleProps, "ref"> & import("react").RefAttributes<HTMLSpanElement>>;
43
42
  export declare const Arrow: import("react").ForwardRefExoticComponent<Omit<Omit<import("react").SVGProps<SVGSVGElement>, "children" | "dangerouslySetInnerHTML"> & StyleProps, "ref"> & import("react").RefAttributes<SVGSVGElement>>;
44
- //# sourceMappingURL=index.d.ts.map
@@ -1,8 +1,9 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { asChildRendering } from "../../utils/asChild.js";
2
3
  import { Tooltip as BaseTooltip } from '@base-ui/react/tooltip';
3
4
  import { forwardRef } from 'react';
4
5
  /**
5
- * Wrap the target element with OpenHandler and keep Popup in the same Root. Popup already includes its portal and positioner. PopupText supplies the help text; Arrow is optional.
6
+ * OpenButton renders its own trigger button; pass asChild to make your own target element the trigger instead. Keep Popup in the same Root. Popup already includes its portal and positioner. PopupText supplies the help text; Arrow is optional.
6
7
  *
7
8
  * @example Complete composition
8
9
  * import { Button, Tooltip } from '@central-ui/react'
@@ -10,9 +11,9 @@ import { forwardRef } from 'react';
10
11
  * function Example() {
11
12
  * return (
12
13
  * <Tooltip.Root>
13
- * <Tooltip.OpenHandler>
14
+ * <Tooltip.OpenButton asChild>
14
15
  * <Button.default variant="secondary">Delivery information</Button.default>
15
- * </Tooltip.OpenHandler>
16
+ * </Tooltip.OpenButton>
16
17
  * <Tooltip.Popup>
17
18
  * <Tooltip.PopupText>Usually arrives within three days.</Tooltip.PopupText>
18
19
  * <Tooltip.Arrow />
@@ -22,15 +23,18 @@ import { forwardRef } from 'react';
22
23
  * }
23
24
  *
24
25
  * @example Place help below its target
25
- * // Keep the same OpenHandler and Root.
26
+ * // Keep the same OpenButton and Root.
26
27
  * ;<Tooltip.Popup side="bottom">
27
28
  * <Tooltip.PopupText>Delivery details</Tooltip.PopupText>
28
29
  * </Tooltip.Popup>
29
30
  */
30
- export const Root = BaseTooltip.Root;
31
- /** Behavior only: give your child control this action. Style the child itself; this wrapper has no preset appearance or disableStyle prop. */
32
- export const OpenHandler = forwardRef(function OpenHandler({ children, ...props }, ref) {
33
- return _jsx(BaseTooltip.Trigger, { ...props, ref: ref, render: children });
31
+ export function Root(props) {
32
+ return _jsx(BaseTooltip.Root, { ...props });
33
+ }
34
+ /** Opens the tooltip on hover or focus. Pass asChild to give this behavior to your own element, like your app's Button. */
35
+ export const OpenButton = /* @__PURE__ */ forwardRef(function OpenButton({ asChild, disableStyle, children, ...props }, ref) {
36
+ const rendering = asChildRendering({ asChild, children, component: 'tooltip-openbutton', disableStyle });
37
+ return _jsx(BaseTooltip.Trigger, { ...props, ref: ref, ...rendering });
34
38
  });
35
39
  /** Already includes the portal and positioner. Keep it in the matching Root and let the native open state control visibility. */
36
40
  export function Popup({ disableStyle, container, keepMounted, anchor, positionMethod, side = 'top', sideOffset = 8, align = 'start', alignOffset, collisionBoundary, collisionPadding, sticky, arrowPadding, disableAnchorTracking, collisionAvoidance, className, style, ...props }) {
@@ -42,10 +46,9 @@ export function Popup({ disableStyle, container, keepMounted, anchor, positionMe
42
46
  ? (state) => ({ ...baseStyle, ...style(state) })
43
47
  : { ...baseStyle, ...style } }) }) }));
44
48
  }
45
- export const PopupText = forwardRef(function PopupText({ disableStyle, className, ...props }, ref) {
49
+ export const PopupText = /* @__PURE__ */ forwardRef(function PopupText({ disableStyle, className, ...props }, ref) {
46
50
  return (_jsx("span", { ...props, ref: ref, "data-component": "tooltip-popuptext", "data-style-disabled": disableStyle ? '' : undefined, className: className }));
47
51
  });
48
- export const Arrow = forwardRef(function Arrow({ disableStyle, className, style, ...props }, ref) {
52
+ export const Arrow = /* @__PURE__ */ forwardRef(function Arrow({ disableStyle, className, style, ...props }, ref) {
49
53
  return (_jsxs(BaseTooltip.Arrow, { style: style, render: _jsx("svg", { ...props, ref: ref, "aria-hidden": true, width: "20", height: "10", viewBox: "0 0 20 10" }), "data-component": "tooltip-arrow", "data-style-disabled": disableStyle ? '' : undefined, className: className, children: [_jsx("path", { d: "M9.66437 2.60207L4.80758 6.97318C4.07308 7.63423 3.11989 8 2.13172 8H0V10H20V8H18.5349C17.5468 8 16.5936 7.63423 15.8591 6.97318L11.0023 2.60207C10.622 2.2598 10.0447 2.25979 9.66437 2.60207Z", "data-component": "tooltip-arrow-1" }), _jsx("path", { d: "M8.99542 1.85876C9.75604 1.17425 10.9106 1.17422 11.6713 1.85878L16.5281 6.22989C17.0789 6.72568 17.7938 7.00001 18.5349 7.00001L15.89 7L11.0023 2.60207C10.622 2.2598 10.0447 2.2598 9.66436 2.60207L4.77734 7L2.13171 7.00001C2.87284 7.00001 3.58774 6.72568 4.13861 6.22989L8.99542 1.85876Z", "data-component": "tooltip-arrow-2" }), _jsx("path", { d: "M10.3333 3.34539L5.47654 7.71648C4.55842 8.54279 3.36693 9 2.13172 9H0V8H2.13172C3.11989 8 4.07308 7.63423 4.80758 6.97318L9.66437 2.60207C10.0447 2.25979 10.622 2.2598 11.0023 2.60207L15.8591 6.97318C16.5936 7.63423 17.5468 8 18.5349 8H20V9H18.5349C17.2998 9 16.1083 8.54278 15.1901 7.71648L10.3333 3.34539Z", "data-component": "tooltip-arrow-3" })] }));
50
54
  });
51
- //# sourceMappingURL=index.js.map
@@ -0,0 +1,154 @@
1
+ import type { StyleProps } from '../../types/Style.ts';
2
+ import type { AsChildProps } from '../../utils/asChild.ts';
3
+ import type { Step as JoyrideStep } from 'react-joyride';
4
+ import type { ComponentProps, ReactElement, ReactNode, SVGProps } from 'react';
5
+ /**
6
+ * A guided tour that highlights elements one by one, each with a popup next to it.
7
+ * Root holds the steps (which element, in which order); Popup holds what every popup shows.
8
+ * Write the popup's frame and buttons once, and put what differs per step in a Content
9
+ * with the step's `value`, like Tabs.Content. Back/Next/Done/Skip/Close are styled buttons that show only when they can act.
10
+ *
11
+ * @example Complete composition, opened from a button
12
+ * import { Button, Tour } from '@central-ui/react'
13
+ *
14
+ * function Example() {
15
+ * const [open, setOpen] = useState(false)
16
+ *
17
+ * return (
18
+ * <>
19
+ * <Button.default onClick={() => setOpen(true)}>Take the tour</Button.default>
20
+ * <div id="search">…</div>
21
+ * <div id="filters">…</div>
22
+ *
23
+ * <Tour.Root
24
+ * steps={[
25
+ * { value: 'search', target: '#search' },
26
+ * { value: 'filters', target: '#filters' },
27
+ * ]}
28
+ * open={open}
29
+ * onOpenChange={setOpen}
30
+ * >
31
+ * <Tour.Popup>
32
+ * <Tour.Content value="search">
33
+ * <Tour.Title>Search</Tour.Title>
34
+ * <Tour.Description>Find any order fast.</Tour.Description>
35
+ * </Tour.Content>
36
+ * <Tour.Content value="filters">
37
+ * <Tour.Title>Filters</Tour.Title>
38
+ * <Tour.Description>Narrow the results.</Tour.Description>
39
+ * </Tour.Content>
40
+ * <Tour.Progress />
41
+ * <Tour.BackButton>Back</Tour.BackButton>
42
+ * <Tour.NextButton>Next</Tour.NextButton>
43
+ * <Tour.DoneButton>Done</Tour.DoneButton>
44
+ * </Tour.Popup>
45
+ * </Tour.Root>
46
+ * </>
47
+ * )
48
+ * }
49
+ *
50
+ * @example Start on its own as soon as the page mounts, with no trigger button
51
+ * // Uncontrolled: defaultOpen starts the tour when Root mounts, and Root closes it itself.
52
+ * // Mount Root conditionally (e.g. only for users who haven't seen it) to show it once.
53
+ * ;<Tour.Root steps={steps} defaultOpen onOpenChange={(open) => { if (!open) markTourSeen() }}>
54
+ * <Tour.Popup>…</Tour.Popup>
55
+ * </Tour.Root>
56
+ *
57
+ * @example Content only one step has, like a video
58
+ * // Anything inside a Content shows only on its step; anything outside shows on every step.
59
+ * ;<Tour.Content value="filters">
60
+ * <Tour.Title>Filters</Tour.Title>
61
+ * <video src="/filters.mp4" autoPlay muted />
62
+ * </Tour.Content>
63
+ *
64
+ * @example Let users click the highlighted element during a step
65
+ * ;<Tour.Root steps={[{ value: 'upload', target: '#upload', interactive: true }]}>
66
+ */
67
+ export declare function Root(props: {
68
+ /**
69
+ * The tour's stops, in order. Each `value` pairs with the Content of the same value,
70
+ * and `target` is the element to highlight, as a CSS selector or an element.
71
+ * Set `interactive` to let users click the highlighted element during that step,
72
+ * e.g. a "try it now" step; otherwise clicks on it are blocked so a click can't navigate away mid-tour.
73
+ */
74
+ steps: readonly ({
75
+ value: string;
76
+ interactive?: boolean;
77
+ } & Pick<JoyrideStep, 'target'>)[];
78
+ /** Whether the tour is showing. Use with onOpenChange to start it from your own button. */
79
+ open?: boolean;
80
+ /**
81
+ * Whether the tour starts as soon as Root mounts, when `open` isn't controlled.
82
+ * Use it for tours that start on their own, like a first visit.
83
+ * @default false
84
+ */
85
+ defaultOpen?: boolean;
86
+ /** Called when the tour starts or ends, including when it ends by Close, Skip, Done, or the Escape key. */
87
+ onOpenChange?: (open: boolean) => void;
88
+ /** The `value` of the step showing. Use with onStepChange to control the step yourself. */
89
+ step?: string;
90
+ /**
91
+ * The `value` of the step the tour starts on, when `step` isn't controlled.
92
+ * @default the first step's value
93
+ */
94
+ defaultStep?: string;
95
+ /** Called with the next step's `value` whenever the tour moves to another step. */
96
+ onStepChange?: (step: string) => void;
97
+ /** The Popup. */
98
+ children: ReactNode;
99
+ }): import("react").JSX.Element;
100
+ type PopupPlacement = {
101
+ side: 'top' | 'bottom' | 'left' | 'right';
102
+ align: 'start' | 'center' | 'end';
103
+ };
104
+ /**
105
+ * The box next to the highlighted element, shown on every step. Write the shared frame and buttons here once.
106
+ * `side` and `align` are where it prefers to sit; Joyride flips it when that side has no room, so it never leaves the screen.
107
+ */
108
+ export declare function Popup({ disableStyle, className, side, align, ...props }: ComponentProps<'div'> & StyleProps & {
109
+ /**
110
+ * The side of the highlighted element the popup prefers.
111
+ * @default 'bottom'
112
+ */
113
+ side?: PopupPlacement['side'];
114
+ /**
115
+ * How the popup lines up along that side.
116
+ * @default 'center'
117
+ */
118
+ align?: PopupPlacement['align'];
119
+ }): import("react").JSX.Element;
120
+ /** Shows its children only while its step is showing, like Tabs.Content. Put anything specific to one step here. */
121
+ export declare function Content({ disableStyle, className, value, ...props }: ComponentProps<'div'> & StyleProps & {
122
+ /** The `value` of the step this content belongs to, matching one of Root's steps. */
123
+ value: string;
124
+ }): import("react").JSX.Element | null;
125
+ export declare function Title({ disableStyle, className, ...props }: ComponentProps<'h2'> & StyleProps): import("react").JSX.Element;
126
+ export declare function Description({ disableStyle, className, ...props }: ComponentProps<'p'> & StyleProps): import("react").JSX.Element;
127
+ /** Shows the position in the tour, like "2 of 5". Pass a function as children to word it differently, e.g. for another language. */
128
+ export declare function Progress({ disableStyle, className, children, ...props }: Omit<ComponentProps<'p'>, 'children'> & StyleProps & {
129
+ children?: (progress: {
130
+ step: number;
131
+ total: number;
132
+ }) => ReactNode;
133
+ }): import("react").JSX.Element;
134
+ type ButtonProps = ComponentProps<'button'> & AsChildProps & StyleProps;
135
+ /** Goes back one step, styled like a secondary Button. Not rendered on the first step, where there's nothing to go back to. Pass asChild to give this behavior to your own button instead. */
136
+ export declare function BackButton(props: ButtonProps): import("react").JSX.Element | null;
137
+ /** Goes to the next step, styled like a primary Button. Not rendered on the last step; DoneButton takes its place there. Pass asChild to give this behavior to your own button instead. */
138
+ export declare function NextButton(props: ButtonProps): import("react").JSX.Element | null;
139
+ /** Finishes the tour, styled like a primary Button. Rendered only on the last step, in NextButton's place. Pass asChild to give this behavior to your own button instead. */
140
+ export declare function DoneButton(props: ButtonProps): import("react").JSX.Element | null;
141
+ /** Ends the tour early, styled like a tertiary Button. Not rendered on the last step, where Done already ends it. Pass asChild to give this behavior to your own button instead. */
142
+ export declare function SkipButton(props: ButtonProps): import("react").JSX.Element | null;
143
+ /**
144
+ * Ends the tour from any step: the round ✕ in the popup's top-right corner, like Dialog's.
145
+ * Icon-only: put just a CloseButtonIcon inside, never text like "Close". It is already named for screen readers by Joyride.
146
+ * Pass asChild to give this behavior to your own button instead.
147
+ */
148
+ export declare function CloseButton(props: ButtonProps): import("react").JSX.Element;
149
+ /** A default ✕ icon is supplied. Omit children for the usual case; pass an icon only to replace that visual. */
150
+ export declare function CloseButtonIcon({ disableStyle, children, className, ...props }: SVGProps<SVGSVGElement> & StyleProps & {
151
+ /** Omit for the supplied default icon; pass a child only to replace it. */
152
+ children?: ReactElement<SVGProps<SVGSVGElement>>;
153
+ }): import("react").FunctionComponentElement<any>;
154
+ export {};
@@ -0,0 +1,280 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { asChildStyleAttributes } from "../../utils/asChild.js";
3
+ import { Joyride, ACTIONS, EVENTS, STATUS } from 'react-joyride';
4
+ import { cloneElement, createContext, useContext, useLayoutEffect, useState, } from 'react';
5
+ import { X } from "../../utils/icons.js";
6
+ import { twMerge } from 'tailwind-merge';
7
+ /**
8
+ * A guided tour that highlights elements one by one, each with a popup next to it.
9
+ * Root holds the steps (which element, in which order); Popup holds what every popup shows.
10
+ * Write the popup's frame and buttons once, and put what differs per step in a Content
11
+ * with the step's `value`, like Tabs.Content. Back/Next/Done/Skip/Close are styled buttons that show only when they can act.
12
+ *
13
+ * @example Complete composition, opened from a button
14
+ * import { Button, Tour } from '@central-ui/react'
15
+ *
16
+ * function Example() {
17
+ * const [open, setOpen] = useState(false)
18
+ *
19
+ * return (
20
+ * <>
21
+ * <Button.default onClick={() => setOpen(true)}>Take the tour</Button.default>
22
+ * <div id="search">…</div>
23
+ * <div id="filters">…</div>
24
+ *
25
+ * <Tour.Root
26
+ * steps={[
27
+ * { value: 'search', target: '#search' },
28
+ * { value: 'filters', target: '#filters' },
29
+ * ]}
30
+ * open={open}
31
+ * onOpenChange={setOpen}
32
+ * >
33
+ * <Tour.Popup>
34
+ * <Tour.Content value="search">
35
+ * <Tour.Title>Search</Tour.Title>
36
+ * <Tour.Description>Find any order fast.</Tour.Description>
37
+ * </Tour.Content>
38
+ * <Tour.Content value="filters">
39
+ * <Tour.Title>Filters</Tour.Title>
40
+ * <Tour.Description>Narrow the results.</Tour.Description>
41
+ * </Tour.Content>
42
+ * <Tour.Progress />
43
+ * <Tour.BackButton>Back</Tour.BackButton>
44
+ * <Tour.NextButton>Next</Tour.NextButton>
45
+ * <Tour.DoneButton>Done</Tour.DoneButton>
46
+ * </Tour.Popup>
47
+ * </Tour.Root>
48
+ * </>
49
+ * )
50
+ * }
51
+ *
52
+ * @example Start on its own as soon as the page mounts, with no trigger button
53
+ * // Uncontrolled: defaultOpen starts the tour when Root mounts, and Root closes it itself.
54
+ * // Mount Root conditionally (e.g. only for users who haven't seen it) to show it once.
55
+ * ;<Tour.Root steps={steps} defaultOpen onOpenChange={(open) => { if (!open) markTourSeen() }}>
56
+ * <Tour.Popup>…</Tour.Popup>
57
+ * </Tour.Root>
58
+ *
59
+ * @example Content only one step has, like a video
60
+ * // Anything inside a Content shows only on its step; anything outside shows on every step.
61
+ * ;<Tour.Content value="filters">
62
+ * <Tour.Title>Filters</Tour.Title>
63
+ * <video src="/filters.mp4" autoPlay muted />
64
+ * </Tour.Content>
65
+ *
66
+ * @example Let users click the highlighted element during a step
67
+ * ;<Tour.Root steps={[{ value: 'upload', target: '#upload', interactive: true }]}>
68
+ */
69
+ export function Root(props) {
70
+ // The step the tour starts on, and rewinds to when it ends
71
+ const firstStep = props.defaultStep ?? props.steps[0].value;
72
+ const [uncontrolledOpen, setUncontrolledOpen] = useState(props.defaultOpen ?? false);
73
+ const [uncontrolledStep, setUncontrolledStep] = useState(firstStep);
74
+ const [placement, setPlacement] = useState({
75
+ side: 'bottom',
76
+ align: 'center',
77
+ });
78
+ // Controlled props win over the internal state, like Base UI's open and value
79
+ const isOpen = props.open ?? uncontrolledOpen;
80
+ const currentStep = props.step ?? uncontrolledStep;
81
+ // Joyride counts steps by position, so the current value becomes its index
82
+ const stepIndex = props.steps.findIndex((step) => step.value === currentStep);
83
+ // Joyride places by one word, so Popup's side and align become e.g. 'left-start'
84
+ const joyridePlacement = placement.align === 'center'
85
+ ? placement.side
86
+ : `${placement.side}-${placement.align}`;
87
+ return (_jsx(RootContext.Provider, { value: { children: props.children, steps: props.steps, setPlacement }, children: _jsx(Joyride, { run: isOpen, stepIndex: stepIndex, steps: props.steps.map((step) => ({
88
+ target: step.target,
89
+ id: step.value,
90
+ // The popup's text lives in Content parts, not in data
91
+ content: null,
92
+ placement: joyridePlacement,
93
+ blockTargetInteraction: !step.interactive,
94
+ })),
95
+ // Next moves straight to the following step, as in a classic guided tour
96
+ continuous: true, scrollToFirstStep: true, options: {
97
+ // Steps open directly, without a pulsing dot to click first
98
+ skipBeacon: true,
99
+ // A stray click on the dark overlay never ends the tour
100
+ overlayClickAction: false,
101
+ // Core layout, not overridable: the arrow matches Popover's and Tooltip's 20×10 size
102
+ arrowBase: 20,
103
+ arrowSize: 10,
104
+ }, tooltipComponent: PopupSlot, arrowComponent: Arrow, onEvent: (event) => {
105
+ // Ending the tour and rewinding it, so it restarts from the first step.
106
+ // Stopping `run` is what removes Joyride's overlay.
107
+ const end = () => {
108
+ setUncontrolledOpen(false);
109
+ props.onOpenChange?.(false);
110
+ setUncontrolledStep(firstStep);
111
+ props.onStepChange?.(firstStep);
112
+ };
113
+ // Ending by Skip, Close, or Escape
114
+ if (event.status === STATUS.SKIPPED || event.action === ACTIONS.CLOSE)
115
+ return end();
116
+ // Moving to the next or previous step, or past a target missing from the page.
117
+ // In controlled mode Joyride waits for the new step, so moving past the last one (Done) must end the tour here.
118
+ if (event.type === EVENTS.STEP_AFTER ||
119
+ event.type === EVENTS.TARGET_NOT_FOUND) {
120
+ const nextStep = props.steps[event.index + (event.action === ACTIONS.PREV ? -1 : 1)];
121
+ if (!nextStep)
122
+ return end();
123
+ setUncontrolledStep(nextStep.value);
124
+ props.onStepChange?.(nextStep.value);
125
+ }
126
+ } }) }));
127
+ }
128
+ const RootContext = /* @__PURE__ */ createContext(null);
129
+ /**
130
+ * Popover's arrow, drawn in Joyride's arrow slot. Its white base strip covers the popup's border where they meet,
131
+ * and it overlaps the popup by 2px, so the arrow reads as part of the popup with the border running around both.
132
+ */
133
+ function Arrow(arrow) {
134
+ // The SVG points up, which fits a popup sitting below its target; other sides rotate it
135
+ const rotation = (() => {
136
+ if (arrow.placement.startsWith('top'))
137
+ return 180;
138
+ if (arrow.placement.startsWith('left'))
139
+ return 90;
140
+ if (arrow.placement.startsWith('right'))
141
+ return -90;
142
+ return 0;
143
+ })();
144
+ return (_jsxs("svg", { "aria-hidden": true, width: "20", height: "10", viewBox: "0 0 20 10", "data-component": "tour-arrow", "data-side": arrow.placement.split('-')[0], className: "pointer-events-none fill-white",
145
+ // Core layout, not overridable: centered in Joyride's slot, rotated to its side, nudged 2px into the popup
146
+ style: {
147
+ position: 'absolute',
148
+ top: '50%',
149
+ left: '50%',
150
+ transform: `translate(-50%, -50%) rotate(${rotation}deg) translateY(2px)`,
151
+ }, children: [_jsx("path", { d: "M9.66437 2.60207L4.80758 6.97318C4.07308 7.63423 3.11989 8 2.13172 8H0V10H20V8H18.5349C17.5468 8 16.5936 7.63423 15.8591 6.97318L11.0023 2.60207C10.622 2.2598 10.0447 2.25979 9.66437 2.60207Z", "data-component": "tour-arrow-1", className: "fill-inherit" }), _jsx("path", { d: "M8.99542 1.85876C9.75604 1.17425 10.9106 1.17422 11.6713 1.85878L16.5281 6.22989C17.0789 6.72568 17.7938 7.00001 18.5349 7.00001L15.89 7L11.0023 2.60207C10.622 2.2598 10.0447 2.2598 9.66436 2.60207L4.77734 7L2.13171 7.00001C2.87284 7.00001 3.58774 6.72568 4.13861 6.22989L8.99542 1.85876Z", "data-component": "tour-arrow-2", className: "fill-neutral-200" }), _jsx("path", { d: "M10.3333 3.34539L5.47654 7.71648C4.55842 8.54279 3.36693 9 2.13172 9H0V8H2.13172C3.11989 8 4.07308 7.63423 4.80758 6.97318L9.66437 2.60207C10.0447 2.25979 10.622 2.2598 11.0023 2.60207L15.8591 6.97318C16.5936 7.63423 17.5468 8 18.5349 8H20V9H18.5349C17.2998 9 16.1083 8.54278 15.1901 7.71648L10.3333 3.34539Z", "data-component": "tour-arrow-3", className: "fill-inherit" })] }));
152
+ }
153
+ const StepContext = /* @__PURE__ */ createContext(null);
154
+ /** Joyride renders this in its popup slot; it shows Root's children with the current step's state. */
155
+ function PopupSlot(joyride) {
156
+ const root = useContext(RootContext);
157
+ if (!root)
158
+ throw new Error('Tour parts must be inside Tour.Root');
159
+ return (_jsx(StepContext.Provider, { value: { value: root.steps[joyride.index].value, joyride }, children: root.children }));
160
+ }
161
+ function useStep(part) {
162
+ const step = useContext(StepContext);
163
+ if (!step)
164
+ throw new Error(`Tour.${part} must be inside Tour.Popup`);
165
+ return step;
166
+ }
167
+ /**
168
+ * The box next to the highlighted element, shown on every step. Write the shared frame and buttons here once.
169
+ * `side` and `align` are where it prefers to sit; Joyride flips it when that side has no room, so it never leaves the screen.
170
+ */
171
+ export function Popup({ disableStyle, className, side = 'bottom', align = 'center', ...props }) {
172
+ const step = useStep('Popup');
173
+ const root = useContext(RootContext);
174
+ // Handing the preferred placement to Root, which passes it to Joyride
175
+ useLayoutEffect(() => {
176
+ root?.setPlacement({ side, align });
177
+ }, [root?.setPlacement, side, align]);
178
+ return (_jsx("div", { ...props, ...step.joyride.tooltipProps, "data-component": "tour-popup", "data-step": step.value, "data-first": step.joyride.index === 0 ? '' : undefined, "data-last": step.joyride.isLastStep ? '' : undefined, "data-style-disabled": disableStyle ? '' : undefined, className: twMerge(!disableStyle &&
179
+ 'relative flex w-80 max-w-[calc(100vw-2rem)] flex-col gap-3 rounded-xl border border-neutral-200 bg-white p-4 text-neutral-950 shadow-lg', className) }));
180
+ }
181
+ /** Shows its children only while its step is showing, like Tabs.Content. Put anything specific to one step here. */
182
+ export function Content({ disableStyle, className, value, ...props }) {
183
+ const step = useStep('Content');
184
+ if (step.value !== value)
185
+ return null;
186
+ return (_jsx("div", { ...props, "data-component": "tour-content", "data-step": value, "data-style-disabled": disableStyle ? '' : undefined, className: twMerge(!disableStyle && 'flex flex-col gap-1', className) }));
187
+ }
188
+ export function Title({ disableStyle, className, ...props }) {
189
+ return (_jsx("h2", { ...props, "data-component": "tour-title", "data-style-disabled": disableStyle ? '' : undefined, className: twMerge(!disableStyle && 'text-sm font-semibold leading-5 text-neutral-950', className) }));
190
+ }
191
+ export function Description({ disableStyle, className, ...props }) {
192
+ return (_jsx("p", { ...props, "data-component": "tour-description", "data-style-disabled": disableStyle ? '' : undefined, className: twMerge(!disableStyle && 'text-sm leading-5 text-neutral-600', className) }));
193
+ }
194
+ /** Shows the position in the tour, like "2 of 5". Pass a function as children to word it differently, e.g. for another language. */
195
+ export function Progress({ disableStyle, className, children, ...props }) {
196
+ const step = useStep('Progress');
197
+ const progress = { step: step.joyride.index + 1, total: step.joyride.size };
198
+ return (_jsx("p", { ...props, "data-component": "tour-progress", "data-last": step.joyride.isLastStep ? '' : undefined, "data-style-disabled": disableStyle ? '' : undefined, className: twMerge(!disableStyle && 'text-xs tabular-nums text-neutral-500', className), children: children ? children(progress) : `${progress.step} of ${progress.total}` }));
199
+ }
200
+ // Shared by every tour button: Polaris Button's base look at its medium size.
201
+ const buttonBase = 'relative flex w-fit min-h-7 cursor-pointer items-center justify-center gap-1.5 rounded-full px-4 py-1 text-[0.8rem] leading-4 font-medium text-nowrap select-none outline-none focus-visible:outline-2 focus-visible:outline-blue-500 active:scale-97 transition-[background-color,box-shadow,transform] duration-400 ease-[cubic-bezier(0.2,0.8,0,1)] motion-reduce:transition-none';
202
+ // Polaris Button's primary variant, neutral tone
203
+ const primaryButton = 'bg-neutral-950 text-white shadow-md hover:bg-black hover:text-neutral-200 focus-visible:bg-black active:bg-black [background-image:radial-gradient(50%_50%_at_50%_0%,_#ffffff33_0%,_#ffffff00_100%),_radial-gradient(49.59%_37.11%_at_50.41%_101.56%,_#ffffff26_0%,_#ffffff00_66.46%)] inset-shadow-[0rem_0rem_.25rem_.0625rem_#101010,0rem_0rem_.25rem_.125rem_#ffffff1a,0rem_0rem_.75rem_-.375rem_#ffffffbf]';
204
+ // Polaris Button's secondary variant, neutral tone
205
+ const secondaryButton = 'bg-neutral-200 text-neutral-950 hover:bg-neutral-300 focus-visible:bg-neutral-300 active:bg-neutral-300';
206
+ // Polaris Button's tertiary variant, neutral tone
207
+ const tertiaryButton = 'bg-transparent text-neutral-950 hover:bg-black/8 focus-visible:bg-black/8 active:bg-black/13';
208
+ /** Spreads Joyride's behavior for one button, keeping the user's own onClick too. With asChild, the consumer's child receives that behavior instead of this part's styled button. */
209
+ function TourButton({ asChild, joyrideProps, part, defaultClassName, disableStyle, className, onClick, children, ...props }) {
210
+ const behaviorProps = {
211
+ ...props,
212
+ ...joyrideProps,
213
+ onClick: (event) => {
214
+ onClick?.(event);
215
+ joyrideProps.onClick(event);
216
+ },
217
+ };
218
+ // Giving the behavior to the consumer's child, which keeps its own appearance and onClick
219
+ if (asChild) {
220
+ const child = children;
221
+ return cloneElement(child, {
222
+ ...behaviorProps,
223
+ className: twMerge(child.props.className, className),
224
+ onClick: (event) => {
225
+ child.props.onClick?.(event);
226
+ behaviorProps.onClick(event);
227
+ },
228
+ });
229
+ }
230
+ return (_jsx("button", { type: "button", ...behaviorProps, ...asChildStyleAttributes({ asChild, component: `tour-${part}`, disableStyle }), className: twMerge(!disableStyle && defaultClassName, className), children: children }));
231
+ }
232
+ /** Goes back one step, styled like a secondary Button. Not rendered on the first step, where there's nothing to go back to. Pass asChild to give this behavior to your own button instead. */
233
+ export function BackButton(props) {
234
+ const step = useStep('BackButton');
235
+ if (step.joyride.index === 0)
236
+ return null;
237
+ return (_jsx(TourButton, { ...props, joyrideProps: step.joyride.backProps, part: "backbutton", defaultClassName: `${buttonBase} ${secondaryButton}` }));
238
+ }
239
+ /** Goes to the next step, styled like a primary Button. Not rendered on the last step; DoneButton takes its place there. Pass asChild to give this behavior to your own button instead. */
240
+ export function NextButton(props) {
241
+ const step = useStep('NextButton');
242
+ if (step.joyride.isLastStep)
243
+ return null;
244
+ return (_jsx(TourButton, { ...props, joyrideProps: step.joyride.primaryProps, part: "nextbutton", defaultClassName: `${buttonBase} ${primaryButton}` }));
245
+ }
246
+ /** Finishes the tour, styled like a primary Button. Rendered only on the last step, in NextButton's place. Pass asChild to give this behavior to your own button instead. */
247
+ export function DoneButton(props) {
248
+ const step = useStep('DoneButton');
249
+ if (!step.joyride.isLastStep)
250
+ return null;
251
+ return (_jsx(TourButton, { ...props, joyrideProps: step.joyride.primaryProps, part: "donebutton", defaultClassName: `${buttonBase} ${primaryButton}` }));
252
+ }
253
+ /** Ends the tour early, styled like a tertiary Button. Not rendered on the last step, where Done already ends it. Pass asChild to give this behavior to your own button instead. */
254
+ export function SkipButton(props) {
255
+ const step = useStep('SkipButton');
256
+ if (step.joyride.isLastStep)
257
+ return null;
258
+ return (_jsx(TourButton, { ...props, joyrideProps: step.joyride.skipProps, part: "skipbutton", defaultClassName: `${buttonBase} ${tertiaryButton}` }));
259
+ }
260
+ /**
261
+ * Ends the tour from any step: the round ✕ in the popup's top-right corner, like Dialog's.
262
+ * Icon-only: put just a CloseButtonIcon inside, never text like "Close". It is already named for screen readers by Joyride.
263
+ * Pass asChild to give this behavior to your own button instead.
264
+ */
265
+ export function CloseButton(props) {
266
+ const step = useStep('CloseButton');
267
+ return (_jsx(TourButton, { ...props, joyrideProps: step.joyride.closeProps, part: "closebutton", defaultClassName: "absolute top-4 right-4 flex h-7 aspect-square w-7 shrink-0 cursor-pointer items-center justify-center rounded-full border border-neutral-200 bg-white p-0 text-neutral-950 shadow-sm hover:bg-neutral-100 hover:text-neutral-950 active:bg-neutral-200 active:text-neutral-950 focus-visible:outline-2 focus-visible:outline-blue-500" }));
268
+ }
269
+ /** A default ✕ icon is supplied. Omit children for the usual case; pass an icon only to replace that visual. */
270
+ export function CloseButtonIcon({ disableStyle, children, className, ...props }) {
271
+ return cloneElement(children ?? _jsx(X, {}), {
272
+ ...props,
273
+ 'aria-hidden': true,
274
+ ...{
275
+ 'data-component': 'tour-closebuttonicon',
276
+ 'data-style-disabled': disableStyle ? '' : undefined,
277
+ },
278
+ className: twMerge(!disableStyle && 'h-4 w-fit shrink-0 text-inherit', children?.props.className, className),
279
+ });
280
+ }
package/dist/index.d.ts CHANGED
@@ -40,11 +40,14 @@ export * as Spinner from './components/spinner/index.tsx';
40
40
  export * as Table from './components/table/index.tsx';
41
41
  export * as Chip from './components/chip/index.tsx';
42
42
  export * as TextLink from './components/textlink/index.tsx';
43
- export type { ToneProps } from './types/Tone.ts';
43
+ export * as Tour from './components/tour/index.tsx';
44
+ export * as BarChart from './components/barchart/index.tsx';
45
+ export * as HorizontalBarChart from './components/horizontalbarchart/index.tsx';
46
+ export * as LineChart from './components/linechart/index.tsx';
47
+ export * as DonutChart from './components/donutchart/index.tsx';
44
48
  export { useVirtualizedCombobox, FilteredItemsSync as ComboboxFilteredItemsSync, } from './utils/virtualization/useVirtualizedCombobox.ts';
45
49
  export type { UseVirtualizedComboboxOptions } from './utils/virtualization/useVirtualizedCombobox.ts';
46
50
  export { useVirtualizedAutocomplete, FilteredItemsSync as AutocompleteFilteredItemsSync, } from './utils/virtualization/useVirtualizedAutocomplete.ts';
47
51
  export type { UseVirtualizedAutocompleteOptions } from './utils/virtualization/useVirtualizedAutocomplete.ts';
48
52
  export { useVirtualizedTable } from './utils/virtualization/useVirtualizedTable.ts';
49
53
  export type { UseVirtualizedTableOptions } from './utils/virtualization/useVirtualizedTable.ts';
50
- //# sourceMappingURL=index.d.ts.map
package/dist/index.js CHANGED
@@ -40,7 +40,11 @@ export * as Spinner from "./components/spinner/index.js";
40
40
  export * as Table from "./components/table/index.js";
41
41
  export * as Chip from "./components/chip/index.js";
42
42
  export * as TextLink from "./components/textlink/index.js";
43
+ export * as Tour from "./components/tour/index.js";
44
+ export * as BarChart from "./components/barchart/index.js";
45
+ export * as HorizontalBarChart from "./components/horizontalbarchart/index.js";
46
+ export * as LineChart from "./components/linechart/index.js";
47
+ export * as DonutChart from "./components/donutchart/index.js";
43
48
  export { useVirtualizedCombobox, FilteredItemsSync as ComboboxFilteredItemsSync, } from "./utils/virtualization/useVirtualizedCombobox.js";
44
49
  export { useVirtualizedAutocomplete, FilteredItemsSync as AutocompleteFilteredItemsSync, } from "./utils/virtualization/useVirtualizedAutocomplete.js";
45
50
  export { useVirtualizedTable } from "./utils/virtualization/useVirtualizedTable.js";
46
- //# sourceMappingURL=index.js.map
@@ -0,0 +1,10 @@
1
+ import type { SVGProps } from 'react';
2
+ /** Props forwarded to built-in SVG icons, without importing the full icon catalog into consumer types. */
3
+ export interface SVGIconProps extends SVGProps<SVGSVGElement> {
4
+ /** Set the icon's width and height together; explicit width or height takes precedence. */
5
+ size?: string | number;
6
+ /** @deprecated Use nonScalingStroke instead. */
7
+ absoluteStrokeWidth?: boolean;
8
+ /** Keep the stroke thickness steady when changing the icon size. */
9
+ nonScalingStroke?: boolean;
10
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -11,4 +11,3 @@ export type StyleProps = {
11
11
  */
12
12
  disableStyle?: boolean;
13
13
  };
14
- //# sourceMappingURL=Style.d.ts.map
@@ -1,2 +1 @@
1
1
  export {};
2
- //# sourceMappingURL=Style.js.map
@@ -1,4 +1,3 @@
1
1
  export type ToneProps = {
2
2
  tone?: 'neutral' | 'valid' | 'invalid';
3
3
  };
4
- //# sourceMappingURL=Tone.d.ts.map
@@ -1,2 +1 @@
1
1
  export {};
2
- //# sourceMappingURL=Tone.js.map
@@ -0,0 +1,12 @@
1
+ /**
2
+ * The field's validation state, with an optional message: `'error'` styles it as invalid, `['error', 'Email is required']` also shows that message in Error. Same for `'success'` and Success.
3
+ * Error and success never coexist, since a field holds one validation state at a time.
4
+ */
5
+ export type Validation = 'error' | 'success' | readonly ['error' | 'success', string];
6
+ export type ValidationProps = {
7
+ /**
8
+ * The field's validation state, with an optional message: `'error'` styles it as invalid, `['error', 'Email is required']` also shows that message in Error. Same for `'success'` and Success.
9
+ * Omit it for a neutral field.
10
+ */
11
+ validation?: Validation;
12
+ };