motile-ui 1.0.1 → 1.0.3
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/components/Accordion/Accordion.css +1 -0
- package/dist/components/Accordion/Accordion.js +121 -0
- package/dist/components/Badge/Badge.css +1 -0
- package/dist/components/Badge/Badge.js +24 -0
- package/dist/components/Button/Button.css +1 -0
- package/dist/components/Button/Button.js +73 -0
- package/dist/components/Checkbox/Checkbox.css +1 -0
- package/dist/components/Checkbox/Checkbox.js +69 -0
- package/dist/components/Dock/Dock.css +1 -0
- package/dist/components/Dock/Dock.js +151 -0
- package/dist/components/Drawer/Drawer.css +1 -0
- package/dist/components/Drawer/Drawer.js +275 -0
- package/dist/components/Input/Input.css +1 -0
- package/dist/components/Input/Input.js +122 -0
- package/dist/components/Modal/Modal.css +1 -0
- package/dist/components/Modal/Modal.js +231 -0
- package/dist/components/Popover/Popover.css +1 -0
- package/dist/components/Popover/Popover.js +197 -0
- package/dist/components/Sheet/Sheet.css +1 -0
- package/dist/components/Sheet/Sheet.js +283 -0
- package/dist/components/Skeleton/Skeleton.css +1 -0
- package/dist/components/Skeleton/Skeleton.js +30 -0
- package/dist/components/SpeedDial/SpeedDial.css +1 -0
- package/dist/components/SpeedDial/SpeedDial.js +149 -0
- package/dist/components/Switch/Switch.css +1 -0
- package/dist/components/Switch/Switch.js +31 -0
- package/dist/components/Textarea/Textarea.css +1 -0
- package/dist/components/Textarea/Textarea.js +111 -0
- package/dist/components/Toast/Toast.css +1 -0
- package/dist/components/Toast/Toast.js +178 -0
- package/dist/components/Toast/useToast.js +30 -0
- package/dist/components/Tooltip/Tooltip.css +1 -0
- package/dist/components/Tooltip/Tooltip.js +321 -0
- package/dist/hooks/useClickOutside.js +24 -0
- package/dist/hooks/useEscapeKey.js +18 -0
- package/dist/hooks/useHistoryClose.js +42 -0
- package/dist/hooks/useScrollLock.js +73 -0
- package/dist/index.js +42 -0
- package/dist/utils/FloatingArrow.js +55 -0
- package/dist/utils/Slot.js +44 -0
- package/package.json +88 -6
- package/dist/index.css +0 -1
- package/dist/motile-ui.es.js +0 -2494
- package/dist/motile-ui.umd.js +0 -2
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { jsx as e, jsxs as h } from "react/jsx-runtime";
|
|
2
|
+
import { forwardRef as p } from "react";
|
|
3
|
+
import './Switch.css';/* empty css */
|
|
4
|
+
const $ = p(
|
|
5
|
+
({ variant: t = "smooth", color: o, className: c, disabled: a, style: i, ...n }, l) => {
|
|
6
|
+
const s = "motile-switch", r = [
|
|
7
|
+
`${s}-container`,
|
|
8
|
+
`${s}-container--${t}`,
|
|
9
|
+
a && `${s}-container--disabled`
|
|
10
|
+
].filter(Boolean).join(" "), m = [s, `${s}--${t}`, c].filter(Boolean).join(" ");
|
|
11
|
+
return /* @__PURE__ */ e("div", { className: r, style: o ? { "--motile-switch-color": o } : void 0, children: /* @__PURE__ */ h("label", { className: `${s}-wrapper`, children: [
|
|
12
|
+
/* @__PURE__ */ e(
|
|
13
|
+
"input",
|
|
14
|
+
{
|
|
15
|
+
...n,
|
|
16
|
+
ref: l,
|
|
17
|
+
type: "checkbox",
|
|
18
|
+
className: m,
|
|
19
|
+
disabled: a,
|
|
20
|
+
style: i,
|
|
21
|
+
role: "switch"
|
|
22
|
+
}
|
|
23
|
+
),
|
|
24
|
+
/* @__PURE__ */ e("span", { className: `${s}__track`, children: /* @__PURE__ */ e("span", { className: `${s}__thumb` }) })
|
|
25
|
+
] }) });
|
|
26
|
+
}
|
|
27
|
+
);
|
|
28
|
+
$.displayName = "Switch";
|
|
29
|
+
export {
|
|
30
|
+
$ as Switch
|
|
31
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.motile-textarea-root{display:block;width:100%}.motile-textarea{width:100%;border:2px solid #e5e8eb;border-radius:12px;padding:12px 16px;font-size:16px;font-weight:400;color:#111827;background:#fff;outline:none;transition:none;min-height:120px;line-height:1.6;box-sizing:border-box;font-family:inherit;resize:none}.motile-textarea:hover:not(:disabled):not(:focus):not(.motile-textarea--error){border-color:#c9cdd2}.motile-textarea:focus{border:2px solid var( --motile-textarea-color, var(--motile-ui-textarea, var(--motile-theme, #3182f6)) )}.motile-textarea:disabled{background:#f9fafb;color:#9ca3af;cursor:not-allowed;border-color:#e5e7eb;resize:none}.motile-textarea.motile-textarea--error{border:2px solid #ef4444;background:#fef5f5}.motile-textarea.motile-textarea--error:focus{border:2px solid #ef4444;background:#fef5f5}.motile-textarea--shake{animation:motile-textarea-shake .5s ease-in-out}@keyframes motile-textarea-shake{0%{transform:translate(0)}15%{transform:translate(-10px)}30%{transform:translate(8px)}45%{transform:translate(-6px)}60%{transform:translate(4px)}75%{transform:translate(-2px)}to{transform:translate(0)}}.motile-textarea::placeholder{color:#9ca3af;opacity:1}.motile-textarea-wrapper{position:relative;width:100%}.motile-textarea--with-clear{padding-right:40px}.motile-textarea--with-clear:focus{padding-right:40px}.motile-textarea__clear-button{position:absolute;right:12px;top:12px;display:flex;align-items:center;justify-content:center;width:20px;height:20px;padding:0;background:transparent;border:none;color:#9ca3af;cursor:pointer;border-radius:4px;transition:background-color .2s ease,color .2s ease}.motile-textarea__clear-button:hover{background:#f3f4f6;color:#6b7280}.motile-textarea__clear-icon{width:16px;height:16px}@media (max-width: 768px){.motile-textarea{font-size:16px;padding:12px;min-height:100px}.motile-textarea:focus{border:2px solid var( --motile-textarea-color, var(--motile-ui-textarea, var(--motile-theme, #3182f6)) )}.motile-textarea--with-clear{padding-right:36px}.motile-textarea--with-clear:focus{padding-right:36px}}@supports (-webkit-touch-callout: none){.motile-textarea{-webkit-tap-highlight-color:transparent}}.motile-textarea__helper-text{display:flex;align-items:flex-start;margin-top:4px;min-height:16px;gap:8px}.motile-textarea__helper-text--both{justify-content:space-between}.motile-textarea__helper-text--error-only{justify-content:flex-start}.motile-textarea__helper-text--counter-only{justify-content:flex-end}.motile-textarea__error-message{font-size:12px;color:#ef4444;line-height:16px;flex:1}.motile-textarea__counter{font-size:12px;color:#9ca3af;line-height:16px;white-space:nowrap;flex-shrink:0}.motile-textarea__label{position:absolute;left:16px;top:16px;font-size:16px;color:#9ca3af;pointer-events:none;transition:all .2s ease;background:transparent;padding:0;z-index:1}.motile-textarea--with-label::placeholder{opacity:0}.motile-textarea--with-label:focus::placeholder{opacity:1}.motile-textarea-wrapper:has(.motile-textarea:focus) .motile-textarea__label,.motile-textarea-wrapper:has(.motile-textarea:not(:placeholder-shown)) .motile-textarea__label{top:0;transform:translateY(-50%);font-size:12px;color:var( --motile-textarea-color, var(--motile-ui-textarea, var(--motile-theme, #3182f6)) );background:#fff;padding:0 4px}.motile-textarea-wrapper:has(.motile-textarea:focus) .motile-textarea__label--error,.motile-textarea-wrapper:has(.motile-textarea:not(:placeholder-shown)) .motile-textarea__label--error{color:#ef4444}.motile-textarea.motile-textarea--with-label{padding-top:12px;padding-bottom:12px}@media (max-width: 768px){.motile-textarea__label{font-size:16px;left:12px;top:16px}.motile-textarea-wrapper:has(.motile-textarea:focus) .motile-textarea__label,.motile-textarea-wrapper:has(.motile-textarea:not(:placeholder-shown)) .motile-textarea__label{font-size:12px}}.motile-textarea{scrollbar-width:thin;scrollbar-color:rgba(0,0,0,.2) transparent}.motile-textarea::-webkit-scrollbar{width:6px}.motile-textarea::-webkit-scrollbar-track{background:transparent}.motile-textarea::-webkit-scrollbar-thumb{background-color:#0003;border-radius:3px;transition:background-color .2s ease}.motile-textarea::-webkit-scrollbar-thumb:hover{background-color:#0000004d}.motile-textarea::-webkit-scrollbar-thumb:active{background-color:#0006}@media (prefers-color-scheme: dark){.motile-textarea{scrollbar-color:rgba(255,255,255,.2) transparent}.motile-textarea::-webkit-scrollbar-thumb{background-color:#fff3}.motile-textarea::-webkit-scrollbar-thumb:hover{background-color:#ffffff4d}.motile-textarea::-webkit-scrollbar-thumb:active{background-color:#fff6}}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { jsxs as h, jsx as y } from "react/jsx-runtime";
|
|
2
|
+
import { forwardRef as Q, useRef as U, useState as V, useMemo as X, useEffect as Z, useLayoutEffect as z } from "react";
|
|
3
|
+
import './Textarea.css';/* empty css */
|
|
4
|
+
const F = Q(
|
|
5
|
+
({
|
|
6
|
+
autoFocus: _ = !1,
|
|
7
|
+
autoSelect: b = !1,
|
|
8
|
+
isError: T,
|
|
9
|
+
errorMessage: o,
|
|
10
|
+
className: C,
|
|
11
|
+
value: c,
|
|
12
|
+
color: R,
|
|
13
|
+
style: j,
|
|
14
|
+
maxLength: m,
|
|
15
|
+
label: a,
|
|
16
|
+
placeholder: v,
|
|
17
|
+
rows: d = 4,
|
|
18
|
+
resize: I = "none",
|
|
19
|
+
autoSize: n = !1,
|
|
20
|
+
...H
|
|
21
|
+
}, S) => {
|
|
22
|
+
const E = U(null), i = S || E, [f, W] = V({ height: void 0, isMaxHeight: !1 }), p = T ?? !!o, t = X(() => typeof n == "boolean" ? n ? { minRows: d, maxRows: void 0 } : void 0 : n ? {
|
|
23
|
+
minRows: n.minRows ?? d,
|
|
24
|
+
maxRows: n.maxRows
|
|
25
|
+
} : void 0, [n, d]);
|
|
26
|
+
Z(() => {
|
|
27
|
+
if (_ && i.current) {
|
|
28
|
+
const s = setTimeout(() => {
|
|
29
|
+
i.current && (i.current.focus(), b && i.current.select());
|
|
30
|
+
}, 50);
|
|
31
|
+
return () => clearTimeout(s);
|
|
32
|
+
}
|
|
33
|
+
}, [_, b]), z(() => {
|
|
34
|
+
if (!t || !i.current) return;
|
|
35
|
+
const s = i.current;
|
|
36
|
+
s.style.height = "auto";
|
|
37
|
+
const J = s.scrollHeight, l = window.getComputedStyle(s), B = parseInt(l.lineHeight, 10), K = parseInt(l.paddingTop, 10), L = parseInt(l.paddingBottom, 10), M = parseInt(l.borderTopWidth, 10), O = parseInt(l.borderBottomWidth, 10), N = K + L + M + O, g = t.minRows ? B * t.minRows + N : void 0, u = t.maxRows ? B * t.maxRows + N : void 0;
|
|
38
|
+
let r = J, w = !1;
|
|
39
|
+
g !== void 0 && r < g && (r = g), u !== void 0 && r > u && (r = u, w = !0), s.style.height = `${r}px`, W(($) => r !== $.height || w !== $.isMaxHeight ? { height: r, isMaxHeight: w } : $);
|
|
40
|
+
}, [c, t]);
|
|
41
|
+
const e = "motile-textarea", k = [
|
|
42
|
+
e,
|
|
43
|
+
p && `${e}--error`,
|
|
44
|
+
p && `${e}--shake`,
|
|
45
|
+
a && `${e}--with-label`,
|
|
46
|
+
C
|
|
47
|
+
].filter(Boolean).join(" "), D = [
|
|
48
|
+
`${e}-wrapper`,
|
|
49
|
+
a && `${e}-wrapper--with-label`
|
|
50
|
+
].filter(Boolean).join(" "), P = [
|
|
51
|
+
`${e}__label`,
|
|
52
|
+
p && `${e}__label--error`
|
|
53
|
+
].filter(Boolean).join(" "), Y = R ? { "--motile-textarea-color": R } : void 0, q = {
|
|
54
|
+
...j,
|
|
55
|
+
resize: t ? "none" : I,
|
|
56
|
+
...t ? {
|
|
57
|
+
height: f.height !== void 0 ? f.height : "auto",
|
|
58
|
+
minHeight: "auto",
|
|
59
|
+
overflowY: f.isMaxHeight ? "auto" : "hidden"
|
|
60
|
+
} : {}
|
|
61
|
+
}, A = c ? String(c).length : 0, x = m !== void 0, G = [
|
|
62
|
+
H["aria-describedby"],
|
|
63
|
+
o ? `${e}-error` : void 0
|
|
64
|
+
].filter(Boolean).join(" ") || void 0;
|
|
65
|
+
return /* @__PURE__ */ h("div", { className: `${e}-root`, children: [
|
|
66
|
+
/* @__PURE__ */ h("div", { className: D, style: Y, children: [
|
|
67
|
+
a && /* @__PURE__ */ y("label", { className: P, children: a }),
|
|
68
|
+
/* @__PURE__ */ y(
|
|
69
|
+
"textarea",
|
|
70
|
+
{
|
|
71
|
+
...H,
|
|
72
|
+
"aria-describedby": G,
|
|
73
|
+
ref: i,
|
|
74
|
+
className: k,
|
|
75
|
+
value: c,
|
|
76
|
+
maxLength: m,
|
|
77
|
+
rows: d,
|
|
78
|
+
style: q,
|
|
79
|
+
placeholder: a ? v || " " : v
|
|
80
|
+
}
|
|
81
|
+
)
|
|
82
|
+
] }),
|
|
83
|
+
(o || x) && /* @__PURE__ */ h(
|
|
84
|
+
"div",
|
|
85
|
+
{
|
|
86
|
+
className: `${e}__helper-text ${o && x ? `${e}__helper-text--both` : o ? `${e}__helper-text--error-only` : `${e}__helper-text--counter-only`}`,
|
|
87
|
+
children: [
|
|
88
|
+
o && /* @__PURE__ */ y(
|
|
89
|
+
"span",
|
|
90
|
+
{
|
|
91
|
+
id: `${e}-error`,
|
|
92
|
+
className: `${e}__error-message`,
|
|
93
|
+
role: "alert",
|
|
94
|
+
children: o
|
|
95
|
+
}
|
|
96
|
+
),
|
|
97
|
+
x && /* @__PURE__ */ h("span", { className: `${e}__counter`, children: [
|
|
98
|
+
A,
|
|
99
|
+
"/",
|
|
100
|
+
m
|
|
101
|
+
] })
|
|
102
|
+
]
|
|
103
|
+
}
|
|
104
|
+
)
|
|
105
|
+
] });
|
|
106
|
+
}
|
|
107
|
+
);
|
|
108
|
+
F.displayName = "Textarea";
|
|
109
|
+
export {
|
|
110
|
+
F as Textarea
|
|
111
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.motile-toast-container{position:fixed;pointer-events:none;display:flex;flex-direction:column;gap:8px}.motile-toast-container{top:0;left:0;right:0;align-items:center;padding:calc(env(safe-area-inset-top,0px) + 16px) 16px 16px 16px}@media (min-width: 768px){.motile-toast-container{top:0;left:auto;right:0;align-items:flex-end;padding:16px;max-width:400px}}.motile-toast{pointer-events:auto;display:inline-flex;align-items:flex-start;width:calc(100vw - 32px);min-width:200px;padding:12px 16px;background:#000000d9;border-radius:8px;backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px);box-shadow:0 2px 8px #00000026;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,sans-serif;-webkit-font-smoothing:antialiased;-webkit-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent;will-change:transform,opacity;animation:slideDown .3s ease-out}@media (min-width: 768px){.motile-toast{width:auto;max-width:320px;animation:slideInRight .3s ease-out}}.motile-toast--exiting{animation:fadeOut .15s ease-out forwards}.motile-toast__icon{flex-shrink:0;width:18px;height:18px;display:flex;align-items:center;justify-content:center;color:#fff;margin-right:8px;margin-top:1px}.motile-toast--success .motile-toast__icon{color:#4ade80}.motile-toast--error .motile-toast__icon{color:#f87171}.motile-toast--warning .motile-toast__icon{color:#fbbf24}.motile-toast--info .motile-toast__icon{color:#60a5fa}.motile-toast__message{flex:1;min-width:0;font-size:14px;font-weight:500;line-height:1.4;color:#fff;word-wrap:break-word;word-break:break-word;overflow-wrap:break-word}@keyframes slideDown{0%{opacity:0;transform:translateY(-16px)}to{opacity:1;transform:translateY(0)}}@keyframes slideInRight{0%{opacity:0;transform:translate(16px)}to{opacity:1;transform:translate(0)}}@keyframes fadeOut{to{opacity:0;transform:scale(.95)}}@media (prefers-color-scheme: dark){.motile-toast{background:#fffffff2}.motile-toast__message,.motile-toast__icon{color:#18181b}.motile-toast--success .motile-toast__icon{color:#22c55e}.motile-toast--error .motile-toast__icon{color:#ef4444}.motile-toast--warning .motile-toast__icon{color:#f59e0b}.motile-toast--info .motile-toast__icon{color:#3b82f6}}@media (prefers-reduced-motion: reduce){.motile-toast{animation:none!important}}.motile-toast *{user-select:none;-webkit-user-select:none}
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
import { jsxs as s, jsx as t } from "react/jsx-runtime";
|
|
2
|
+
import { useState as x, useEffect as g, useCallback as w, useMemo as p, createContext as L, useContext as y } from "react";
|
|
3
|
+
import { createPortal as I } from "react-dom";
|
|
4
|
+
import './Toast.css';/* empty css */
|
|
5
|
+
const C = L(null);
|
|
6
|
+
function V() {
|
|
7
|
+
const e = y(C);
|
|
8
|
+
if (!e)
|
|
9
|
+
throw new Error("useToastContext must be used within ToastProvider");
|
|
10
|
+
return e;
|
|
11
|
+
}
|
|
12
|
+
function $({ toast: e, onRemove: a }) {
|
|
13
|
+
const [o, c] = x(!1), l = w(() => {
|
|
14
|
+
c(!0), setTimeout(() => {
|
|
15
|
+
a(e.id);
|
|
16
|
+
}, 250);
|
|
17
|
+
}, [e.id, a]);
|
|
18
|
+
g(() => {
|
|
19
|
+
const h = setTimeout(l, e.duration);
|
|
20
|
+
return () => {
|
|
21
|
+
clearTimeout(h);
|
|
22
|
+
};
|
|
23
|
+
}, [l, e.duration]);
|
|
24
|
+
const d = p(() => e.variant === "success" ? /* @__PURE__ */ s(
|
|
25
|
+
"svg",
|
|
26
|
+
{
|
|
27
|
+
width: "20",
|
|
28
|
+
height: "20",
|
|
29
|
+
viewBox: "0 0 20 20",
|
|
30
|
+
fill: "none",
|
|
31
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
32
|
+
children: [
|
|
33
|
+
/* @__PURE__ */ t("circle", { cx: "10", cy: "10", r: "9", fill: "currentColor", opacity: "0.2" }),
|
|
34
|
+
/* @__PURE__ */ t(
|
|
35
|
+
"path",
|
|
36
|
+
{
|
|
37
|
+
d: "M6 10L8.5 12.5L14 7",
|
|
38
|
+
stroke: "currentColor",
|
|
39
|
+
strokeWidth: "2",
|
|
40
|
+
strokeLinecap: "round",
|
|
41
|
+
strokeLinejoin: "round"
|
|
42
|
+
}
|
|
43
|
+
)
|
|
44
|
+
]
|
|
45
|
+
}
|
|
46
|
+
) : e.variant === "error" ? /* @__PURE__ */ s(
|
|
47
|
+
"svg",
|
|
48
|
+
{
|
|
49
|
+
width: "20",
|
|
50
|
+
height: "20",
|
|
51
|
+
viewBox: "0 0 20 20",
|
|
52
|
+
fill: "none",
|
|
53
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
54
|
+
children: [
|
|
55
|
+
/* @__PURE__ */ t("circle", { cx: "10", cy: "10", r: "9", fill: "currentColor", opacity: "0.2" }),
|
|
56
|
+
/* @__PURE__ */ t(
|
|
57
|
+
"path",
|
|
58
|
+
{
|
|
59
|
+
d: "M7 7L13 13M13 7L7 13",
|
|
60
|
+
stroke: "currentColor",
|
|
61
|
+
strokeWidth: "2",
|
|
62
|
+
strokeLinecap: "round"
|
|
63
|
+
}
|
|
64
|
+
)
|
|
65
|
+
]
|
|
66
|
+
}
|
|
67
|
+
) : e.variant === "warning" ? /* @__PURE__ */ s(
|
|
68
|
+
"svg",
|
|
69
|
+
{
|
|
70
|
+
width: "20",
|
|
71
|
+
height: "20",
|
|
72
|
+
viewBox: "0 0 20 20",
|
|
73
|
+
fill: "none",
|
|
74
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
75
|
+
children: [
|
|
76
|
+
/* @__PURE__ */ t("path", { d: "M10 2L2 17H18L10 2Z", fill: "currentColor", opacity: "0.2" }),
|
|
77
|
+
/* @__PURE__ */ t(
|
|
78
|
+
"path",
|
|
79
|
+
{
|
|
80
|
+
d: "M10 7V11M10 14V14.5",
|
|
81
|
+
stroke: "currentColor",
|
|
82
|
+
strokeWidth: "2",
|
|
83
|
+
strokeLinecap: "round"
|
|
84
|
+
}
|
|
85
|
+
)
|
|
86
|
+
]
|
|
87
|
+
}
|
|
88
|
+
) : e.variant === "info" ? /* @__PURE__ */ s(
|
|
89
|
+
"svg",
|
|
90
|
+
{
|
|
91
|
+
width: "20",
|
|
92
|
+
height: "20",
|
|
93
|
+
viewBox: "0 0 20 20",
|
|
94
|
+
fill: "none",
|
|
95
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
96
|
+
children: [
|
|
97
|
+
/* @__PURE__ */ t("circle", { cx: "10", cy: "10", r: "9", fill: "currentColor", opacity: "0.2" }),
|
|
98
|
+
/* @__PURE__ */ t(
|
|
99
|
+
"path",
|
|
100
|
+
{
|
|
101
|
+
d: "M10 7V7.5M10 10V14",
|
|
102
|
+
stroke: "currentColor",
|
|
103
|
+
strokeWidth: "2",
|
|
104
|
+
strokeLinecap: "round"
|
|
105
|
+
}
|
|
106
|
+
)
|
|
107
|
+
]
|
|
108
|
+
}
|
|
109
|
+
) : null, [e.variant]), n = "motile-toast", u = [
|
|
110
|
+
n,
|
|
111
|
+
`${n}--${e.variant}`,
|
|
112
|
+
o && `${n}--exiting`
|
|
113
|
+
].filter(Boolean).join(" ");
|
|
114
|
+
return /* @__PURE__ */ s(
|
|
115
|
+
"div",
|
|
116
|
+
{
|
|
117
|
+
className: u,
|
|
118
|
+
role: "status",
|
|
119
|
+
"aria-live": "polite",
|
|
120
|
+
"aria-atomic": "true",
|
|
121
|
+
"data-toast-id": e.id,
|
|
122
|
+
children: [
|
|
123
|
+
d && /* @__PURE__ */ t("div", { className: `${n}__icon`, children: d }),
|
|
124
|
+
/* @__PURE__ */ t("div", { className: `${n}__message`, children: e.message })
|
|
125
|
+
]
|
|
126
|
+
}
|
|
127
|
+
);
|
|
128
|
+
}
|
|
129
|
+
function j({ children: e, zIndex: a = 9999 }) {
|
|
130
|
+
const [o, c] = x([]), [l, d] = x(!1);
|
|
131
|
+
g(() => {
|
|
132
|
+
d(!0);
|
|
133
|
+
}, []);
|
|
134
|
+
const n = w(
|
|
135
|
+
(r, m = "default", i) => {
|
|
136
|
+
const f = `toast-${Date.now()}-${Math.random()}`, T = {
|
|
137
|
+
id: f,
|
|
138
|
+
message: r,
|
|
139
|
+
variant: m,
|
|
140
|
+
duration: (i == null ? void 0 : i.duration) ?? 4e3,
|
|
141
|
+
zIndex: i == null ? void 0 : i.zIndex,
|
|
142
|
+
createdAt: Date.now()
|
|
143
|
+
};
|
|
144
|
+
return c((M) => [T, ...M]), f;
|
|
145
|
+
},
|
|
146
|
+
[]
|
|
147
|
+
), u = w((r) => {
|
|
148
|
+
c((m) => m.filter((i) => i.id !== r));
|
|
149
|
+
}, []), h = p(
|
|
150
|
+
() => ({
|
|
151
|
+
toasts: o,
|
|
152
|
+
addToast: n
|
|
153
|
+
}),
|
|
154
|
+
[o, n]
|
|
155
|
+
), v = o.filter(
|
|
156
|
+
(r) => r.zIndex !== void 0
|
|
157
|
+
), k = v.length > 0 ? Math.max(...v.map((r) => r.zIndex)) : a;
|
|
158
|
+
return /* @__PURE__ */ s(C.Provider, { value: h, children: [
|
|
159
|
+
e,
|
|
160
|
+
l && I(
|
|
161
|
+
/* @__PURE__ */ t(
|
|
162
|
+
"div",
|
|
163
|
+
{
|
|
164
|
+
className: "motile-toast-container",
|
|
165
|
+
"aria-live": "polite",
|
|
166
|
+
"aria-label": "Notifications",
|
|
167
|
+
style: { zIndex: k },
|
|
168
|
+
children: o.map((r) => /* @__PURE__ */ t($, { toast: r, onRemove: u }, r.id))
|
|
169
|
+
}
|
|
170
|
+
),
|
|
171
|
+
document.body
|
|
172
|
+
)
|
|
173
|
+
] });
|
|
174
|
+
}
|
|
175
|
+
export {
|
|
176
|
+
j as ToastProvider,
|
|
177
|
+
V as useToastContext
|
|
178
|
+
};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { useCallback as o } from "react";
|
|
2
|
+
import { useToastContext as i } from "./Toast.js";
|
|
3
|
+
function d() {
|
|
4
|
+
const { addToast: r } = i(), s = o(
|
|
5
|
+
(t, n) => r(t, "default", n),
|
|
6
|
+
[r]
|
|
7
|
+
), e = o(
|
|
8
|
+
(t, n) => r(t, "success", n),
|
|
9
|
+
[r]
|
|
10
|
+
), u = o(
|
|
11
|
+
(t, n) => r(t, "error", n),
|
|
12
|
+
[r]
|
|
13
|
+
), c = o(
|
|
14
|
+
(t, n) => r(t, "warning", n),
|
|
15
|
+
[r]
|
|
16
|
+
), a = o(
|
|
17
|
+
(t, n) => r(t, "info", n),
|
|
18
|
+
[r]
|
|
19
|
+
);
|
|
20
|
+
return {
|
|
21
|
+
show: s,
|
|
22
|
+
success: e,
|
|
23
|
+
error: u,
|
|
24
|
+
warning: c,
|
|
25
|
+
info: a
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
export {
|
|
29
|
+
d as useToast
|
|
30
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.motile-tooltip-trigger{position:relative;display:inline-block;line-height:normal;vertical-align:middle}.motile-tooltip-bubble{position:fixed;z-index:2147483647;padding:8px 12px;border-radius:8px;font-size:14px;font-weight:500;line-height:1.4;box-shadow:0 6px 20px #0003;opacity:0;pointer-events:none;transition:opacity .2s cubic-bezier(.16,1,.3,1),transform .2s cubic-bezier(.16,1,.3,1)}.motile-tooltip-bubble[data-placement=top]{transform:translateY(8px) scale(.96)}.motile-tooltip-bubble[data-placement=bottom]{transform:translateY(-8px) scale(.96)}.motile-tooltip-bubble[data-placement=left]{transform:translate(8px) scale(.96)}.motile-tooltip-bubble[data-placement=right]{transform:translate(-8px) scale(.96)}.motile-tooltip-bubble[data-open=true]{opacity:1;transform:translate(0) scale(1)}.motile-tooltip-bubble[data-keep-open]{pointer-events:auto}.motile-tooltip-bubble--filled{--arrow-color: var( --motile-tooltip-color, var(--motile-ui-tooltip, rgba(0, 0, 0, .9)) );background:var(--arrow-color);color:#fff}.motile-tooltip-bubble--outlined{--arrow-color: var(--motile-tooltip-color, var(--motile-ui-tooltip, #3b82f6));background:#fff;color:var(--arrow-color);border:1px solid var(--arrow-color)}.motile-tooltip-bubble.measuring{visibility:hidden!important;opacity:1!important;max-width:none!important;max-height:none!important;left:0!important;top:0!important}.motile-tooltip-arrow{position:absolute;pointer-events:none;z-index:1}.motile-tooltip-bubble[data-placement=top] .motile-tooltip-arrow{bottom:-7.25px;left:var(--arrow-offset, 50%);transform:translate(-50%) rotate(180deg)}.motile-tooltip-bubble[data-placement=bottom] .motile-tooltip-arrow{top:-7px;left:var(--arrow-offset, 50%);transform:translate(-50%) rotate(0)}.motile-tooltip-bubble[data-placement=left] .motile-tooltip-arrow{right:-9.25px;top:var(--arrow-offset, 50%);transform:translateY(-50%) rotate(90deg)}.motile-tooltip-bubble[data-placement=right] .motile-tooltip-arrow{left:-9.25px;top:var(--arrow-offset, 50%);transform:translateY(-50%) rotate(-90deg)}
|
|
@@ -0,0 +1,321 @@
|
|
|
1
|
+
import { jsxs as tt, jsx as W } from "react/jsx-runtime";
|
|
2
|
+
import et, { useState as A, useEffect as H, useCallback as T, useId as ot, useRef as I, useLayoutEffect as nt, createContext as rt, useContext as it } from "react";
|
|
3
|
+
import { createPortal as st } from "react-dom";
|
|
4
|
+
import { Slot as at } from "../../utils/Slot.js";
|
|
5
|
+
import { FloatingArrow as lt } from "../../utils/FloatingArrow.js";
|
|
6
|
+
import './Tooltip.css';/* empty css */
|
|
7
|
+
const G = rt(null);
|
|
8
|
+
function X() {
|
|
9
|
+
const t = it(G);
|
|
10
|
+
if (!t)
|
|
11
|
+
throw new Error("Tooltip components must be used within Tooltip.Root");
|
|
12
|
+
return t;
|
|
13
|
+
}
|
|
14
|
+
const s = 8;
|
|
15
|
+
function D(t, e, r, i, a, m, u) {
|
|
16
|
+
switch (t) {
|
|
17
|
+
case "top":
|
|
18
|
+
return e.top - a.top - i >= s;
|
|
19
|
+
case "bottom":
|
|
20
|
+
return e.bottom + a.bottom + i <= u - s;
|
|
21
|
+
case "left":
|
|
22
|
+
return e.left - a.left - r >= s;
|
|
23
|
+
case "right":
|
|
24
|
+
return e.right + a.right + r <= m - s;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
function ct(t) {
|
|
28
|
+
return [{
|
|
29
|
+
top: "bottom",
|
|
30
|
+
bottom: "top",
|
|
31
|
+
left: "right",
|
|
32
|
+
right: "left"
|
|
33
|
+
}[t]];
|
|
34
|
+
}
|
|
35
|
+
function ut(t, e, r, i) {
|
|
36
|
+
if (!(r < 768))
|
|
37
|
+
return ct(t);
|
|
38
|
+
const u = e.top + e.height / 2 < i / 2;
|
|
39
|
+
return t === "left" || t === "right" ? [u ? "bottom" : "top", u ? "top" : "bottom", t === "left" ? "right" : "left"] : t === "top" || t === "bottom" ? [t === "top" ? "bottom" : "top"] : [];
|
|
40
|
+
}
|
|
41
|
+
function pt(t, e, r, i) {
|
|
42
|
+
const a = {
|
|
43
|
+
top: t.top - e.top - s,
|
|
44
|
+
bottom: i - t.bottom - e.bottom - s,
|
|
45
|
+
left: t.left - e.left - s,
|
|
46
|
+
right: r - t.right - e.right - s
|
|
47
|
+
};
|
|
48
|
+
let m = "bottom", u = a.bottom;
|
|
49
|
+
for (const [n, l] of Object.entries(a))
|
|
50
|
+
l > u && (u = l, m = n);
|
|
51
|
+
return m;
|
|
52
|
+
}
|
|
53
|
+
function ft({
|
|
54
|
+
children: t,
|
|
55
|
+
position: e = "top",
|
|
56
|
+
align: r = "center",
|
|
57
|
+
variant: i = "filled",
|
|
58
|
+
color: a,
|
|
59
|
+
showArrow: m = !1,
|
|
60
|
+
keepOpen: u = !1,
|
|
61
|
+
offset: n
|
|
62
|
+
}) {
|
|
63
|
+
const l = n === void 0 ? { top: 7, bottom: 6, left: 6, right: 6 } : typeof n == "number" ? { top: n, bottom: n, left: n, right: n } : {
|
|
64
|
+
top: n.top ?? 7,
|
|
65
|
+
bottom: n.bottom ?? 6,
|
|
66
|
+
left: n.left ?? 6,
|
|
67
|
+
right: n.right ?? 6
|
|
68
|
+
}, k = ot().replace(/:/g, ""), w = I(null), x = I(null), p = I(), [b, N] = A(!1), [P, Z] = A(e), [J, K] = A({}), F = I(null), B = T((M, E = 0) => {
|
|
69
|
+
p.current && (clearTimeout(p.current), p.current = void 0), !M && E > 0 ? p.current = window.setTimeout(
|
|
70
|
+
() => N(!1),
|
|
71
|
+
E
|
|
72
|
+
) : N(M);
|
|
73
|
+
}, []);
|
|
74
|
+
nt(() => {
|
|
75
|
+
if (!b || !w.current || !x.current) return;
|
|
76
|
+
const M = () => {
|
|
77
|
+
if (!w.current || !x.current) return;
|
|
78
|
+
const o = w.current.getBoundingClientRect(), y = x.current;
|
|
79
|
+
y.classList.add("measuring"), y.offsetHeight;
|
|
80
|
+
const $ = window.getComputedStyle(y), V = parseFloat($.width), Y = parseFloat($.height);
|
|
81
|
+
let c = V, d = Y;
|
|
82
|
+
y.classList.remove("measuring");
|
|
83
|
+
const R = window.innerWidth, O = window.innerHeight;
|
|
84
|
+
(isNaN(c) || c <= 0) && (c = 100), (isNaN(d) || d <= 0) && (d = 50);
|
|
85
|
+
const _ = R - s * 2, z = O - s * 2;
|
|
86
|
+
c > _ && (c = _), d > z && (d = z);
|
|
87
|
+
let v = e;
|
|
88
|
+
if (o.width === 0 && o.height === 0 || D(e, o, c, d, l, R, O))
|
|
89
|
+
v = e;
|
|
90
|
+
else {
|
|
91
|
+
const L = ut(e, o, R, O);
|
|
92
|
+
let q = !1;
|
|
93
|
+
for (const U of L)
|
|
94
|
+
if (D(U, o, c, d, l, R, O)) {
|
|
95
|
+
v = U, q = !0;
|
|
96
|
+
break;
|
|
97
|
+
}
|
|
98
|
+
q || (v = pt(o, l, R, O));
|
|
99
|
+
}
|
|
100
|
+
let f = 0, g = 0;
|
|
101
|
+
if (v === "top" || v === "bottom") {
|
|
102
|
+
switch (r) {
|
|
103
|
+
case "start":
|
|
104
|
+
f = o.left;
|
|
105
|
+
break;
|
|
106
|
+
case "center":
|
|
107
|
+
f = o.left + o.width / 2 - c / 2;
|
|
108
|
+
break;
|
|
109
|
+
case "end":
|
|
110
|
+
f = o.right - c;
|
|
111
|
+
break;
|
|
112
|
+
}
|
|
113
|
+
f = Math.max(s, Math.min(f, R - s - c)), g = v === "top" ? o.top - l.top - d : o.bottom + l.bottom, g = Math.max(s, Math.min(g, O - s - d));
|
|
114
|
+
} else {
|
|
115
|
+
switch (r) {
|
|
116
|
+
case "start":
|
|
117
|
+
g = o.top;
|
|
118
|
+
break;
|
|
119
|
+
case "center":
|
|
120
|
+
g = o.top + o.height / 2 - d / 2;
|
|
121
|
+
break;
|
|
122
|
+
case "end":
|
|
123
|
+
g = o.bottom - d;
|
|
124
|
+
break;
|
|
125
|
+
}
|
|
126
|
+
g = Math.max(s, Math.min(g, O - s - d)), v === "left" ? (f = o.left - l.left - c, f < s && (c = o.left - l.left - s, f = s)) : (f = o.right + l.right, f + c > R - s && (c = R - s - f));
|
|
127
|
+
}
|
|
128
|
+
let h = 0;
|
|
129
|
+
const S = 12, C = 16;
|
|
130
|
+
if (v === "left" || v === "right") {
|
|
131
|
+
switch (r) {
|
|
132
|
+
case "start":
|
|
133
|
+
h = o.top - g + S;
|
|
134
|
+
break;
|
|
135
|
+
case "center":
|
|
136
|
+
h = o.top + o.height / 2 - g;
|
|
137
|
+
break;
|
|
138
|
+
case "end":
|
|
139
|
+
h = o.bottom - g - S;
|
|
140
|
+
break;
|
|
141
|
+
}
|
|
142
|
+
const L = Math.max(C, d - C);
|
|
143
|
+
h = Math.max(
|
|
144
|
+
C,
|
|
145
|
+
Math.min(h, L)
|
|
146
|
+
);
|
|
147
|
+
} else {
|
|
148
|
+
switch (r) {
|
|
149
|
+
case "start":
|
|
150
|
+
h = o.left - f + S;
|
|
151
|
+
break;
|
|
152
|
+
case "center":
|
|
153
|
+
h = o.left + o.width / 2 - f;
|
|
154
|
+
break;
|
|
155
|
+
case "end":
|
|
156
|
+
h = o.right - f - S;
|
|
157
|
+
break;
|
|
158
|
+
}
|
|
159
|
+
const L = Math.max(C, c - C);
|
|
160
|
+
h = Math.max(
|
|
161
|
+
C,
|
|
162
|
+
Math.min(h, L)
|
|
163
|
+
);
|
|
164
|
+
}
|
|
165
|
+
isNaN(h) && (h = C), Z(v), K({
|
|
166
|
+
left: Math.round(f),
|
|
167
|
+
top: Math.round(g),
|
|
168
|
+
...c !== V && { maxWidth: c },
|
|
169
|
+
...d !== Y && { maxHeight: z },
|
|
170
|
+
"--arrow-offset": `${Math.round(h)}px`,
|
|
171
|
+
...a && { "--motile-tooltip-color": a }
|
|
172
|
+
});
|
|
173
|
+
}, E = () => {
|
|
174
|
+
F.current === null && (F.current = requestAnimationFrame(() => {
|
|
175
|
+
M(), F.current = null;
|
|
176
|
+
}));
|
|
177
|
+
};
|
|
178
|
+
M(), window.addEventListener("scroll", E, {
|
|
179
|
+
passive: !0,
|
|
180
|
+
capture: !0
|
|
181
|
+
}), window.addEventListener("resize", E, { passive: !0 });
|
|
182
|
+
const j = new ResizeObserver(E);
|
|
183
|
+
return w.current && j.observe(w.current), () => {
|
|
184
|
+
F.current !== null && (cancelAnimationFrame(F.current), F.current = null), window.removeEventListener("scroll", E, { capture: !0 }), window.removeEventListener("resize", E), j.disconnect();
|
|
185
|
+
};
|
|
186
|
+
}, [b, e, r, a, n]), H(() => {
|
|
187
|
+
if (!b) return;
|
|
188
|
+
const M = () => {
|
|
189
|
+
B(!1, 0);
|
|
190
|
+
};
|
|
191
|
+
return window.addEventListener("scroll", M, { capture: !0 }), () => {
|
|
192
|
+
window.removeEventListener("scroll", M, { capture: !0 });
|
|
193
|
+
};
|
|
194
|
+
}, [b, B]), H(() => () => {
|
|
195
|
+
p.current && clearTimeout(p.current);
|
|
196
|
+
}, []);
|
|
197
|
+
const Q = {
|
|
198
|
+
open: b,
|
|
199
|
+
setOpen: B,
|
|
200
|
+
position: e,
|
|
201
|
+
align: r,
|
|
202
|
+
variant: i,
|
|
203
|
+
showArrow: m,
|
|
204
|
+
color: a,
|
|
205
|
+
keepOpen: u,
|
|
206
|
+
tooltipId: `${k}-tooltip`,
|
|
207
|
+
triggerRef: w,
|
|
208
|
+
contentRef: x,
|
|
209
|
+
style: J,
|
|
210
|
+
placement: P
|
|
211
|
+
};
|
|
212
|
+
return /* @__PURE__ */ W(G.Provider, { value: Q, children: t });
|
|
213
|
+
}
|
|
214
|
+
function mt({ children: t, asChild: e = !1 }) {
|
|
215
|
+
const { open: r, setOpen: i, tooltipId: a, triggerRef: m, keepOpen: u } = X(), n = T(() => {
|
|
216
|
+
i(!0, 0);
|
|
217
|
+
}, [i]), l = T(() => {
|
|
218
|
+
u ? i(!1, 100) : i(!1, 0);
|
|
219
|
+
}, [i, u]), k = T(() => {
|
|
220
|
+
i(!0, 0);
|
|
221
|
+
}, [i]), w = T(() => {
|
|
222
|
+
i(!1, 0);
|
|
223
|
+
}, [i]), x = T(() => {
|
|
224
|
+
i(!r, 0);
|
|
225
|
+
}, [i, r]);
|
|
226
|
+
return e ? /* @__PURE__ */ W(
|
|
227
|
+
at,
|
|
228
|
+
{
|
|
229
|
+
ref: (p) => {
|
|
230
|
+
m.current = p;
|
|
231
|
+
},
|
|
232
|
+
className: "motile-tooltip-trigger",
|
|
233
|
+
"aria-describedby": r ? a : void 0,
|
|
234
|
+
tabIndex: 0,
|
|
235
|
+
onMouseEnter: n,
|
|
236
|
+
onMouseLeave: l,
|
|
237
|
+
onFocus: k,
|
|
238
|
+
onBlur: w,
|
|
239
|
+
onClick: x,
|
|
240
|
+
children: t
|
|
241
|
+
}
|
|
242
|
+
) : et.cloneElement(t, {
|
|
243
|
+
ref: (p) => {
|
|
244
|
+
m.current = p;
|
|
245
|
+
const b = t.props.ref || t.ref;
|
|
246
|
+
b && (typeof b == "function" ? b(p) : typeof b == "object" && b !== null && (b.current = p));
|
|
247
|
+
},
|
|
248
|
+
className: `motile-tooltip-trigger ${t.props.className || ""}`.trim(),
|
|
249
|
+
"aria-describedby": r ? a : void 0,
|
|
250
|
+
tabIndex: t.props.tabIndex ?? 0,
|
|
251
|
+
onMouseEnter: n,
|
|
252
|
+
onMouseLeave: l,
|
|
253
|
+
onFocus: k,
|
|
254
|
+
onBlur: w,
|
|
255
|
+
onClick: x
|
|
256
|
+
});
|
|
257
|
+
}
|
|
258
|
+
function bt({ children: t }) {
|
|
259
|
+
const {
|
|
260
|
+
open: e,
|
|
261
|
+
setOpen: r,
|
|
262
|
+
tooltipId: i,
|
|
263
|
+
contentRef: a,
|
|
264
|
+
variant: m,
|
|
265
|
+
showArrow: u,
|
|
266
|
+
keepOpen: n,
|
|
267
|
+
align: l,
|
|
268
|
+
style: k,
|
|
269
|
+
placement: w
|
|
270
|
+
} = X(), [x, p] = A(!1);
|
|
271
|
+
H(() => {
|
|
272
|
+
e ? requestAnimationFrame(() => {
|
|
273
|
+
p(!0);
|
|
274
|
+
}) : p(!1);
|
|
275
|
+
}, [e]);
|
|
276
|
+
const b = T(() => {
|
|
277
|
+
n && r(!0, 0);
|
|
278
|
+
}, [n, r]), N = T(() => {
|
|
279
|
+
n && r(!1, 0);
|
|
280
|
+
}, [n, r]), P = k["--motile-tooltip-color"] || (m === "filled" ? "var(--motile-ui-tooltip, rgba(0, 0, 0, 0.9))" : "var(--motile-ui-tooltip, #3b82f6)");
|
|
281
|
+
return !e || typeof document > "u" ? null : st(
|
|
282
|
+
/* @__PURE__ */ tt(
|
|
283
|
+
"div",
|
|
284
|
+
{
|
|
285
|
+
ref: a,
|
|
286
|
+
id: i,
|
|
287
|
+
role: "tooltip",
|
|
288
|
+
className: `motile-tooltip-bubble motile-tooltip-bubble--${m}`,
|
|
289
|
+
"data-open": x || void 0,
|
|
290
|
+
"data-placement": w,
|
|
291
|
+
"data-align": l,
|
|
292
|
+
"data-show-arrow": u || void 0,
|
|
293
|
+
"data-keep-open": n || void 0,
|
|
294
|
+
style: k,
|
|
295
|
+
"aria-hidden": !e,
|
|
296
|
+
onMouseEnter: b,
|
|
297
|
+
onMouseLeave: N,
|
|
298
|
+
children: [
|
|
299
|
+
t,
|
|
300
|
+
u && /* @__PURE__ */ W(
|
|
301
|
+
lt,
|
|
302
|
+
{
|
|
303
|
+
className: "motile-tooltip-arrow",
|
|
304
|
+
variant: m,
|
|
305
|
+
color: P
|
|
306
|
+
}
|
|
307
|
+
)
|
|
308
|
+
]
|
|
309
|
+
}
|
|
310
|
+
),
|
|
311
|
+
document.body
|
|
312
|
+
);
|
|
313
|
+
}
|
|
314
|
+
const Mt = {
|
|
315
|
+
Root: ft,
|
|
316
|
+
Trigger: mt,
|
|
317
|
+
Content: bt
|
|
318
|
+
};
|
|
319
|
+
export {
|
|
320
|
+
Mt as Tooltip
|
|
321
|
+
};
|