adnbn-ui 0.0.1 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.prettierignore +3 -0
- package/.prettierrc +28 -0
- package/.storybook/main.ts +22 -0
- package/.storybook/preview.tsx +100 -0
- package/.storybook/styles/custom.scss +59 -0
- package/.storybook/styles/preview.css +58 -0
- package/.storybook/vitest.setup.ts +9 -0
- package/README.md +1057 -0
- package/eslint.config.js +39 -0
- package/package.json +95 -4
- package/src/components/Avatar/Avatar.stories.tsx +118 -0
- package/src/components/Avatar/Avatar.tsx +65 -0
- package/src/components/Avatar/avatar.module.scss +77 -0
- package/src/components/Avatar/index.ts +2 -0
- package/src/components/BaseButton/BaseButton.tsx +36 -0
- package/src/components/BaseButton/base-button.module.scss +24 -0
- package/src/components/BaseButton/index.ts +2 -0
- package/src/components/Button/Button.stories.tsx +148 -0
- package/src/components/Button/Button.tsx +73 -0
- package/src/components/Button/button.module.scss +140 -0
- package/src/components/Button/index.ts +2 -0
- package/src/components/Checkbox/Checkbox.stories.tsx +180 -0
- package/src/components/Checkbox/Checkbox.tsx +71 -0
- package/src/components/Checkbox/checkbox.module.scss +82 -0
- package/src/components/Checkbox/index.ts +2 -0
- package/src/components/Dialog/Dialog.tsx +125 -0
- package/src/components/Dialog/dialog.module.scss +55 -0
- package/src/components/Dialog/index.ts +2 -0
- package/src/components/Drawer/Drawer.stories.tsx +89 -0
- package/src/components/Drawer/Drawer.tsx +57 -0
- package/src/components/Drawer/drawer.module.scss +170 -0
- package/src/components/Drawer/index.ts +2 -0
- package/src/components/Footer/Footer.stories.tsx +118 -0
- package/src/components/Footer/Footer.tsx +58 -0
- package/src/components/Footer/footer.module.scss +44 -0
- package/src/components/Footer/index.ts +2 -0
- package/src/components/Header/Header.stories.tsx +49 -0
- package/src/components/Header/Header.tsx +73 -0
- package/src/components/Header/header.module.scss +56 -0
- package/src/components/Header/index.ts +2 -0
- package/src/components/Highlight/Highlight.stories.tsx +83 -0
- package/src/components/Highlight/Highlight.tsx +40 -0
- package/src/components/Highlight/highlight.module.scss +47 -0
- package/src/components/Highlight/index.ts +2 -0
- package/src/components/Icon/Icon.tsx +46 -0
- package/src/components/Icon/icon.module.scss +17 -0
- package/src/components/Icon/index.ts +2 -0
- package/src/components/IconButton/IconButton.stories.tsx +179 -0
- package/src/components/IconButton/IconButton.tsx +65 -0
- package/src/components/IconButton/icon-button.module.scss +86 -0
- package/src/components/IconButton/index.ts +2 -0
- package/src/components/Layout/Layout.stories.tsx +88 -0
- package/src/components/Layout/Provider.tsx +47 -0
- package/src/components/Layout/context.ts +24 -0
- package/src/components/Layout/index.ts +2 -0
- package/src/components/Layout/layout.module.scss +17 -0
- package/src/components/List/List.stories.tsx +81 -0
- package/src/components/List/List.tsx +24 -0
- package/src/components/List/index.ts +2 -0
- package/src/components/List/list.module.scss +8 -0
- package/src/components/ListItem/ListItem.tsx +75 -0
- package/src/components/ListItem/index.ts +2 -0
- package/src/components/ListItem/list-item.module.scss +36 -0
- package/src/components/Modal/Modal.stories.tsx +95 -0
- package/src/components/Modal/Modal.tsx +94 -0
- package/src/components/Modal/index.ts +2 -0
- package/src/components/Modal/modal.module.scss +97 -0
- package/src/components/Odometer/Odometer.stories.tsx +66 -0
- package/src/components/Odometer/Odometer.tsx +45 -0
- package/src/components/Odometer/hooks/useOdometer.tsx +24 -0
- package/src/components/Odometer/index.ts +3 -0
- package/src/components/Odometer/odometer.module.scss +81 -0
- package/src/components/Odometer/odometr.d.ts +9 -0
- package/src/components/ScrollArea/ScrollArea.stories.tsx +58 -0
- package/src/components/ScrollArea/ScrollArea.tsx +63 -0
- package/src/components/ScrollArea/index.ts +2 -0
- package/src/components/ScrollArea/scroll-area.module.scss +54 -0
- package/src/components/SvgSprite/SvgSprite.tsx +21 -0
- package/src/components/SvgSprite/index.ts +2 -0
- package/src/components/Switch/Switch.stories.tsx +25 -0
- package/src/components/Switch/Switch.tsx +23 -0
- package/src/components/Switch/index.ts +2 -0
- package/src/components/Switch/switch.module.scss +65 -0
- package/src/components/Tag/Tag.stories.tsx +157 -0
- package/src/components/Tag/Tag.tsx +71 -0
- package/src/components/Tag/index.ts +2 -0
- package/src/components/Tag/tag.module.scss +118 -0
- package/src/components/TextArea/TextArea.stories.tsx +145 -0
- package/src/components/TextArea/TextArea.tsx +143 -0
- package/src/components/TextArea/index.ts +2 -0
- package/src/components/TextArea/text-area.module.scss +88 -0
- package/src/components/TextField/TextField.stories.tsx +177 -0
- package/src/components/TextField/TextField.tsx +162 -0
- package/src/components/TextField/index.ts +2 -0
- package/src/components/TextField/text-field.module.scss +129 -0
- package/src/components/Toast/Toast.stories.tsx +209 -0
- package/src/components/Toast/Toast.tsx +142 -0
- package/src/components/Toast/index.ts +2 -0
- package/src/components/Toast/toast.module.scss +267 -0
- package/src/components/Tooltip/Tooltip.stories.tsx +80 -0
- package/src/components/Tooltip/Tooltip.tsx +79 -0
- package/src/components/Tooltip/index.ts +2 -0
- package/src/components/Tooltip/tooltip.module.scss +93 -0
- package/src/components/View/View.stories.tsx +47 -0
- package/src/components/View/View.tsx +68 -0
- package/src/components/View/index.ts +2 -0
- package/src/components/View/view.module.scss +38 -0
- package/src/components/ViewDrawer/ViewDrawer.stories.tsx +75 -0
- package/src/components/ViewDrawer/ViewDrawer.tsx +24 -0
- package/src/components/ViewDrawer/index.ts +2 -0
- package/src/components/ViewModal/ViewModal.stories.tsx +68 -0
- package/src/components/ViewModal/ViewModal.tsx +24 -0
- package/src/components/ViewModal/index.ts +2 -0
- package/src/components/index.ts +29 -0
- package/src/components/types.ts +65 -0
- package/src/config/default.ts +3 -0
- package/src/config/index.ts +26 -0
- package/src/declaration.d.ts +8 -0
- package/src/index.ts +3 -0
- package/src/plugin/builder/ConfigBuilder.ts +32 -0
- package/src/plugin/builder/StyleBuilder.ts +34 -0
- package/src/plugin/builder/virtual.config.ts +7 -0
- package/src/plugin/finder/ConfigFinder.ts +26 -0
- package/src/plugin/finder/Finder.ts +76 -0
- package/src/plugin/finder/StyleFinder.ts +23 -0
- package/src/plugin/index.ts +70 -0
- package/src/plugin/types.ts +8 -0
- package/src/providers/UIProvider.tsx +26 -0
- package/src/providers/icons/IconsProvider.tsx +34 -0
- package/src/providers/icons/context.ts +22 -0
- package/src/providers/icons/index.ts +3 -0
- package/src/providers/index.ts +3 -0
- package/src/providers/theme/ThemeProvider.tsx +39 -0
- package/src/providers/theme/context.ts +30 -0
- package/src/providers/theme/index.ts +2 -0
- package/src/providers/theme/styles/default.scss +95 -0
- package/src/providers/theme/styles/reset.css +111 -0
- package/src/styles/mixins.scss +23 -0
- package/src/types/theme.ts +4 -0
- package/src/utils/index.ts +2 -0
- package/src/utils/react.ts +21 -0
- package/src/utils/utils.ts +12 -0
- package/tsconfig.json +18 -0
- package/vite.config.ts +11 -0
- package/vitest.workspace.ts +19 -0
- package/components/Button/index.ts +0 -0
@@ -0,0 +1,209 @@
|
|
1
|
+
import {FC, useState} from "react";
|
2
|
+
import {Meta, StoryObj} from "@storybook/react";
|
3
|
+
|
4
|
+
import {hideInTable} from "../../utils";
|
5
|
+
|
6
|
+
import {Button, ButtonColor, ButtonVariant} from "../index";
|
7
|
+
|
8
|
+
import ToastComponent, {ToastColor, ToastProps, ToastRadius, ToastSide} from "./Toast";
|
9
|
+
|
10
|
+
const sides: ToastSide[] = [
|
11
|
+
ToastSide.TopLeft,
|
12
|
+
ToastSide.TopCenter,
|
13
|
+
ToastSide.TopRight,
|
14
|
+
ToastSide.BottomRight,
|
15
|
+
ToastSide.BottomCenter,
|
16
|
+
ToastSide.BottomLeft,
|
17
|
+
];
|
18
|
+
const colors: (ToastColor | "default")[] = ["default", ToastColor.Success, ToastColor.Error];
|
19
|
+
const radius: (ToastRadius | "default")[] = [
|
20
|
+
ToastRadius.None,
|
21
|
+
ToastRadius.Small,
|
22
|
+
"default",
|
23
|
+
ToastRadius.Medium,
|
24
|
+
ToastRadius.Large,
|
25
|
+
];
|
26
|
+
|
27
|
+
const meta: Meta<typeof ToastComponent> = {
|
28
|
+
title: "Components/Toast",
|
29
|
+
component: ToastComponent,
|
30
|
+
tags: ["autodocs"],
|
31
|
+
argTypes: {
|
32
|
+
duration: {
|
33
|
+
description: "The time in milliseconds that should elapse before automatically closing each toast.",
|
34
|
+
},
|
35
|
+
swipeDirection: {
|
36
|
+
options: ["right", "left", "up", "down"],
|
37
|
+
control: {type: "select"},
|
38
|
+
description: "The direction of the pointer swipe that should close the toast.",
|
39
|
+
},
|
40
|
+
swipeThreshold: {
|
41
|
+
description: "The distance in pixels that the swipe gesture must travel before a close is triggered.",
|
42
|
+
control: {type: "number"},
|
43
|
+
},
|
44
|
+
side: {
|
45
|
+
options: sides,
|
46
|
+
control: {type: "select"},
|
47
|
+
},
|
48
|
+
radius: {
|
49
|
+
options: radius,
|
50
|
+
control: {type: "select"},
|
51
|
+
},
|
52
|
+
color: {
|
53
|
+
options: colors,
|
54
|
+
control: {type: "select"},
|
55
|
+
},
|
56
|
+
|
57
|
+
action: hideInTable,
|
58
|
+
closeIcon: hideInTable,
|
59
|
+
closeProps: hideInTable,
|
60
|
+
onClose: hideInTable,
|
61
|
+
children: hideInTable,
|
62
|
+
className: hideInTable,
|
63
|
+
titleClassName: hideInTable,
|
64
|
+
actionClassName: hideInTable,
|
65
|
+
viewportClassName: hideInTable,
|
66
|
+
descriptionClassName: hideInTable,
|
67
|
+
},
|
68
|
+
};
|
69
|
+
|
70
|
+
export default meta;
|
71
|
+
|
72
|
+
export const Toast: StoryObj<typeof ToastComponent> = {
|
73
|
+
args: {
|
74
|
+
open: true,
|
75
|
+
sticky: false,
|
76
|
+
fullWidth: false,
|
77
|
+
children: (
|
78
|
+
<Button variant={ButtonVariant.Contained} color={ButtonColor.Primary}>
|
79
|
+
Show toast
|
80
|
+
</Button>
|
81
|
+
),
|
82
|
+
title: "New notification",
|
83
|
+
description: "Description",
|
84
|
+
side: ToastSide.BottomRight,
|
85
|
+
duration: 5000,
|
86
|
+
onClose: () => undefined,
|
87
|
+
},
|
88
|
+
};
|
89
|
+
|
90
|
+
const ToastClickable: FC<ToastProps> = ({children, ...props}) => {
|
91
|
+
const [open, setOpen] = useState(false);
|
92
|
+
const handleClick = () => setOpen(prev => !prev);
|
93
|
+
const handleClose = () => setOpen(false);
|
94
|
+
|
95
|
+
return (
|
96
|
+
<ToastComponent
|
97
|
+
open={open}
|
98
|
+
title="New notification"
|
99
|
+
description="Description"
|
100
|
+
onOpenChange={setOpen}
|
101
|
+
onClose={handleClose}
|
102
|
+
{...props}
|
103
|
+
>
|
104
|
+
<Button variant={ButtonVariant.Contained} color={ButtonColor.Primary} onClick={handleClick}>
|
105
|
+
{children}
|
106
|
+
</Button>
|
107
|
+
</ToastComponent>
|
108
|
+
);
|
109
|
+
};
|
110
|
+
|
111
|
+
export const Side = () => {
|
112
|
+
return (
|
113
|
+
<div style={{display: "grid", gridTemplateColumns: "repeat(6, auto)", gap: "10px"}}>
|
114
|
+
<ToastClickable side={ToastSide.TopLeft} description="Top Left">
|
115
|
+
Top Left
|
116
|
+
</ToastClickable>
|
117
|
+
|
118
|
+
<ToastClickable side={ToastSide.TopCenter} description="Top Center">
|
119
|
+
Top Center
|
120
|
+
</ToastClickable>
|
121
|
+
|
122
|
+
<ToastClickable side={ToastSide.TopRight} description="Top Right">
|
123
|
+
Top Right
|
124
|
+
</ToastClickable>
|
125
|
+
|
126
|
+
<ToastClickable side={ToastSide.BottomLeft} description="Bottom Left">
|
127
|
+
Bottom Left
|
128
|
+
</ToastClickable>
|
129
|
+
|
130
|
+
<ToastClickable side={ToastSide.BottomCenter} description="Bottom Center">
|
131
|
+
Bottom Center
|
132
|
+
</ToastClickable>
|
133
|
+
|
134
|
+
<ToastClickable side={ToastSide.BottomRight} description="Bottom Right">
|
135
|
+
Bottom Right
|
136
|
+
</ToastClickable>
|
137
|
+
</div>
|
138
|
+
);
|
139
|
+
};
|
140
|
+
|
141
|
+
export const Radius = () => {
|
142
|
+
return (
|
143
|
+
<div style={{display: "flex", gap: "10px"}}>
|
144
|
+
<ToastClickable side={ToastSide.TopLeft} radius={ToastRadius.None} description="None Radius">
|
145
|
+
None
|
146
|
+
</ToastClickable>
|
147
|
+
|
148
|
+
<ToastClickable side={ToastSide.TopCenter} radius={ToastRadius.Small} description="Small Radius">
|
149
|
+
Small
|
150
|
+
</ToastClickable>
|
151
|
+
|
152
|
+
<ToastClickable side={ToastSide.TopRight} description="Default Radius">
|
153
|
+
Default
|
154
|
+
</ToastClickable>
|
155
|
+
|
156
|
+
<ToastClickable side={ToastSide.BottomLeft} radius={ToastRadius.Medium} description="Medium Radius">
|
157
|
+
Medium
|
158
|
+
</ToastClickable>
|
159
|
+
|
160
|
+
<ToastClickable side={ToastSide.BottomRight} radius={ToastRadius.Large} description="Large Radius">
|
161
|
+
Large
|
162
|
+
</ToastClickable>
|
163
|
+
</div>
|
164
|
+
);
|
165
|
+
};
|
166
|
+
|
167
|
+
export const FullWidth = () => {
|
168
|
+
return (
|
169
|
+
<div style={{display: "flex", flexDirection: "column", gap: "10px"}}>
|
170
|
+
<ToastClickable
|
171
|
+
side={ToastSide.TopCenter}
|
172
|
+
radius={ToastRadius.None}
|
173
|
+
fullWidth
|
174
|
+
sticky
|
175
|
+
description="Top full width without padding"
|
176
|
+
>
|
177
|
+
Top
|
178
|
+
</ToastClickable>
|
179
|
+
|
180
|
+
<ToastClickable
|
181
|
+
side={ToastSide.BottomCenter}
|
182
|
+
radius={ToastRadius.None}
|
183
|
+
fullWidth
|
184
|
+
sticky
|
185
|
+
description="Bottom full width without padding"
|
186
|
+
>
|
187
|
+
Bottom
|
188
|
+
</ToastClickable>
|
189
|
+
</div>
|
190
|
+
);
|
191
|
+
};
|
192
|
+
|
193
|
+
export const Color = () => {
|
194
|
+
return (
|
195
|
+
<div style={{display: "flex", gap: "10px"}}>
|
196
|
+
<ToastClickable side={ToastSide.TopLeft} color={ToastColor.Error} description="Error color">
|
197
|
+
Error
|
198
|
+
</ToastClickable>
|
199
|
+
|
200
|
+
<ToastClickable side={ToastSide.TopCenter} description="Default color">
|
201
|
+
Default
|
202
|
+
</ToastClickable>
|
203
|
+
|
204
|
+
<ToastClickable side={ToastSide.TopRight} color={ToastColor.Success} description="Success color">
|
205
|
+
Success
|
206
|
+
</ToastClickable>
|
207
|
+
</div>
|
208
|
+
);
|
209
|
+
};
|
@@ -0,0 +1,142 @@
|
|
1
|
+
import React, {FC, memo, ReactElement, ReactNode} from "react";
|
2
|
+
import classnames from "classnames";
|
3
|
+
import {
|
4
|
+
Description,
|
5
|
+
Provider,
|
6
|
+
Root,
|
7
|
+
Title,
|
8
|
+
ToastProps as ToastRootProps,
|
9
|
+
ToastProviderProps,
|
10
|
+
Viewport,
|
11
|
+
} from "@radix-ui/react-toast";
|
12
|
+
|
13
|
+
import {IconButton, IconButtonProps} from "../IconButton";
|
14
|
+
import {cloneOrCreateElement} from "../../utils";
|
15
|
+
import {useComponentProps} from "../../providers";
|
16
|
+
|
17
|
+
import styles from "./toast.module.scss";
|
18
|
+
|
19
|
+
export enum ToastSide {
|
20
|
+
TopCenter = "top-center",
|
21
|
+
TopLeft = "top-left",
|
22
|
+
TopRight = "top-right",
|
23
|
+
BottomRight = "bottom-right",
|
24
|
+
BottomLeft = "bottom-left",
|
25
|
+
BottomCenter = "bottom-center",
|
26
|
+
}
|
27
|
+
|
28
|
+
export enum ToastRadius {
|
29
|
+
None = "none",
|
30
|
+
Small = "small",
|
31
|
+
Medium = "medium",
|
32
|
+
Large = "large",
|
33
|
+
}
|
34
|
+
|
35
|
+
export enum ToastColor {
|
36
|
+
Error = "error",
|
37
|
+
Success = "success",
|
38
|
+
}
|
39
|
+
|
40
|
+
const toastSideBySwipeDirectionMap = {
|
41
|
+
[ToastSide.TopLeft]: "left",
|
42
|
+
[ToastSide.TopCenter]: "up",
|
43
|
+
[ToastSide.TopRight]: "right",
|
44
|
+
[ToastSide.BottomRight]: "right",
|
45
|
+
[ToastSide.BottomCenter]: "down",
|
46
|
+
[ToastSide.BottomLeft]: "left",
|
47
|
+
} as Record<ToastSide, ToastProviderProps["swipeDirection"]>;
|
48
|
+
|
49
|
+
export interface ToastProps extends Omit<ToastRootProps, "title">, Omit<ToastProviderProps, "children"> {
|
50
|
+
side?: ToastSide;
|
51
|
+
color?: ToastColor;
|
52
|
+
radius?: ToastRadius;
|
53
|
+
title?: ReactNode;
|
54
|
+
action?: ReactNode;
|
55
|
+
description?: ReactNode;
|
56
|
+
closeIcon?: ReactElement;
|
57
|
+
closeProps?: IconButtonProps;
|
58
|
+
titleClassName?: string;
|
59
|
+
actionClassName?: string;
|
60
|
+
viewportClassName?: string;
|
61
|
+
descriptionClassName?: string;
|
62
|
+
onClose?: () => void;
|
63
|
+
fullWidth?: boolean;
|
64
|
+
sticky?: boolean;
|
65
|
+
}
|
66
|
+
|
67
|
+
const Toast: FC<ToastProps> = props => {
|
68
|
+
const defaultProps = useComponentProps("toast");
|
69
|
+
const mergedProps = {...defaultProps, ...props};
|
70
|
+
const {
|
71
|
+
side = ToastSide.BottomRight,
|
72
|
+
color,
|
73
|
+
radius,
|
74
|
+
title,
|
75
|
+
action,
|
76
|
+
description,
|
77
|
+
fullWidth,
|
78
|
+
sticky,
|
79
|
+
closeIcon = "✖",
|
80
|
+
closeProps,
|
81
|
+
|
82
|
+
label,
|
83
|
+
duration,
|
84
|
+
swipeDirection = toastSideBySwipeDirectionMap[side],
|
85
|
+
swipeThreshold = ["up", "down"].includes(swipeDirection || "") ? 15 : 50,
|
86
|
+
|
87
|
+
className,
|
88
|
+
titleClassName,
|
89
|
+
actionClassName,
|
90
|
+
viewportClassName,
|
91
|
+
descriptionClassName,
|
92
|
+
children,
|
93
|
+
onClose,
|
94
|
+
...other
|
95
|
+
} = mergedProps;
|
96
|
+
|
97
|
+
const {className: closeClassName, ...otherCloseProps} = closeProps || {};
|
98
|
+
return (
|
99
|
+
<Provider label={label} duration={duration} swipeDirection={swipeDirection} swipeThreshold={swipeThreshold}>
|
100
|
+
{children}
|
101
|
+
<Root
|
102
|
+
className={classnames(
|
103
|
+
styles["toast"],
|
104
|
+
{
|
105
|
+
[styles[`toast--${side}`]]: side,
|
106
|
+
[styles[`toast--${color}-color`]]: color,
|
107
|
+
[styles[`toast--${radius}-radius`]]: radius,
|
108
|
+
[styles["toast--sticky"]]: sticky,
|
109
|
+
[styles["toast--full-width"]]: fullWidth,
|
110
|
+
},
|
111
|
+
className
|
112
|
+
)}
|
113
|
+
{...other}
|
114
|
+
>
|
115
|
+
{title && <Title className={classnames(styles["toast__title"], titleClassName)}>{title}</Title>}
|
116
|
+
|
117
|
+
{description && (
|
118
|
+
<Description className={classnames(styles["toast__description"], descriptionClassName)}>
|
119
|
+
{description}
|
120
|
+
</Description>
|
121
|
+
)}
|
122
|
+
|
123
|
+
{cloneOrCreateElement(action, {className: classnames(styles["toast__action"], actionClassName)})}
|
124
|
+
|
125
|
+
{onClose && (
|
126
|
+
<IconButton
|
127
|
+
aria-label="Close"
|
128
|
+
onClick={onClose}
|
129
|
+
className={classnames(styles["toast__close"], closeClassName)}
|
130
|
+
{...otherCloseProps}
|
131
|
+
>
|
132
|
+
{closeIcon}
|
133
|
+
</IconButton>
|
134
|
+
)}
|
135
|
+
</Root>
|
136
|
+
|
137
|
+
<Viewport className={classnames(styles["toast__viewport"], viewportClassName)} />
|
138
|
+
</Provider>
|
139
|
+
);
|
140
|
+
};
|
141
|
+
|
142
|
+
export default memo(Toast);
|
@@ -0,0 +1,267 @@
|
|
1
|
+
@use "../../styles/mixins" as dir;
|
2
|
+
|
3
|
+
$root: toast;
|
4
|
+
|
5
|
+
.#{$root} {
|
6
|
+
box-sizing: border-box;
|
7
|
+
position: relative;
|
8
|
+
display: grid;
|
9
|
+
align-items: center;
|
10
|
+
grid-template-areas: "title action" "description action";
|
11
|
+
grid-template-columns: auto max-content;
|
12
|
+
column-gap: var(--toast-gap, 15px);
|
13
|
+
background-color: var(--toast-bg-color, var(--bg-secondary-color));
|
14
|
+
border-radius: var(--toast-border-radius, 10px);
|
15
|
+
padding: var(--toast-padding, var(--side-padding-xs));
|
16
|
+
|
17
|
+
&[data-state="open"] {
|
18
|
+
&.#{$root}--top-left,
|
19
|
+
&.#{$root}--bottom-left {
|
20
|
+
animation: slideInLeft var(--toast-transition-speed, var(--transition-speed-md)) ease-out;
|
21
|
+
}
|
22
|
+
|
23
|
+
&.#{$root}--top-right,
|
24
|
+
&.#{$root}--bottom-right {
|
25
|
+
animation: slideInRight var(--toast-transition-speed, var(--transition-speed-md)) ease-out;
|
26
|
+
}
|
27
|
+
|
28
|
+
&.#{$root}--top-center {
|
29
|
+
animation: slideInTop var(--toast-transition-speed, var(--transition-speed-md)) ease-out;
|
30
|
+
}
|
31
|
+
|
32
|
+
&.#{$root}--bottom-center {
|
33
|
+
animation: slideInBottom var(--toast-transition-speed, var(--transition-speed-md)) ease-out;
|
34
|
+
}
|
35
|
+
}
|
36
|
+
|
37
|
+
&[data-state="closed"] {
|
38
|
+
animation: hide var(--toast-transition-speed, var(--transition-speed-md)) ease-in;
|
39
|
+
}
|
40
|
+
|
41
|
+
&[data-swipe="move"] {
|
42
|
+
transform: translateX(var(--radix-toast-swipe-move-x)) translateY(var(--radix-toast-swipe-move-y));
|
43
|
+
}
|
44
|
+
|
45
|
+
&[data-swipe="cancel"] {
|
46
|
+
transform: translateX(0) translateY(0);
|
47
|
+
transition: transform var(--toast-transition-speed, var(--transition-speed-md)) ease-out;
|
48
|
+
}
|
49
|
+
|
50
|
+
&[data-swipe="end"] {
|
51
|
+
&.#{$root}--top-left,
|
52
|
+
&.#{$root}--bottom-left {
|
53
|
+
animation: swipeOutLeft var(--toast-transition-speed, var(--transition-speed-md)) ease-out;
|
54
|
+
}
|
55
|
+
&.#{$root}--top-right,
|
56
|
+
&.#{$root}--bottom-right {
|
57
|
+
animation: swipeOutRight var(--toast-transition-speed, var(--transition-speed-md)) ease-out;
|
58
|
+
}
|
59
|
+
|
60
|
+
&.#{$root}--top-center {
|
61
|
+
animation: swipeOutTop var(--toast-transition-speed, var(--transition-speed-md)) ease-out;
|
62
|
+
}
|
63
|
+
&.#{$root}--bottom-center {
|
64
|
+
animation: swipeOutBottom var(--toast-transition-speed, var(--transition-speed-md)) ease-out;
|
65
|
+
}
|
66
|
+
}
|
67
|
+
|
68
|
+
&--none-radius {
|
69
|
+
border-radius: 0;
|
70
|
+
}
|
71
|
+
&--small-radius {
|
72
|
+
border-radius: var(--toast-border-radius, 6px);
|
73
|
+
}
|
74
|
+
&--medium-radius {
|
75
|
+
border-radius: var(--toast-border-radius, 15px);
|
76
|
+
}
|
77
|
+
&--large-radius {
|
78
|
+
border-radius: var(--toast-border-radius, 20px);
|
79
|
+
}
|
80
|
+
|
81
|
+
&--error-color {
|
82
|
+
background-color: var(--toast-error-bg-color, var(--error-color));
|
83
|
+
}
|
84
|
+
|
85
|
+
&--success-color {
|
86
|
+
background-color: var(--toast-success-bg-color, var(--success-color));
|
87
|
+
}
|
88
|
+
|
89
|
+
&__title,
|
90
|
+
&__description {
|
91
|
+
.#{$root}--error-color & {
|
92
|
+
color: var(--toast-error-text-color, white);
|
93
|
+
}
|
94
|
+
.#{$root}--success-color & {
|
95
|
+
color: var(--toast-success-text-color, white);
|
96
|
+
}
|
97
|
+
}
|
98
|
+
|
99
|
+
&__title {
|
100
|
+
grid-area: title;
|
101
|
+
margin-bottom: 5px;
|
102
|
+
font-weight: 500;
|
103
|
+
color: var(--text-primary-color);
|
104
|
+
font-size: 15px;
|
105
|
+
}
|
106
|
+
|
107
|
+
&__description {
|
108
|
+
grid-area: description;
|
109
|
+
margin: 0;
|
110
|
+
color: var(--text-secondary-color);
|
111
|
+
font-size: 13px;
|
112
|
+
line-height: 1.3;
|
113
|
+
}
|
114
|
+
|
115
|
+
&__action {
|
116
|
+
grid-area: action;
|
117
|
+
}
|
118
|
+
|
119
|
+
&__close {
|
120
|
+
position: absolute !important;
|
121
|
+
top: var(--toast-close-offset, 5px);
|
122
|
+
|
123
|
+
@include dir.ltr {
|
124
|
+
right: var(--toast-close-offset, 5px);
|
125
|
+
}
|
126
|
+
|
127
|
+
@include dir.rtl {
|
128
|
+
left: var(--toast-close-offset, 5px);
|
129
|
+
}
|
130
|
+
}
|
131
|
+
|
132
|
+
&__viewport {
|
133
|
+
box-sizing: border-box;
|
134
|
+
position: fixed;
|
135
|
+
display: flex;
|
136
|
+
flex-direction: column;
|
137
|
+
gap: var(--toast-viewport-gap, 10px);
|
138
|
+
width: var(--toast-width, 300px);
|
139
|
+
padding: var(--toast-viewport-padding, var(--side-padding-xs));
|
140
|
+
max-width: 100vw;
|
141
|
+
margin: 0;
|
142
|
+
list-style: none;
|
143
|
+
z-index: 999999;
|
144
|
+
outline: none;
|
145
|
+
|
146
|
+
&:has(.#{$root}--full-width) {
|
147
|
+
width: 100%;
|
148
|
+
}
|
149
|
+
|
150
|
+
&:has(.#{$root}--sticky) {
|
151
|
+
padding: 0;
|
152
|
+
}
|
153
|
+
|
154
|
+
&:has(.#{$root}--top-center) {
|
155
|
+
top: 0;
|
156
|
+
left: 50%;
|
157
|
+
transform: translateX(-50%);
|
158
|
+
}
|
159
|
+
|
160
|
+
&:has(.#{$root}--top-left) {
|
161
|
+
top: 0;
|
162
|
+
left: 0;
|
163
|
+
}
|
164
|
+
|
165
|
+
&:has(.#{$root}--top-right) {
|
166
|
+
top: 0;
|
167
|
+
right: 0;
|
168
|
+
}
|
169
|
+
|
170
|
+
&:has(.#{$root}--bottom-right) {
|
171
|
+
bottom: 0;
|
172
|
+
right: 0;
|
173
|
+
}
|
174
|
+
|
175
|
+
&:has(.#{$root}--bottom-left) {
|
176
|
+
bottom: 0;
|
177
|
+
left: 0;
|
178
|
+
}
|
179
|
+
|
180
|
+
&:has(.#{$root}--bottom-center) {
|
181
|
+
bottom: 0;
|
182
|
+
left: 50%;
|
183
|
+
transform: translateX(-50%);
|
184
|
+
}
|
185
|
+
}
|
186
|
+
}
|
187
|
+
|
188
|
+
@keyframes hide {
|
189
|
+
from {
|
190
|
+
opacity: 1;
|
191
|
+
}
|
192
|
+
to {
|
193
|
+
opacity: 0;
|
194
|
+
}
|
195
|
+
}
|
196
|
+
|
197
|
+
@keyframes slideInRight {
|
198
|
+
from {
|
199
|
+
transform: translateX(100%);
|
200
|
+
}
|
201
|
+
to {
|
202
|
+
transform: translateX(0);
|
203
|
+
}
|
204
|
+
}
|
205
|
+
|
206
|
+
@keyframes slideInLeft {
|
207
|
+
from {
|
208
|
+
transform: translateX(-100%);
|
209
|
+
}
|
210
|
+
to {
|
211
|
+
transform: translateX(0);
|
212
|
+
}
|
213
|
+
}
|
214
|
+
|
215
|
+
@keyframes slideInTop {
|
216
|
+
from {
|
217
|
+
transform: translateY(-100%);
|
218
|
+
}
|
219
|
+
to {
|
220
|
+
transform: translateX(0);
|
221
|
+
}
|
222
|
+
}
|
223
|
+
|
224
|
+
@keyframes slideInBottom {
|
225
|
+
from {
|
226
|
+
transform: translateY(100%);
|
227
|
+
}
|
228
|
+
to {
|
229
|
+
transform: translateX(0);
|
230
|
+
}
|
231
|
+
}
|
232
|
+
|
233
|
+
@keyframes swipeOutRight {
|
234
|
+
from {
|
235
|
+
transform: translateX(var(--radix-toast-swipe-end-x));
|
236
|
+
}
|
237
|
+
to {
|
238
|
+
transform: translateX(100%);
|
239
|
+
}
|
240
|
+
}
|
241
|
+
|
242
|
+
@keyframes swipeOutLeft {
|
243
|
+
from {
|
244
|
+
transform: translateX(var(--radix-toast-swipe-end-x));
|
245
|
+
}
|
246
|
+
to {
|
247
|
+
transform: translateX(-100%);
|
248
|
+
}
|
249
|
+
}
|
250
|
+
|
251
|
+
@keyframes swipeOutTop {
|
252
|
+
from {
|
253
|
+
transform: translateY(var(--radix-toast-swipe-end-y));
|
254
|
+
}
|
255
|
+
to {
|
256
|
+
transform: translateY(-100%);
|
257
|
+
}
|
258
|
+
}
|
259
|
+
|
260
|
+
@keyframes swipeOutBottom {
|
261
|
+
from {
|
262
|
+
transform: translateY(var(--radix-toast-swipe-end-y));
|
263
|
+
}
|
264
|
+
to {
|
265
|
+
transform: translateY(100%);
|
266
|
+
}
|
267
|
+
}
|
@@ -0,0 +1,80 @@
|
|
1
|
+
import {Meta, StoryObj} from "@storybook/react";
|
2
|
+
|
3
|
+
import {hideInTable} from "../../utils";
|
4
|
+
|
5
|
+
import {Button} from "../index";
|
6
|
+
|
7
|
+
import TooltipComponent from "./Tooltip";
|
8
|
+
|
9
|
+
const meta: Meta<typeof TooltipComponent> = {
|
10
|
+
title: "Components/Tooltip",
|
11
|
+
component: TooltipComponent,
|
12
|
+
tags: ["autodocs"],
|
13
|
+
argTypes: {
|
14
|
+
open: {
|
15
|
+
options: [true, false, undefined],
|
16
|
+
control: "select",
|
17
|
+
type: "boolean",
|
18
|
+
description: "The controlled open state of the tooltip. Must be used in conjunction with onOpenChange.",
|
19
|
+
},
|
20
|
+
side: {
|
21
|
+
options: ["top", "right", "bottom", "left"],
|
22
|
+
control: "select",
|
23
|
+
description:
|
24
|
+
"The preferred side of the trigger to render against when open. Will be reversed when collisions occur and avoidCollisions is enabled.",
|
25
|
+
},
|
26
|
+
align: {
|
27
|
+
options: ["start", "center", "end"],
|
28
|
+
control: "select",
|
29
|
+
description: "The preferred alignment against the trigger. May change when collisions occur.",
|
30
|
+
},
|
31
|
+
delayDuration: {
|
32
|
+
description:
|
33
|
+
"Override the duration given to the `Provider` to customise the open delay for a specific tooltip.",
|
34
|
+
},
|
35
|
+
arrowWidth: {
|
36
|
+
description: "The width of the arrow in pixels.",
|
37
|
+
},
|
38
|
+
arrowHeight: {
|
39
|
+
description: "The height of the arrow in pixels.",
|
40
|
+
},
|
41
|
+
arrowPadding: {
|
42
|
+
description:
|
43
|
+
"The padding between the arrow and the edges of the content. If your content has border-radius, this will prevent it from overflowing the corners.",
|
44
|
+
},
|
45
|
+
alignOffset: {
|
46
|
+
description: 'An offset in pixels from the "start" or "end" alignment options.',
|
47
|
+
},
|
48
|
+
avoidCollisions: {
|
49
|
+
description:
|
50
|
+
"When true, overrides the side and align preferences to prevent collisions with boundary edges.",
|
51
|
+
},
|
52
|
+
matchTriggerWidth: {
|
53
|
+
description: "Whether to set the content width equal to the trigger width",
|
54
|
+
},
|
55
|
+
|
56
|
+
arrowClassName: hideInTable,
|
57
|
+
contentClassName: hideInTable,
|
58
|
+
children: hideInTable,
|
59
|
+
},
|
60
|
+
};
|
61
|
+
|
62
|
+
export default meta;
|
63
|
+
|
64
|
+
export const Tooltip: StoryObj<typeof TooltipComponent> = {
|
65
|
+
args: {
|
66
|
+
content: "Tooltip content",
|
67
|
+
open: undefined,
|
68
|
+
align: "center",
|
69
|
+
alignOffset: 0,
|
70
|
+
side: "top",
|
71
|
+
sideOffset: 0,
|
72
|
+
arrowHeight: 5,
|
73
|
+
arrowWidth: 10,
|
74
|
+
arrowPadding: 0,
|
75
|
+
delayDuration: 700,
|
76
|
+
matchTriggerWidth: false,
|
77
|
+
avoidCollisions: true,
|
78
|
+
children: <Button style={{marginTop: "40px"}}>Button</Button>,
|
79
|
+
},
|
80
|
+
};
|