@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.
- package/LICENSE +49 -0
- package/README.md +1 -1
- package/dist/components/accordion/index.d.ts +7 -6
- package/dist/components/accordion/index.js +13 -10
- package/dist/components/autocomplete/index.d.ts +22 -33
- package/dist/components/autocomplete/index.js +90 -73
- package/dist/components/avatar/index.d.ts +1 -2
- package/dist/components/avatar/index.js +6 -6
- package/dist/components/badge/index.d.ts +0 -1
- package/dist/components/badge/index.js +2 -2
- package/dist/components/banner/index.d.ts +1 -1
- package/dist/components/banner/index.js +24 -26
- package/dist/components/barchart/index.d.ts +106 -0
- package/dist/components/barchart/index.js +122 -0
- package/dist/components/breadcrumb/index.d.ts +0 -1
- package/dist/components/breadcrumb/index.js +6 -7
- package/dist/components/button/index.d.ts +3 -4
- package/dist/components/button/index.js +11 -12
- package/dist/components/card/index.d.ts +0 -1
- package/dist/components/card/index.js +0 -1
- package/dist/components/checkbox/index.d.ts +13 -11
- package/dist/components/checkbox/index.js +59 -39
- package/dist/components/chip/index.d.ts +1 -1
- package/dist/components/chip/index.js +2 -3
- package/dist/components/combobox/index.d.ts +32 -44
- package/dist/components/combobox/index.js +112 -88
- package/dist/components/datepicker/index.d.ts +54 -55
- package/dist/components/datepicker/index.js +105 -100
- package/dist/components/dialog/index.d.ts +17 -30
- package/dist/components/dialog/index.js +25 -26
- package/dist/components/divider/index.d.ts +0 -1
- package/dist/components/divider/index.js +0 -1
- package/dist/components/donutchart/index.d.ts +100 -0
- package/dist/components/donutchart/index.js +178 -0
- package/dist/components/drawer/index.d.ts +15 -24
- package/dist/components/drawer/index.js +45 -47
- package/dist/components/empty/index.d.ts +1 -2
- package/dist/components/empty/index.js +2 -4
- package/dist/components/fileupload/index.d.ts +4 -9
- package/dist/components/fileupload/index.js +27 -39
- package/dist/components/form/index.d.ts +0 -1
- package/dist/components/form/index.js +0 -1
- package/dist/components/horizontalbarchart/index.d.ts +120 -0
- package/dist/components/horizontalbarchart/index.js +193 -0
- package/dist/components/input/index.d.ts +23 -23
- package/dist/components/input/index.js +86 -115
- package/dist/components/linechart/index.d.ts +114 -0
- package/dist/components/linechart/index.js +139 -0
- package/dist/components/menu/index.d.ts +14 -16
- package/dist/components/menu/index.js +56 -53
- package/dist/components/metric/index.d.ts +0 -1
- package/dist/components/metric/index.js +0 -1
- package/dist/components/numberinput/index.d.ts +16 -23
- package/dist/components/numberinput/index.js +55 -68
- package/dist/components/otpinput/index.d.ts +14 -9
- package/dist/components/otpinput/index.js +32 -25
- package/dist/components/page/index.d.ts +0 -1
- package/dist/components/page/index.js +2 -4
- package/dist/components/passwordinput/index.d.ts +16 -13
- package/dist/components/passwordinput/index.js +47 -56
- package/dist/components/popover/index.d.ts +21 -19
- package/dist/components/popover/index.js +40 -21
- package/dist/components/radio/index.d.ts +13 -9
- package/dist/components/radio/index.js +80 -71
- package/dist/components/ratinginput/index.d.ts +15 -10
- package/dist/components/ratinginput/index.js +38 -18
- package/dist/components/select/index.d.ts +29 -32
- package/dist/components/select/index.js +79 -50
- package/dist/components/skeleton/index.d.ts +0 -1
- package/dist/components/skeleton/index.js +0 -1
- package/dist/components/slider/index.d.ts +14 -9
- package/dist/components/slider/index.js +75 -74
- package/dist/components/spinner/index.d.ts +2 -3
- package/dist/components/spinner/index.js +2 -3
- package/dist/components/splitter/index.d.ts +1 -2
- package/dist/components/splitter/index.js +6 -7
- package/dist/components/stepper/index.d.ts +8 -20
- package/dist/components/stepper/index.js +15 -16
- package/dist/components/switch/index.d.ts +12 -10
- package/dist/components/switch/index.js +52 -36
- package/dist/components/table/index.d.ts +3 -3
- package/dist/components/table/index.js +17 -16
- package/dist/components/tabs/index.d.ts +3 -4
- package/dist/components/tabs/index.js +6 -7
- package/dist/components/textarea/index.d.ts +16 -13
- package/dist/components/textarea/index.js +46 -55
- package/dist/components/textlink/index.d.ts +3 -1
- package/dist/components/textlink/index.js +4 -1
- package/dist/components/toast/index.d.ts +8 -14
- package/dist/components/toast/index.js +54 -54
- package/dist/components/toggle/index.d.ts +5 -6
- package/dist/components/toggle/index.js +19 -26
- package/dist/components/tooltip/index.d.ts +11 -13
- package/dist/components/tooltip/index.js +14 -11
- package/dist/components/tour/index.d.ts +154 -0
- package/dist/components/tour/index.js +280 -0
- package/dist/index.d.ts +5 -2
- package/dist/index.js +5 -1
- package/dist/types/Icon.d.ts +10 -0
- package/dist/types/Icon.js +1 -0
- package/dist/types/Style.d.ts +0 -1
- package/dist/types/Style.js +0 -1
- package/dist/types/Tone.d.ts +0 -1
- package/dist/types/Tone.js +0 -1
- package/dist/types/Validation.d.ts +12 -0
- package/dist/types/Validation.js +1 -0
- package/dist/utils/ArkStateToDataAttributes.d.ts +0 -1
- package/dist/utils/ArkStateToDataAttributes.js +3 -2
- package/dist/utils/Tone.d.ts +0 -1
- package/dist/utils/Tone.js +1 -2
- package/dist/utils/Validation.d.ts +14 -0
- package/dist/utils/Validation.js +23 -0
- package/dist/utils/asChild.d.ts +41 -0
- package/dist/utils/asChild.js +15 -0
- package/dist/utils/icons.d.ts +24 -0
- package/dist/utils/icons.js +160 -0
- package/dist/utils/useForwardClickToInput.d.ts +0 -1
- package/dist/utils/useForwardClickToInput.js +4 -3
- package/dist/utils/virtualization/useVirtualizedAutocomplete.d.ts +0 -1
- package/dist/utils/virtualization/useVirtualizedAutocomplete.js +0 -1
- package/dist/utils/virtualization/useVirtualizedCombobox.d.ts +0 -1
- package/dist/utils/virtualization/useVirtualizedCombobox.js +0 -1
- package/dist/utils/virtualization/useVirtualizedTable.d.ts +0 -1
- package/dist/utils/virtualization/useVirtualizedTable.js +0 -1
- package/package.json +12 -11
- package/src/presets/shopify-polaris/shopify-polaris-autocomplete.css +15 -6
- package/src/presets/shopify-polaris/shopify-polaris-badge.css +1 -1
- package/src/presets/shopify-polaris/shopify-polaris-barchart.css +64 -0
- package/src/presets/shopify-polaris/shopify-polaris-checkbox.css +2 -2
- package/src/presets/shopify-polaris/shopify-polaris-chip.css +3 -3
- package/src/presets/shopify-polaris/shopify-polaris-combobox.css +19 -10
- package/src/presets/shopify-polaris/shopify-polaris-datepicker.css +20 -11
- package/src/presets/shopify-polaris/shopify-polaris-dialog.css +16 -0
- package/src/presets/shopify-polaris/shopify-polaris-donutchart.css +172 -0
- package/src/presets/shopify-polaris/shopify-polaris-drawer.css +16 -0
- package/src/presets/shopify-polaris/shopify-polaris-fileupload.css +1 -1
- package/src/presets/shopify-polaris/shopify-polaris-horizontalbarchart.css +60 -0
- package/src/presets/shopify-polaris/shopify-polaris-input.css +14 -5
- package/src/presets/shopify-polaris/shopify-polaris-linechart.css +68 -0
- package/src/presets/shopify-polaris/shopify-polaris-menu.css +47 -6
- package/src/presets/shopify-polaris/shopify-polaris-numberinput.css +16 -7
- package/src/presets/shopify-polaris/shopify-polaris-otpinput.css +3 -3
- package/src/presets/shopify-polaris/shopify-polaris-passwordinput.css +14 -5
- package/src/presets/shopify-polaris/shopify-polaris-popover.css +29 -0
- package/src/presets/shopify-polaris/shopify-polaris-radio.css +2 -2
- package/src/presets/shopify-polaris/shopify-polaris-ratinginput.css +2 -2
- package/src/presets/shopify-polaris/shopify-polaris-select.css +15 -6
- package/src/presets/shopify-polaris/shopify-polaris-slider.css +2 -2
- package/src/presets/shopify-polaris/shopify-polaris-stepper.css +16 -0
- package/src/presets/shopify-polaris/shopify-polaris-switch.css +2 -2
- package/src/presets/shopify-polaris/shopify-polaris-textarea.css +13 -4
- package/src/presets/shopify-polaris/shopify-polaris-toast.css +43 -0
- package/src/presets/shopify-polaris/shopify-polaris-tooltip.css +16 -0
- package/src/presets/shopify-polaris/shopify-polaris.css +5 -0
- package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-autocomplete.css +2 -2
- package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-barchart.css +64 -0
- package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-checkbox.css +2 -2
- package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-combobox.css +2 -2
- package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-datepicker.css +2 -2
- package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-dialog.css +9 -0
- package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-donutchart.css +172 -0
- package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-drawer.css +9 -0
- package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-fileupload.css +1 -1
- package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-horizontalbarchart.css +60 -0
- package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-input.css +2 -2
- package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-linechart.css +68 -0
- package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-menu.css +9 -0
- package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-numberinput.css +2 -2
- package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-otpinput.css +2 -2
- package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-passwordinput.css +2 -2
- package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-popover.css +22 -0
- package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-radio.css +2 -2
- package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-ratinginput.css +2 -2
- package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-slider.css +2 -2
- package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-stepper.css +9 -0
- package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-switch.css +2 -2
- package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-textarea.css +2 -2
- package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-tooltip.css +9 -0
- package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy.css +4 -0
- package/dist/components/accordion/index.d.ts.map +0 -1
- package/dist/components/accordion/index.js.map +0 -1
- package/dist/components/autocomplete/index.d.ts.map +0 -1
- package/dist/components/autocomplete/index.js.map +0 -1
- package/dist/components/avatar/index.d.ts.map +0 -1
- package/dist/components/avatar/index.js.map +0 -1
- package/dist/components/badge/index.d.ts.map +0 -1
- package/dist/components/badge/index.js.map +0 -1
- package/dist/components/banner/index.d.ts.map +0 -1
- package/dist/components/banner/index.js.map +0 -1
- package/dist/components/breadcrumb/index.d.ts.map +0 -1
- package/dist/components/breadcrumb/index.js.map +0 -1
- package/dist/components/button/index.d.ts.map +0 -1
- package/dist/components/button/index.js.map +0 -1
- package/dist/components/card/index.d.ts.map +0 -1
- package/dist/components/card/index.js.map +0 -1
- package/dist/components/checkbox/index.d.ts.map +0 -1
- package/dist/components/checkbox/index.js.map +0 -1
- package/dist/components/chip/index.d.ts.map +0 -1
- package/dist/components/chip/index.js.map +0 -1
- package/dist/components/combobox/index.d.ts.map +0 -1
- package/dist/components/combobox/index.js.map +0 -1
- package/dist/components/datepicker/index.d.ts.map +0 -1
- package/dist/components/datepicker/index.js.map +0 -1
- package/dist/components/dialog/index.d.ts.map +0 -1
- package/dist/components/dialog/index.js.map +0 -1
- package/dist/components/divider/index.d.ts.map +0 -1
- package/dist/components/divider/index.js.map +0 -1
- package/dist/components/drawer/index.d.ts.map +0 -1
- package/dist/components/drawer/index.js.map +0 -1
- package/dist/components/empty/index.d.ts.map +0 -1
- package/dist/components/empty/index.js.map +0 -1
- package/dist/components/fileupload/index.d.ts.map +0 -1
- package/dist/components/fileupload/index.js.map +0 -1
- package/dist/components/form/index.d.ts.map +0 -1
- package/dist/components/form/index.js.map +0 -1
- package/dist/components/input/index.d.ts.map +0 -1
- package/dist/components/input/index.js.map +0 -1
- package/dist/components/menu/index.d.ts.map +0 -1
- package/dist/components/menu/index.js.map +0 -1
- package/dist/components/metric/index.d.ts.map +0 -1
- package/dist/components/metric/index.js.map +0 -1
- package/dist/components/numberinput/index.d.ts.map +0 -1
- package/dist/components/numberinput/index.js.map +0 -1
- package/dist/components/otpinput/index.d.ts.map +0 -1
- package/dist/components/otpinput/index.js.map +0 -1
- package/dist/components/page/index.d.ts.map +0 -1
- package/dist/components/page/index.js.map +0 -1
- package/dist/components/passwordinput/index.d.ts.map +0 -1
- package/dist/components/passwordinput/index.js.map +0 -1
- package/dist/components/popover/index.d.ts.map +0 -1
- package/dist/components/popover/index.js.map +0 -1
- package/dist/components/radio/index.d.ts.map +0 -1
- package/dist/components/radio/index.js.map +0 -1
- package/dist/components/ratinginput/index.d.ts.map +0 -1
- package/dist/components/ratinginput/index.js.map +0 -1
- package/dist/components/select/index.d.ts.map +0 -1
- package/dist/components/select/index.js.map +0 -1
- package/dist/components/skeleton/index.d.ts.map +0 -1
- package/dist/components/skeleton/index.js.map +0 -1
- package/dist/components/slider/index.d.ts.map +0 -1
- package/dist/components/slider/index.js.map +0 -1
- package/dist/components/spinner/index.d.ts.map +0 -1
- package/dist/components/spinner/index.js.map +0 -1
- package/dist/components/splitter/index.d.ts.map +0 -1
- package/dist/components/splitter/index.js.map +0 -1
- package/dist/components/stepper/index.d.ts.map +0 -1
- package/dist/components/stepper/index.js.map +0 -1
- package/dist/components/switch/index.d.ts.map +0 -1
- package/dist/components/switch/index.js.map +0 -1
- package/dist/components/table/index.d.ts.map +0 -1
- package/dist/components/table/index.js.map +0 -1
- package/dist/components/tabs/index.d.ts.map +0 -1
- package/dist/components/tabs/index.js.map +0 -1
- package/dist/components/textarea/index.d.ts.map +0 -1
- package/dist/components/textarea/index.js.map +0 -1
- package/dist/components/textlink/index.d.ts.map +0 -1
- package/dist/components/textlink/index.js.map +0 -1
- package/dist/components/toast/index.d.ts.map +0 -1
- package/dist/components/toast/index.js.map +0 -1
- package/dist/components/toggle/index.d.ts.map +0 -1
- package/dist/components/toggle/index.js.map +0 -1
- package/dist/components/tooltip/index.d.ts.map +0 -1
- package/dist/components/tooltip/index.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/types/Style.d.ts.map +0 -1
- package/dist/types/Style.js.map +0 -1
- package/dist/types/Tone.d.ts.map +0 -1
- package/dist/types/Tone.js.map +0 -1
- package/dist/utils/ArkStateToDataAttributes.d.ts.map +0 -1
- package/dist/utils/ArkStateToDataAttributes.js.map +0 -1
- package/dist/utils/Tone.d.ts.map +0 -1
- package/dist/utils/Tone.js.map +0 -1
- package/dist/utils/useForwardClickToInput.d.ts.map +0 -1
- package/dist/utils/useForwardClickToInput.js.map +0 -1
- package/dist/utils/virtualization/useVirtualizedAutocomplete.d.ts.map +0 -1
- package/dist/utils/virtualization/useVirtualizedAutocomplete.js.map +0 -1
- package/dist/utils/virtualization/useVirtualizedCombobox.d.ts.map +0 -1
- package/dist/utils/virtualization/useVirtualizedCombobox.js.map +0 -1
- package/dist/utils/virtualization/useVirtualizedTable.d.ts.map +0 -1
- 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
|
|
4
|
+
import type { ComponentPropsWithRef } from 'react';
|
|
4
5
|
/**
|
|
5
|
-
*
|
|
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.
|
|
14
|
+
* <Tooltip.OpenButton asChild>
|
|
14
15
|
* <Button.default variant="secondary">Delivery information</Button.default>
|
|
15
|
-
* </Tooltip.
|
|
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
|
|
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
|
|
31
|
-
/**
|
|
32
|
-
export declare const
|
|
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
|
-
|
|
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
|
|
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
|
-
*
|
|
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.
|
|
14
|
+
* <Tooltip.OpenButton asChild>
|
|
14
15
|
* <Button.default variant="secondary">Delivery information</Button.default>
|
|
15
|
-
* </Tooltip.
|
|
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
|
|
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
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
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
|
|
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 {};
|
package/dist/types/Style.d.ts
CHANGED
package/dist/types/Style.js
CHANGED
package/dist/types/Tone.d.ts
CHANGED
package/dist/types/Tone.js
CHANGED
|
@@ -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
|
+
};
|