@versini/ui-panel 2.0.8 → 2.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/README.md +44 -1
- package/dist/components/Panel/Panel.js +31 -32
- package/dist/index.js +5 -5
- package/package.json +7 -3
package/README.md
CHANGED
|
@@ -1,3 +1,46 @@
|
|
|
1
1
|
# @versini/ui-panel
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[](https://www.npmjs.com/package/@versini/ui-panel)
|
|
4
|
+
|
|
5
|
+
> An accessible React slide-out panel component built with TypeScript and TailwindCSS.
|
|
6
|
+
|
|
7
|
+
The Panel component provides slide-out panels and drawers with focus management, keyboard navigation, and customizable positioning.
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
## Table of Contents
|
|
11
|
+
|
|
12
|
+
- [Features](#features)
|
|
13
|
+
- [Installation](#installation)
|
|
14
|
+
- [Usage](#usage)
|
|
15
|
+
|
|
16
|
+
## Installation
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
npm install @versini/ui-panel
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
> **Note**: This component requires TailwindCSS and the `@versini/ui-styles` plugin for proper styling. See the [root README](../../README.md#tailwindcss-setup) for complete setup instructions.
|
|
23
|
+
|
|
24
|
+
## Usage
|
|
25
|
+
|
|
26
|
+
```tsx
|
|
27
|
+
import { Panel } from "@versini/ui-panel";
|
|
28
|
+
import { useState } from "react";
|
|
29
|
+
|
|
30
|
+
function App() {
|
|
31
|
+
const [open, setOpen] = useState(false);
|
|
32
|
+
|
|
33
|
+
return (
|
|
34
|
+
<>
|
|
35
|
+
<button onClick={() => setOpen(true)}>Open Panel</button>
|
|
36
|
+
<Panel
|
|
37
|
+
title="Panel Title"
|
|
38
|
+
open={open}
|
|
39
|
+
onOpenChange={setOpen}
|
|
40
|
+
>
|
|
41
|
+
Panel content goes here.
|
|
42
|
+
</Panel>
|
|
43
|
+
</>
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
```
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { jsx as l, jsxs as T, Fragment as J } from "react/jsx-runtime";
|
|
2
2
|
import * as f from "react";
|
|
3
|
-
import
|
|
3
|
+
import $, { useRef as I, useLayoutEffect as G, useEffect as B, useState as K, useMemo as Q, useCallback as ue, useId as Z } from "react";
|
|
4
4
|
import n from "clsx";
|
|
5
5
|
import { useFloating as me, useClick as ge, useDismiss as he, useRole as fe, useInteractions as be, useMergeRefs as ve, FloatingPortal as ye, FloatingOverlay as pe, FloatingFocusManager as ke } from "@floating-ui/react";
|
|
6
|
-
const Y = "av-messagebox", H = "av-panel", W = "av-button", F = "icon", ee = "button",
|
|
6
|
+
const Y = "av-messagebox", H = "av-panel", W = "av-button", F = "icon", ee = "button", z = "link", xe = ({
|
|
7
7
|
type: e,
|
|
8
8
|
size: t,
|
|
9
9
|
labelRight: r,
|
|
@@ -14,7 +14,7 @@ const Y = "av-messagebox", H = "av-panel", W = "av-button", F = "icon", ee = "bu
|
|
|
14
14
|
const c = "max-h-8 py-0 px-2", u = "max-h-9 h-8 px-3", s = "max-h-12 py-2 px-4";
|
|
15
15
|
switch (e) {
|
|
16
16
|
case ee:
|
|
17
|
-
case
|
|
17
|
+
case z:
|
|
18
18
|
return n({
|
|
19
19
|
[c]: t === "small",
|
|
20
20
|
[u]: t === "medium",
|
|
@@ -48,9 +48,9 @@ const Y = "av-messagebox", H = "av-panel", W = "av-button", F = "icon", ee = "bu
|
|
|
48
48
|
const o = "text-sm font-medium", i = "text-base font-medium", c = "text-lg font-medium";
|
|
49
49
|
switch (e) {
|
|
50
50
|
case ee:
|
|
51
|
-
case
|
|
51
|
+
case z:
|
|
52
52
|
return n({
|
|
53
|
-
"text-center": e ===
|
|
53
|
+
"text-center": e === z,
|
|
54
54
|
[o]: t === "small",
|
|
55
55
|
[i]: t === "medium",
|
|
56
56
|
[c]: t === "large"
|
|
@@ -297,9 +297,8 @@ const Y = "av-messagebox", H = "av-panel", W = "av-button", F = "icon", ee = "bu
|
|
|
297
297
|
}),
|
|
298
298
|
t
|
|
299
299
|
)), Le = (e, t, r) => {
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
}, re = z.forwardRef((e, t) => {
|
|
300
|
+
!t && (!document.activeElement || document.activeElement !== e.currentTarget) && typeof e?.currentTarget?.focus == "function" && e.currentTarget.focus(), typeof r == "function" && r(e);
|
|
301
|
+
}, re = $.forwardRef((e, t) => {
|
|
303
302
|
const { onClick: r, noInternalClick: a = !1, ...o } = e;
|
|
304
303
|
return /* @__PURE__ */ l(
|
|
305
304
|
"button",
|
|
@@ -313,13 +312,13 @@ const Y = "av-messagebox", H = "av-panel", W = "av-button", F = "icon", ee = "bu
|
|
|
313
312
|
);
|
|
314
313
|
});
|
|
315
314
|
re.displayName = "BaseButton";
|
|
316
|
-
function
|
|
315
|
+
function Ae() {
|
|
317
316
|
const e = I(!1);
|
|
318
317
|
return B(() => (e.current = !0, () => {
|
|
319
318
|
e.current = !1;
|
|
320
319
|
}), []), ue(() => e.current, []);
|
|
321
320
|
}
|
|
322
|
-
function
|
|
321
|
+
function Oe(e) {
|
|
323
322
|
return Q(() => e.every((t) => t == null) ? () => {
|
|
324
323
|
} : (t) => {
|
|
325
324
|
e.forEach((r) => {
|
|
@@ -327,7 +326,7 @@ function Ae(e) {
|
|
|
327
326
|
});
|
|
328
327
|
}, [...e]);
|
|
329
328
|
}
|
|
330
|
-
const
|
|
329
|
+
const De = {
|
|
331
330
|
x: 0,
|
|
332
331
|
y: 0,
|
|
333
332
|
width: 0,
|
|
@@ -337,15 +336,15 @@ const Pe = {
|
|
|
337
336
|
bottom: 0,
|
|
338
337
|
right: 0
|
|
339
338
|
};
|
|
340
|
-
function
|
|
341
|
-
const t =
|
|
339
|
+
function P(e) {
|
|
340
|
+
const t = Ae(), r = I(0), a = I(null), [o, i] = K(De), c = Q(() => typeof ResizeObserver > "u" ? null : new ResizeObserver((u) => {
|
|
342
341
|
const s = u[0];
|
|
343
342
|
s && (cancelAnimationFrame(r.current), r.current = requestAnimationFrame(() => {
|
|
344
343
|
a.current && t() && i(s.contentRect);
|
|
345
344
|
}));
|
|
346
345
|
}), [t]);
|
|
347
|
-
return B(() => (a.current &&
|
|
348
|
-
c
|
|
346
|
+
return B(() => (a.current && c?.observe(a.current, e), () => {
|
|
347
|
+
c?.disconnect(), r.current && cancelAnimationFrame(r.current);
|
|
349
348
|
}), [c, e]), [a, o];
|
|
350
349
|
}
|
|
351
350
|
const R = {
|
|
@@ -355,14 +354,14 @@ const R = {
|
|
|
355
354
|
// w-8
|
|
356
355
|
large: 48
|
|
357
356
|
// w-12
|
|
358
|
-
},
|
|
359
|
-
small:
|
|
357
|
+
}, Pe = {
|
|
358
|
+
small: 16,
|
|
360
359
|
// px-2 x 2
|
|
361
|
-
medium:
|
|
360
|
+
medium: 24,
|
|
362
361
|
// px-3 x 2
|
|
363
|
-
large:
|
|
362
|
+
large: 32
|
|
364
363
|
// px-4 x 2
|
|
365
|
-
},
|
|
364
|
+
}, ze = 2, $e = 300, V = $.forwardRef(
|
|
366
365
|
({
|
|
367
366
|
children: e,
|
|
368
367
|
disabled: t = !1,
|
|
@@ -403,21 +402,21 @@ const R = {
|
|
|
403
402
|
radius: w,
|
|
404
403
|
variant: ae,
|
|
405
404
|
animated: p
|
|
406
|
-
}), ce = Re({ mode: r, raw: u, iconClassName: ie }), U = Me({ animated: p }), se = "flex items-center justify-center relative w-full h-full overflow-hidden", [v,
|
|
405
|
+
}), ce = Re({ mode: r, raw: u, iconClassName: ie }), U = Me({ animated: p }), se = "flex items-center justify-center relative w-full h-full overflow-hidden", [v, A] = P(), [y, O] = P(), [S, j] = P(), D = I(0), k = I(null), _ = I(null), de = Oe([ne, k]);
|
|
407
406
|
return G(() => {
|
|
408
|
-
S && S.current && p && (
|
|
407
|
+
S && S.current && p && (D.current = j.width + Pe[m] + (s ? 0 : ze), k.current && !k.current.style.width && (k.current.style.width = `${R[m]}px`));
|
|
409
408
|
}, [j, S, m, s, p]), G(() => {
|
|
410
409
|
if (k && k.current && p) {
|
|
411
410
|
let N = R[m];
|
|
412
|
-
d && v &&
|
|
411
|
+
d && v && A.width > 0 ? N = A.width + D.current : h && y && O.width > 0 && (N = O.width + D.current), _.current && clearTimeout(_.current), N !== parseInt(k.current.style.width || "0", 10) && (v.current && (v.current.style.opacity = "0"), y.current && (y.current.style.opacity = "0"), k.current.style.width = `${N}px`, N > R[m] && (_.current = setTimeout(() => {
|
|
413
412
|
v.current && d && (v.current.style.opacity = "1"), y.current && h && (y.current.style.opacity = "1"), _.current = null;
|
|
414
|
-
},
|
|
413
|
+
}, $e * 0.8))), N === R[m] && (v.current && (v.current.style.opacity = "0"), y.current && (y.current.style.opacity = "0"));
|
|
415
414
|
}
|
|
416
415
|
}, [
|
|
417
|
-
|
|
416
|
+
A,
|
|
418
417
|
d,
|
|
419
418
|
v,
|
|
420
|
-
|
|
419
|
+
O,
|
|
421
420
|
h,
|
|
422
421
|
y,
|
|
423
422
|
m,
|
|
@@ -476,19 +475,19 @@ const R = {
|
|
|
476
475
|
);
|
|
477
476
|
V.displayName = "ButtonIcon";
|
|
478
477
|
/*!
|
|
479
|
-
@versini/ui-button v6.0.
|
|
478
|
+
@versini/ui-button v6.0.9
|
|
480
479
|
© 2025 gizmette.com
|
|
481
480
|
*/
|
|
482
481
|
try {
|
|
483
482
|
window.__VERSINI_UI_BUTTON__ || (window.__VERSINI_UI_BUTTON__ = {
|
|
484
|
-
version: "6.0.
|
|
485
|
-
buildTime: "
|
|
483
|
+
version: "6.0.9",
|
|
484
|
+
buildTime: "08/04/2025 04:16 AM EDT",
|
|
486
485
|
homepage: "https://github.com/aversini/ui-components",
|
|
487
486
|
license: "MIT"
|
|
488
487
|
});
|
|
489
488
|
} catch {
|
|
490
489
|
}
|
|
491
|
-
const Fe =
|
|
490
|
+
const Fe = $.forwardRef(
|
|
492
491
|
({
|
|
493
492
|
children: e,
|
|
494
493
|
mode: t = "system",
|
|
@@ -688,7 +687,7 @@ const Ye = f.forwardRef(function(e, t) {
|
|
|
688
687
|
try {
|
|
689
688
|
window.__VERSINI_UI_MODAL__ || (window.__VERSINI_UI_MODAL__ = {
|
|
690
689
|
version: "2.0.5",
|
|
691
|
-
buildTime: "
|
|
690
|
+
buildTime: "08/04/2025 04:16 AM EDT",
|
|
692
691
|
homepage: "https://github.com/aversini/ui-components",
|
|
693
692
|
license: "MIT"
|
|
694
693
|
});
|
|
@@ -703,7 +702,7 @@ const C = "panel", M = "messagebox", Xe = ({
|
|
|
703
702
|
main: n("prose prose-lighter flex flex-col bg-surface-medium", {
|
|
704
703
|
"duration-200 ease-out": a,
|
|
705
704
|
[`${H} max-h-full sm:max-h-[95%] min-h-full sm:min-h-[10rem] sm:rounded-lg sm:border-2`]: t === C,
|
|
706
|
-
[`${H} w-full sm:w-[95%] md:max-w-
|
|
705
|
+
[`${H} w-full sm:w-[95%] md:max-w-4xl`]: t === C && !e,
|
|
707
706
|
[`${Y} rounded-lg border-2`]: t === M,
|
|
708
707
|
[`${Y} w-[95%] sm:w-[50%] md:max-w-2xl`]: t === M && !e,
|
|
709
708
|
[`${e}`]: !!e,
|
package/dist/index.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import { MESSAGEBOX_CLASSNAME as o, PANEL_CLASSNAME as E, Panel as
|
|
1
|
+
import { MESSAGEBOX_CLASSNAME as o, PANEL_CLASSNAME as E, Panel as A } from "./components/Panel/Panel.js";
|
|
2
2
|
/*!
|
|
3
|
-
@versini/ui-panel v2.0
|
|
3
|
+
@versini/ui-panel v2.1.0
|
|
4
4
|
© 2025 gizmette.com
|
|
5
5
|
*/
|
|
6
6
|
try {
|
|
7
7
|
window.__VERSINI_UI_PANEL__ || (window.__VERSINI_UI_PANEL__ = {
|
|
8
|
-
version: "2.0
|
|
9
|
-
buildTime: "
|
|
8
|
+
version: "2.1.0",
|
|
9
|
+
buildTime: "08/04/2025 04:16 AM EDT",
|
|
10
10
|
homepage: "https://github.com/aversini/ui-components",
|
|
11
11
|
license: "MIT"
|
|
12
12
|
});
|
|
@@ -15,5 +15,5 @@ try {
|
|
|
15
15
|
export {
|
|
16
16
|
o as MESSAGEBOX_CLASSNAME,
|
|
17
17
|
E as PANEL_CLASSNAME,
|
|
18
|
-
|
|
18
|
+
A as Panel
|
|
19
19
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@versini/ui-panel",
|
|
3
|
-
"version": "2.0
|
|
3
|
+
"version": "2.1.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"author": "Arno Versini",
|
|
6
6
|
"publishConfig": {
|
|
@@ -27,6 +27,7 @@
|
|
|
27
27
|
"dev:types": "tsup --watch src",
|
|
28
28
|
"dev": "npm-run-all clean --parallel dev:js dev:types",
|
|
29
29
|
"lint": "biome lint src",
|
|
30
|
+
"lint:fix": "biome check src --write --no-errors-on-unmatched",
|
|
30
31
|
"prettier": "biome check --write --no-errors-on-unmatched",
|
|
31
32
|
"start": "static-server dist --port 5173",
|
|
32
33
|
"test:coverage:ui": "vitest --coverage --ui",
|
|
@@ -38,9 +39,12 @@
|
|
|
38
39
|
"react": "^18.3.1 || ^19.0.0",
|
|
39
40
|
"react-dom": "^18.3.1 || ^19.0.0"
|
|
40
41
|
},
|
|
42
|
+
"devDependencies": {
|
|
43
|
+
"@testing-library/jest-dom": "6.6.3"
|
|
44
|
+
},
|
|
41
45
|
"dependencies": {
|
|
42
46
|
"@tailwindcss/typography": "0.5.16",
|
|
43
|
-
"@versini/ui-button": "6.0.
|
|
47
|
+
"@versini/ui-button": "6.0.9",
|
|
44
48
|
"@versini/ui-icons": "4.10.0",
|
|
45
49
|
"@versini/ui-modal": "2.0.5",
|
|
46
50
|
"clsx": "2.1.1",
|
|
@@ -49,5 +53,5 @@
|
|
|
49
53
|
"sideEffects": [
|
|
50
54
|
"**/*.css"
|
|
51
55
|
],
|
|
52
|
-
"gitHead": "
|
|
56
|
+
"gitHead": "01e4f01a0a5bc280c14a3dfa5728db1012792c6f"
|
|
53
57
|
}
|