@caseparts-org/caseblocks 0.0.90 → 0.0.92
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/dist/Cart.module-9txlotpz.js +18 -0
- package/dist/assets/Cart.css +1 -1
- package/dist/assets/Icon.css +1 -1
- package/dist/assets/Popover.css +1 -0
- package/dist/assets/SlideInPanel.css +1 -0
- package/dist/assets/Tooltip.css +1 -1
- package/dist/assets/buttonClassName.css +1 -1
- package/dist/atoms/Button/buttonClassName.js +25 -25
- package/dist/atoms/Icon/Icon.d.ts +3 -1
- package/dist/atoms/Icon/Icon.js +48 -32
- package/dist/atoms/Input/Input.js +4 -4
- package/dist/atoms/Popover/Popover.d.ts +14 -0
- package/dist/atoms/Popover/Popover.js +110 -0
- package/dist/atoms/Popover/Popover.stories.d.ts +66 -0
- package/dist/atoms/Popover/Popover.stories.js +207 -0
- package/dist/atoms/SlideInPanel/SlideInPanel.d.ts +18 -0
- package/dist/atoms/SlideInPanel/SlideInPanel.js +99 -0
- package/dist/atoms/SlideInPanel/SlideInPanel.stories.d.ts +10 -0
- package/dist/atoms/SlideInPanel/SlideInPanel.stories.js +117 -0
- package/dist/atoms/Tooltip/Tooltip.d.ts +16 -0
- package/dist/atoms/Tooltip/Tooltip.js +137 -0
- package/dist/{molecules → atoms}/Tooltip/Tooltip.stories.d.ts +8 -26
- package/dist/atoms/Tooltip/Tooltip.stories.js +209 -0
- package/dist/index-B4KbmMH3.js +383 -0
- package/dist/main-client.d.ts +5 -1
- package/dist/main-client.js +49 -45
- package/dist/molecules/AddToCart/AddToCart.js +18 -18
- package/dist/molecules/Cart/Cart.d.ts +10 -11
- package/dist/molecules/Cart/Cart.js +42 -93
- package/dist/molecules/Cart/Cart.stories.js +63 -45
- package/dist/molecules/Cart/CartSlideInPanel.d.ts +15 -0
- package/dist/molecules/Cart/CartSlideInPanel.js +97 -0
- package/dist/molecules/CategoryNav/CategoryNav.js +2 -2
- package/dist/molecules/StatefulButton/StatefulButton.stories.js +4 -4
- package/dist/molecules/ToggleView/ToggleView.js +6 -6
- package/dist/organisms/Carousel/Carousel.js +44 -44
- package/dist/organisms/Footer/Footer.js +1 -1
- package/dist/organisms/MainNav/MainNav.d.ts +13 -15
- package/dist/organisms/MainNav/MainNav.js +78 -84
- package/dist/organisms/MainNav/MainNav.stories.d.ts +1 -2
- package/dist/organisms/MainNav/MainNav.stories.js +94 -77
- package/package.json +28 -7
- package/dist/molecules/Cart/Cart.stories.d.ts +0 -15
- package/dist/molecules/Tooltip/Tooltip.d.ts +0 -12
- package/dist/molecules/Tooltip/Tooltip.js +0 -2321
- package/dist/molecules/Tooltip/Tooltip.stories.js +0 -202
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
import { jsxs as t, jsx as e, Fragment as n } from "react/jsx-runtime";
|
|
2
|
+
import a from "react";
|
|
3
|
+
import { Popover as i } from "./Popover.js";
|
|
4
|
+
import { Button as o } from "../Button/Button.js";
|
|
5
|
+
const k = {
|
|
6
|
+
title: "Case Parts/Atoms/Popover",
|
|
7
|
+
component: i,
|
|
8
|
+
parameters: {
|
|
9
|
+
layout: "centered",
|
|
10
|
+
controls: { sort: "requiredFirst" },
|
|
11
|
+
docs: {
|
|
12
|
+
description: {
|
|
13
|
+
component: "Interactive popover opened by clicking its trigger. Closes on outside click or Escape. Position accepts side plus optional alignment."
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
tags: ["autodocs"],
|
|
18
|
+
args: {
|
|
19
|
+
position: "top center",
|
|
20
|
+
closeOnOutsideClick: !0,
|
|
21
|
+
disabled: !1
|
|
22
|
+
},
|
|
23
|
+
argTypes: {
|
|
24
|
+
position: {
|
|
25
|
+
control: "select",
|
|
26
|
+
options: [
|
|
27
|
+
"top",
|
|
28
|
+
"top left",
|
|
29
|
+
"top center",
|
|
30
|
+
"top right",
|
|
31
|
+
"right",
|
|
32
|
+
"right top",
|
|
33
|
+
"right center",
|
|
34
|
+
"right bottom",
|
|
35
|
+
"bottom",
|
|
36
|
+
"bottom left",
|
|
37
|
+
"bottom center",
|
|
38
|
+
"bottom right",
|
|
39
|
+
"left",
|
|
40
|
+
"left top",
|
|
41
|
+
"left center",
|
|
42
|
+
"left bottom"
|
|
43
|
+
],
|
|
44
|
+
description: "Side plus optional alignment; single side centers automatically."
|
|
45
|
+
},
|
|
46
|
+
closeOnOutsideClick: {
|
|
47
|
+
control: "boolean",
|
|
48
|
+
description: "Close when clicking outside the popover."
|
|
49
|
+
},
|
|
50
|
+
disabled: {
|
|
51
|
+
control: "boolean",
|
|
52
|
+
description: "Disable opening."
|
|
53
|
+
},
|
|
54
|
+
popoverClassName: { table: { disable: !0 } },
|
|
55
|
+
contentClassName: { table: { disable: !0 } },
|
|
56
|
+
trigger: { table: { disable: !0 }, description: "Trigger element (click opens)." },
|
|
57
|
+
children: { description: "Popover content (interactive)." }
|
|
58
|
+
}
|
|
59
|
+
}, r = () => /* @__PURE__ */ e("style", { children: ".storyRoboto{font-family:'Roboto',sans-serif;}" }), R = {
|
|
60
|
+
render: (c) => /* @__PURE__ */ t(n, { children: [
|
|
61
|
+
/* @__PURE__ */ e(r, {}),
|
|
62
|
+
/* @__PURE__ */ e(
|
|
63
|
+
i,
|
|
64
|
+
{
|
|
65
|
+
...c,
|
|
66
|
+
contentClassName: "storyRoboto",
|
|
67
|
+
trigger: /* @__PURE__ */ e(o, { size: "md", variant: "primary", children: "Open form" }),
|
|
68
|
+
children: /* @__PURE__ */ e(() => {
|
|
69
|
+
const [s, m] = a.useState(""), [p, h] = a.useState(""), [g, u] = a.useState(!1);
|
|
70
|
+
return /* @__PURE__ */ t(
|
|
71
|
+
"form",
|
|
72
|
+
{
|
|
73
|
+
onSubmit: (l) => {
|
|
74
|
+
l.preventDefault(), u(!0);
|
|
75
|
+
},
|
|
76
|
+
style: { display: "flex", flexDirection: "column", gap: 8, minWidth: 220 },
|
|
77
|
+
children: [
|
|
78
|
+
/* @__PURE__ */ t("label", { style: { display: "flex", flexDirection: "column", gap: 4 }, children: [
|
|
79
|
+
/* @__PURE__ */ e("span", { children: "Name" }),
|
|
80
|
+
/* @__PURE__ */ e(
|
|
81
|
+
"input",
|
|
82
|
+
{
|
|
83
|
+
value: s,
|
|
84
|
+
onChange: (l) => m(l.target.value),
|
|
85
|
+
placeholder: "Jane Doe",
|
|
86
|
+
style: { padding: 4 }
|
|
87
|
+
}
|
|
88
|
+
)
|
|
89
|
+
] }),
|
|
90
|
+
/* @__PURE__ */ t("label", { style: { display: "flex", flexDirection: "column", gap: 4 }, children: [
|
|
91
|
+
/* @__PURE__ */ e("span", { children: "Email" }),
|
|
92
|
+
/* @__PURE__ */ e(
|
|
93
|
+
"input",
|
|
94
|
+
{
|
|
95
|
+
type: "email",
|
|
96
|
+
value: p,
|
|
97
|
+
onChange: (l) => h(l.target.value),
|
|
98
|
+
placeholder: "jane@example.com",
|
|
99
|
+
style: { padding: 4 }
|
|
100
|
+
}
|
|
101
|
+
)
|
|
102
|
+
] }),
|
|
103
|
+
/* @__PURE__ */ e("button", { type: "submit", style: { padding: "4px 8px" }, children: "Submit" }),
|
|
104
|
+
g && /* @__PURE__ */ t("div", { style: { fontSize: 12, color: "var(--color-neutrals-neutral-6)" }, children: [
|
|
105
|
+
"Submitted: ",
|
|
106
|
+
s || "(no name)",
|
|
107
|
+
", ",
|
|
108
|
+
p || "(no email)"
|
|
109
|
+
] })
|
|
110
|
+
]
|
|
111
|
+
}
|
|
112
|
+
);
|
|
113
|
+
}, {})
|
|
114
|
+
}
|
|
115
|
+
)
|
|
116
|
+
] })
|
|
117
|
+
}, N = {
|
|
118
|
+
render: () => /* @__PURE__ */ t(n, { children: [
|
|
119
|
+
/* @__PURE__ */ e(r, {}),
|
|
120
|
+
/* @__PURE__ */ e(
|
|
121
|
+
i,
|
|
122
|
+
{
|
|
123
|
+
position: "bottom center",
|
|
124
|
+
contentClassName: "storyRoboto",
|
|
125
|
+
trigger: /* @__PURE__ */ e(o, { size: "md", variant: "secondary", children: "Bottom" }),
|
|
126
|
+
children: "Positioned below the trigger."
|
|
127
|
+
}
|
|
128
|
+
)
|
|
129
|
+
] })
|
|
130
|
+
}, S = {
|
|
131
|
+
render: () => /* @__PURE__ */ t(n, { children: [
|
|
132
|
+
/* @__PURE__ */ e(r, {}),
|
|
133
|
+
/* @__PURE__ */ e(
|
|
134
|
+
i,
|
|
135
|
+
{
|
|
136
|
+
position: "right center",
|
|
137
|
+
contentClassName: "storyRoboto",
|
|
138
|
+
trigger: /* @__PURE__ */ e(o, { size: "md", variant: "cta-primary", children: "Right" }),
|
|
139
|
+
children: "Popover to the right."
|
|
140
|
+
}
|
|
141
|
+
)
|
|
142
|
+
] })
|
|
143
|
+
}, P = {
|
|
144
|
+
render: () => /* @__PURE__ */ t(n, { children: [
|
|
145
|
+
/* @__PURE__ */ e(r, {}),
|
|
146
|
+
/* @__PURE__ */ e(
|
|
147
|
+
i,
|
|
148
|
+
{
|
|
149
|
+
position: "left center",
|
|
150
|
+
contentClassName: "storyRoboto",
|
|
151
|
+
trigger: /* @__PURE__ */ e(o, { size: "md", variant: "tertiary", children: "Left" }),
|
|
152
|
+
children: "Popover to the left."
|
|
153
|
+
}
|
|
154
|
+
)
|
|
155
|
+
] })
|
|
156
|
+
}, O = {
|
|
157
|
+
render: () => /* @__PURE__ */ e(y, {})
|
|
158
|
+
}, y = () => {
|
|
159
|
+
const [c, d] = a.useState(0);
|
|
160
|
+
return /* @__PURE__ */ t(n, { children: [
|
|
161
|
+
/* @__PURE__ */ e(r, {}),
|
|
162
|
+
/* @__PURE__ */ e(
|
|
163
|
+
i,
|
|
164
|
+
{
|
|
165
|
+
position: "bottom left",
|
|
166
|
+
contentClassName: "storyRoboto",
|
|
167
|
+
trigger: /* @__PURE__ */ e(o, { size: "md", variant: "primary", children: "More interactivity" }),
|
|
168
|
+
children: /* @__PURE__ */ t("div", { style: { display: "flex", flexDirection: "column", gap: 10, minWidth: 240 }, children: [
|
|
169
|
+
/* @__PURE__ */ e("div", { style: { fontWeight: 500 }, children: "Counter demo" }),
|
|
170
|
+
/* @__PURE__ */ t("div", { style: { display: "flex", gap: 8, alignItems: "center" }, children: [
|
|
171
|
+
/* @__PURE__ */ e(o, { size: "sm", variant: "secondary", onClick: () => d((s) => s + 1), children: "Increment" }),
|
|
172
|
+
/* @__PURE__ */ e("span", { style: { minWidth: 32, textAlign: "center" }, children: c }),
|
|
173
|
+
/* @__PURE__ */ e(o, { size: "sm", variant: "tertiary", onClick: () => d(0), children: "Reset" })
|
|
174
|
+
] }),
|
|
175
|
+
/* @__PURE__ */ e("hr", { style: { border: 0, height: 1, background: "#ddd" } }),
|
|
176
|
+
/* @__PURE__ */ t("label", { style: { display: "flex", flexDirection: "column", gap: 4 }, children: [
|
|
177
|
+
/* @__PURE__ */ e("span", { children: "Notes" }),
|
|
178
|
+
/* @__PURE__ */ e("textarea", { rows: 3, placeholder: "Type notes...", style: { padding: 4 } })
|
|
179
|
+
] })
|
|
180
|
+
] })
|
|
181
|
+
}
|
|
182
|
+
)
|
|
183
|
+
] });
|
|
184
|
+
}, z = {
|
|
185
|
+
render: () => /* @__PURE__ */ t(n, { children: [
|
|
186
|
+
/* @__PURE__ */ e(r, {}),
|
|
187
|
+
/* @__PURE__ */ e(
|
|
188
|
+
i,
|
|
189
|
+
{
|
|
190
|
+
position: "top center",
|
|
191
|
+
closeOnOutsideClick: !1,
|
|
192
|
+
contentClassName: "storyRoboto",
|
|
193
|
+
trigger: /* @__PURE__ */ e(o, { size: "md", variant: "destructive", children: "Manual close" }),
|
|
194
|
+
children: "Outside clicks will NOT close me. Press Escape."
|
|
195
|
+
}
|
|
196
|
+
)
|
|
197
|
+
] })
|
|
198
|
+
};
|
|
199
|
+
export {
|
|
200
|
+
R as BasicClick,
|
|
201
|
+
N as BottomClick,
|
|
202
|
+
O as InteractiveContent,
|
|
203
|
+
z as OutsideClickDisabled,
|
|
204
|
+
P as PositionLeft,
|
|
205
|
+
S as PositionRight,
|
|
206
|
+
k as default
|
|
207
|
+
};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { HideAtProps } from '../HideAt';
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
export type SlideInSide = "left" | "right" | "bottom";
|
|
4
|
+
export interface SlideInPanelProps extends HideAtProps {
|
|
5
|
+
side: SlideInSide;
|
|
6
|
+
open: boolean;
|
|
7
|
+
onClose: () => void;
|
|
8
|
+
children: React.ReactNode;
|
|
9
|
+
width?: number | string;
|
|
10
|
+
height?: number | string;
|
|
11
|
+
className?: string;
|
|
12
|
+
overlayClassName?: string;
|
|
13
|
+
panelClassName?: string;
|
|
14
|
+
closeOnOverlayClick?: boolean;
|
|
15
|
+
disableEsc?: boolean;
|
|
16
|
+
ariaLabel?: string;
|
|
17
|
+
}
|
|
18
|
+
export declare const SlideInPanel: React.FC<SlideInPanelProps>;
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { jsxs as k, jsx as u } from "react/jsx-runtime";
|
|
2
|
+
import * as r from "react";
|
|
3
|
+
import { r as A } from "../../index-B4KbmMH3.js";
|
|
4
|
+
import { c } from "../../clsx-OuTLNxxd.js";
|
|
5
|
+
import { getHideAtStyles as N } from "../HideAt.js";
|
|
6
|
+
import '../../assets/SlideInPanel.css';const q = "_root_12lt6_1", P = "_overlay_12lt6_8", R = "_panel_12lt6_16", j = "_active_12lt6_52", o = {
|
|
7
|
+
root: q,
|
|
8
|
+
overlay: P,
|
|
9
|
+
panel: R,
|
|
10
|
+
"panel-left": "_panel-left_12lt6_29",
|
|
11
|
+
"panel-right": "_panel-right_12lt6_36",
|
|
12
|
+
"panel-bottom": "_panel-bottom_12lt6_43",
|
|
13
|
+
active: j,
|
|
14
|
+
"from-left": "_from-left_12lt6_52",
|
|
15
|
+
"from-right": "_from-right_12lt6_53",
|
|
16
|
+
"from-bottom": "_from-bottom_12lt6_54"
|
|
17
|
+
}, D = ({
|
|
18
|
+
side: a,
|
|
19
|
+
open: t,
|
|
20
|
+
onClose: l,
|
|
21
|
+
children: d,
|
|
22
|
+
width: v = 375,
|
|
23
|
+
height: p = "50%",
|
|
24
|
+
className: y,
|
|
25
|
+
overlayClassName: b,
|
|
26
|
+
panelClassName: h,
|
|
27
|
+
closeOnOverlayClick: x = !0,
|
|
28
|
+
disableEsc: m = !1,
|
|
29
|
+
hideAt: E,
|
|
30
|
+
ariaLabel: g = "Panel"
|
|
31
|
+
}) => {
|
|
32
|
+
const [n, _] = r.useState(t), [s, i] = r.useState(!1);
|
|
33
|
+
r.useEffect(() => {
|
|
34
|
+
t ? (n || _(!0), i(!1), requestAnimationFrame(() => {
|
|
35
|
+
requestAnimationFrame(() => i(!0));
|
|
36
|
+
})) : i(!1);
|
|
37
|
+
}, [t, n]), r.useEffect(() => {
|
|
38
|
+
if (!t || m) return;
|
|
39
|
+
const e = (S) => {
|
|
40
|
+
S.key === "Escape" && l();
|
|
41
|
+
};
|
|
42
|
+
return window.addEventListener("keydown", e), () => window.removeEventListener("keydown", e);
|
|
43
|
+
}, [t, m, l]);
|
|
44
|
+
const f = r.useRef(null);
|
|
45
|
+
if (r.useEffect(() => {
|
|
46
|
+
if (t && s && f.current) {
|
|
47
|
+
const e = f.current.querySelector(
|
|
48
|
+
'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])'
|
|
49
|
+
);
|
|
50
|
+
e == null || e.focus();
|
|
51
|
+
}
|
|
52
|
+
}, [t, s]), !n || typeof document > "u") return null;
|
|
53
|
+
const w = a === "bottom" ? { height: p } : { width: v };
|
|
54
|
+
return A.createPortal(
|
|
55
|
+
/* @__PURE__ */ k(
|
|
56
|
+
"div",
|
|
57
|
+
{
|
|
58
|
+
className: c(
|
|
59
|
+
o.root,
|
|
60
|
+
o[`from-${a}`],
|
|
61
|
+
s && o.active,
|
|
62
|
+
N(E),
|
|
63
|
+
y
|
|
64
|
+
),
|
|
65
|
+
"aria-hidden": !t,
|
|
66
|
+
children: [
|
|
67
|
+
/* @__PURE__ */ u(
|
|
68
|
+
"div",
|
|
69
|
+
{
|
|
70
|
+
className: c(o.overlay, b),
|
|
71
|
+
onClick: () => {
|
|
72
|
+
t && x && l();
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
),
|
|
76
|
+
/* @__PURE__ */ u(
|
|
77
|
+
"div",
|
|
78
|
+
{
|
|
79
|
+
ref: f,
|
|
80
|
+
role: "dialog",
|
|
81
|
+
"aria-modal": "true",
|
|
82
|
+
"aria-label": g,
|
|
83
|
+
className: c(o.panel, o[`panel-${a}`], h),
|
|
84
|
+
style: w,
|
|
85
|
+
onTransitionEnd: (e) => {
|
|
86
|
+
e.propertyName === "transform" && !t && _(!1);
|
|
87
|
+
},
|
|
88
|
+
children: d
|
|
89
|
+
}
|
|
90
|
+
)
|
|
91
|
+
]
|
|
92
|
+
}
|
|
93
|
+
),
|
|
94
|
+
document.body
|
|
95
|
+
);
|
|
96
|
+
};
|
|
97
|
+
export {
|
|
98
|
+
D as SlideInPanel
|
|
99
|
+
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Meta, StoryObj } from '@storybook/react-vite';
|
|
2
|
+
import { SlideInPanel } from './SlideInPanel';
|
|
3
|
+
declare const meta: Meta<typeof SlideInPanel>;
|
|
4
|
+
export default meta;
|
|
5
|
+
type Story = StoryObj<typeof SlideInPanel>;
|
|
6
|
+
export declare const RightPanel: Story;
|
|
7
|
+
export declare const LeftPanel: Story;
|
|
8
|
+
export declare const BottomPanel: Story;
|
|
9
|
+
export declare const CustomSize: Story;
|
|
10
|
+
export declare const OverlayClickDisabled: Story;
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import { jsx as t, jsxs as i, Fragment as h } from "react/jsx-runtime";
|
|
2
|
+
import * as a from "react";
|
|
3
|
+
import { SlideInPanel as c } from "./SlideInPanel.js";
|
|
4
|
+
import { Button as l } from "../Button/Button.js";
|
|
5
|
+
const y = {
|
|
6
|
+
title: "Case Parts/Atoms/SlideInPanel",
|
|
7
|
+
component: c,
|
|
8
|
+
parameters: {
|
|
9
|
+
layout: "centered",
|
|
10
|
+
controls: { sort: "requiredFirst" }
|
|
11
|
+
},
|
|
12
|
+
tags: ["autodocs"],
|
|
13
|
+
args: {
|
|
14
|
+
side: "right",
|
|
15
|
+
open: !1,
|
|
16
|
+
width: 360,
|
|
17
|
+
height: "50%",
|
|
18
|
+
closeOnOverlayClick: !0,
|
|
19
|
+
disableEsc: !1,
|
|
20
|
+
ariaLabel: "Panel"
|
|
21
|
+
},
|
|
22
|
+
argTypes: {
|
|
23
|
+
side: {
|
|
24
|
+
control: "select",
|
|
25
|
+
options: ["left", "right", "bottom"],
|
|
26
|
+
description: "Edge the panel slides in from."
|
|
27
|
+
},
|
|
28
|
+
open: {
|
|
29
|
+
control: "boolean",
|
|
30
|
+
description: "Panel visibility (storybook control)."
|
|
31
|
+
},
|
|
32
|
+
width: {
|
|
33
|
+
control: "text",
|
|
34
|
+
description: "Panel width (left/right). Number or CSS width."
|
|
35
|
+
},
|
|
36
|
+
height: {
|
|
37
|
+
control: "text",
|
|
38
|
+
description: "Panel height (bottom). Number or CSS height."
|
|
39
|
+
},
|
|
40
|
+
closeOnOverlayClick: {
|
|
41
|
+
control: "boolean",
|
|
42
|
+
description: "Close when clicking the dark overlay."
|
|
43
|
+
},
|
|
44
|
+
disableEsc: {
|
|
45
|
+
control: "boolean",
|
|
46
|
+
description: "Disable Escape key closing."
|
|
47
|
+
},
|
|
48
|
+
ariaLabel: {
|
|
49
|
+
control: "text",
|
|
50
|
+
description: "Accessible label for dialog."
|
|
51
|
+
},
|
|
52
|
+
hideAt: { table: { disable: !0 } },
|
|
53
|
+
// internal responsive prop
|
|
54
|
+
onClose: { table: { disable: !0 } },
|
|
55
|
+
// implemented internally
|
|
56
|
+
children: { description: "Panel content." }
|
|
57
|
+
}
|
|
58
|
+
}, m = () => /* @__PURE__ */ t("style", { children: ".storyRoboto{font-family:'Roboto',sans-serif;}" });
|
|
59
|
+
function o(e) {
|
|
60
|
+
const [r, n] = a.useState(e.open);
|
|
61
|
+
a.useEffect(() => n(e.open), [e.open]);
|
|
62
|
+
const s = () => n(!1);
|
|
63
|
+
return /* @__PURE__ */ i(h, { children: [
|
|
64
|
+
/* @__PURE__ */ t(m, {}),
|
|
65
|
+
/* @__PURE__ */ t(l, { size: "md", variant: "primary", onClick: () => n((d) => !d), children: r ? "Hide Panel" : "Show Panel" }),
|
|
66
|
+
/* @__PURE__ */ t(
|
|
67
|
+
c,
|
|
68
|
+
{
|
|
69
|
+
...e,
|
|
70
|
+
open: r,
|
|
71
|
+
onClose: s,
|
|
72
|
+
panelClassName: "storyRoboto",
|
|
73
|
+
children: /* @__PURE__ */ i("div", { style: { padding: 16 }, children: [
|
|
74
|
+
/* @__PURE__ */ t("h3", { style: { margin: "0 0 12px" }, children: "SlideInPanel" }),
|
|
75
|
+
/* @__PURE__ */ i("p", { style: { margin: 0, fontSize: 14 }, children: [
|
|
76
|
+
"This panel slides from the ",
|
|
77
|
+
/* @__PURE__ */ t("strong", { children: e.side }),
|
|
78
|
+
". Resize it with width/height args. Press Escape or click overlay (if enabled) to close."
|
|
79
|
+
] }),
|
|
80
|
+
/* @__PURE__ */ i("div", { style: { marginTop: 16, display: "flex", gap: 8 }, children: [
|
|
81
|
+
/* @__PURE__ */ t(l, { size: "sm", variant: "secondary", onClick: s, children: "Close" }),
|
|
82
|
+
/* @__PURE__ */ t(l, { size: "sm", variant: "tertiary", onClick: () => alert("Action"), children: "Action" })
|
|
83
|
+
] })
|
|
84
|
+
] })
|
|
85
|
+
}
|
|
86
|
+
)
|
|
87
|
+
] });
|
|
88
|
+
}
|
|
89
|
+
const C = {
|
|
90
|
+
name: "Right",
|
|
91
|
+
render: (e) => /* @__PURE__ */ t(o, { ...e }),
|
|
92
|
+
args: { side: "right", width: 360 }
|
|
93
|
+
}, u = {
|
|
94
|
+
name: "Left",
|
|
95
|
+
render: (e) => /* @__PURE__ */ t(o, { ...e }),
|
|
96
|
+
args: { side: "left", width: 320 }
|
|
97
|
+
}, P = {
|
|
98
|
+
name: "Bottom",
|
|
99
|
+
render: (e) => /* @__PURE__ */ t(o, { ...e }),
|
|
100
|
+
args: { side: "bottom", height: "40%" }
|
|
101
|
+
}, k = {
|
|
102
|
+
name: "Custom Size",
|
|
103
|
+
render: (e) => /* @__PURE__ */ t(o, { ...e }),
|
|
104
|
+
args: { side: "right", width: "480px" }
|
|
105
|
+
}, v = {
|
|
106
|
+
name: "Overlay Click Disabled",
|
|
107
|
+
render: (e) => /* @__PURE__ */ t(o, { ...e }),
|
|
108
|
+
args: { side: "right", closeOnOverlayClick: !1 }
|
|
109
|
+
};
|
|
110
|
+
export {
|
|
111
|
+
P as BottomPanel,
|
|
112
|
+
k as CustomSize,
|
|
113
|
+
u as LeftPanel,
|
|
114
|
+
v as OverlayClickDisabled,
|
|
115
|
+
C as RightPanel,
|
|
116
|
+
y as default
|
|
117
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
type PositionKeyword = "top" | "right" | "bottom" | "left";
|
|
3
|
+
type Position = "top left" | "top center" | "top right" | "right top" | "right center" | "right bottom" | "bottom left" | "bottom center" | "bottom right" | "left top" | "left center" | "left bottom" | PositionKeyword;
|
|
4
|
+
export type TooltipProps = {
|
|
5
|
+
children: React.ReactNode;
|
|
6
|
+
trigger: React.ReactElement;
|
|
7
|
+
tooltipClassName?: string;
|
|
8
|
+
contentClassName?: string;
|
|
9
|
+
position?: Position;
|
|
10
|
+
openDelay?: number;
|
|
11
|
+
closeDelay?: number;
|
|
12
|
+
disabled?: boolean;
|
|
13
|
+
leaveGraceMs?: number;
|
|
14
|
+
};
|
|
15
|
+
export declare const Tooltip: React.FC<TooltipProps>;
|
|
16
|
+
export {};
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import { jsxs as N, Fragment as O, jsx as M } from "react/jsx-runtime";
|
|
2
|
+
import * as i from "react";
|
|
3
|
+
import { c as S } from "../../clsx-OuTLNxxd.js";
|
|
4
|
+
import { r as W } from "../../index-B4KbmMH3.js";
|
|
5
|
+
import '../../assets/Tooltip.css';const A = "_tooltip_17o7a_1", D = "_content_17o7a_11", j = {
|
|
6
|
+
tooltip: A,
|
|
7
|
+
content: D
|
|
8
|
+
};
|
|
9
|
+
function I(l) {
|
|
10
|
+
return l ? l.includes(" ") ? l : `${l} center` : "top center";
|
|
11
|
+
}
|
|
12
|
+
function $(l) {
|
|
13
|
+
const v = I(l).toLowerCase(), [s, t] = v.split(" ");
|
|
14
|
+
return { side: ["top", "right", "bottom", "left"].includes(s) ? s : "top", align: t === "left" || t === "top" ? "start" : t === "right" || t === "bottom" ? "end" : "center" };
|
|
15
|
+
}
|
|
16
|
+
function q(l, v, s, t, d = 8) {
|
|
17
|
+
const n = l.getBoundingClientRect(), u = v.getBoundingClientRect();
|
|
18
|
+
let f = 0, c = 0;
|
|
19
|
+
s === "top" ? f = n.top - u.height - d : s === "bottom" ? f = n.bottom + d : s === "left" ? c = n.left - u.width - d : s === "right" && (c = n.right + d), s === "top" || s === "bottom" ? t === "start" ? c = n.left : t === "end" ? c = n.right - u.width : c = n.left + n.width / 2 - u.width / 2 : t === "start" ? f = n.top : t === "end" ? f = n.bottom - u.height : f = n.top + n.height / 2 - u.height / 2;
|
|
20
|
+
const E = window.innerWidth, R = window.innerHeight;
|
|
21
|
+
return f = Math.max(4, Math.min(R - u.height - 4, f)), c = Math.max(4, Math.min(E - u.width - 4, c)), { top: f, left: c };
|
|
22
|
+
}
|
|
23
|
+
const Q = ({
|
|
24
|
+
tooltipClassName: l,
|
|
25
|
+
contentClassName: v,
|
|
26
|
+
children: s,
|
|
27
|
+
trigger: t,
|
|
28
|
+
position: d,
|
|
29
|
+
disabled: n,
|
|
30
|
+
openDelay: u = 150,
|
|
31
|
+
closeDelay: f = 100,
|
|
32
|
+
leaveGraceMs: c = 0
|
|
33
|
+
}) => {
|
|
34
|
+
const { side: E, align: R } = $(d), [o, y] = i.useState(!1), [m, C] = i.useState(null), T = i.useRef(null), g = i.useRef(null), x = i.useRef(null), L = i.useRef(null), P = i.useRef(null), w = i.useRef(!1), a = (e) => {
|
|
35
|
+
e.current && (window.clearTimeout(e.current), e.current = null);
|
|
36
|
+
}, B = () => {
|
|
37
|
+
a(x), a(L), a(P);
|
|
38
|
+
};
|
|
39
|
+
i.useEffect(() => () => B(), []);
|
|
40
|
+
const k = () => {
|
|
41
|
+
n || o || (a(x), x.current = window.setTimeout(() => y(!0), u));
|
|
42
|
+
}, _ = () => {
|
|
43
|
+
o && (a(L), L.current = window.setTimeout(() => {
|
|
44
|
+
w.current || y(!1);
|
|
45
|
+
}, f));
|
|
46
|
+
}, z = () => {
|
|
47
|
+
if (o) {
|
|
48
|
+
if (a(P), c <= 0) {
|
|
49
|
+
_();
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
P.current = window.setTimeout(() => {
|
|
53
|
+
w.current || _();
|
|
54
|
+
}, c);
|
|
55
|
+
}
|
|
56
|
+
}, b = (e, r) => (h) => {
|
|
57
|
+
e == null || e(h), r == null || r(h);
|
|
58
|
+
}, H = i.cloneElement(t, {
|
|
59
|
+
ref: (e) => {
|
|
60
|
+
const { ref: r } = t;
|
|
61
|
+
typeof r == "function" ? r(e) : r && (r.current = e), T.current = e;
|
|
62
|
+
},
|
|
63
|
+
onPointerEnter: b(t.props.onPointerEnter, k),
|
|
64
|
+
onPointerLeave: b(t.props.onPointerLeave, z),
|
|
65
|
+
onFocus: b(t.props.onFocus, k),
|
|
66
|
+
onBlur: b(t.props.onBlur, _),
|
|
67
|
+
"aria-describedby": o ? "tooltip-popup" : void 0,
|
|
68
|
+
style: { ...t.props.style || {}, outline: "none" }
|
|
69
|
+
});
|
|
70
|
+
return i.useEffect(() => {
|
|
71
|
+
n && o && (B(), y(!1));
|
|
72
|
+
}, [n]), i.useEffect(() => {
|
|
73
|
+
if (!o) return;
|
|
74
|
+
const e = (r) => {
|
|
75
|
+
r.key === "Escape" && y(!1);
|
|
76
|
+
};
|
|
77
|
+
return window.addEventListener("keydown", e), () => window.removeEventListener("keydown", e);
|
|
78
|
+
}, [o]), i.useLayoutEffect(() => {
|
|
79
|
+
if (!o) {
|
|
80
|
+
C(null);
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
const e = T.current, r = g.current;
|
|
84
|
+
if (!e || !r) return;
|
|
85
|
+
const h = 8, p = () => {
|
|
86
|
+
C(q(e, r, E, R, h));
|
|
87
|
+
};
|
|
88
|
+
return p(), window.addEventListener("resize", p), window.addEventListener("scroll", p, !0), () => {
|
|
89
|
+
window.removeEventListener("resize", p), window.removeEventListener("scroll", p, !0);
|
|
90
|
+
};
|
|
91
|
+
}, [o, E, R, s]), i.useEffect(() => {
|
|
92
|
+
if (!o) return;
|
|
93
|
+
const e = (r) => {
|
|
94
|
+
const h = T.current, p = g.current;
|
|
95
|
+
if (!h || !p) return;
|
|
96
|
+
const F = r.target;
|
|
97
|
+
!h.contains(F) && !p.contains(F) && (w.current = !1, z());
|
|
98
|
+
};
|
|
99
|
+
return document.addEventListener("pointermove", e), () => document.removeEventListener("pointermove", e);
|
|
100
|
+
}, [o]), i.useEffect(() => {
|
|
101
|
+
o || (w.current = !1);
|
|
102
|
+
}, [o]), /* @__PURE__ */ N(O, { children: [
|
|
103
|
+
H,
|
|
104
|
+
o && typeof document < "u" && W.createPortal(
|
|
105
|
+
/* @__PURE__ */ M(
|
|
106
|
+
"div",
|
|
107
|
+
{
|
|
108
|
+
id: "tooltip-popup",
|
|
109
|
+
ref: g,
|
|
110
|
+
role: "tooltip",
|
|
111
|
+
"aria-hidden": !o,
|
|
112
|
+
"data-side": E,
|
|
113
|
+
"data-align": R,
|
|
114
|
+
className: S(j.tooltip, l),
|
|
115
|
+
style: {
|
|
116
|
+
position: "absolute",
|
|
117
|
+
top: (m == null ? void 0 : m.top) ?? 0,
|
|
118
|
+
left: (m == null ? void 0 : m.left) ?? 0,
|
|
119
|
+
visibility: m ? "visible" : "hidden",
|
|
120
|
+
zIndex: 10
|
|
121
|
+
},
|
|
122
|
+
onPointerEnter: () => {
|
|
123
|
+
w.current = !0, a(L), a(P);
|
|
124
|
+
},
|
|
125
|
+
onPointerLeave: () => {
|
|
126
|
+
w.current = !1, z();
|
|
127
|
+
},
|
|
128
|
+
children: /* @__PURE__ */ M("div", { className: S(j.content, v), children: s })
|
|
129
|
+
}
|
|
130
|
+
),
|
|
131
|
+
document.body
|
|
132
|
+
)
|
|
133
|
+
] });
|
|
134
|
+
};
|
|
135
|
+
export {
|
|
136
|
+
Q as Tooltip
|
|
137
|
+
};
|
|
@@ -2,7 +2,7 @@ import { StoryObj } from '@storybook/react-vite';
|
|
|
2
2
|
import { Tooltip } from './Tooltip';
|
|
3
3
|
declare const meta: {
|
|
4
4
|
title: string;
|
|
5
|
-
component:
|
|
5
|
+
component: import('react').FC<import('./Tooltip').TooltipProps>;
|
|
6
6
|
parameters: {
|
|
7
7
|
layout: string;
|
|
8
8
|
controls: {
|
|
@@ -16,42 +16,24 @@ declare const meta: {
|
|
|
16
16
|
};
|
|
17
17
|
tags: string[];
|
|
18
18
|
args: {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
mouseLeaveDelay: number;
|
|
23
|
-
arrow: true;
|
|
19
|
+
position: "top center";
|
|
20
|
+
openDelay: number;
|
|
21
|
+
closeDelay: number;
|
|
24
22
|
};
|
|
25
23
|
argTypes: {
|
|
26
|
-
|
|
24
|
+
position: {
|
|
27
25
|
control: "select";
|
|
28
26
|
options: string[];
|
|
29
27
|
description: string;
|
|
30
28
|
};
|
|
31
|
-
|
|
32
|
-
control: "select";
|
|
33
|
-
options: string[];
|
|
34
|
-
description: string;
|
|
35
|
-
};
|
|
36
|
-
mouseEnterDelay: {
|
|
29
|
+
openDelay: {
|
|
37
30
|
control: "number";
|
|
38
31
|
description: string;
|
|
39
32
|
};
|
|
40
|
-
|
|
33
|
+
closeDelay: {
|
|
41
34
|
control: "number";
|
|
42
35
|
description: string;
|
|
43
36
|
};
|
|
44
|
-
delay: {
|
|
45
|
-
control: false;
|
|
46
|
-
table: {
|
|
47
|
-
category: string;
|
|
48
|
-
};
|
|
49
|
-
description: string;
|
|
50
|
-
};
|
|
51
|
-
arrow: {
|
|
52
|
-
control: "boolean";
|
|
53
|
-
description: string;
|
|
54
|
-
};
|
|
55
37
|
contentClassName: {
|
|
56
38
|
table: {
|
|
57
39
|
disable: true;
|
|
@@ -76,7 +58,7 @@ declare const meta: {
|
|
|
76
58
|
export default meta;
|
|
77
59
|
type Story = StoryObj<typeof Tooltip>;
|
|
78
60
|
export declare const OnHover: Story;
|
|
79
|
-
export declare const
|
|
61
|
+
export declare const BottomHover: Story;
|
|
80
62
|
export declare const PositionRight: Story;
|
|
81
63
|
export declare const PositionLeft: Story;
|
|
82
64
|
export declare const AbsolutelyPositioned: Story;
|